Webhook
Webhook đến cho phép một hệ thống khác đăng bài vào một kênh bằng cách gửi JSON đến một URL bí mật. Webhook đi làm điều ngược lại: nó gửi tin nhắn đến URL của bạn, bao gồm các tin nhắn bắt đầu bằng từ kích hoạt hoặc các tin nhắn mà người dùng chọn trong menu tin nhắn, và đăng tải câu trả lời của bạn.
Quản lý webhook ở đâu
Mở hồ sơ của bạn ở góc trên bên phải, sau đó chọn Tích Hợp. Các trang tích hợp của cộng đồng hiện tại liệt kê Webhooks đến và Webhook đi. Mỗi webhook thuộc về một cộng đồng.
By default, community admins and system admins can create webhooks. A system admin can give the right to other roles in the permission settings of the System Console. A system admin can also turn each kind off in System Console › Integrations › Integration Management: Enable Incoming Webhooks and Enable Outgoing Webhooks are both on by default.

Tạo webhook đến
- Trong Tích Hợp, chọn Webhooks đến, sau đó chọn Webhooks đến.
- Điền Tiêu đề và Mô tả: chúng chỉ hiển thị trên các trang tích hợp.
- Chọn Kênh mà tin nhắn sẽ gửi đến theo mặc định. Đối với kênh riêng tư, bạn phải là thành viên của kênh đó.
- Đánh dấu Khóa kênh này nếu người gửi không được phép đăng bài ở nơi khác.
- Tùy chọn: đặt Tên người dùng và URL Hình ảnh hồ sơ cho tin nhắn của nó (xem Tên và biểu tượng).
- Chọn Lưu. Sao chép URL hiển thị:
https://chat.example.com/hooks/<key>.
Dùng API: POST /api/v4/hooks/incoming với {"channel_id", "display_name", "description", "username", "icon_url", "channel_locked"}; trường id trong phản hồi là khóa. Từ dòng lệnh: amctl webhook create-incoming --channel <channel id> --user <user> --display-name "CI".
Gửi tin nhắn đến webhook đến
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:"}'
Máy chủ trả về 200 với nội dung ok. Nó cũng chấp nhận application/x-www-form-urlencoded với JSON trong trường payload, giống như webhook của Slack, nên các công cụ làm cho Slack thường hoạt động không cần thay đổi.
| Trường | Ý nghĩa |
|---|---|
text | Tin nhắn, ở định dạng Markdown. Bắt buộc trừ khi có attachments. Tin nhắn dài hơn giới hạn tin nhắn của máy chủ sẽ được chia thành nhiều tin nhắn. |
channel | Một kênh khác của cộng đồng chứa webhook, theo tên (ops-alerts hoặc #ops-alerts), hoặc @username cho một tin nhắn trực tiếp từ chủ sở hữu của webhook. Yêu cầu sẽ bị từ chối nếu webhook bị khóa vào kênh của nó. Tên cũ town-square vẫn trỏ đến kênh mặc định của cộng đồng, hiện được gọi là general. |
username, icon_url, icon_emoji | Tên và hình ảnh để hiển thị, khi máy chủ cho phép ghi đè. |
attachments | Tệp đính kèm của tin nhắn, hiển thị dưới dạng thẻ (phía dưới). |
props | Các thuộc tính bổ sung được lưu trên tin nhắn, dành cho các ứng dụng đọc chúng. |
type | Một loại bài đăng tùy chỉnh, chẳng hạn như custom_poll, cho một ứng dụng hiển thị nó. Các loại bắt đầu bằng system_ sẽ bị từ chối. |
root_id | ID của tin nhắn đầu tiên của một chủ đề, để trả lời trong chủ đề đó. |
priority | Độ ưu tiên của tin nhắn, ví dụ {"priority": "urgent"}. |
silent | true gửi tin nhắn mà không có thông báo đẩy. |
Mọi tin nhắn do webhook đăng đều có thẻ BOT bên cạnh tên của nó, ngay cả khi nó hiển thị dưới tên người tạo, để mọi người có thể phân biệt với tin nhắn của người dùng thực. Tin nhắn từ webhook không bao giờ kích hoạt các webhook đi.
Tên và biểu tượng
Webhook đăng bài dưới danh tính của người đã tạo nó, trừ khi máy chủ cho phép ghi đè. Hai cài đặt trong Bảng điều khiển Hệ thống › Tích hợp › Quản lý tích hợp, cả hai đều tắt theo mặc định, thay đổi điều đó:
- Bật tích hợp để ghi đè tên người dùng (
ServiceSettings.EnablePostUsernameOverride): Tên người dùng của webhook hoặcusernametrong yêu cầu sẽ được hiển thị; nếu không có cả hai, tên sẽ làwebhook. - Bật tích hợp để ghi đè các biểu tượng ảnh hồ sơ (
ServiceSettings.EnablePostIconOverride): Ảnh hồ sơ của webhook, hoặcicon_urlhoặcicon_emojitrong yêu cầu, sẽ được hiển thị.
Giá trị trong yêu cầu sẽ ưu tiên hơn giá trị đã lưu trên webhook.
Tệp đính kèm
Tệp đính kèm thêm nội dung có cấu trúc bên dưới văn bản. Chúng tuân theo định dạng tệp đính kèm tin nhắn của 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
}]
}
| Trường | Ý nghĩa |
|---|---|
fallback | Văn bản thuần túy cho các nơi không thể hiển thị thẻ, chẳng hạn như thông báo. |
color | Thanh màu: một màu hex, hoặc good, warning, danger. |
pretext | Văn bản phía trên thẻ. |
author_name, author_link, author_icon | Một dòng tiêu đề nhỏ. |
title, title_link | Tiêu đề của thẻ, tùy chọn là một liên kết. |
text | Nội dung chính của thẻ, ở định dạng Markdown. |
fields | Một danh sách {"title", "value", "short"}; các trường short nằm cạnh nhau. |
image_url, thumb_url | Một hình ảnh lớn bên dưới, hoặc một hình ảnh nhỏ ở bên cạnh. |
footer, footer_icon, ts | Một dòng chân và một thời gian (giây Unix). |
actions | Nút và menu: xem Tin nhắn tương tác. |
Thẻ: giai đoạn và biểu đồ
Antimatter thêm hai trường vào tệp đính kèm, được hiển thị bởi giao diện mặc định:
stages: các bước của một quy trình dưới dạng nhãn, tối đa 20. Mỗi nhãn có dạng{"name", "status"}, với trạng thái làpassed,failed,running,pending,skippedhoặccanceled.chart: một biểu đồ đường nhỏ hiển thị các giá trị gần đây,{"values": [2 to 200 numbers], "threshold": number, "label": "…"}. Ngưỡng được vẽ bằng đường đứt đoạn, đại diện cho giới hạn của cảnh báo.
{
"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"}
}]
}
Giao diện cổ điển và các client khác sẽ bỏ qua hai trường này, vì vậy hãy đưa các thông tin quan trọng vào text hoặc fields.
Tạo webhook đi ra
Webhook đi theo dõi các kênh Công khai của một cộng đồng. Nó gửi tin nhắn đến URL của bạn khi từ đầu tiên của tin nhắn đối sánh chính xác với một trong các từ kích hoạt của nó, hoặc khi một người dùng chọn nó trong menu của tin nhắn (một thao tác trên tin nhắn).
- Trong Tích Hợp, chọn Webhook đi, sau đó chọn Thêm Webhook đi.
- Điền Tiêu đề và Mô tả.
- Chọn Loại Nội dung của yêu cầu:
application/x-www-form-urlencodedhoặcapplication/json. - Chọn một Kênh, nhập Các từ kích hoạt (Mỗi từ một dòng), hoặc cả hai. Nếu có kênh và không có từ kích hoạt, mọi tin nhắn của kênh đó sẽ được gửi. Nếu có cả hai, tin nhắn phải khớp cả hai.
- Trong phần Kích hoạt Khi nào, chọn Từ đầu tiên đối sánh chính xác với từ kích hoạt, Từ đầu tiên bắt đầu bằng một từ kích hoạt, hoặc Từ menu tin nhắn. Khi chọn Từ menu tin nhắn, các từ kích hoạt sẽ biến mất, trường Kênh là tùy chọn (nếu không có, thao tác sẽ được đề xuất trong mọi kênh công khai của cộng đồng), và trường Tiêu đề là bắt buộc: đây là tên của thao tác trong menu.
- Nhập Callback URLs (Mỗi dòng 1 liên kết). Mỗi URL sẽ nhận mọi tin nhắn khớp.
- Tùy chọn, hãy đặt Tên người dùng và Ảnh hồ sơ được sử dụng cho các phản hồi. Đối với một thao tác từ menu tin nhắn, trường Biểu tượng thay thế cho Ảnh hồ sơ: đây là URL của một tệp ảnh .png hoặc .jpg hoặc, trong giao diện mặc định của Antimatter, một tệp ảnh đã tải lên. Menu sẽ hiển thị nó màu xám; nếu không có, thao tác sẽ nhận được một biểu tượng trung tính.
- Chọn Lưu và sao chép token được hiển thị. Dịch vụ của bạn sẽ sử dụng nó để kiểm tra rằng các yêu cầu đến từ máy chủ của bạn.
Thông qua API: POST /api/v4/hooks/outgoing với {"team_id", "channel_id", "trigger_words", "trigger_when", "callback_urls", "content_type", "display_name"} (trigger_when: 0 cho khớp chính xác, 1 cho "bắt đầu bằng", 2 cho "từ menu tin nhắn"). Webhook có trigger_when là 2 không cần từ kích hoạt và bắt buộc phải có display_name. Tải lên biểu tượng của nó bằng POST /api/v4/hooks/outgoing/{hook_id}/icon (multipart, trường image: PNG, JPEG hoặc GIF, được lưu dưới dạng PNG 128 px); icon_url của nó sẽ trỏ đến GET /api/v4/hooks/outgoing/{hook_id}/icon.
ServiceSettings.AllowedUntrustedInternalConnections). Nếu không, máy chủ sẽ không gọi các địa chỉ riêng.Yêu cầu đi ra
Antimatter gửi một POST với các trường sau, dưới dạng JSON hoặc form-encoded tùy theo loại nội dung:
{
"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": ""
}
So sánh token với token của webhook trước khi thực hiện bất kỳ thao tác nào. Trong phiên bản form-encoded, timestamp được tính bằng giây thay vì mili giây. Máy chủ sẽ chờ câu trả lời của bạn trong khoảng thời gian cho phép bởi Thời gian chờ yêu cầu tích hợp (mặc định là 30 giây, ServiceSettings.OutgoingIntegrationRequestsTimeout).
Trả lời một webhook đi
Để đăng một phản hồi, hãy trả lời bằng JSON. Để không đăng gì, hãy trả lời với một body rỗng.
{
"text": "Deploying **api 2.4.0** to staging…",
"response_type": "comment",
"username": "deploy-bot",
"icon_url": "https://chat.example.com/static/deploy.png"
}
textvàattachments: nội dung phản hồi. Nếu không có cả hai, sẽ không có gì được đăng.response_type:commentsẽ đăng phản hồi vào chủ đề của tin nhắn kích hoạt; nếu không, nó sẽ được đăng vào kênh.username,icon_url: được hiển thị khi máy chủ cho phép ghi đè; nếu không, giá trị của chính webhook sẽ được sử dụng.props,type,priority: giống như với webhook đến.
Phản hồi sẽ được đăng dưới danh tính của người tạo webhook, dưới tên đã ghi đè nếu có. Đối với nội dung dài hơn một câu trả lời ngắn, hãy trả lời ngay lập tức và đăng sau đó bằng webhook đến hoặc API.
Hành động tin nhắn
Hành động cho tin nhắn là một webhook đi ra có Kích hoạt Khi nào được đặt thành Từ menu tin nhắn. Nó không bao giờ được kích hoạt bởi các tin nhắn đã gửi. Thay vào đó, người dùng sẽ thấy nó trong menu của một tin nhắn: Hành động cho tin nhắn (⋯) › Hành động khác, dưới tiêu đề Tích Hợp, cùng với biểu tượng của nó. Giao diện cổ điển không hiển thị các hành động cho tin nhắn. Khi chọn nó, tin nhắn đó sẽ được gửi đến các URL gọi lại, và một thông báo ngắn sẽ hiển thị Đã gửi đến tên của hành động, hoặc hiển thị ephemeral_text của bạn.
- Nơi hiển thị: trong kênh của webhook, hoặc, nếu không có kênh, trong mọi kênh công khai của cộng đồng đó. Chỉ các kênh công khai mới có hành động cho tin nhắn.
- Khách chỉ nhận được các hành động được liên kết với kênh mà họ đang tham gia, không bao gồm các hành động trên toàn cộng đồng.
- Kênh đã lưu trữ và chỉ đọc: tin nhắn vẫn có thể được gửi. Việc lưu trữ một kênh sẽ xóa các webhook được liên kết với nó, do đó một kênh đã lưu trữ chỉ giữ lại các hành động trên toàn cộng đồng. Một câu trả lời mà người dùng không thể đăng vào kênh đó sẽ chỉ được hiển thị cho riêng họ.
- Giới hạn tần suất: mỗi người có thể thực hiện 10 hành động cho tin nhắn mỗi phút, sau một đợt tăng vọt là 5. Vượt quá mức này, máy chủ sẽ trả về
429. - Mạng riêng: giống như các webhook đi ra khác, các địa chỉ nội bộ phải được cho phép trong Cho phép các kết nối nội bộ không đáng tin cậy vào.
Yêu cầu
Dữ liệu tải lên (payload) được gửi dưới dạng JSON hoặc form-encoded, tùy theo loại nội dung của webhook:
{
"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_idvàuser_namelà người đã chọn hành động;post_user_idvàpost_user_namelà tác giả của tin nhắn.- Chỉ tin nhắn đó được gửi, không bao gồm phần còn lại của chủ đề.
filesliệt kê các tệp của tin nhắn chỉ khi người đã chọn hành động có quyền tải chúng xuống. Việc tải xuống mộtlinkcần phiên hoặc token, giống như bất kỳ tệp nào của API.- Tin nhắn tự hủy sau khi đọc được gửi đi không kèm nội dung và tệp, với
burn_on_readđược đặt thànhtrue. - Khi mã hóa dạng biểu mẫu, các tệp được gửi dưới dạng các trường
file_id,file_namevàfile_linklặp lại, theo cùng một thứ tự.
Câu trả lời
Trả lời như với bất kỳ webhook đi nào (xem Trả lời webhook đi): text hoặc attachments sẽ đăng một phản hồi trong kênh, và "response_type": "comment" sẽ đăng nó trong chủ đề của tin nhắn. Bạn cũng có thể trả lời bằng ephemeral_text (cắt xuống còn 300 ký tự): nó chỉ hiển thị cho người đã chọn hành động, trong thông báo. Thân tin nhắn trống sẽ không đăng gì.
{"ephemeral_text": "Ticket OPS-412 created"}
Bằng API
GET /api/v4/channels/{channel_id}/message_actions: các hành động bạn có thể chọn trong một kênh, vớiid,display_name,descriptionvàicon_url. Không có token hay URL callback nào được trả về.POST /api/v4/posts/{post_id}/message_actions/{hook_id}: chạy một hành động trên một tin nhắn mà bạn có thể đọc. Nó trả về{"ephemeral_text"}.
Khi một webhook không hoạt động
- 501 từ hook URL: webhook đến đã bị tắt trên máy chủ.
- 400 "Failed to decode the payload…": JSON không hợp lệ, hoặc trường form không có tên là
payload. "No text specified." có nghĩa là yêu cầu không có cảtextlẫnattachments. - 403: webhook bị khóa cho một kênh khác, hoặc chủ sở hữu của nó không còn có thể đọc kênh đó.
- Webhook đi không bao giờ kích hoạt: kênh là riêng tư, từ khóa kích hoạt không phải từ đầu tiên, tin nhắn đến từ một webhook, hoặc webhook được đặt để kích hoạt Từ menu tin nhắn.
- Hành động tin nhắn không có trong menu: kênh là riêng tư, hành động được liên kết với kênh khác, người dùng là khách và hành động không có kênh, hoặc webhook đi đã bị tắt.
- 404 khi chạy hành động tin nhắn: hành động không tồn tại, hoặc nó không bao phủ kênh của tin nhắn đó cho người dùng đó. 429: người dùng đã chạy hơn 10 hành động trong một phút. 502: không thể truy cập bất kỳ URL callback nào (nhật ký có chứa lý do).
- Logs: khi bật Bật Webhook Debugging (
LogSettings.EnableWebhookDebugging) và đặt mức log ởDEBUG, máy chủ sẽ ghi log các payload của các yêu cầu đến thất bại. Các cuộc gọi đi thất bại sẽ được ghi log làOutgoing Webhook POST failed.