คำสั่งสแลช
คำสั่งสแลชแบบกำหนดเองช่วยให้ผู้ใช้พิมพ์ /something ในช่องข้อความเพื่อเรียกใช้บริการของคุณ Antimatter จะส่งคำสั่งไปยัง URL ของคุณและแสดงคำตอบของคุณ ซึ่งอาจแสดงเฉพาะแก่ผู้ใช้คนนั้นหรือแสดงแก่ทุกคนในช่อง
หลักการทำงานของคำสั่งสแลช
- ผู้ใช้พิมพ์
/weather Parisและส่งข้อความ ข้อความนี้จะไม่ถูกโพสต์ - Antimatter ส่งคำขอ HTTP ไปยัง URL ของคำสั่ง พร้อมข้อมูลว่าใครเป็นผู้พิมพ์, พิมพ์ที่ไหน, และข้อความหลังคำสั่ง
- บริการของคุณต้องตอบกลับภายในเวลาหมดอายุของคำขอ (30 วินาทีโดยค่าเริ่มต้น) ด้วยข้อความ
- Antimatter แสดงคำตอบ: เฉพาะแก่ผู้ใช้คนนั้น (ephemeral) หรือในช่องสำหรับทุกคน
คำสั่งจะสังกัดชุมชน และคำสั่ง (trigger word) ต้องไม่ซ้ำกันภายในชุมชนนั้น คำสั่งที่มีมาให้แล้ว เช่น /join, /msg หรือ /away ไม่สามารถถูกแทนที่ได้ แอป (ปลั๊กอิน) สามารถลงทะเบียนคำสั่งได้ด้วย ดู ส่วนเซิร์ฟเวอร์
สร้างคำสั่ง
คำสั่งสแลชแบบกำหนดเองเปิิดใช้อยู่แลวโดยปริยาย (เปิดใช้งานคำสั่งสแลชแบบกำหนดเอง ใน คอนโซลระบบ › อินทิเกรชัน › การจัดการอินทิเกรชัน, ServiceSettings.EnableCommands) ผู้ดูแลชุมชนและผู้ดูแลระบบสามารถสร้างคำสั่งเหล่านีไ้ด้โดยปริยาย
- เปิิดอวตารของคุณท่ีมุมบนขวา แลวเลืก อินทิเกรชัน › คำสั่งสแลช แลวเลืก เพิ่มคำสั่งสแลช
- กรอกชื่อ และ คำอธิบาย (ท่ีจะแสดงในหน้างานอินทิเกรชัน)
- กรอกคำสั่ง โดยไม่มีสััญลักษณ์สแลชและไม่มีช่องไฟ เช่น
weather - กรอกURL คำขอ และเลืกเมธอดคำขอ: POST (ค่าโดยปริยาย) หรือ GET
- กำหนดชื่อผู้ใช้สำหรบตอบกลับ และ ไอคอนของคำตอบ (ถ้าต้องการ) ค่าเหล่านีจ้ะถูกใช้อย่างเดียวเมื่อบอรด์อนุญาตให้อินทิเกรชันเปลี่นชื่อและไอคอน (ดูชื่อและไอคอน)
- ทำเครื่อกกรอกให่เต็มอัตโนมัติ เพื่อบันทึกรายการคำสั่งเมื่อบุคคลใดกรอก
/พร้อมคำใบ้สำหรบเติมอัตโนมัติ (พารามิเตอร์ของคำสั่ง เช่น[city]) และคำอธิบายสำหรบเติมอัตโนมัติ - เลืกบันทึก แลวคัดลอกโทเคนท่ีแสดง ระบบของคุณจะใชโทเคนนี้เพื่อกำหนดว่าคำขอมาจากบอรด์ของคุณ
ด้วย 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 จะสร้างโทเคนใหม่
คำขอที่บริการของคุณได้รับ
คำสั่ง POST จะส่ง body แบบ form-encoded (application/x-www-form-urlencoded) ส่วนคำสั่ง GET จะส่งฟิลด์เดียวกันใน query string โทเคนยังอยู่ใน header Authorization: Token <token> ด้วย
| ฟิลด์ | ค่า |
|---|---|
token | โทเคนของคำสั่ง ตรวจสอบทุกครั้งที่มีคำขอ |
command | trigger พร้อมเครื่องหมายสแลช เช่น /weather |
text | ข้อความทั้งหมดหลัง trigger เช่น Paris |
user_id, user_name | ผู้ที่ใช้คำสั่ง |
channel_id, channel_name | ตำแหน่งที่ใช้คำสั่ง |
team_id, team_domain | ID และชื่อ URL ของชุมชน |
root_id | เธรด เมื่อใช้คำสั่งในกล่องตอบกลับของเธรด |
trigger_id | เปิดให้คำตอบของคุณเปิดไดอะล็อก (ดู Dialogs) ได้ มีอายุสั้นเท่านั้น |
response_url | URL สำหรับโพสต์คำตอบเพิ่มเติมภายหลัง (ดู Delayed answers) |
user_mentions, user_mentions_ids, channel_mentions, channel_mentions_ids | บุคคลและช่องสาธารณะท่ีถูกเมนชันในข้อความ (ถ้ามี) ช่องจะถูกรวมในการนับไม่ว่าจะเขียนเป็น #channel-name หรือ ~channel-name |
response_url จากค่านี้การตอบกลับ
ตอบกลับด้วย 200 พร้อม JSON (Content-Type: application/json):
{
"response_type": "in_channel",
"text": "Paris: 18 °C, light rain",
"attachments": []
}
| ฟิลด์ | ความหมาย |
|---|---|
response_type | ephemeral (ค่าเริ่มต้น): เฉพาะผู้ใช้คำสั่งเท่านั้นที่เห็นคำตอบ และจะไม่ถูกเก็บไว้หลังรีโหลด in_channel: คำตอบจะถูกโพสต์ในช่อง |
text, attachments | ข้อความ เช่นเดียวกับเว็บฮุค: ข้อความ Markdown และ ไฟล์แนบ รวมถึงปุ่มและเมนู |
username, icon_url | ชื่อและรูปภาพที่จะแสดง (เมื่ออนุญาตให้ override ได้) การตั้งค่าของคำสั่งเองจะมีผลเหนือกว่าค่าเหล่านี้ |
channel_id | โพสต์คำตอบในช่องอื่น ซึ่งผู้ใช้ต้องเป็นสมาชิกของช่องนั้น |
goto_location | URL ที่จะเปิดเมื่อคำสั่งทำงานเสร็จ |
props, type | คุณสมบัติเพิ่มเติมและประเภทโพสต์แบบกำหนดเอง เช่นเดียวกับเว็บฮุค |
extra_responses | คำตอบเพิ่มเติม แต่ละคำตอบมีฟิลด์เดียวกัน โพสต์หลังคำตอบแรก |
skip_slack_parsing | true จะเก็บข้อความไว้ตามเดิม โดยไม่แปลงลิงก์และเมนชันแบบ Slack |
การตอบกลับที่ไม่ใช่ JSON จะแสดงเป็นข้อความ ephemeral โดยใช้ body เป็นข้อความ 204 No Content จะไม่แสดงอะไร สถานะใด ๆ นอกช่วง 200–299 จะแสดงข้อผิดพลาดให้ผู้ใช้
ตัวอย่างบริการ
บริการคำสั่งขั้นต่ำใน Python โดยใช้เพียง standard library:
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)
การตอบกลับแบบหน่วงเวลา
สำหรับงานที่ใช้เวลานานกว่าค่า timeout ให้ตอบกลับทันที (เช่น ด้วยข้อความชั่วคราวว่า "กำลังดำเนินการอยู่…") จากนั้นจึง POST คำตอบจริงไปยัง response_url ซึ่งรับ JSON ในรูปแบบเดียวกับคำตอบ และสามารถใช้ได้สูงสุด 5 ครั้งภายใน 30 นาทีหลังคำสั่ง
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 แสดงรายการคำสั่งที่ผู้ใช้สามารถเติมอัตโนมัติได้ในชุมชน
การเติมอัตโนมัติ
คำสั่งที่สร้างจากหน้าการเชื่อมต่อจะเติมอัตโนมัติพร้อม trigger, hint และคำอธิบาย คำสั่งที่แอปลงทะเบียนไว้สามารถอธิบายคำสั่งย่อยและอาร์กิวเมนต์อย่างละเอียดด้วย 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 คือ route ของแอปของคุณ เช่น/plugins/com.example.weather/citiesซึ่งจะได้รับข้อมูลผู้ใช้ ช่อง และชุมชน และคืนค่าเป็น JSON list ของ{"Item", "Hint", "HelpText"}
รูปแบบ Named… (เช่น AddNamedTextArgument และอื่นๆ) เพิ่มแฟลก --name value ทั้งสองอินเทอร์เฟซเว็บจะแสดงคำแนะนำเหล่านี้
ในขณะท่ีผู้ใช้กำลังพิมพ์คำสั่ง Fusion จะแสดงคำสั่งและอาร์กิวเมนต์แต่ละข้อนเป็นบล็อก โดยอาร์กิวเมนต์ท่ีกำลังพิมพ์อยู่จะเด่นชัดพร้อมข้อความช่วย (help text) อาร์กิวเมนต์เหล่านี้มาจาก AutocompleteData หรือหากไม่มี จะมาจาก hint: ใน hint เช่น @[username]... #[channel] คำท่ีขึ้นต้นด้วย @ จะถูกจัดให้อยู่ในอาร์กิวเมนต์ของบุคคล และคำท่ีขึ้นต้นด้วย # จะถูกจัดให้อยู่ในอาร์กิวเมนต์ของช่อง โดยไม่ว่าลำดับจะเป็นอย่างไร ... หมายถิงว่าอาร์กิวเมนต์นั้นสามารถซ้ำได้ และอาร์กิวเมนต์สุดท้ายจะรับข้อความที่เหลือทั้งหมด
ช่องในอาร์กิวเมนต์
ในอาร์กิวเมนต์ของคำสั่ง @ จะแนะนำบุคคล # จะแนะนำช่องและเติมเต็มเป็น #channel-name และ ~ จะเติมเต็มเป็น ~channel-name หน้าจอเว็บและแอปมือถือของ Antimatter จะเขียนลิงก์ช่องด้วย # ดังนั้นคำสั่งท่ีรับช่องควรยอมรับทั้งสองรูปแบบ: คำสั่งในตัวของระบบ เช่น /join, /mute และ /invite ทำเช่นนั้น และ hint ของคำสั่งเหล่านี้ระบุไว้ว่า #[channel]