Slash-opdrachten

Met een aangepaste slash-opdracht kunnen mensen /iets in het berichtvak typen om uw service aan te roepen. Antimatter stuurt de opdracht naar uw URL en toont uw antwoord, alleen voor die persoon of voor het hele kanaal.

Hoe een slash-opdracht werkt

  1. Iemand typt /weather Paris en stuurt het. De tekst wordt niet gepost.
  2. Antimatter stuurt een HTTP-aanvraag naar de URL van de opdracht, met wie hem heeft getypt, waar en de tekst na de trigger.
  3. Uw service antwoordt binnen de timeout van de aanvraag (standaard 30 seconden) met een bericht.
  4. Antimatter toont het antwoord: alleen voor die persoon (tijdelijk) of in het kanaal voor iedereen.

Opdrachten horen bij een community, en een triggerwoord is uniek binnen die community. Ingebouwde opdrachten zoals /join, /msg of /away kunnen niet worden vervangen. Apps (plugins) kunnen ook opdrachten registreren; zie Het servergedeelte.

Een opdracht aanmaken

Aangepaste slash-opdrachten zijn standaard ingeschakeld (Inschakelen van Slash opdrachten in Systeem console › Integraties › Integratiebeheer, ServiceSettings.EnableCommands). Gemeenschapsbeheerders en systeembeheerders kunnen ze standaard aanmaken.

  1. Klik rechtsboven op je avatar, ga daarna naar Integraties › Slash opdrachten en klik op Slash opdracht toevoegen.
  2. Vul de Titel en de Omschrijving in (getoond op de integratiepagina's).
  3. Voer het Sleutelwoord voor opdracht in, zonder de slash en zonder spaties, bijvoorbeeld weather.
  4. Voer de Aanvraag-URL in en kies de Aanvraagmethode: POST (standaard) of GET.
  5. Stel optioneel een Gebruikersnaam voor de reactie en een Reactie-icoon in. Deze worden alleen gebruikt wanneer de server integraties toelaat om namen en iconen te overschrijven (zie Naam en icoon).
  6. Vink Automatisch aanvullen aan om de opdracht weer te geven wanneer mensen / typen, met een Automatisch-aanvullen-tip (de argumenten, zoals [city]) en een Automatisch aanvullen omgeschrijving.
  7. Kies Opslaan en kopieer het getoonde token. Uw service gebruikt dit om te controleren of aanvragen van uw server komen.

Via de API: POST /api/v4/commands met {"team_id", "trigger", "url", "method": "P", "display_name", "description", "auto_complete": true, "auto_complete_hint", "auto_complete_desc", "username", "icon_url"}. De methode is P voor POST of G voor GET. PUT /api/v4/commands/{command_id}/regen_token geeft een nieuw token uit.

De aanvraag die uw service ontvangt

Een POST-opdracht stuurt een form-encoded body (application/x-www-form-urlencoded); een GET-opdracht stuurt dezelfde velden in de query string. Het token staat ook in de Authorization: Token <token>-header.

VeldWaarde
tokenHet token van de opdracht. Controleer dit bij elke aanvraag.
commandDe trigger met de slash, bijvoorbeeld /weather.
textAlles na de trigger, bijvoorbeeld Paris.
user_id, user_nameWie het heeft uitgevoerd.
channel_id, channel_nameWaar het is uitgevoerd.
team_id, team_domainDe ID en de URL-naam van de community.
root_idHet draadje, wanneer het is uitgevoerd in het antwoordvak van een draadje.
trigger_idMaakt het mogelijk dat uw antwoord een dialoog opent (zie Dialogen). Het is slechts voor een korte tijd geldig.
response_urlEen URL om later meer antwoorden te plaatsen (zie Vertraagde antwoorden).
user_mentions, user_mentions_ids, channel_mentions, channel_mentions_idsDe personen en publieke kanalen die in de tekst worden genoemd, als er althans enkele zijn. Kanalen tellen zowel wanneer ze als #channel-name als wanneer ze als ~channel-name worden geschreven.
De Site URL van de server moet zijn ingesteld voor het uitvoeren van aangepaste opdrachten: Antimatter bouwt response_url hieruit.

Het antwoord

Antwoord met 200 en JSON (Content-Type: application/json):

{
  "response_type": "in_channel",
  "text": "Paris: 18 °C, light rain",
  "attachments": []
}
VeldBetekenis
response_typeephemeral (standaard): alleen de persoon die de opdracht heeft uitgevoerd, ziet het antwoord, en het wordt niet bewaard na een herladen. in_channel: het antwoord wordt geplaatst in het kanaal.
text, attachmentsHet bericht, zoals bij webhooks: Markdown-tekst en bijlagen, inclusief knoppen en menu's.
username, icon_urlDe naam en het afbeelding om weer te geven, wanneer overrides zijn toegestaan. De eigen instellingen van de opdracht hebben voorrang op deze.
channel_idPlaats het antwoord in een ander kanaal, waarvan de persoon lid moet zijn.
goto_locationEen URL om te openen zodra de opdracht is uitgevoerd.
props, typeExtra eigenschappen en een aangepaste post-type, zoals bij webhooks.
extra_responsesMeer antwoorden, elk met dezelfde velden, geplaatst na het eerste.
skip_slack_parsingtrue behoudt de tekst zoals deze is, zonder Slack-stijl links en vermeldingen te converteren.

Een antwoord dat geen JSON is, wordt weergegeven als een ephemeral-bericht met de body als tekst. 204 No Content toont niets. Elke status buiten 200–299 toont de persoon een fout.

Voorbeelddienst

Een minimale opdrachtdienst in Python, met alleen de standaardbibliotheek:

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

Als de service op een privaat netwerkadres draait, moet een systeembeheerder dit toestaan in Niet-vertrouwde interne verbindingen toestaan naar (ServiceSettings.AllowedUntrustedInternalConnections).

Vertraagde antwoorden

Voor werk dat langer duurt dan de time-out, antwoord onmiddellijk (bijvoorbeeld met een tijdelijk "Ik werk eraan…") en stuur het echte antwoord vervolgens via POST naar response_url. Het accepteert dezelfde JSON als het antwoord en werkt tot 5 keer binnen 30 minuten na het commando.

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

Een commando uitvoeren via de API

Scripts en bots kunnen elk commando uitvoeren, ingebouwd of aangepast, alsof ze het zelf hadden getypt:

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 toont de commando's die mensen kunnen voltooien in een community.

Voltooiing

Commando's die op de integratiepagina's zijn aangemaakt, worden voltooid met hun trigger, hint en beschrijving. Commando's die door apps zijn geregistreerd, kunnen hun subcommando's en argumenten in detail beschrijven met AutocompleteData, vanaf model.NewAutocompleteData(trigger, hint, helpText):

  • AddCommand(sub) voegt een subcommando toe, dat zelf een AutocompleteData is.
  • AddTextArgument(helpText, hint, pattern) voegt vrije tekst toe.
  • AddStaticListArgument(helpText, required, items) biedt een vaste lijst van AutocompleteListItem{Item, Hint, HelpText}.
  • AddDynamicListArgument(helpText, url, required) vraagt uw app om suggesties terwijl mensen typen. De URL is een route van uw app, zoals /plugins/com.example.weather/cities. Het ontvangt de gebruiker, het kanaal en de community en geeft een JSON-lijst van {"Item", "Hint", "HelpText"} terug.

De Named…-varianten (AddNamedTextArgument en andere) voegen --name value-vlaggen toe. Beide webinterfaces tonen deze suggesties.

Wanneer iemand een opdracht typt, toont Fusion de opdracht en elk van de argumenten als een blok, waarbij het blok dat wordt getypt is gemarkeerd met de bijbehorende help tekst. De argumenten komen uit AutocompleteData of, indien dat niet aanwezig is, uit de hint: in een hint zoals @[username]... #[channel] gaan woorden die beginnen met @ naar het argument voor personen en woorden die beginnen met # naar het argument voor kanalen, ongeacht de volgorde; ... betekent dat het argument zich herhaalt, en het laatste argument neemt de rest van de tekst over.

Kanalen in argumenten

In de argumenten van een opdracht, @ suggereert personen, # suggereert kanalen en voltooit ze als #channel-name, en ~ voltooit ze als ~channel-name. De webinterface en de mobiele app van Antimatter schrijven kanaallinks met #, dus een opdracht die een kanaal accepteert, moet beide vormen accepteren: de ingebouwde /join, /mute en /invite doen dat, en hun hints zeggen #[channel].