وب‌هوک‌ها

یک وب‌هوک ورودی به سیستم دیگری اجازه می‌دهد با ارسال JSON به یک URL مخفی، در یک کانال پیام بفرستد. یک وب‌هوک خروجی کار معکوس را انجام می‌دهد: پیام‌هایی که با یک کلمه ماشه شروع می‌شوند یا کسانی که آن را در منوی پیام انتخاب می‌کنند را به URL شما ارسال می‌کند و پاسخ شما را منتشر می‌سازد.

کجا وب‌هوک‌ها را مدیریت کنیم

منوی تیم را باز کنید، سپس روی تنظیمات تیم کلیک کنید و در انتهای زبانه‌ها، ادغام ها را انتخاب کنید. صفحات ادغام در تیم فعلی، وب هوک های ورودی و وب هوک های خروجی را فهرست می‌کند. هر وب‌هوک متعلق به یک تیم است.

به‌طور پیش‌فرض، مدیران جامعه و مدیران سیستم می‌توانند وب‌هوک بسازند. یک مدیر سیستم می‌تواند این حق را در تنظیمات مجوزهای کنسول سیستم به نقش‌های دیگر بدهد. یک مدیر سیستم همچنین می‌تواند هر نوع را در کنسول سیستم › ادغام ها › مدیریت یکپارچه سازی غیرفعال کند: فعال کردن وب هوک های ورودی و فعال کردن وب هوک های خروجی هر دو به‌طور پیش‌فرض فعال هستند.

A channel with messages from a CI bot and from GitHub, shown as cards with fields, pipeline stages and a button
پیام‌های یکپارچه‌سازی به‌صورت کارت‌ها: فیلدها، مراحل خط لوله و یک دکمه عمل.

ساختن یک وب‌هوک ورودی

  1. در ادغام ها، وب هوک های ورودی را انتخاب کنید، سپس اضافه کردن وب هوک ورودی را بزنید.
  2. یک عنوان و یک شرح وارد کنید: این‌ها فقط در صفحات ادغام‌ها نمایش داده می‌شوند.
  3. Channel مقصد پیش‌فرض پیام‌ها را انتخاب کنید. برای یک کانال خصوصی، باید عضو آن باشید.
  4. اگر فرستنده‌ها نباید بتوانند در جای دیگری ارسال کنند، این کانال را قفل کنید را تیک بزنید.
  5. در صورت نیاز، یک نام کاربری و یک URL برای عکس پروفایل برای پیام‌های آن تنظیم کنید (به نام و نماد مراجعه کنید).
  6. صرفه جویی را انتخاب کنید. URL نمایش داده شده را کپی کنید: https://chat.example.com/hooks/<key>.
URL تنها راز است: هر کس که آن را داشته باشد می‌تواند در کانال پیام بفرستد. آن را از مخازن عمومی دور نگه دارید و اگر نشت کند، وب‌هوک را حذف کنید.

با API: POST /api/v4/hooks/incoming با {"channel_id", "display_name", "description", "username", "icon_url", "channel_locked"}؛ id پاسخ کلید است. از خط فرمان: amctl webhook create-incoming --channel <channel id> --user <user> --display-name "CI".

ارسال پیام به یک وب‌هوک ورودی

curl -X POST https://chat.example.com/hooks/xgh5ycrx1jf7mbs9w8z4c8e7ho \
  -H 'Content-Type: application/json' \
  -d '{"text": "Deploy of **api 2.4.0** finished :white_check_mark:"}'

سرور با 200 و بدنه ok پاسخ می‌دهد. همچنین application/x-www-form-urlencoded را با JSON در یک فیلد payload می‌پذیرد، همان‌طور که وب‌هوک‌های Slack انجام می‌دهند، بنابراین ابزارهای ساخته‌شده برای Slack معمولاً بدون تغییر کار می‌کنند.

فیلدمعنا
textمتن پیام به صورت Markdown. الزامی است مگر اینکه attachments وجود داشته باشد. متنی که از حد مجاز پیام سرور بلندتر باشد، به چند پیام تقسیم می‌شود.
channelیک کانال دیگر از جامعه وب‌هوک، با نام (ops-alerts یا #ops-alerts)، یا @username برای یک پیام مستقیم از طرف مالک وب‌هوک. وقتی وب‌هوک به کانال خود قفل شده باشد، درخواست رد می‌شود. نام قدیمی town-square هنوز به کانال پیش‌فرض جامعه می‌رسد که اکنون general نامیده می‌شود.
username, icon_url, icon_emojiنام و تصویر نمایش داده‌شده، در صورتی که سرور اجازه تغییرات را بدهد.
attachmentsپیوست‌های پیام که به صورت کارت نمایش داده می‌شوند (در ادامه).
propsویژگی‌های اضافی ذخیره‌شده در پیام، برای برنامه‌هایی که آن‌ها را می‌خوانند. ارسال پیام در یک کانال تالار گفتگو نیازمند props.am_thread_title (۱ تا ۱۰۰ کاراکتر) است: بدون این ویژگی، وب‌هوک رد می‌شود (به تالارهای گفتگو فقط موضوع را می‌پذیرند مراجعه کنید).
typeیک نوع پیام سفارشی، مانند custom_poll، برای اپلیکیشنی که آن را رسم می‌کند. انواعی که با system_ شروع می‌شوند، رد می‌شوند.
root_idشناسه (ID) اولین پیام یک رشته، برای پاسخ‌دهی در همان رشته.
priorityاولویت پیام، برای مثال {"priority": "urgent"}.
silenttrue پیام را بدون اعلان‌های push ارسال می‌کند.

هر پیامی که یک وب‌هوک منتشر می‌کند، یک برچسب بات کنار نامش دارد، حتی وقتی زیر نام سازنده‌اش نمایش داده می‌شود، تا افراد بتوانند آن را از پیام یک شخص واقعی تشخیص دهند. پیام‌های وب‌هوک هرگز وب‌هوک‌های خروجی را فعال نمی‌کنند.

نام و آیکون

یک وب‌هوک به‌عنوان شخصی که آن را ایجاد کرده ارسال می‌کند، مگر اینکه سرور اجازه جایگزینی بدهد. دو تنظیم در کنسول سیستم › ادغام ها › مدیریت یکپارچه سازی که هر دو به‌طور پیش‌فرض غیرفعال هستند، این را تغییر می‌دهند:

  • ادغام ها را برای لغو نام های کاربری فعال کنید (ServiceSettings.EnablePostUsernameOverride): نام کاربری وب‌هوک یا username درخواست به‌جای آن نمایش داده می‌شود؛ بدون هیچ‌کدام، نام webhook است.
  • ادغام ها را برای لغو نمادهای عکس نمایه فعال کنید (ServiceSettings.EnablePostIconOverride): عکس پروفایل وب‌هوک، یا icon_url یا icon_emoji درخواست نمایش داده می‌شود.

مقدار موجود در درخواست بر مقدار ذخیره‌شده روی وب‌هوک اولویت دارد.

پیوست‌ها

پیوست‌ها محتوای ساختاریافته‌ای را زیر متن اضافه می‌کنند. آن‌ها از قالب پیوست پیام Slack پیروی می‌کنند:

{
  "text": "Build failed on `main`",
  "attachments": [{
    "fallback": "main #1902 failed",
    "color": "#d24b4e",
    "author_name": "GitHub Actions",
    "author_icon": "https://chat.example.com/static/ci.png",
    "title": "main #1902 failed",
    "title_link": "https://ci.example.com/runs/1902",
    "text": "Commit `0f4d8e2` by Jonas Weber",
    "fields": [
      {"title": "Branch", "value": "zephyr-3.7", "short": true},
      {"title": "Duration", "value": "3m 40s", "short": true}
    ],
    "footer": "Lumen CI",
    "ts": 1760000000
  }]
}
فیلدمعنا
fallbackمتن ساده برای جاهایی که نمی‌توانند کارت را نمایش دهند، مانند اعلان‌ها.
colorنوار رنگی: یک رنگ hex، یا good، warning، danger.
pretextمتن بالای کارت.
author_name, author_link, author_iconیک خط سربرگ کوچک.
title, title_linkعنوان کارت، در صورت نیاز یک پیوند.
textبدنه کارت، به صورت Markdown.
fieldsیک فهرست از {"title", "value", "short"}؛ فیلدهای short کنار هم قرار می‌گیرند.
image_url, thumb_urlیک تصویر بزرگ در پایین، یا یک تصویر کوچک در کنار.
footer, footer_icon, tsیک خط پاورقی و یک زمان (ثانیه Unix).
actionsدکمه‌ها و منوها: به پیام‌های تعاملی مراجعه کنید.

کارت‌ها: مراحل و نمودارها

Antimatter دو فیلد به پیوست‌ها اضافه می‌کند که در رابط کاربری پیش‌فرض نمایش داده می‌شوند:

  • stages: مراحل یک خط لوله به‌صورت برچسب‌های کوچک (pill)، حداکثر ۲۰ مورد. هر کدام به شکل {"name", "status"} است و وضعیت آن یکی از passed، failed، running، pending، skipped یا canceled است.
  • chart: یک نمودار خطی کوچک از مقادیر اخیر، به شکل {"values": [2 to 200 numbers], "threshold": number, "label": "…"}. آستانه به‌صورت یک خط‌چین رسم می‌شود تا حد مجاز هشدار را نشان دهد.
{
  "attachments": [{
    "color": "danger",
    "title": "main #1902 failed",
    "stages": [
      {"name": "build", "status": "failed"},
      {"name": "unit", "status": "skipped"},
      {"name": "publish", "status": "skipped"}
    ]
  }, {
    "color": "warning",
    "title": "API latency above 400 ms",
    "chart": {"values": [210, 230, 260, 390, 450, 470], "threshold": 400, "label": "p95 latency, ms"}
  }]
}

رابط کاربری کلاسیک و سایر کلاینت‌ها این دو فیلد را نادیده می‌گیرند، بنابراین اطلاعات ضروری را در text یا fields نیز قرار دهید.

ایجاد یک وب‌هوک خروجی

یک وب‌هوک خروجی کانال‌های عمومی یک جامعه را زیر نظر دارد. یک پیام را به URL شما ارسال می‌کند یا وقتی کلمه اول پیام با یکی از کلمات ماشه آن مطابقت دارد، یا وقتی کسی آن را در منوی پیام انتخاب می‌کند (یک عملیات پیام).

  1. در ادغام ها، وب هوک های خروجی را انتخاب کنید، سپس اضافه کردن وب هوک خروجی را بزنید.
  2. عنوان و شرح را پر کنید.
  3. نوع محتوا درخواست را انتخاب کنید: application/x-www-form-urlencoded یا application/json.
  4. یک کانال انتخاب کنید، کلمات محرک (یکی در هر خط) را وارد کنید، یا هر دو. با یک کانال و بدون کلمات محرک، هر پیام آن کانال ارسال می‌شود. با هر دو، پیام باید با هر دو مطابقت داشته باشد.
  5. زیر ماشه وقتی، کلمه اول دقیقا‌ با یک کلمه ماشه مطابقت دارد، کلمه اول با یک کلمه ماشه شروع می شود، یا از منوی پیام را انتخاب کنید. با از منوی پیام، کلمات ماشه ناپدید می‌شوند، کانال اختیاری است (بدون آن، عملیات در هر کانال عمومی جامعه ارائه می‌شود) و عنوان الزامی است: این نام عملیات در منو است.
  6. URL های برگشت به تماس (یکی در هر خط) را وارد کنید. هر URL هر پیام مطابقت‌دار را دریافت می‌کند.
  7. اختیاری نام کاربری و عکس پروفایل مورد استفاده برای پاسخ‌ها را تنظیم کنید. برای یک عملیات از منوی پیام، فیلد آیکون جایگزین عکس پروفایل می‌شود: URL یک تصویر .png یا .jpg یا، در رابط پیش‌فرض Antimatter، یک تصویر بارگذاری‌شده. منو آن را با رنگ خاکستری نمایش می‌دهد؛ بدون آن، عملیات یک آیکون خنثی دریافت می‌کند.
  8. صرفه جویی را انتخاب کنید و توکن نمایش‌داده‌شده را کپی کنید. سرویس شما از آن برای اطمینان از اینکه درخواست‌ها از سرور شما می‌آیند، استفاده می‌کند.

با استفاده از API: POST /api/v4/hooks/outgoing با {"team_id", "channel_id", "trigger_words", "trigger_when", "callback_urls", "content_type", "display_name"} (trigger_when: 0 برای تطبیق دقیق، 1 برای «شروع با»، 2 برای «از منوی پیام»). وب‌هوک با trigger_when برابر 2، کلمات ماشه‌ای نمی‌گیرد و به display_name نیاز دارد. آیکون آن را با POST /api/v4/hooks/outgoing/{hook_id}/icon بارگذاری کنید (multipart، فیلد image: PNG، JPEG یا GIF، به صورت PNG با ابعاد 128 پیکسل ذخیره می‌شود)؛ در این صورت icon_url به GET /api/v4/hooks/outgoing/{hook_id}/icon اشاره می‌کند.

The outgoing webhook form with Trigger When set to From the message menu, and the Icon field below it
در بخش «Trigger When» گزینه از منوی پیام را انتخاب کنید و فیلد آیکون را پر کنید.
اگر سرویس شما در یک شبکه خصوصی قرار دارد، یک مدیر سیستم باید آدرس آن را در اتصالات داخلی غیرقابل اعتماد را مجاز کنید (ServiceSettings.AllowedUntrustedInternalConnections) مجاز کند. در غیر این صورت، سرور به آدرس‌های خصوصی دسترسی پیدا نمی‌کند.

درخواست خروجی

Antimatter یک درخواست POST با این فیلدها ارسال می‌کند، به‌صورت JSON یا فرم-کدگذاری‌شده بسته به نوع محتوا:

{
  "token": "6kd1ofo5ojr5zgu5ipfipybgnc",
  "team_id": "…",
  "team_domain": "lumen-labs",
  "channel_id": "…",
  "channel_name": "ops-alerts",
  "timestamp": 1760010000000,
  "user_id": "…",
  "user_name": "priya",
  "post_id": "…",
  "text": "deploy api 2.4.0",
  "trigger_word": "deploy",
  "file_ids": ""
}

قبل از هر کاری، token را با توکن وب‌هوک مقایسه کنید. در نسخه فرم‌کدگذاری‌شده، timestamp بر حسب ثانیه است، نه میلی‌ثانیه. سرور تا زمانی که مهلت انتظار درخواست یکپارچه‌سازی اجازه می‌دهد (به‌طور پیش‌فرض ۳۰ ثانیه، ServiceSettings.OutgoingIntegrationRequestsTimeout) برای پاسخ شما منتظر می‌ماند.

پاسخ به یک وب‌هوک خروجی

برای ارسال پاسخ، با JSON پاسخ دهید. برای ارسال هیچ‌چیز، با بدنه خالی پاسخ دهید.

{
  "text": "Deploying **api 2.4.0** to staging…",
  "response_type": "comment",
  "username": "deploy-bot",
  "icon_url": "https://chat.example.com/static/deploy.png"
}
  • text و attachments: پاسخ شما. بدون هیچ‌کدام از این دو، چیزی ارسال نمی‌شود.
  • response_type: comment پاسخ را در رشته پیام محرک منتشر می‌کند؛ در غیر این صورت، به کانال ارسال می‌شود.
  • username، icon_url: در صورتی که سرور اجازه تغییرات را بدهد، نمایش داده می‌شوند؛ در غیر این صورت، مقادیر خود وب‌هوک استفاده می‌شوند.
  • props، type، priority: مانند وب‌هوک‌های ورودی.

پاسخ به‌عنوان سازنده وب‌هوک و با نام جایگزین (در صورت وجود) منتشر می‌شود. برای هر چیزی طولانی‌تر از یک پاسخ سریع، فوراً پاسخ دهید و بعداً با یک وب‌هوک ورودی یا API منتشر کنید.

اقدامات پیام

یک عملیات پیام، یک وب‌هوک خروجی است که ماشه وقتی آن روی از منوی پیام تنظیم شده است. این عملیات هرگز برای پیام‌های ارسال‌شده فعال نمی‌شود. به جای آن، کاربران آن را در منوی پیام می‌بینند: عملیات پیام (⋯) › اقدامات بیشتر، زیر عنوان ادغام ها، همراه با آیکون آن. در رابط کلاسیک، عملیات پیام نمایش داده نمی‌شود. با انتخاب آن، همان یک پیام به آدرس‌های بازگشت (callback) ارسال می‌شود و یک اعلان کوتاه با عنوان Sent to همراه با نام عملیات نمایش داده می‌شود، یا ephemeral_text شما نمایش داده می‌شود.

  • محل نمایش: در کانال مربوط به وب‌هوک یا، در صورتی که کانالی مشخص نشده باشد، در تمام کانال‌های عمومی آن جامعه. فقط کانال‌های عمومی دارای عملیات پیام هستند.
  • میهمانان فقط به عملیات‌هایی دسترسی دارند که به کانالی که در آن عضو هستند متصل شده‌اند، نه به عملیات‌های سراسری جامعه.
  • کانال‌های بایگانی‌شده و فقط‌خواندنی: پیام همچنان می‌تواند ارسال شود. بایگانی یک کانال، وب‌هوک‌های متصل به آن را حذف می‌کند، بنابراین یک کانال بایگانی‌شده فقط عملیات‌های سراسری جامعه را حفظ می‌کند. پاسخی که کاربر نمی‌تواند در آن کانال ارسال کند، فقط برای همان کاربر نمایش داده می‌شود.
  • محدودیت نرخ: هر کاربر می‌تواند در هر دقیقه 10 عملیات پیام را اجرا کند، پس از یک انفجار اولیه 5 تایی. در صورت عبور از این حد، سرور پاسخ 429 را برمی‌گرداند.
  • شبکه‌های خصوصی: مانند سایر وب‌هوک‌های خروجی، آدرس‌های داخلی باید در اتصالات داخلی غیرقابل اعتماد را مجاز کنید مجاز شوند.

درخواست

بار داده (payload) به صورت JSON یا فرم-کدگذاری‌شده ارسال می‌شود، همان‌طور که نوع محتوای وب‌هوک مشخص می‌کند:

{
  "token": "6kd1ofo5ojr5zgu5ipfipybgnc",
  "trigger": "message_action",
  "team_id": "…",
  "team_domain": "lumen-labs",
  "channel_id": "…",
  "channel_name": "ops-alerts",
  "timestamp": 1760010000000,
  "user_id": "…",
  "user_name": "priya",
  "post_id": "…",
  "post_root_id": "",
  "post_create_at": 1760009000000,
  "post_user_id": "…",
  "post_user_name": "jonas",
  "permalink": "https://chat.example.com/lumen-labs/pl/…",
  "text": "The staging database is full again",
  "files": [{"id": "…", "name": "df.txt", "link": "https://chat.example.com/api/v4/files/…"}],
  "priority": "",
  "requested_ack": false,
  "burn_on_read": false
}
  • user_id و user_name مربوط به شخصی است که عملیات را انتخاب کرده است؛ post_user_id و post_user_name مربوط به نویسنده پیام هستند.
  • فقط همان پیام ارسال می‌شود، هرگز بقیه رشته (thread) آن.
  • files فقط در صورتی فایل‌های پیام را فهرست می‌کند که شخصی که عملیات را انتخاب کرده باشد، مجاز به دانلود آن‌ها باشد. دانلود یک link مانند هر فایل دیگری از API، به یک نشست (session) یا توکن نیاز دارد.
  • پیام «سوزان‌شده پس از خواندن» بدون متن و فایل‌هایش ارسال می‌شود و burn_on_read روی true تنظیم شده است.
  • در فرمت فرم، فایل‌ها به‌صورت فیلدهای تکرارشونده file_id، file_name و file_link و به همان ترتیب ارسال می‌شوند.

پاسخ

پاسخ‌دهی مانند هر وب‌هوکی خروجی (به پاسخ به وب‌هوک خروجی مراجعه کنید): text یا attachments یک پاسخ در کانال منتشر می‌کند و "response_type": "comment" آن را در رشته پیام منتشر می‌کند. همچنین می‌توانید با ephemeral_text (تا ۳۰۰ کاراکتر) پاسخ دهید: این متن فقط برای شخصی که عملیات را انتخاب کرده است، در اعلان نمایش داده می‌شود. بدنه خالی هیچ‌چیز منتشر نمی‌کند.

{"ephemeral_text": "Ticket OPS-412 created"}

با API

  • GET /api/v4/channels/{channel_id}/message_actions: عملیات‌هایی که می‌توانید در یک کانال انتخاب کنید، همراه با id، display_name، description و icon_url. هیچ توکن یا URL بازخوردی برگردانده نمی‌شود.
  • POST /api/v4/posts/{post_id}/message_actions/{hook_id}: یک عملیات را روی پیامی که می‌توانید بخوانید اجرا می‌کند. پاسخ {"ephemeral_text"} است.

وقتی یک وب‌هوک کار نمی‌کند

  • 501 از URL هوک: وب‌هوک‌های ورودی روی سرور غیرفعال شده‌اند.
  • 400 "Failed to decode the payload…": JSON نامعتبر است، یا نام فیلد فرم payload نیست. "No text specified." به این معنی است که درخواست نه text دارد و نه attachments.
  • 403: وب‌هوک به کانال دیگری قفل شده است، یا مالک آن دیگر نمی‌تواند کانال را بخواند.
  • یک وب‌هوک خروجی هرگز فعال نمی‌شود: کانال خصوصی است، محرک اولین کلمه نیست، پیام از یک وب‌هوک آمده است، یا وب‌هوک برای فعال‌سازی از منوی پیام تنظیم شده است.
  • یک عملیات پیام در منو نیست: کانال خصوصی است، عملیات به کانال دیگری متصل شده است، شخص یک مهمان است و عملیات کانالی ندارد، یا وب‌هوک‌های خروجی غیرفعال شده‌اند.
  • 404 هنگام اجرای عملیات پیام: عملیات وجود ندارد یا کانال آن پیام را برای آن شخص پوشش نمی‌دهد. 429: شخص بیش از ۱۰ عملیات در یک دقیقه اجرا کرده است. 502: هیچ‌یک از URLهای بازخورد قابل دسترسی نبودند (دلیل در لاگ آمده است).
  • ارسال پیام به تالار گفتگو رد می‌شود: پیام وب‌هوک نیازمند یک عنوان است (props.am_thread_title)؛ خطا به جای یک شکست عمومی، دلیل را مشخص می‌کند، مانند app.post.forum.title_required.app_error (به انواع کانال مراجعه کنید).
  • گزارش‌ها: با فعال بودن فعال کردن Webhook Debugging (LogSettings.EnableWebhookDebugging) و تنظیم سطح گزارش‌دهی روی DEBUG، سرور داده‌های درخواست‌های ورودی ناموفق را ثبت می‌کند. فراخوانی‌های خروجی ناموفق با عنوان Outgoing Webhook POST failed ثبت می‌شوند.