봇 및 대화형 메시지

봇 계정은 프로그램용으로 생성된 사용자입니다. 고유한 이름, 프로필 사진, 토큰을 가지며 이름 옆에 BOT 태그가 표시됩니다. 이 페이지에서는 모든 통합이 사용할 수 있는 메시지의 대화형 요소인 버튼, 메뉴, 다이얼로그도 다룹니다.

봇 계정이 필요한 이유

  • 동료의 계정 대신 명확한 정체성과 BOT 태그가 있는 계정으로 메시지가 전송됩니다.
  • 설치한 사람의 역할이 변경되거나 탈퇴하더라도 토큰은 계속 작동합니다(비활성화된 소유자의 봇을 서버가 비활성화하도록 설정된 경우 제외, 아래 참조).
  • 봇은 비밀번호로 로그인할 수 없으며 웹 앱을 절대 볼 수 없습니다.

애플리케이션은 Todo나 Playbooks 봇과 같이 플러그인 API(EnsureBotUser)를 통해 자체 봇을 생성합니다.

봇 계정 활성화

시스템 관리자가 시스템 콘솔 › 통합 › 봇 계정에서 계정 생성을 활성화합니다(ServiceSettings.EnableBotAccountCreation, AM_SERVICESETTINGS_ENABLEBOTACCOUNTCREATION). 기본적으로 비활성화되어 있습니다. 권한 설정에서 다른 역할에 권한을 부여하지 않는 한, 봇을 만들 수 있는 사람은 시스템 관리자뿐입니다.

같은 페이지의 소유자 비활성화 시 봇 계정 비활성화(ServiceSettings.DisableBotsWhenOwnerIsDeactivated, 기본적으로 활성화됨)는 소유자의 계정이 비활성화되면 해당 봇을 비활성화합니다.

봇 생성

  1. 우측 상단의 아바타를 클릭한 후 통합 › 봇 계정, 그리고 봇 계정 추가를 선택합니다.
  2. 사용자 이름(소문자, 숫자, 마침표, 대시, 밑줄)을 입력하고, 필요에 따라 봇 아이콘, 표시명, 설명을 입력합니다.
  3. 역할을 선택합니다: 멤버 또는 서버를 관리하는 봇의 경우 시스템 관리자. 봇에는 필요한 최소 권한만 부여하세요.
  4. 모든 공개 채널에 게시할 수 있도록 게시물:채널을 선택하거나, 멤버가 아니어도 모든 채널, 비공개 채널, 다이렉트 메시지에 게시할 수 있도록 게시물:모두를 선택합니다.
  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'"}'

게시물:채널 또는 게시물:모두 권한이 있는 봇은 멤버가 아니어도 게시할 수 있지만, 자신이 속한 채널에 대해서만 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, 웹훅 및 슬래시 명령 응답으로 게시된 메시지에서 작동합니다. 누군가 작업을 사용하면 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 또는 16진수 색상.
  • 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입니다.
  • 빈 본문(body)을 반환하면 아무것도 변경되지 않습니다.

서버는 통합 요청 시간 초과(기본값 30초) 허용 범위 내에서 대기합니다. 사설 네트워크 주소의 통합 URL은 웹훅과 마찬가지로 시스템 관리자가 허용해야 합니다.

대화상자(Dialog)

대화상자는 채팅 위에 열리는 양식입니다. 대화상자는 해당 요청의 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"}
      ]
    }
  }'
요소 유형표시 내용
text1줄 필드입니다. subtype: text, email, number, password, tel 또는 url. min_length와 max_length로 길이를 제한할 수 있습니다.
textarea여러 줄 필드입니다.
select목록입니다: options 또는 data_source가 users, channels 또는 data_source_url이 있는 dynamic일 수 있습니다. multiselect를 사용하면 여러 값을 선택할 수 있습니다.
bool체크박스입니다.
radiooptions 중 하나를 선택합니다.
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는 동일한 요청을 사용합니다.