通过API创建通知

您好,有个小问题:能否通过 API 向用户发送通知(或其他方式)?
在文档中,我找到了如何获取用户通知、如何将其标记为已读,但没有找到如何 POST 发送通知。如果无法实现,我想或许可以使用私信作为替代方案。
非常期待您的反馈。谢谢。

2 个赞

我认为这需要借助插件。您希望收到哪种类型的通知?能否描述一下您的使用场景?

2 个赞

通常的做法是用 Discourse 的通知替换来自外部服务的电子邮件通知。该服务将免费提供给会员(*)。这将有助于将所有内容集中到 Discourse 平台,并激励用户定期登录论坛。这就是我最初的想法。我不确定这个想法是否合理,或者推理过程中是否存在漏洞。欢迎提出任何建议或批评。

(*):会员指论坛参与者,至少包括已注册论坛的用户。至于是否需要达到最低参与度或信任等级,还是仅注册即可,还有待确定。

该插件会接收信息并在 Discourse 中触发通知吗?通知功能是否可以通过插件更轻松地实现?

2 个赞

我可以想象有一个插件可以添加一个路由,允许你推送包含用户ID(或电子邮件地址)、URL 和标题的负载来创建通知。我认为如果没有插件就无法实现这一点,但我还没有仔细查看相关代码。

我直到昨天才开始考虑为我正在开发的插件添加通知功能,因此我对它的工作原理还不太熟悉。

3 个赞

我本人也在计划开发一个类似的插件,将我的网站非邮件通知以 Discourse 为核心,然后通过 MessageBus 进行订阅,并实现统一的推送通知配置。

我计划的是提供一个自定义端点来创建自定义通知。在查看了这些代码片段后,我认为这是可行的。

创建自定义通知的参考:

自定义通知项在通知列表中显示方式的参考:
https://github.com/discourse/discourse-code-review/blob/master/assets/javascripts/discourse/widgets/code-review-commit-approved-notification-item.js.es6

如果存在用于创建通知的核心 API,我认为这个通知项组件完全可以通过主题组件来实现,那样会更加简单。

4 个赞

我不确定这样做可能会变得多么复杂,但直接将通知创建功能添加到 API 中是否更合理呢?也许团队会愿意这样做,或者愿意接受 PR(如果有人有能力且愿意完成这项工作)?

2 个赞

目前尚未有文档说明,但存在一个 创建通知 API 端点

 POST /notifications(.:format) notifications#create {:format=>/(json|html|\*\//)/}

您可能可以直接使用 custom 通知类型,而无需自行创建。

5 个赞

太棒了!谢谢。

那么,如果我理解正确的话,针对该端点,如果需要覆盖 DefaultNotificationItem,是否仍然需要一个插件来注册额外的通知类型,以便在自定义小部件中使用?

Notification.types[:following] = 800

(来自 discourse-follow/plugin.rb at main · discourse/discourse-follow · GitHub

使用 custom 类型时,它将通过 https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/widgets/custom-notification-item.js 进行渲染。因此,如果要覆盖目标 url,是否仍然需要一个自定义小部件?

我看到有一个插件在类似场景中覆盖了 custom-notification-itemclothing-deals/assets/javascripts/discourse/app/widgets/custom-notification-item.js.es6 at master · Borasification/clothing-deals · GitHub data 中有特定内容时,直接覆盖 url 并在其他情况下回退到 this._super.url 这样做安全吗?

2 个赞

谢谢,@renato

这是我目前得到的结果。

Notification.create!(
  notification_type: Notification.types[:custom],
  user_id: 1,
  topic_id: nil,
  post_number: nil,
  high_priority: true,
  data: {
    message: 'pfaffmanager.title',
    display_username: 'pfaffman',
    topic_title: 'my title'
  }.to_json
)

我确实看到了通知,但不出所料(编辑:),点击后什么也没发生。另外(直到我操作后才意识到,这对我来说并不明显),message 是一个 I18n 键,而不是任意字符串…… 我希望能够传入调用该通知的模型的 URL。

2 个赞

我想你的意思是“没有任何反应”吧?
如果你能点击它并被重定向到通过 API 加入的 URL,那确实太棒了。

2 个赞

DefaultNotificationItem 会在你填写 data.badge_idtopic_iddata.group_id 时自动生成一个 url

我测试过这种方法,它是可行的。只需填写 data.url,并在主题组件中使用以下代码:

  api.reopenWidget("custom-notification-item", {
      url(data) {
          return data.url || this._super(data);
      }
  })
4 个赞

我无法使其正常工作……

POST https://XXX/notifications
Api-Key:XXX
Api-Username:system
Content-Type:application/json
Accept:application/json

{
    "notification_type":9,
    "user_id": 123,
    "post_number": 1,
    "topic_id": 956,
    "data": {
        "topic_title": "Test",
        "original_post_id": 2222,
        "original_post_type": 1,
        "original_username": "User.Name",
        "revision_number": 1,
        "display_username": "Text"
            }

}

我收到的响应是:


{
  "errors": [
    "Data can't be blank"
  ],
  "error_type": "record_invalid"
}

格式错误,还是我理解错了?或者我在 data 中遗漏了什么?

我无法从网络上逆向工程出这个——或者这个 API 在别处被调用了吗?

1 个赞

您需要对 data 值进行编码。

例如:

"data": "{\"topic_title\":\"Test\",\"original_post_id\":2222,\"original_post_type\":1,\"original_username\":\"User.Name\",\"revision_number\":1,\"display_username\":\"Text\"}"
4 个赞