burke
(Burke)
1
有没有可能让 user_badge Webhook 在返回 user_id 的同时也包含 username?目前 user_badge 事件的负载(payload)看起来是这样的:
{
"user_badge": {
"id": 123456,
"granted_at": "2026-09-25T14:54:42.073Z",
"created_at": "2026-09-26T05:34:12.965Z",
"post_id": 234567,
"post_number": 1,
"badge_id": 123,
"user_id": 456,
"granted_by_id": -1,
"topic_id": 56789
}
}
要获取 user_id(以及如果不是 -1 的 granted_by_id)对应的用户名,需要额外调用 /admin/users/{user_id}.json。据我了解,这不仅需要额外的请求,还需要管理员权限。
有没有办法在使用 API 密钥的情况下,无需管理员权限即可根据给定的 user_id 获取 username?
我正在开发一个外部服务,希望能在特定徽章被授予时触发该服务;然而,该服务需要用户名,而徽章 Webhook 只返回用户 ID。
putty
(putty)
2
仅供参考,对于非标准 Webhook 或需要额外数据的情况,我的变通方法是先通过 Workflows 进行处理,然后再将结果发送到 n8n。
顺便提一下,从用户 ID 获取用户名只需要一次 API 调用。除非你瞬间手动授予成千上万个徽章,否则默认的 API 限制应该完全够用。
burke
(Burke)
5
听到这个消息太好了!你能否提供一下那个 API 调用的详细信息?它显然不是 /admin/users/{user_id}.json(该接口需要管理员权限)。我没能找到一个可以使用 API 密钥且不需要管理员权限来完成此操作的端点。
管理员 API 密钥有什么问题?这应该是个后台任务吧?
burke
(Burke)
7
最小权限原则。这个外部服务将运行在另一台服务器上,只需要对 Discourse 的只读访问权限即可完成其工作。在基础设施中流传的主密钥越少越好。
这就引出了一个有趣的问题:如果未选择 login_required,为什么没有提供一个面向公众的端点,通过用户 ID 获取仅显示公开字段的用户信息呢?这难道不是很有用吗?我很好奇为什么没有这样做。或者也许只有登录用户才能享有这种权限,但无论如何,应该有一种方式可以访问它,而不必使用管理端点……
@burke 一个更繁琐的变通方法是查看 /groups/trust_level_0/members.json(或任何更具体的组),并通过其 ID 找到该用户,因为其中也包含用户名。
这是因为在 Discourse 中,用户 ID 本质上是一种内部约定,适用于所有场景和目的。我们被期望依赖用户名,因为用户名在各个方面都更为突出。
RGJ
(Richard - Communiteq)
10
这就回到了最初的需求。Webhook 应遵循该概念,发送用户名,而不是用户 ID。
burke
(Burke)
11
同意!这似乎是最好的解决方案。添加 username 和 granted_by_username,并弃用 user_id 和 granted_by_id,可以实现一个非破坏性的过渡期。
目前,如果徽章由系统更改(即自动更改),Webhook 会返回 granted_by_id 为 -1。那么 granted_by_username 的等效值是什么?
""(空字符串)
"<system>"(一个不可能作为用户名的魔法值)
null
- 无——即,如果是系统驱动的事件,则从有效负载中省略
granted_by_username
我认为 null 或“无”是最合理的。
RGJ
(Richard - Communiteq)
12
实际上,-1 是一个有效的用户 ID,它关联着一个用户名(通常是 system),就像其他任何用户一样。没有理由将其区别对待。
参见 meta 站点:https://meta.discourse.org/u/system/summary
burke
(Burke)
13
哦,谢谢你的科普。那么,对于自动化的更改,granted_by_username 应该就只是 "system" 了。
burke
(Burke)
14
@putty 我一直在研究 Workflows。在徽章事件包含用户名之前(或者即使不包含,因为我可以利用 Workflows 中的过滤器,只向我服务需要感知的更改发送 POST 请求),这看起来是一个极好的替代方案!再次感谢!
在使用 Webhook 时,有一个 X-Discourse-Event-Signature 请求头,它使用密钥对有效负载进行 HMAC-SHA256 签名,从而允许我验证发送者。请问有没有办法对来自 Workflows 的 HTTP 请求(POST)进行签名?也许只是我还没找到。我曾希望有一个类似“使用密钥签名请求”的设置,可以开启并提供密钥。我目前看到的最接近的方法是添加一个 header_auth 凭据,以便在请求头中发送密钥(例如 X-Discourse-Event-Secret: Discourse Rocks!)。这总比什么都没有好,但使用密钥进行签名(而不是直接发送密钥本身)会更理想。
putty
(putty)
15
不幸的是,我也依赖通过请求头来传递密钥。也许 @j.jaffeux 能建议一个更好的替代方案,我会立即采用 