Comandos de barra

Um comando de barra personalizado permite às pessoas escreverem /algo na caixa de mensagens para chamar o seu serviço. O Antimatter envia o comando para a sua URL e mostra a sua resposta, seja apenas para a pessoa em questão ou para todo o canal.

Como funciona um comando de barra

  1. Alguém escreve /weather Paris e envia. O texto não é publicado.
  2. O Antimatter envia um pedido HTTP para a URL do comando, com quem o escreveu, onde e o texto após a palavra de gatilho.
  3. O seu serviço responde dentro do tempo limite do pedido (30 segundos por omissão) com uma mensagem.
  4. O Antimatter mostra a resposta: apenas para essa pessoa (efémera) ou no canal para todos.

Os comandos pertencem a uma comunidade, e uma palavra de gatilho é única dentro dela. Os comandos integrados, como /join, /msg ou /away, não podem ser substituídos. As aplicações (plugins) também podem registar comandos; consulte A parte do servidor.

Criar um comando

Os comandos de barra personalizados estão ativados por omissão (Ativar comandos de barra personalizados em Consola do sistema › Integrações › Gestão de integrações, ServiceSettings.EnableCommands). Os administradores da comunidade e os administradores do sistema podem criá-los por omissão.

  1. Abra o seu avatar no canto superior direito, depois Integrações › Comandos de barra, depois Adicionar comando de barra.
  2. Preencha o Título e a Descrição (mostrados nas páginas de integrações).
  3. Introduza a Palavra de gatilho do comando, sem a barra e sem espaços, por exemplo weather.
  4. Introduza a URL do pedido e escolha o Método de pedido: POST (o predefinido) ou GET.
  5. Opcionalmente, defina um Nome de utilizador da resposta e um Ícone de resposta. Estes são usados apenas quando o servidor permite que as integrações substituam nomes e ícones (consulte Nome e ícone).
  6. Marque Autocompletar para listar o comando quando as pessoas escrevem /, com uma Dica de preenchimento automático (os seus argumentos, como [city]) e uma Descrição do preenchimento automático.
  7. Escolha Guardar e copie o token apresentado. O seu serviço usa-o para verificar que os pedidos provêm do seu servidor.

Através da API: POST /api/v4/commands com {"team_id", "trigger", "url", "method": "P", "display_name", "description", "auto_complete": true, "auto_complete_hint", "auto_complete_desc", "username", "icon_url"}. O método é P para POST ou G para GET. PUT /api/v4/commands/{command_id}/regen_token emite um novo token.

A solicitação que o seu serviço recebe

Um comando POST envia um corpo codificado em formulário (application/x-www-form-urlencoded); um comando GET envia os mesmos campos na string de consulta. O token também está no cabeçalho Authorization: Token <token>.

CampoValor
tokenO token do comando. Verifique-o em cada solicitação.
commandO gatilho com a sua barra, por exemplo /weather.
textTudo depois do gatilho, por exemplo Paris.
user_id, user_nameQuem o executou.
channel_id, channel_nameOnde foi executado.
team_id, team_domainO ID e o nome da URL da comunidade.
root_idO tópico, quando foi executado na caixa de resposta de um tópico.
trigger_idPermite que a sua resposta abra um diálogo (ver Diálogos). É válido apenas por um curto período de tempo.
response_urlUma URL para publicar mais respostas mais tarde (ver Respostas diferidas).
user_mentions, user_mentions_ids, channel_mentions, channel_mentions_idsAs pessoas e os canais públicos mencionados no texto, quando existirem. Os canais contam independentemente de estarem escritos como #channel-name ou ~channel-name.
O URL do site do servidor deve estar definido para que os comandos personalizados sejam executados: o Antimatter constrói response_url a partir dele.

A resposta

Responder com 200 e JSON (Content-Type: application/json):

{
  "response_type": "in_channel",
  "text": "Paris: 18 °C, light rain",
  "attachments": []
}
CampoSignificado
response_typeephemeral (o padrão): apenas a pessoa que executou o comando vê a resposta, e esta não é mantida após uma recarga. in_channel: a resposta é publicada no canal.
text, attachmentsA mensagem, tal como para webhooks: texto Markdown e anexos, incluindo botões e menus.
username, icon_urlO nome e a imagem a mostrar, quando as substituições forem permitidas. As definições do próprio comando têm prioridade sobre estas.
channel_idPublicar a resposta noutro canal, do qual a pessoa deve ser membro.
goto_locationUma URL para abrir uma vez que o comando tenha sido executado.
props, typePropriedades adicionais e um tipo de publicação personalizado, tal como para webhooks.
extra_responsesMais respostas, cada uma com os mesmos campos, publicadas após a primeira.
skip_slack_parsingtrue mantém o texto como está, sem converter ligações e menções no estilo Slack.

Uma resposta que não seja JSON é mostrada como uma mensagem efémera com o corpo como o seu texto. 204 No Content não mostra nada. Qualquer estado fora de 200–299 mostra à pessoa um erro.

Serviço de exemplo

Um serviço de comando mínimo em Python, com apenas a biblioteca padrão:

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

Se o serviço for executado num endereço de rede privada, um administrador do sistema deve autorizá-lo em Permitir ligações internas não fiáveis a (ServiceSettings.AllowedUntrustedInternalConnections).

Respostas com atraso

Para trabalhos que demoram mais do que o tempo limite, responda de imediato (por exemplo, com uma mensagem efémera "A trabalhar nisso…") e, em seguida, envie a resposta real para response_url. Aceita o mesmo JSON da resposta e funciona até 5 vezes num período de 30 minutos após o comando.

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

Executar um comando através da API

Scripts e bots podem executar qualquer comando, incorporado ou personalizado, como se o tivessem digitado:

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 lista os comandos que as pessoas podem autocompletar numa comunidade.

Autocompletar

Os comandos criados nas páginas de integrações autocompletam com o seu gatilho, dica e descrição. Os comandos registados por aplicações podem descrever em detalhe os seus subcomandos e argumentos com AutocompleteData, a partir de model.NewAutocompleteData(trigger, hint, helpText):

  • AddCommand(sub) adiciona um subcomando, que é por sua vez um AutocompleteData.
  • AddTextArgument(helpText, hint, pattern) adiciona texto livre.
  • AddStaticListArgument(helpText, required, items) oferece uma lista fixa de AutocompleteListItem{Item, Hint, HelpText}.
  • AddDynamicListArgument(helpText, url, required) pede à sua aplicação sugestões à medida que as pessoas escrevem. A URL é uma rota da sua aplicação, como /plugins/com.example.weather/cities. Recebe o utilizador, o canal e a comunidade, e devolve uma lista JSON de {"Item", "Hint", "HelpText"}.

As variantes Named… (AddNamedTextArgument e outras) adicionam bandeiras --name value. Ambas as interfaces web mostram estas sugestões.

Enquanto alguém escreve um comando, o Fusion mostra o comando e cada um dos seus argumentos como um bloco, com o que está a ser escrito destacado juntamente com o seu texto de ajuda. Os argumentos provêm de AutocompleteData ou, na sua ausência, da dica: numa dica como @[username]... #[channel], as palavras que começam com @ vão para o argumento de pessoas e as que começam com # para o argumento de canal, independentemente da ordem; ... significa que o argumento se repete, e o último argumento recebe o resto do texto.

Canais nos argumentos

Nos argumentos de um comando, @ sugere pessoas, # sugere canais e completa-os como #channel-name, e ~ completa-os como ~channel-name. A interface web e a aplicação móvel do Antimatter escrevem ligações de canais com #, pelo que um comando que receba um canal deve aceitar ambas as formas: os comandos integrados /join, /mute e /invite fazem-no, e as respetivas dicas indicam #[channel].