机器人和交互式消息

机器人账号是专为程序创建的用户。它拥有自己的名称、头像和令牌,并且名称旁会显示 BOT 标签。本页还涵盖消息的交互部分:按钮、菜单和对话框,任何集成都可以使用这些功能。

为什么使用机器人账号

  • 其消息来自一个明确的身份,并带有 机器人 标签,而不是来自同事的账号。
  • 即使设置该机器人的人员更改角色或离开,其令牌仍可继续使用(除非服务器禁用了已停用所有者的机器人,见下文)。
  • 机器人无法使用密码登录,也永远不会看到 Web 应用。

应用会通过插件 API(EnsureBotUser)创建自己的机器人,例如待办事项或操作手册机器人。

启用机器人账号

系统管理员在 系统控制台 › 集成 › 机器人账号 中开启 开启机器人账号创建(ServiceSettings.EnableBotAccountCreation,AM_SERVICESETTINGS_ENABLEBOTACCOUNTCREATION)。该选项默认处于关闭状态。除非在权限设置中授予其他角色相应权限,否则只有系统管理员可以创建机器人。

在同一页面中,当拥有者被停用时停用机器人账号(ServiceSettings.DisableBotsWhenOwnerIsDeactivated,默认开启)会在机器人拥有者的账号被停用时将该机器人停用。

创建机器人

  1. 点击右上角的头像,然后选择 集成 › 机器人账号,再选择 添加机器人账号。
  2. 输入 用户名(仅限小写字母、数字、句点、连字符和下划线),以及可选的 机器人图标、显示名称 和 描述。
  3. 选择 角色:成员,或者用于管理服务器的 系统管理员。请赋予机器人所需的最小权限。
  4. 勾选 post:channels 以允许其在所有公共频道中发布消息,或勾选 post:all 以允许其在所有频道(包括私有频道和私信)中发布消息,而无需成为成员。
  5. 设置其默认令牌的过期时间,然后选择 创建机器人账号。
  6. 复制显示的访问令牌。该令牌不会再次显示。

稍后,在机器人的行上选择 创建新令牌 可添加令牌,每个令牌都可以被禁用或删除。即使针对个人关闭了个人访问令牌,机器人令牌仍然有效。

使用 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 接受相同的请求。