使用 GetStream 实现通知系统

Notifications system implementation with GetStream

我正在尝试使用 GS

实现通知系统

基本上相关的机型有:

在 GS 中有以下提要:

让我简要解释一下提要之间的基本关系:

1) Admin 创建 Entity:

2) User 加入 Organization:

3) User 购买 Entity:

以此类推

所描述模型的问题在于,在第一种情况下,作为 Entity 的创建者的 User 也会通过 Org:$orgId 收到他创建了 Entity 的通知其他 Organization 名成员。与第二种情况相同。

这是通知系统不需要的行为。

理想情况下,我们不应该通知 User 他在 "shared" 提要中的活动,例如 Org:$orgId。问题是——如何实现这一目标?也许 GS 提要应该以不同的方式组织,或者可以通过 Aggregation Format 语法来完成?

已编辑:如我所见,可能的解决方案是:

我不确定这是否是与 GS 一起使用的惯用解决方案。

我认为您的结构可能比您最初设计的更简单,并且更接近您在 post 底部提到的结构。我还建议您通读 http://blog.getstream.io/best-practices-for-instagram-style-feeds/,这听起来与您想在这里做的事情相似。

对于我们的 Feed 类型的简化分类:

  • 通知供稿是为内容创作者准备的(“15 人喜欢你的 post”)。
  • 汇总供稿供关注者使用(“添加了 12 post”)。
  • 平面提要是添加核心活动的好地方("entities" 在你的情况下?),但你也可以使用 [=114= 将这些活动的额外副本保存到其他聚合和通知提要中] activity 模型上的字段,类似于抄送电子邮件

任何 Feed 类型都可以跟随 Flat Feed,但我们通常建议仅 Flat Feed 和聚合 Feed 跟随其他 Flat Feed。通知提要通常是独立的,我将在下面进行描述。

让我们做出以下假设:

  • 有一个名为 "Silverthorne" 的管理员用户,其 ID 为 12
  • 组织 ID 56 是 "Acme Inc"
  • Ian 是 ID 为 74
  • 的普通用户
  • Silverthorne 准备了一些实体内容,当保存到您自己的数据库时,这些内容的 ID 为 63

让我们创建一个名为 org 的平面提要,其中将进行实体活动,并为聚合数据创建一个名为 org_aggregated 的聚合提要,一个名为 notifications 的通知提要,一个平面提要用于用户叫 timeline。如果您的用户可以看到由另一个用户(而不是组织)创作的所有内容的提要,那么我会推荐另一个名为 usercontent.

的平面提要

对于 Silverthorne 到 post this activity 到 GetStream,activity 参与者将是 "user:12",动词可以是 "post",宾语将是成为 "entity:63"

要对此进行伪编码,因为我不知道您使用的是哪个 SDK,将类似于:

# acme inc gets created as an organization, and so its aggregated feed
# should follow the org's flat feed
acme_org_feed = getstreamClient->feed('org', '56')
acme_org_agg_feed = getstreamClient->feed('org_aggregated', '56')
acme_org_agg_feed->follow(acme_org_feed)

此时,添加到 Acme 的 org 平面 Feed 中的每个实体也将被聚合。您可以在 GetStream 仪表板上设置这些信息的汇总方式。

现在,让 Ian 跟随 Acme:

# ian is a member of Acme Inc, so follow their entity feed
ian_feed = getstreamClient->feed('timeline', '74')
ian_feed->follow(acme_org_feed)

如果 Ian 是新注册的,您可以像这样向 Acme 的通知源发送 activity:

acme_notif_feed = getstreamClient->feed('org_notification', '56')
acme_notif_feed->addActivity({
  'actor': 'user:74',
  'verb': 'registration',
  'object': 'user:74'
})

当您稍后检索此通知提要时,它会将所有动词组合在一起,然后分解通知活动,因此您的 UI 可以根据您的选择以不同方式报告这些内容。

现在让 Silverthorne 将该实体添加到 GetStream: # Silverthorne 添加一个 activity 到 Acme Inc 的实体提要 # 我们将 "cc" activity 到聚合提要 acme_org_feed->添加活动({ 'actor': 'user:12', 'verb': 'post', 'object': 'entity:63', 'to': ['usercontent:12'], ...您要跟踪的任何其他元数据 })

保存后,GetStream 将执行以下操作:

  • 它将 activity 存储在 Acme (org:56)
  • org flat feed 中
  • 它将副本保存到 Ian 的时间轴中,因为 user:74 遵循 org:56
  • 的固定提要
  • 它还会从 'To' 字段保存一个副本到 Silverthorne 的提要 (usercontent:12);这完全是可选的
  • 它将副本保存到 Acme (org_aggregated:56) 的聚合提要中,因为聚合提要遵循平面提要

当 Ian 登录时,您的应用程序现在可以显示多个可能的提要和选项,这完全取决于您的应用程序:

  • 如果 Ian 应该看到他所遵循的一切的时间轴,您将获取 timeline:74 提要,其中将包含实体 #63
  • 的副本
  • 如果 Ian 应该看到他关注的所有组织的列表,您可以获取 ian_feed->followed() 以获取 Ian 关注的每个提要的列表
  • 对于 Ian 关注的每个提要,您可以获取该组织的聚合提要供 Ian 查看摘要(即,获取 org_aggregated:56 并且 Ian 可以看到 one new entity added in the past day 如果这是您聚合您的方式的方式内容)

这里的关键是 Ian 没有 关注提要来查看内容,您的应用可以提取任何提要以显示给任何用户。

如果 Ian 'share' 或 'like' Silverthorne post 编辑的那个实体,您将向 'org_notification:56' 提要添加一个新的 activity 'user:74' 作为 Actor,'entity:63' 是宾语,verb 是你想要的任何字符串(最多 20 个字符)。如果您希望您的应用程序查看其他用户如何与组织的 post 交互,您可以获取 org_notification:56 并且所有用户都可以看到 "Ian liked entity 63",或者您的 UI 需要呈现那个。

希望这有助于澄清事情并为您提供一些额外的细节。如果您需要进一步的帮助或想法,请通过电子邮件联系我们的支持团队。

最后一点,我认为我不会 $userId-$orgId ...我们的一些 SDK(即 Rails 和 Django)会自动尝试 'enrich' 数据库中的那些值,因此您需要额外的逻辑来稍后尝试拆分这些值。我们建议使用 UUID 作为 collision-free 标识符,但这完全取决于您的控制。如果一个用户真的可以成为多个组织的一部分,您可以只让该用户 'follow' 组织的提要。