أوامر الشرطة المائلة

يتيح أمر الشرطة المائلة المخصصة للأشخاص كتابة /something في مربع الرسالة لاستدعاء خدمتك. يرسل Antimatter الأمر إلى عنوان URL الخاص بك ويعرض إجابتك، إما للشخص المعني فقط أو للقناة بأكملها.

كيف يعمل أمر الشرطة المائلة

  1. يكتب شخص ما /weather Paris ويرسله. لا يتم نشر النص.
  2. يرسل Antimatter طلب HTTP إلى عنوان URL الخاص بالأمر، مع ذكر من قام بكتابته، وأين، والنص الذي يلي كلمة التشغيل.
  3. تستجيب خدمتك برسالة خلال مهلة انتهاء صلاحية الطلب (30 ثانية افتراضياً).
  4. يعرض Antimatter الإجابة: إما لذلك الشخص فقط (مؤقتة) أو داخل القناة للجميع.

تنتمي الأوامر إلى مجتمع، وتكون كلمة التشغيل فريدة داخله. لا يمكن استبدال الأوامر المدمجة مثل /join أو /msg أو /away. يمكن للتطبيقات (الإضافات) تسجيل الأوامر أيضاً؛ راجع الجزء الخاص بالخادم.

إنشاء أمر

تكون أوامر الشرطة المائلة المخصصة مفعّلة افتراضياً (تفعيل أوامر الشرطة المائلة المخصصة في وحدة التحكم بالنظام › التكاملات › إدارة التكاملات، ServiceSettings.EnableCommands). يمكن لمديري المجتمع والمديرين النظاميين إنشاؤها افتراضياً.

  1. افتح قائمة الفريق، ثم إعدادات الفريق، وانقر على التكاملات في نهاية تبويباته، ثم أوامر الشرطة المائلة وإضافة أمر شرطة مائلة.
  2. املأ العنوان والوصف (يظهران في صفحات التكاملات).
  3. أدخل كلمة تشغيل الأمر، دون شرطة مائلة ودون مسافات، على سبيل المثال weather.
  4. أدخل عنوان URL للطلب واختر طريقة الطلب: POST (الافتراضي) أو GET.
  5. اختيارياً، اضبط اسم المستخدم للرد وأيقونة الاستجابة. تُستخدم هذه العناصر فقط عندما يسمح الخادم للتكاملات بتجاوز الأسماء والأيقونات (راجع الاسم والأيقونة).
  6. علّم الإكمال التلقائي لعرض الأمر في القائمة عندما يكتب الأشخاص /، مع تلميح الإكمال التلقائي (معلماته، مثل [city]) ووصف الإكمال التلقائي.
  7. اختر حفظ، وانسخ الرمز المعروض. تستخدم خدمتك هذا الرمز للتحقق من أن الطلبات تأتي من خادمك.

عبر واجهة برمجة التطبيقات: 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"}. تكون القيمة P للمطابقة مع POST أو G للمطابقة مع GET. يُصدر PUT /api/v4/commands/{command_id}/regen_token رمزًا جديدًا.

الطلب الذي يستقبله خدمتك

أرسل الأمر POST جسمًا مُرمّزًا كنموذج (application/x-www-form-urlencoded); بينما يرسل الأمر GET الحقول نفسها في سلسلة الاستعلام. يوجد الرمز أيضًا في ترويسة Authorization: Token <token>.

الحقلالقيمة
tokenرمز الأمر. تحقّق منه في كل طلب.
commandالمحفّز مع شرطة مائلة، على سبيل المثال /weather.
textكل ما يلي المحفّز، على سبيل المثال Paris.
user_id, user_nameمن نفّذ الأمر.
channel_id, channel_nameمكان تنفيذ الأمر.
team_id, team_domainمعرّف المجتمع واسمه في عنوان URL.
root_idسلسلة الرسائل، إذا نُفّذ الأمر في صندوق الردود الخاص بها.
trigger_idيتيح لردّك فتح مربع حوار (انظر مربعات الحوار). يبقى صالحًا لفترة قصيرة فقط.
response_urlعنوان URL لنشر المزيد من الردود لاحقًا (انظر الردود المؤجلة).
user_mentions, user_mentions_ids, channel_mentions, channel_mentions_idsالأشخاص والقنوات العامة المذكورة في النص، إن وُجدت. تُحتسب القنوات سواء كُتبت #channel-name أو ~channel-name.
يجب ضبط عنوان URL للموقع في الخادم حتى تعمل الأوامر المخصصة: يبني Antimatter response_url بناءً عليه.

الرد

أجب بـ 200 بصيغة JSON (Content-Type: application/json):

{
  "response_type": "in_channel",
  "text": "Paris: 18 °C, light rain",
  "attachments": []
}
الحقلالمعنى
response_typeephemeral (الافتراضي): يرى الشخص الذي نفّذ الأمر الرد فقط، ولا يُحفظ بعد إعادة التحميل. in_channel: يُنشر الرد في القناة.
text, attachmentsالرسالة، كما في خطافات الويب: نص Markdown ومرفقات، بما في ذلك الأزرار والقوائم.
username, icon_urlالاسم والصورة المعروضة، إذا كان التجاوز مسموحًا به. تتفوق إعدادات الأمر نفسه على هذه القيم.
channel_idانشر الرد في قناة أخرى، يجب أن يكون الشخص عضوًا فيها.
goto_locationعنوان URL يُفتح مرة واحدة بعد تنفيذ الأمر.
props, typeخصائص إضافية ونوع منشور مخصص، كما هو الحال في خطافات الويب. يجب أن يحتوي الرد المنشور في قناة منتدى على props.am_thread_title، وإلا سيتم رفضه.
extra_responsesردود إضافية، لكل منها الحقول نفسها، تُنشر بعد الرد الأول.
skip_slack_parsingيُبقي true النص كما هو، دون تحويل الروابط والإشارات بأسلوب 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).

إجابات مؤجلة

للأعمال التي تستغرق وقتًا أطول من مهلة الإيقاف، أجب فورًا (على سبيل المثال برسالة عابرة مثل «جارٍ العمل عليها…»)، ثم أرسل الإجابة الفعلية إلى 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"}'

تشغيل أمر عبر واجهة برمجة التطبيقات

يمكن للبرامج النصية والبوتات تشغيل أي أمر، مدمج أو مخصص، كأنها كتبته:

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) يطلب من تطبيقك اقتراحات أثناء كتابة المستخدمين. الرابط هو مسار لتطبيقك، مثل /plugins/com.example.weather/cities. يستقبل المستخدم والقناة والمجتمع، ويعيد قائمة JSON من {"Item", "Hint", "HelpText"}.

تضيف المتغيّرات Named… (مثل AddNamedTextArgument وغيرها) أعلام --name value. يعرض كلا واجهتي الويب هذه الاقتراحات. يمكن وضع قيمة تحتوي على مسافات بين علامات اقتباس ليُكتمل إكمالها تلقائيًا كوسيط واحد، على سبيل المثال --name "my remote": تعمل علامات الاقتباس المزدوجة مع كل الأوامر، كما تقبل أوامر Antimatter الخاصة التي تأخذ أعلامًا علامات الاقتباس المفردة أو المنحنية.

عندما يكتب شخص ما أمرًا، يعرض Fusion الأمر وكل حِججه على شكل كتل، مع تمييز الكتلة قيد الكتابة وعرض النص التوضيحي الخاص بها. تأتي الحِجج من AutocompleteData أو، في غيابها، من التلميح: في تلميح مثل @[username]... #[channel]، تُرسل الكلمات التي تبدأ بـ @ إلى حِجج الأشخاص، والكلمات التي تبدأ بـ # إلى حِجج القنوات، بغض النظر عن ترتيبها؛ ويعني ... أن الحِجج تتكرر، وأن الحِجج الأخيرة تستوعب بقية النص.

القنوات في الحِجج

في حِجج الأمر، يقترح @ الأشخاص، ويقترح # القنوات ويكتملها على شكل #channel-name، بينما يكتمل ~ على شكل ~channel-name. يكتب واجهة الويب وتطبيق الجوال الخاص بـ Antimatter روابط القنوات باستخدام #، لذا يجب أن يقبل الأمر الذي يستقبل قناة كلا الشكلين؛ تفعل ذلك الأوامر المدمجة /join و/mute و/invite، وتُظهر تلميحاتها #[channel].