斜線指令

自訂斜線指令可讓使用者在訊息輸入框中輸入 /something 來呼叫您的服務。Antimatter 會將指令傳送至您的 URL,並顯示您的回應,可以是僅讓該使用者看到,或是讓整個頻道看到。

斜線指令的運作方式

  1. 某人輸入 /weather Paris 並送出。文字不會被發布。
  2. Antimatter 會向指令的 URL 發送 HTTP 請求,包含輸入者、位置以及觸發詞後的文字。
  3. 您的服務需在請求逾時時間內(預設為 30 秒)以訊息回應。
  4. Antimatter 會顯示回應:僅讓該使用者看到(暫時性)或在頻道中讓所有人看到。

指令屬於特定社群,且觸發詞在該社群內必須是獨一無二的。內建指令(例如 /join、/msg 或 /away)無法被取代。應用程式(外掛程式)也可以註冊指令;請參閱 伺服器部分。

建立指令

自訂斜線指令預設為啟用狀態(位於系統控制台 › 整合 › 整合管理中的啟用自訂斜線命令,ServiceSettings.EnableCommands)。社群管理員與系統管理員預設皆可建立。

  1. 開啟右上角的個人頭像,然後選擇整合 › 斜線命令,接著點選新增斜線命令。
  2. 填寫標題與敘述(顯示於整合頁面)。
  3. 輸入命令觸發關鍵字,不需包含斜線或空格,例如 weather。
  4. 輸入請求網址並選擇請求方法: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"}。method 欄位使用 P 代表 POST,或 G 代表 GET。PUT /api/v4/commands/{command_id}/regen_token 可重新產生新的 token。

您的服務收到的請求

POST 指令會傳送表單編碼的請求主體(application/x-www-form-urlencoded);GET 指令則將相同的欄位放在查詢字串中。Token 也會包含在 Authorization: Token <token> 標頭中。

欄位值
token該指令的 token。請在每個請求中進行驗證。
command包含斜線的觸發詞,例如 /weather。
text觸發詞之後的所有內容,例如 Paris。
user_id, user_name執行者。
channel_id, channel_name執行位置。
team_id, team_domain社群的 ID 與 URL 名稱。
root_id討論串,若是在討論串的回覆框中執行。
trigger_id讓您的回覆開啟對話框(請參閱 對話框)。此值僅在短時間內有效。
response_url稍後用於發布更多回覆的 URL(請參閱 延遲回覆)。
user_mentions, user_mentions_ids, channel_mentions, channel_mentions_ids文字中提及的人員與公開頻道(如有)。頻道無論以 #channel-name 或 ~channel-name 格式撰寫,皆會被計算在內。
必須設定伺服器的網站網址,自訂指令才能執行:Antimatter 會據此建立 response_url。

回應

以 JSON 回應 200(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_location指令執行完畢後要開啟的 URL。
props, type與 Webhook 相同的額外屬性與自訂發布類型。
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,並可在指令執行後 30 分鐘內使用最多 5 次。

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。它會接收使用者、頻道和社群資訊,並回傳包含 {"Item", "Hint", "HelpText"} 的 JSON 清單。

Named… 變體(如 AddNamedTextArgument 等)會新增 --name value 旗標。兩個網頁介面都會顯示這些建議。

當使用者輸入指令時,Fusion 會將該指令及其每個參數顯示為區塊,並高亮顯示正在輸入的參數及其說明文字。參數來自 AutocompleteData;若無此資料,則來自提示:在如 @[username]... #[channel] 的提示中,以 @ 開頭的詞彙會歸入人員參數,以 # 開頭的詞彙會歸入頻道參數,順序不限;... 表示該參數可重複,而最後一個參數會接收剩餘的文字。

參數中的頻道

在指令的參數中,@ 會建議人員,# 會建議頻道並補全為 #channel-name,而 ~ 則補全為 ~channel-name。Antimatter 的網頁介面與行動應用程式使用 # 來撰寫頻道連結,因此接受頻道的指令應同時支援這兩種格式:內建的 /join、/mute 和 /invite 皆如此,且其提示顯示為 #[channel]。