机器人作者提示:处理每个帖子

:information_source: 注意:本指南假设您在 Discourse 论坛上运营一个经过授权的机器人,可能使用了 用户 API管理员 API 密钥。如果您的机器人被管理员屏蔽,请与他们讨论机器人的用途,切勿试图绕过该屏蔽。

:information_source: 您的机器人是否更适合在服务器上运行?请考虑创建一个插件:Developing Discourse Plugins - Part 1 - Create a basic plugin

简介

本指南将展示一种算法,使机器人用户能够检查并处理其在 Discourse 论坛上有权访问的所有帖子(私人消息除外)。

您需要持久化存储一个整数,即已成功处理的最高帖子 ID。例如,您可以将其写入 Redis 或纯文本文件中。使用 Redis 将允许您在进程重启后持久化消息总线订阅。

强烈建议为机器人创建一个全新的用户账号,以便根据需要将其添加到群组或进行私人消息通信。请勿使用 @system 账号。

以下算法集模仿了 WHATWG 规范的风格编写,并逐步构建出用于持续监控新帖子的算法。

算法规范

论坛基础 URL为不带尾部斜杠的网站 URL,例如 https://meta.discourse.org,或对于子文件夹安装,例如 https://www.contoso.com/forum

获取下一批近期帖子

给定一个整数 已看到的最高帖子 ID 和一个标志 由消息总线触发,要获取下一批近期帖子,请执行以下步骤:

  • 最大响应帖子 ID 为将五十 (50) 加到 已看到的最高帖子 ID 的结果。
  • 请求 URI论坛基础 URL/posts.json?before= 以及 最大响应帖子 ID 的拼接。
  • 响应 为使用 请求 URI凭证 执行 :satellite: 遵守速率限制的 JSON 获取 的结果。
  • 如果 响应 是 HTTP 错误,则中止这些步骤并报错。
  • 帖子响应 中路径 latest_posts 处的 JSON 数组。
  • 看到新帖子 标志为未设置。
  • 对于 帖子 中的每个 JSON 对象 post(按逆序执行),执行以下步骤:
    • 帖子 IDpost 内部路径 id 处的 JSON 数字。
    • 已看到的最高帖子 ID 设置为 帖子 ID
    • 设置 看到新帖子 标志。
    • :white_check_mark: 发出 post。(:information_source: 换句话说:将帖子发送给您想要执行的任何自定义处理。)
    • 如果 发出 返回了背压信号,则中断此循环。
  • :information_source: 上述循环按逆序执行,因此您的代码会先看到最旧的帖子,最后看到最新的帖子。

  • 如果 看到新帖子 标志已设置:
    • 执行 :floppy_disk: 将状态持久化到存储 的步骤,传入 已看到的最高帖子 ID
  • 结束这些步骤,返回 已看到的最高帖子 ID

探测一个较高的现有帖子 ID

探测一个较高的现有帖子 ID,请执行以下步骤:

  • 最新探测请求 URI论坛基础 URL/posts.json 的拼接。
  • 最新探测响应 为使用 最新探测请求 URI凭证 执行 :satellite: 遵守速率限制的 JSON 获取 的结果。
  • 如果 最新探测响应 是 HTTP 错误,则中止这些步骤并报错。
  • 探测帖子最新探测响应 中路径 latest posts 处的 JSON 数组。
  • 对于 探测帖子 中的每个 JSON 对象 post
    • 帖子 IDpost 内部路径 id 处的 JSON 数字。
    • 结束这些步骤,返回 帖子 ID
  • 中止这些步骤并报错。

从最新状态回填

给定一个可选整数 已看到的最高帖子 ID,要从最新状态回填,请执行以下步骤:

  • 最小帖子 ID 为如果存在则取 已看到的最高帖子 ID,否则为零 (0)。
  • 较高现有帖子 ID 为执行 探测一个较高的现有帖子 ID 的结果。
  • 如果 最大帖子 ID 是错误,则中止这些步骤并报错。
  • 执行 回填 的步骤,传入 最小帖子 ID较高现有帖子 ID

回填

给定两个整数 最小帖子 ID较高现有帖子 ID,要回填,请执行以下步骤:

  • 当前最小帖子 ID最小帖子 ID
  • 重复以下步骤:
    • 执行 获取下一批近期帖子 的步骤,传入 当前最小帖子 ID 和一个未设置的 由消息总线触发 标志。
    • 如果 获取下一批近期帖子 的步骤未成功完成:
      • 使用失败信号更新指数退避算法,并等待指定的时间。
      • 继续下一次循环迭代(不更新 当前最小帖子 ID)。
    • 候选最大响应帖子 ID 为将五十 (50) 加到 当前最小帖子 ID 的结果。
    • 如果 候选最大响应帖子 ID 大于或等于 较高现有帖子 ID,则 :white_check_mark: 结束这些步骤。
    • 当前最小帖子 ID 设置为 候选最大响应帖子 ID

持续监控新帖子

持续监控新帖子,请执行以下步骤:

  • 已看到的最高帖子 ID 为一个未设置的可选整数。
  • 已看到的最高帖子 ID 设置为执行 :arrow_forward: 从存储恢复状态 的结果。
  • 如果 已看到的最高帖子 ID 未设置:
    • 初始帖子 ID 为执行 探测一个较高的现有帖子 ID 的结果。
    • 执行 :floppy_disk: 将状态持久化到存储 的步骤,传入 初始帖子 ID
    • 已看到的最高帖子 ID 设置为 初始帖子 ID
  • 通知 为执行 :satellite: 订阅消息总线 步骤的结果,通道为 /latest
  • 重复执行以下步骤:
    • 新的已看到的最高帖子 ID 为执行 获取下一批近期帖子 的结果,如果发生了消息总线更新则设置 由消息总线触发 标志,并传入 已看到的最高帖子 ID
    • 如果 获取下一批近期帖子 的步骤未成功完成:
      • 使用失败信号更新指数退避算法,并等待指定的时间。
      • 继续下一次循环迭代。
    • 如果 新的已看到的最高帖子 ID已看到的最高帖子 ID 不同:
      • 使用成功信号更新指数退避算法。
      • 已看到的最高帖子 ID 设置为 新的已看到的最高帖子 ID
    • 等待 通知 上的消息或发生实现定义的超时。此超时不得短于 10 分钟,并且可以合理范围延长至 24 小时或略高。

您需要提供的算法:

  • :satellite: 遵守速率限制的 JSON 获取,接受请求 URI 和可选凭证。
    • 当遇到 429 错误时,这必须自动使用指数退避算法和/或服务器提供的 Retry-After 信息进行退避和重试。
  • :arrow_forward: 从存储恢复状态
  • :floppy_disk: 将状态持久化到存储,接受一个整数
  • :satellite: 订阅消息总线

14 个赞