Slash-Befehle
Mit einem eigenen Slash-Befehl können Personen /etwas in das Nachrichtenfeld eingeben, um Ihren Dienst aufzurufen. Antimatter sendet den Befehl an Ihre URL und zeigt Ihre Antwort an, entweder nur für die betreffende Person oder für den gesamten Kanal.
So funktioniert ein Slash-Befehl
- Jemand gibt
/weather Parisein und sendet es. Der Text wird nicht veröffentlicht. - Antimatter sendet eine HTTP-Anfrage an die URL des Befehls, mit Angaben dazu, wer ihn eingegeben hat, wo und dem Text nach dem Triggerwort.
- Ihr Dienst antwortet innerhalb der Anfrage-Timeout-Zeit (standardmäßig 30 Sekunden) mit einer Nachricht.
- Antimatter zeigt die Antwort an: nur für diese Person (ephemeral) oder im Kanal für alle.
Befehle gehören zu einer Community, und ein Triggerwort ist innerhalb dieser eindeutig. Eingebaute Befehle wie /join, /msg oder /away können nicht ersetzt werden. Apps (Plugins) können ebenfalls Befehle registrieren; siehe Der Server-Teil.
Befehl erstellen
Benutzerdefinierte Slash-Befehle sind standardmäßig aktiviert (Aktiviere benutzerdefinierte Slash-Befehle in Systemkonsole › Integrationen › Integrationsverwaltung, ServiceSettings.EnableCommands). Community-Administratoren und Systemadministratoren können sie standardmäßig erstellen.
- Öffnen Sie das Community-Menü, dann Teameinstellungen, klicken Sie auf Integrationen am Ende der Registerkarten, dann auf Slash-Befehle und Slash-Befehl hinzufügen.
- Geben Sie Titel und Beschreibung ein (diese werden auf den Integrationsseiten angezeigt).
- Gib das Befehlsauslösewort ein, ohne Schrägstrich und ohne Leerzeichen, zum Beispiel
weather. - Gib die Anfrage-URL ein und wähle die Anforderungsmethode: POST (Standard) oder GET.
- Gib optional einen Benutzernamen der Antwort und ein Antwort-Symbol an. Sie werden nur verwendet, wenn der Server es Integrationen erlaubt, Namen und Symbole zu überschreiben (siehe Name und Symbol).
- Aktiviere Autovervollständigung, um den Befehl aufzulisten, wenn Personen
/eingeben, mit einem Autovervollständigungshinweis (seine Argumente, z. B.[city]) und einer Beschreibung Autovervollständigung. - Wählen Sie Speichern und kopieren Sie den angezeigten Token. Ihr Dienst verwendet ihn, um sicherzustellen, dass Anfragen von Ihrem Server stammen.
Über die API: POST /api/v4/commands mit {"team_id", "trigger", "url", "method": "P", "display_name", "description", "auto_complete": true, "auto_complete_hint", "auto_complete_desc", "username", "icon_url"}. Die Methode ist P für POST oder G für GET. PUT /api/v4/commands/{command_id}/regen_token erstellt ein neues Token.
Die Anfrage, die Ihr Dienst erhält
Ein POST-Befehl sendet einen form-kodierten Body (application/x-www-form-urlencoded); ein GET-Befehl sendet dieselben Felder in der Query-String. Das Token befindet sich außerdem im Authorization: Token <token>-Header.
| Feld | Wert |
|---|---|
token | Das Token des Befehls. Prüfen Sie es bei jeder Anfrage. |
command | Der Trigger mit seinem Schrägstrich, zum Beispiel /weather. |
text | Alles nach dem Trigger, zum Beispiel Paris. |
user_id, user_name | Wer ihn ausgeführt hat. |
channel_id, channel_name | Wo er ausgeführt wurde. |
team_id, team_domain | Die ID und der URL-Name des Arbeitsbereichs. |
root_id | Der Thread, wenn er in der Antwortbox eines Threads ausgeführt wurde. |
trigger_id | Ermöglicht es, dass Ihre Antwort einen Dialog öffnet (siehe Dialoge). Es ist nur für kurze Zeit gültig. |
response_url | Eine URL, um später weitere Antworten zu senden (siehe Verspätete Antworten). |
user_mentions, user_mentions_ids, channel_mentions, channel_mentions_ids | Die im Text erwähnten Personen und öffentlichen Kanäle, sofern vorhanden. Kanäle werden gezählt, unabhängig davon, ob sie als #channel-name oder ~channel-name geschrieben sind. |
response_url daraus.Die Antwort
Antworten Sie mit 200 und JSON (Content-Type: application/json):
{
"response_type": "in_channel",
"text": "Paris: 18 °C, light rain",
"attachments": []
}
| Feld | Bedeutung |
|---|---|
response_type | ephemeral (Standard): Nur die Person, die den Befehl ausgeführt hat, sieht die Antwort, und sie wird nach einem Neuladen nicht gespeichert. in_channel: Die Antwort wird im Kanal gepostet. |
text, attachments | Die Nachricht, wie bei Webhooks: Markdown-Text und Anhänge, einschließlich Buttons und Menüs. |
username, icon_url | Der Name und das Bild, die angezeigt werden sollen, wenn Überschreibungen erlaubt sind. Die eigenen Einstellungen des Befehls haben Vorrang vor diesen. |
channel_id | Posten Sie die Antwort in einem anderen Kanal, dessen Mitglied die Person sein muss. |
goto_location | Eine URL, die geöffnet werden soll, sobald der Befehl ausgeführt wurde. |
props, type | Zusätzliche Eigenschaften und ein benutzerdefinierter Beitragstyp, wie bei Webhooks. Eine Antwort, die in einen Forum-Kanal gepostet wird, benötigt props.am_thread_title, andernfalls wird sie abgelehnt. |
extra_responses | Weitere Antworten, jeweils mit denselben Feldern, die nach der ersten gepostet werden. |
skip_slack_parsing | true belässt den Text unverändert, ohne Slack-Stil-Links und Erwähnungen umzuwandeln. |
Eine Antwort, die kein JSON ist, wird als ephemeral Nachricht mit dem Body als Text angezeigt. 204 No Content zeigt nichts an. Jeder Status außerhalb des Bereichs 200–299 zeigt der Person einen Fehler an.
Beispiel-Dienst
Ein minimaler Befehlsdienst in Python, nur mit der Standardbibliothek:
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()
Wenn der Dienst auf einer privaten Netzwerkadresse ausgeführt wird, muss ein Systemadministrator ihn unter Erlaube ungesicherte interne Verbindungen zu (ServiceSettings.AllowedUntrustedInternalConnections) erlauben.
Verzögerte Antworten
Für Arbeit, die länger dauert als die Zeitüberschreitung, antworten Sie sofort (z. B. mit einer ephemeralen Nachricht „Ich arbeite daran …“), und senden Sie dann die eigentliche Antwort per POST an response_url. Sie akzeptiert dasselbe JSON wie die Antwort und funktioniert bis zu 5-mal innerhalb von 30 Minuten nach dem Befehl.
curl -X POST "$RESPONSE_URL" -H 'Content-Type: application/json' \
-d '{"response_type": "in_channel", "text": "Report ready: https://reports.example.com/42"}'
Befehl über die API ausführen
Skripte und Bots können jeden Befehl, eingebaut oder benutzerdefiniert, ausführen, als hätten sie ihn eingegeben:
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 listet die Befehle, die Personen in einer Community automatisch vervollständigen können.
Autovervollständigung
Befehle, die auf den Integrationsseiten erstellt werden, werden mit ihrem Trigger, ihrer Anzeige und ihrer Beschreibung automatisch vervollständigt. Von Apps registrierte Befehle können ihre Unterbefehle und Argumente mit AutocompleteData im Detail beschreiben, abgeleitet von model.NewAutocompleteData(trigger, hint, helpText):
AddCommand(sub)fügt einen Unterbefehl hinzu, der selbst einAutocompleteDataist.AddTextArgument(helpText, hint, pattern)fügt freien Text hinzu.AddStaticListArgument(helpText, required, items)bietet eine feste Liste vonAutocompleteListItem{Item, Hint, HelpText}an.AddDynamicListArgument(helpText, url, required)fragt Ihre App um Vorschläge, während Personen tippen. Die URL ist eine Route Ihrer App, z. B./plugins/com.example.weather/cities. Sie erhält Benutzer, Kanal und Community und gibt eine JSON-Liste von{"Item", "Hint", "HelpText"}zurück.
Die Varianten Named… (AddNamedTextArgument und andere) fügen Flags wie --name value hinzu. Beide Web-Oberflächen zeigen diese Vorschläge an. Ein Wert mit Leerzeichen kann in Anführungszeichen gesetzt werden, damit er als ein Argument autocompletiert wird, zum Beispiel --name "my remote": Doppelte Anführungszeichen funktionieren bei jedem Befehl, und Antimatters eigene Befehle, die Flags akzeptieren, akzeptieren auch einfache oder geschweifte Anführungszeichen.
Während jemand einen Befehl eingibt, zeigt Fusion den Befehl und jedes seiner Argumente als Block an, wobei das gerade eingegebene Argument mit seinem Hilfetext hervorgehoben wird. Die Argumente stammen aus AutocompleteData oder, falls dieses fehlt, aus dem Hinweis: In einem Hinweis wie @[username]... #[channel] werden Wörter, die mit @ beginnen, dem Personen-Argument und Wörter, die mit # beginnen, dem Kanal-Argument zugeordnet, unabhängig von ihrer Reihenfolge; ... bedeutet, dass das Argument wiederholt wird, und das letzte Argument nimmt den Rest des Textes auf.
Kanäle in Argumenten
In den Argumenten eines Befehls schlägt @ Personen vor, # schlägt Kanäle vor und vervollständigt sie als #channel-name, und ~ vervollständigt sie als ~channel-name. Die Web-Oberfläche und die mobile App von Antimatter schreiben Kanallinks mit #, daher sollte ein Befehl, der einen Kanal erwartet, beide Formen akzeptieren: Die integrierten Befehle /join, /mute und /invite tun dies, und ihre Hinweise lauten #[channel].