Polecenia z ukośnikiem

Niestandardowe polecenie z ukośnikiem pozwala użytkownikom wpisać /coś w polu wiadomości, aby wywołać Twoją usługę. Antimatter przesyła polecenie na Twój adres URL i wyświetla odpowiedź – wyłącznie dla danej osoby lub dla całego kanału.

Jak działa polecenie z ukośnikiem

  1. Ktoś wpisuje /weather Paris i wysyła. Tekst nie jest publikowany.
  2. Antimatter wysyła żądanie HTTP na adres URL polecenia, zawierając dane o tym, kto je wpisał, gdzie oraz tekst po słowie wyzwalającym.
  3. Twoja usługa odpowiada w ramach limitu czasu żądania (domyślnie 30 sekund) wiadomością.
  4. Antimatter wyświetla odpowiedź: tylko dla tej osoby (tymczasowo) lub w kanale dla wszystkich.

Polecenia należą do społeczności, a słowo wyzwalające jest w niej unikalne. Wbudowane polecenia, takie jak /join, /msg lub /away, nie mogą zostać zastąpione. Aplikacje (wtyczki) również mogą rejestrować polecenia; zobacz Część serwerowa.

Utworzenie polecenia

Niestandardowe polecenia z ukośnikiem są domyślnie włączone (Włącz Niestandardowe Polecenia z Ukośnikiem w Konsola systemu › Integracje › Zarządzanie Integracjami, ServiceSettings.EnableCommands). Domyślnie mogą je tworzyć administratorzy społeczności i administratorzy systemu.

  1. Otwórz swój awatar w prawym górnym rogu, następnie Integracje › Polecenia po ukośniku, a potem Dodaj Polecenie.
  2. Wypełnij Tytuł i Opis (wyświetlane na stronach integracji).
  3. Wpisz Słowo Wyzwalacza Polecenia, bez ukośnika i bez spacji, na przykład weather.
  4. Wpisz URL żądania i wybierz Metodę Zapytania: POST (domyślnie) lub GET.
  5. Opcjonalnie ustaw Nazwę użytkownika odpowiedzi i Ikona odpowiedzi. Są one używane tylko wtedy, gdy serwer pozwala integracjom na nadpisywanie nazw i ikon (zobacz Nazwa i ikona).
  6. Zaznacz Automatyczne uzupełnianie, aby wykazać polecenie, gdy użytkownicy wpisują /, wraz z Automatyczne uzupełnianie podpowiedzi (jego argumentami, takimi jak [city]) i Opis autouzupełniania.
  7. Wybierz Zapisz i skopiuj wyświetlany token. Twoja usługa używa go do weryfikacji, że żądania pochodzą z Twojego serwera.

Za pomocą API: POST /api/v4/commands z {"team_id", "trigger", "url", "method": "P", "display_name", "description", "auto_complete": true, "auto_complete_hint", "auto_complete_desc", "username", "icon_url"}. Metoda to P dla POST lub G dla GET. PUT /api/v4/commands/{command_id}/regen_token wydaje nowy token.

Żądanie otrzymywane przez usługę

Polecenie POST wysyła treść w formacie formularza (application/x-www-form-urlencoded); polecenie GET wysyła te same pola w ciągu zapytania. Token znajduje się również w nagłówku Authorization: Token <token>.

PoleWartość
tokenToken polecenia. Weryfikuj go przy każdym żądaniu.
commandWyzwalacz z ukośnikiem, na przykład /weather.
textWszystko po wyzwalaczu, na przykład Paris.
user_id, user_nameKto wykonał polecenie.
channel_id, channel_nameGdzie zostało wykonane.
team_id, team_domainID i nazwa URL przestrzeni roboczej.
root_idWątek, jeśli polecenie zostało wykonane w polu odpowiedzi wątku.
trigger_idUmożliwia otwarcie okna dialogowego w odpowiedzi (patrz Okna dialogowe). Jest ważny tylko przez krótki czas.
response_urlURL do wysłania kolejnych odpowiedzi później (patrz Opóźnione odpowiedzi).
user_mentions, user_mentions_ids, channel_mentions, channel_mentions_idsOsoby i kanały publiczne wymienione w tekście, jeśli takie występują. Kanały są liczone niezależnie od tego, czy są zapisane jako #channel-name, czy ~channel-name.
Aby niestandardowe polecenia mogły działać, w URL strony serwera musi być ustawiona wartość: Antimatter tworzy na jej podstawie response_url.

Odpowiedź

Odpowiedz kodem 200 z danymi JSON (Content-Type: application/json):

{
  "response_type": "in_channel",
  "text": "Paris: 18 °C, light rain",
  "attachments": []
}
PoleZnaczenie
response_typeephemeral (domyślnie): tylko osoba, która wykonała polecenie, widzi odpowiedź, a ta nie jest zachowywana po odświeżeniu strony. in_channel: odpowiedź jest publikowana w kanale.
text, attachmentsWiadomość, podobnie jak dla webhooków: tekst w Markdown oraz załączniki, w tym przyciski i menu.
username, icon_urlNazwa i obrazek do wyświetlenia, jeśli są dozwolone nadpisy. Własne ustawienia polecenia mają pierwszeństwo przed nimi.
channel_idOpublikuj odpowiedź w innym kanale, którego użytkownik musi być członkiem.
goto_locationURL do otwarcia po wykonaniu polecenia.
props, typeDodatkowe właściwości i niestandardowy typ posta, podobnie jak dla webhooków.
extra_responsesKolejne odpowiedzi, każda z tymi samymi polami, publikowane po pierwszej.
skip_slack_parsingWartość true zachowuje tekst bez zmian, bez konwersji linków i wzmianek w stylu Slack.

Odpowiedź inna niż JSON jest wyświetlana jako wiadomość tymczasowa, a jej treść staje się tekstem wiadomości. Kod 204 No Content nie wyświetla niczego. Każdy kod statusu spoza zakresu 200–299 wyświetla użytkownikowi błąd.

Przykładowa usługa

Minimalna usługa polecenia w Pythonie, korzystająca wyłącznie z biblioteki standardowej:

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()

Jeśli usługa działa na adresie prywatnej sieci, administrator systemu musi ją dozwolić w Pozwól na niezaufane połączenia wewnętrzne do (ServiceSettings.AllowedUntrustedInternalConnections).

Opóźnione odpowiedzi

W przypadku pracy, która trwa dłużej niż limit czasu, odpowiedz od razu (na przykład efemerycznym „Pracuję nad tym…”), a następnie wyślij właściwą odpowiedź metodą POST na response_url. Przyjmuje ten sam JSON co odpowiedź i działa do 5 razy w ciągu 30 minut od polecenia.

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

Uruchomienie polecenia za pomocą API

Skrypty i boty mogą uruchamiać dowolne polecenie, wbudowane lub niestandardowe, tak jakby je wpisali:

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 wyświetla listę poleceń, które użytkownicy mogą uzupełniać automatycznie w społeczności.

Uzupełnianie automatyczne

Polecenia utworzone na stronach integracji są uzupełniane automatycznie na podstawie wyzwalacza, podpowiedzi i opisu. Polecenia zarejestrowane przez aplikacje mogą szczegółowo opisywać swoje podpolecenia i argumenty za pomocą AutocompleteData, od model.NewAutocompleteData(trigger, hint, helpText):

  • AddCommand(sub) dodaje podpolecenie, które jest również AutocompleteData.
  • AddTextArgument(helpText, hint, pattern) dodaje dowolny tekst.
  • AddStaticListArgument(helpText, required, items) oferuje stałą listę AutocompleteListItem{Item, Hint, HelpText}.
  • AddDynamicListArgument(helpText, url, required) prosi Twoją aplikację o podpowiedzi podczas pisania. Adres URL to trasa Twojej aplikacji, np. /plugins/com.example.weather/cities. Otrzymuje użytkownika, kanał i społeczność, a zwraca listę JSON z elementami {"Item", "Hint", "HelpText"}.

Warianty Named… (takie jak AddNamedTextArgument i inne) dodają flagi --name value. Oba interfejsy sieciowe wyświetlają te podpowiedzi.

Podczas gdy ktoś wpisuje polecenie, Fusion wyświetla je wraz z każdym z jego argumentów jako blok, a argument, który jest właśnie wpisywany, jest podświetlony wraz z tekstem pomocy. Argumenty pochodzą z AutocompleteData lub, w jego braku, z podpowiedzi: w podpowiedzi takiej jak @[username]... #[channel] słowa zaczynające się od @ trafiają do argumentu osób, a słowa zaczynające się od # do argumentu kanału, niezależnie od ich kolejności; ... oznacza, że argument się powtarza, a ostatni argument przyjmuje resztę tekstu.

Kanały w argumentach

W argumentach polecenia @ sugeruje osoby, # sugeruje kanały i uzupełnia je jako #channel-name, a ~ uzupełnia je jako ~channel-name. Interfejs webowy Antimatter oraz aplikacja mobilna zapisują linki do kanałów jako #, więc polecenie, które przyjmuje kanał, powinno akceptować oba formaty: wbudowane /join, /mute i /invite to robią, a ich podpowiedzi mówią #[channel].