Boty i interaktywne wiadomości

Konto bota to użytkownik przeznaczony dla programu. Posiada własną nazwę, zdjęcie i tokeny, a obok jego nazwy wyświetlana jest etykieta BOT. Ta strona obejmuje również interaktywne elementy wiadomości: przyciski, menu i okna dialogowe, z których może korzystać dowolna integracja.

Dlaczego konto bota

  • Jego wiadomości pochodzą z jasno określonej tożsamości, z etykietą BOT, a nie z konta kolegi z zespołu.
  • Jego tokeny działają nadal, gdy osoba, która je skonfigurowała, zmienia rolę lub opuszcza organizację (chyba że serwer wyłącza boty dezaktywowanych właścicieli, patrz niżej).
  • Boty nie mogą się logować hasłem i nigdy nie mają dostępu do aplikacji webowej.

Aplikacje tworzą własne boty, takie jak boty Do zrobienia lub Playbooków, za pośrednictwem API pluginów (EnsureBotUser).

Włączanie kont botów

Administrator systemu włącza opcję Włącz tworzenie kont dla botów w Konsola systemu › Integracje › Konta botów (ServiceSettings.EnableBotAccountCreation, AM_SERVICESETTINGS_ENABLEBOTACCOUNTCREATION). Domyślnie jest wyłączona. Tylko administratorzy systemu mogą tworzyć boty, chyba że przyznają to uprawnienie innym rolom w ustawieniach uprawnień.

Na tej samej stronie opcja Wyłącz konta botów jeśli właściciel jest dezaktywowany (ServiceSettings.DisableBotsWhenOwnerIsDeactivated, domyślnie włączona) wyłącza bota, gdy konto jego właściciela zostanie dezaktywowane.

Tworzenie bota

  1. Otwórz swój awatar w prawym górnym rogu, następnie przejdź do Integracje › Konta botów, a potem kliknij Dodaj konto bota.
  2. Wpisz Nazwę użytkownika (małe litery, cyfry, kropki, myślniki i podkreślenia) oraz opcjonalnie Ikona bota, Nazwę wyświetlaną i Opis.
  3. Wybierz Rolę: Członek lub Administrator Systemu dla bota zarządzającego serwerem. Przyznaj botowi tylko te uprawnienia, których naprawdę potrzebuje.
  4. Zaznacz wiadomości:kanały, aby bot mógł publikować we wszystkich kanałach publicznych, lub wiadomość:wszystkie, aby mógł publikować we wszystkich kanałach, w tym prywatnych, oraz w wiadomościach bezpośrednich, bez konieczności bycia ich członkiem.
  5. Ustaw datę wygaśnięcia jego domyślnego tokena, a następnie wybierz Stwórz konto bota.
  6. Skopiuj wyświetlany token dostępu. Nie zostanie on ponownie wyświetlony.

Później opcja Utwórz nowy token w wierszu bota dodaje nowy token, a każdy token może zostać wyłączony lub usunięty. Tokeny botów działają nawet wtedy, gdy osobiste tokeny dostępu są wyłączone dla użytkowników.

Za pomocą 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"}'

Z wiersza poleceń, zalogowany jako administrator (nie w trybie lokalnym): amctl bot create deploy-bot --display-name Deploy --with-token --expires-in 90d. Inne punkty końcowe: GET /api/v4/bots, PUT /api/v4/bots/{bot_user_id}, POST /api/v4/bots/{bot_user_id}/disable oraz /enable, a także POST /api/v4/bots/{bot_user_id}/assign/{user_id} w celu zmiany właściciela.

Dodaj bota do społeczności i kanałów

Nowy bot nie należy do żadnej społeczności. Dodaj go tak jak osobę, z poziomu zarządzania członkami społeczności lub za pomocą 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'"}'

Bot z uprawnieniem wiadomości:kanały lub wiadomość:wszystkie może publikować bez bycia członkiem, ale otrzymuje zdarzenia WebSocket tylko dla kanałów, w których się znajduje.

Publikuj jako bot

Użyj tokena bota w dowolnym wywołaniu API; POST /api/v4/posts jest najczęstsze (patrz Główne zasoby). Aby pisać bezpośrednio do kogoś, najpierw otwórz kanał wiadomości bezpośredniej:

# 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'"]'

Aby reagować na to, co mówią ludzie, nasłuchuj WebSocket za pomocą tokena bota i odpowiadaj na zdarzenia posted, które Cię interesują. Ignoruj własne wiadomości bota, aby uniknąć pętli.

Wiadomość widoczna tylko dla jednej osoby (wiadomość tymczasowa) jest wysyłana za pomocą POST /api/v4/posts/ephemeral i {"user_id", "post": {"channel_id", "message"}}. Wymaga uprawnienia create_post_ephemeral, które domyślnie mają tylko administratorzy systemu. Integracje zwykle wysyłają wiadomości tymczasowe jako odpowiedzi na polecenia z ukośnikiem i przyciski.

Wiadomości interaktywne: przyciski i menu

Dowolna wiadomość z załącznikami może zawierać akcje: przyciski oraz menu do wyboru. Działają one w wiadomościach publikowanych za pomocą API, webhooków oraz odpowiedziach na polecenia z ukośnikiem. Gdy ktoś użyje jednej z nich, Antimatter wywołuje URL Twojej integracji.

{
  "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 lub select.
  • id: litery, cyfry, myślniki i podkreślenia, inny dla każdej akcji w wiadomości. Jest generowany, jeśli go pominiesz.
  • style (przyciski): default, primary, success, good, warning, danger lub kolor w formacie szesnastkowym.
  • options (menu) lub data_source: users lub channels, aby wybrać osobę lub kanał. default_option zaznacza wartość domyślnie.
  • integration.url: adres, do którego wysyłane jest kliknięcie. Aplikacja (wtyczka) może użyć własnej trasy, np. /plugins/com.example.deploy/actions. integration.context należy do Ciebie: wraca wraz z kliknięciem, a klienci nigdy go nie widzą.

Żądanie otrzymane przez integrację

{
  "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"}
}

W przypadku menu wartość type to select, a context.selected_option zawiera wybraną wartość.

Twoja odpowiedź

{
  "update": {"message": "Deploy of **api 2.4.0** approved by @priya", "props": {}},
  "ephemeral_text": "Done. The deploy starts in a minute."
}
  • update: zastępuje tekst i właściwości wiadomości, np. aby usunąć przyciski po użyciu (puste props).
  • ephemeral_text: wiadomość widoczna tylko dla osoby, która kliknęła.
  • goto_location: adres URL do otwarcia.
  • Pusta odpowiedź nie zmienia niczego.

Serwer czeka tak długo, jak pozwala na to Limit czasu żądania integracji (domyślnie 30 sekund). Adresy URL integracji w sieci prywatnej muszą zostać dozwolone przez administratora systemu, podobnie jak webhooks.

Okna dialogowe

Okno dialogowe to formularz otwierany nad czatem. Można je otworzyć tylko w odpowiedzi na coś, co osoba właśnie zrobiła, np. polecenie z ukośnikiem lub przycisk, ponieważ wymaga trigger_id z tego żądania. trigger_id jest ważny przez czas trwania limitu czasu żądania integracji.

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"}
      ]
    }
  }'
Typ elementuCo wyświetla
textPole jednolinijkowe. subtype: text, email, number, password, tel lub url. min_length i max_length ograniczają długość.
textareaPole wielolinijkowe.
selectLista: options, lub data_source users, channels, lub dynamic z data_source_url. multiselect pozwala na wiele wartości.
boolPole wyboru (checkbox).
radioJedno z options.
date, datetimeData, lub data i czas.

Każdy element przyjmuje display_name, name, help_text, placeholder, default i optional.

Po wysłaniu formularza Antimatter wysyła żądanie POST do url okna dialogowego:

{
  "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
}

Odpowiedz pustym ciałem, aby zamknąć okno dialogowe, lub zostaw je otwarte i pokaż, co jest nie tak:

{"errors": {"version": "This version already exists."}}

{"error": "…"} wyświetla komunikat dla całego formularza. Przy notify_on_cancel zamknięcie okna dialogowego wysyła "cancelled": true. Okna dialogowe działają tak samo w aplikacjach: OpenInteractiveDialog z API wtyczek przyjmuje to samo żądanie.