Команди с наклонена черта

Персонализирана команда с наклонена черта позволява на хората да въведат /something в полето за съобщение, за да повикат вашия сервис. Antimatter изпраща командата към вашия URL и показва вашия отговор, или само на съответното лице, или на целия канал.

Как работи команда с наклонена черта

  1. Някой въвежда /weather Paris и я изпраща. Текстът не се публикува.
  2. Antimatter изпраща HTTP заявка към URL-а на командата, съдържаща кой я е въвел, къде и текста след тригъра.
  3. Вашият сервис отговаря в рамките на таймаута на заявката (30 секунди по подразбиране) с съобщение.
  4. Antimatter показва отговора: само на това лице (ефемерен) или в канала за всички.

Командите принадлежат на общност, а тригърната дума е уникална в рамките на нея. Вградените команди като /join, /msg или /away не могат да бъдат заменени. Приложенията (плъгини) също могат да регистрират команди; вижте Сървърната част.

Създаване на команда

Персонализираните / команди са активни по подразбиране (Активиране на персонализираните / команди в Системна конзола › Интеграции › Управление на интеграциите, ServiceSettings.EnableCommands). Администраторите на общността и системните администратори могат по подразбиране да ги създават.

  1. Отворете менюто на екипа, след това Настройки на екипа, кликнете върху Интеграции в края на разделите, след това върху Команди с наклонена черта и Добавете / команда.
  2. Попълнете Заглавие и Описание (показват се на страниците за интеграции).
  3. Въведете Задействаща дума на команда, без наклонена черта и без интервали, например weather.
  4. Въведете URL адрес на заявка и изберете Метод на заявка: POST (по подразбиране) или GET.
  5. По желание задайте Потребителско име на отговора и Иконка на отговора. Те се използват само когато сървърът позволява на интеграциите да замянят имената и иконките (вижте Име и иконка).
  6. Отметнете Автодовършване, за да се показва командата, когато хората въвеждат /, с Подсказка за автодовършване (аргументите ѝ, например [city]) и Описание за автодовършване.
  7. Изберете Запиши и копирайте показвания токен. Услугата ви го използва, за да проверява, че заявките идват от вашия сървър.

Чрез API: POST /api/v4/commands с {"team_id", "trigger", "url", "method": "P", "display_name", "description", "auto_complete": true, "auto_complete_hint", "auto_complete_desc", "username", "icon_url"}. Методът е P за POST или G за GET. PUT /api/v4/commands/{command_id}/regen_token издава нов токен.

Заявката, която услугата ви получава

Команда от тип POST изпраща тяло, кодирано като форма (application/x-www-form-urlencoded); команда от тип GET изпраща същите полета в строка за запитване. Токенът се намира и в заглавието Authorization: Token <token>.

ПолеСтойност
tokenТокенът на командата. Проверявайте го при всяка заявка.
commandТригърът с наклонената черта, например /weather.
textВсичко след тригъра, например Paris.
user_id, user_nameКой я е изпълнил.
channel_id, channel_nameКъде е била изпълнена.
team_id, team_domainИдентификаторът и URL името на общността.
root_idНишката, ако е била изпълнена в кутията за отговор в нишка.
trigger_idПозволява отговорът да отвори диалог (вижте Диалози). Валиден е само за кратко време.
response_urlURL, чрез който по-късно могат да се публикуват допълнителни отговори (вижте Отложени отговори).
user_mentions, user_mentions_ids, channel_mentions, channel_mentions_idsЛичности и публични канали, споменати в текста, ако има такива. Каналите се отчитат независимо дали са записани като #channel-name или ~channel-name.
Трябва да е зададен URL адрес на сайта на сървъра, за да могат персонализираните команди да се изпълняват: Antimatter изгражда response_url от него.

Отговорът

Отговорете с 200 и JSON (Content-Type: application/json):

{
  "response_type": "in_channel",
  "text": "Paris: 18 °C, light rain",
  "attachments": []
}
ПолеЗначение
response_typeephemeral (по подразбиране): само лицето, което е изпълнило командата, вижда отговора, и той не се запазва след презареждане. in_channel: отговорът се публикува в канала.
text, attachmentsСъобщението, както при webhook-ове: Markdown текст и прикачени файлове, включително бутони и менюта.
username, icon_urlИмето и изображението, които да се показват, когато са разрешени замяни. Собствените настройки на командата имат предимство пред тях.
channel_idПубликуване на отговора в друг канал, чийто член трябва да бъде лицето.
goto_locationURL, който да се отвори след изпълнението на командата.
props, typeДопълнителни свойства и тип публикация по избор, както при webhook-ите. Отговорът, публикуван във форумен канал, изисква props.am_thread_title, в противен случай е отказан.
extra_responsesДопълнителни отговори, всеки със същите полета, публикувани след първия.
skip_slack_parsingtrue запазва текста такъв, какъвто е, без да конвертира връзки и споменавания в стил Slack.

Отговор, който не е JSON, се показва като ефемерно съобщение с тялото като негов текст. 204 No Content не показва нищо. Всеки статус извън обхвата 200–299 показва грешка на лицето.

Примерна услуга

Минимална услуга за команди на Python, използваща само стандартната библиотека:

import hmac
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import parse_qs

TOKEN = "the token shown when you saved the command"

class Handler(BaseHTTPRequestHandler):
    def do_POST(self):
        body = self.rfile.read(int(self.headers["Content-Length"])).decode()
        form = {key: values[0] for key, values in parse_qs(body).items()}
        if not hmac.compare_digest(form.get("token", ""), TOKEN):
            self.send_response(401)
            self.end_headers()
            return
        answer = {
            "response_type": "ephemeral",
            "text": f"Hello @{form['user_name']}, you asked for: {form.get('text', '')}",
        }
        data = json.dumps(answer).encode()
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.end_headers()
        self.wfile.write(data)

HTTPServer(("0.0.0.0", 8080), Handler).serve_forever()

Ако услугата се изпълнява на частен мрежов адрес, системният администратор трябва да я разреши в Разрешаване на ненадеждни вътрешни връзки към (ServiceSettings.AllowedUntrustedInternalConnections).

Отложено отговаряне

За работа, която отнема повече време от зададеното ограничение, отговорете веднага (например с ефемерно „Работя върху това…“), а след това изпратете истинския отговор чрез POST към response_url. Използва се същия JSON като за отговора и е валидно до 5 пъти в рамките на 30 минути след командата.

curl -X POST "$RESPONSE_URL" -H 'Content-Type: application/json' \
  -d '{"response_type": "in_channel", "text": "Report ready: https://reports.example.com/42"}'

Изпълнение на команда чрез API

Скриптове и ботове могат да изпълняват всяка команда, вградена или персонализирана, сякаш са я въвели ръчно:

curl -X POST https://chat.example.com/api/v4/commands/execute \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"channel_id": "'$CHANNEL_ID'", "command": "/weather Paris"}'

GET /api/v4/teams/{team_id}/commands/autocomplete изрежда командите, които потребителите могат да завършат автоматично в общност.

Автоматично завършване

Командите, създадени на страниците за интеграции, се завършват автоматично с техните тригер, подсказка и описание. Командите, регистрирани от приложения, могат да опишат подробно подкомандите и аргументите си чрез AutocompleteData, от model.NewAutocompleteData(trigger, hint, helpText):

  • AddCommand(sub) добавя подкоманда, която сама е AutocompleteData.
  • AddTextArgument(helpText, hint, pattern) добавя свободен текст.
  • AddStaticListArgument(helpText, required, items) предлага фиксиран списък от AutocompleteListItem{Item, Hint, HelpText}.
  • AddDynamicListArgument(helpText, url, required) изисква от вашето приложение предложения, докато потребителите въвеждат текст. URL-ът е маршрут на вашето приложение, например /plugins/com.example.weather/cities. Той получава потребителя, канала и общността и връща JSON списък от {"Item", "Hint", "HelpText"}.

Вариантите Named… (AddNamedTextArgument и други) добавят флагове --name value. И двата уеб интерфейса показват тези предложения. Стойност с интервали може да бъде поставена в кавички, за да се автозавърши като един аргумент, например --name "my remote": двойните кавички работят за всяка команда, а собствените команди на Antimatter, които приемат флагове, също приемат единични или фигуративни кавички.

Докато някой въвежда команда, Fusion показва командата и всеки от аргументите ѝ като блок, като текущият аргумент е подчертан заедно с текста за помощ. Аргументите идват от AutocompleteData или, ако няма такъв, от подсказката: в подсказка като @[username]... #[channel], думите, започващи с @, отиват към аргумента за личности, а думите, започващи с #, към аргумента за канали, независимо от реда им; ... означава, че аргументът се повтаря, а последният аргумент поема останалата част от текста.

Канали в аргументи

В аргументите на команда @ предлага личности, # предлага канали и ги завършва като #channel-name, а ~ ги завършва като ~channel-name. Уеб интерфейсът и мобилното приложение на Antimatter записват линкове към канали с #, така че команда, която приема канал, трябва да приема и двете форми: вградените /join, /mute и /invite го правят, а техните подсказки гласят #[channel].