注意:本指南假设您在 Discourse 论坛上运营一个经过授权的机器人,可能使用了 用户 API 或 管理员 API 密钥。如果您的机器人被管理员屏蔽,请与他们讨论机器人的用途,切勿试图绕过该屏蔽。
您的机器人是否更适合在服务器上运行?请考虑创建一个插件: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 和 凭证 执行
遵守速率限制的 JSON 获取 的结果。 - 如果 响应 是 HTTP 错误,则中止这些步骤并报错。
- 设 帖子 为 响应 中路径
latest_posts处的 JSON 数组。 - 设 看到新帖子 标志为未设置。
- 对于 帖子 中的每个 JSON 对象 post(按逆序执行),执行以下步骤:
- 设 帖子 ID 为 post 内部路径
id处的 JSON 数字。 - 将 已看到的最高帖子 ID 设置为 帖子 ID。
- 设置 看到新帖子 标志。
发出 post。(
换句话说:将帖子发送给您想要执行的任何自定义处理。)- 如果 发出 返回了背压信号,则中断此循环。
- 设 帖子 ID 为 post 内部路径
-
上述循环按逆序执行,因此您的代码会先看到最旧的帖子,最后看到最新的帖子。 - 如果 看到新帖子 标志已设置:
- 执行
将状态持久化到存储 的步骤,传入 已看到的最高帖子 ID。
- 执行
- 结束这些步骤,返回 已看到的最高帖子 ID。
探测一个较高的现有帖子 ID
要探测一个较高的现有帖子 ID,请执行以下步骤:
- 设 最新探测请求 URI 为 论坛基础 URL 和
/posts.json的拼接。 - 设 最新探测响应 为使用 最新探测请求 URI 和 凭证 执行
遵守速率限制的 JSON 获取 的结果。 - 如果 最新探测响应 是 HTTP 错误,则中止这些步骤并报错。
- 设 探测帖子 为 最新探测响应 中路径
latest posts处的 JSON 数组。 - 对于 探测帖子 中的每个 JSON 对象 post:
- 设 帖子 ID 为 post 内部路径
id处的 JSON 数字。 - 结束这些步骤,返回 帖子 ID。
- 设 帖子 ID 为 post 内部路径
- 中止这些步骤并报错。
从最新状态回填
给定一个可选整数 已看到的最高帖子 ID,要从最新状态回填,请执行以下步骤:
- 设 最小帖子 ID 为如果存在则取 已看到的最高帖子 ID,否则为零 (0)。
- 设 较高现有帖子 ID 为执行 探测一个较高的现有帖子 ID 的结果。
- 如果 最大帖子 ID 是错误,则中止这些步骤并报错。
- 执行 回填 的步骤,传入 最小帖子 ID 和 较高现有帖子 ID。
回填
给定两个整数 最小帖子 ID 和 较高现有帖子 ID,要回填,请执行以下步骤:
- 设 当前最小帖子 ID 为 最小帖子 ID。
- 重复以下步骤:
- 执行 获取下一批近期帖子 的步骤,传入 当前最小帖子 ID 和一个未设置的 由消息总线触发 标志。
- 如果 获取下一批近期帖子 的步骤未成功完成:
- 使用失败信号更新指数退避算法,并等待指定的时间。
- 继续下一次循环迭代(不更新 当前最小帖子 ID)。
- 设 候选最大响应帖子 ID 为将五十 (50) 加到 当前最小帖子 ID 的结果。
- 如果 候选最大响应帖子 ID 大于或等于 较高现有帖子 ID,则
结束这些步骤。 - 将 当前最小帖子 ID 设置为 候选最大响应帖子 ID。
持续监控新帖子
要持续监控新帖子,请执行以下步骤:
- 设 已看到的最高帖子 ID 为一个未设置的可选整数。
- 将 已看到的最高帖子 ID 设置为执行
从存储恢复状态 的结果。 - 如果 已看到的最高帖子 ID 未设置:
- 设 初始帖子 ID 为执行 探测一个较高的现有帖子 ID 的结果。
- 执行
将状态持久化到存储 的步骤,传入 初始帖子 ID。 - 将 已看到的最高帖子 ID 设置为 初始帖子 ID。
- 设 通知 为执行
订阅消息总线 步骤的结果,通道为 /latest。 - 重复执行以下步骤:
- 设 新的已看到的最高帖子 ID 为执行 获取下一批近期帖子 的结果,如果发生了消息总线更新则设置 由消息总线触发 标志,并传入 已看到的最高帖子 ID。
- 如果 获取下一批近期帖子 的步骤未成功完成:
- 使用失败信号更新指数退避算法,并等待指定的时间。
- 继续下一次循环迭代。
- 如果 新的已看到的最高帖子 ID 与 已看到的最高帖子 ID 不同:
- 使用成功信号更新指数退避算法。
- 将 已看到的最高帖子 ID 设置为 新的已看到的最高帖子 ID。
- 等待 通知 上的消息或发生实现定义的超时。此超时不得短于 10 分钟,并且可以合理范围延长至 24 小时或略高。
您需要提供的算法:
遵守速率限制的 JSON 获取,接受请求 URI 和可选凭证。
- 当遇到 429 错误时,这必须自动使用指数退避算法和/或服务器提供的
Retry-After信息进行退避和重试。
- 当遇到 429 错误时,这必须自动使用指数退避算法和/或服务器提供的
从存储恢复状态
将状态持久化到存储,接受一个整数
订阅消息总线