机器人和交互式消息
机器人账号是专为程序创建的用户。它拥有自己的名称、头像和令牌,并且名称旁会显示 BOT 标签。本页还涵盖消息的交互部分:按钮、菜单和对话框,任何集成都可以使用这些功能。
为什么使用机器人账号
- 其消息来自一个明确的身份,并带有 机器人 标签,而不是来自同事的账号。
- 即使设置该机器人的人员更改角色或离开,其令牌仍可继续使用(除非服务器禁用了已停用所有者的机器人,见下文)。
- 机器人无法使用密码登录,也永远不会看到 Web 应用。
应用会通过插件 API(EnsureBotUser)创建自己的机器人,例如待办事项或操作手册机器人。
启用机器人账号
系统管理员在 系统控制台 › 集成 › 机器人账号 中开启 开启机器人账号创建(ServiceSettings.EnableBotAccountCreation,AM_SERVICESETTINGS_ENABLEBOTACCOUNTCREATION)。该选项默认处于关闭状态。除非在权限设置中授予其他角色相应权限,否则只有系统管理员可以创建机器人。
在同一页面中,当拥有者被停用时停用机器人账号(ServiceSettings.DisableBotsWhenOwnerIsDeactivated,默认开启)会在机器人拥有者的账号被停用时将该机器人停用。
创建机器人
- 点击右上角的头像,然后选择 集成 › 机器人账号,再选择 添加机器人账号。
- 输入 用户名(仅限小写字母、数字、句点、连字符和下划线),以及可选的 机器人图标、显示名称 和 描述。
- 选择 角色:成员,或者用于管理服务器的 系统管理员。请赋予机器人所需的最小权限。
- 勾选 post:channels 以允许其在所有公共频道中发布消息,或勾选 post:all 以允许其在所有频道(包括私有频道和私信)中发布消息,而无需成为成员。
- 设置其默认令牌的过期时间,然后选择 创建机器人账号。
- 复制显示的访问令牌。该令牌不会再次显示。
稍后,在机器人的行上选择 创建新令牌 可添加令牌,每个令牌都可以被禁用或删除。即使针对个人关闭了个人访问令牌,机器人令牌仍然有效。
使用 API:
# create the bot (you become its owner)
curl -X POST https://chat.example.com/api/v4/bots \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"username": "deploy-bot", "display_name": "Deploy", "description": "Posts deployments"}'
# give it a token
curl -X POST https://chat.example.com/api/v4/users/$BOT_USER_ID/tokens \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"description": "deploy pipeline"}'
在命令行中,以管理员身份登录(非本地模式):amctl bot create deploy-bot --display-name Deploy --with-token --expires-in 90d。其他端点:GET /api/v4/bots、PUT /api/v4/bots/{bot_user_id}、POST /api/v4/bots/{bot_user_id}/disable 和 /enable,以及 POST /api/v4/bots/{bot_user_id}/assign/{user_id} 用于更改其所有者。
将机器人添加到社区和频道
新建的机器人不属于任何社区。请像添加人员一样将其添加,可通过社区的成员管理或 API 操作:
curl -X POST https://chat.example.com/api/v4/teams/$TEAM_ID/members \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"team_id": "'$TEAM_ID'", "user_id": "'$BOT_USER_ID'"}'
curl -X POST https://chat.example.com/api/v4/channels/$CHANNEL_ID/members \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"user_id": "'$BOT_USER_ID'"}'
拥有 post:channels 或 post:all 权限的机器人无需成为成员即可发布消息,但它只会接收其所在频道的 WebSocket 事件。
以机器人身份发布
在任何 API 调用中使用机器人的令牌;POST /api/v4/posts 是最常用的(参见 主要资源)。若要直接向某人发送消息,请先打开私信频道:
# returns the channel; use its "id" as channel_id
curl -X POST https://chat.example.com/api/v4/channels/direct \
-H "Authorization: Bearer $BOT_TOKEN" -H 'Content-Type: application/json' \
-d '["'$BOT_USER_ID'", "'$USER_ID'"]'
若要回应他人的发言,请使用机器人的令牌连接 WebSocket,并处理您关心的 posted 事件。请忽略机器人自身的消息以避免循环。
仅一人可见的消息(临时消息)通过 POST /api/v4/posts/ephemeral 发送,参数为 {"user_id", "post": {"channel_id", "message"}}。这需要 create_post_ephemeral 权限,默认仅系统管理员拥有。集成通常将临时消息作为对斜杠命令和按钮的回复发送。
交互式消息:按钮和菜单
任何带有附件的消息都可以包含操作:按钮和供选择的菜单。它们适用于通过 API、Webhook 和斜杠命令回复发布的消息。当有人使用这些操作时,Antimatter 会调用您的集成 URL。
{
"channel_id": "…",
"message": "Deploy **api 2.4.0** to production?",
"props": {
"attachments": [{
"actions": [
{
"id": "approve",
"type": "button",
"name": "Approve",
"style": "primary",
"integration": {"url": "https://deploy.example.com/actions", "context": {"release": "2.4.0", "action": "approve"}}
},
{
"id": "env",
"type": "select",
"name": "Pick an environment",
"options": [{"text": "Staging", "value": "staging"}, {"text": "Production", "value": "production"}],
"integration": {"url": "https://deploy.example.com/actions", "context": {"release": "2.4.0", "action": "env"}}
}
]
}]
}
}
type:button或select。id:字母、数字、连字符和下划线,消息中的每个操作需唯一。如果省略,系统会自动生成。style(按钮):default、primary、success、good、warning、danger,或十六进制颜色值。options(菜单),或data_source:users或channels,用于选择人员或频道。default_option用于预选值。integration.url:点击事件发送到的地址。应用(插件)可以使用自己的路由,例如/plugins/com.example.deploy/actions。integration.context由您自定义:它会随点击事件一起返回,客户端不会看到它。
您的集成接收到的请求
{
"user_id": "…",
"user_name": "priya",
"channel_id": "…",
"channel_name": "releases",
"team_id": "…",
"team_domain": "lumen-labs",
"post_id": "…",
"trigger_id": "…",
"type": "button",
"context": {"release": "2.4.0", "action": "approve"}
}
对于菜单,type 为 select,context.selected_option 包含所选的值。
您的响应
{
"update": {"message": "Deploy of **api 2.4.0** approved by @priya", "props": {}},
"ephemeral_text": "Done. The deploy starts in a minute."
}
update:替换消息的文本和属性,例如在按钮使用过后移除它们(使用空的props)。ephemeral_text:仅点击者可见的消息。goto_location:要打开的 URL。- 空响应体表示不更改任何内容。
服务器会等待,直到达到集成请求超时限制(默认为 30 秒)。位于私有网络地址的集成 URL 必须由系统管理员允许,这与 Webhook 的要求相同。
对话框
对话框是覆盖在聊天界面上的表单。您只能在响应用户刚刚执行的操作(如斜杠命令或按钮点击)时打开它,因为这需要该请求的 trigger_id。trigger_id 的有效时长与集成请求超时时间相同。
curl -X POST https://chat.example.com/api/v4/actions/dialogs/open \
-H 'Content-Type: application/json' \
-d '{
"trigger_id": "'$TRIGGER_ID'",
"url": "https://deploy.example.com/dialog",
"dialog": {
"callback_id": "new-release",
"title": "New release",
"introduction_text": "Fill in the release details.",
"submit_label": "Create",
"notify_on_cancel": false,
"state": "anything you want back",
"elements": [
{"display_name": "Version", "name": "version", "type": "text", "placeholder": "2.4.0"},
{"display_name": "Notes", "name": "notes", "type": "textarea", "optional": true},
{"display_name": "Environment", "name": "env", "type": "select",
"options": [{"text": "Staging", "value": "staging"}, {"text": "Production", "value": "production"}]},
{"display_name": "Owner", "name": "owner", "type": "select", "data_source": "users"},
{"display_name": "Notify the channel", "name": "notify", "type": "bool", "default": "true"}
]
}
}'
| 元素类型 | 显示内容 |
|---|---|
text | 单行字段。subtype 可以是:text、email、number、password、tel 或 url。min_length 和 max_length 用于限制长度。 |
textarea | 多行字段。 |
select | 列表:可以是 options,或者是 data_source 为 users、channels 或 dynamic(配合 data_source_url 使用)。multiselect 允许选择多个值。 |
bool | 复选框。 |
radio | 从 options 中选择一个选项。 |
date, datetime | 日期,或日期和时间。 |
每个元素都接受 display_name、name、help_text、placeholder、default 和 optional。
当用户提交时,Antimatter 会向对话框的 url 发送 POST 请求:
{
"type": "dialog_submission",
"callback_id": "new-release",
"state": "anything you want back",
"user_id": "…",
"channel_id": "…",
"team_id": "…",
"submission": {"version": "2.4.0", "notes": "", "env": "staging", "owner": "…", "notify": true},
"cancelled": false
}
返回空响应体以关闭对话框,或者保持对话框打开并显示错误信息:
{"errors": {"version": "This version already exists."}}
{"error": "…"} 显示针对整个表单的消息。如果设置了 notify_on_cancel,关闭对话框时会发送 "cancelled": true。对话框在应用中的工作方式相同:插件 API 的 OpenInteractiveDialog 接受相同的请求。