透過 UnifyPort 新增及移除訊息表情回應
透過 UnifyPort 新增訊息表情回應,應呼叫 POST /v1/messages/reaction,提交所選帳戶、對話、訊息、原訊息發送者及 emoji。如要移除已連接帳戶的現有回應,保留同一目標並傳送 emoji: ""。最重要的分別是:sender_id 代表原訊息作者,不是操作員,亦不是任意一位你想更改其回應的用戶。
重點
- 目前發送操作支援
whatsapp和telegram;接收回應事件是另一項能力。 - 目標應來自所選原訊息,不是回應事件本身的訊息 ID。
- 回應其他人的訊息時,明確填入
sender_id;省略時預設為已連接帳戶本身。 - 新增與移除應是明確指令,不應是遇到錯誤便反覆重試的切換開關。
將請求欄位對應至原訊息
訊息回應 API 文件定義的是對現有訊息的操作,不是發送一則表情文字,亦不使用引用回覆 token。
| 請求欄位 | 從已儲存的 message.received 事件取值 |
|---|---|
account_id | 頂層 account_id |
conversation_id | data.conversation.id |
message_id | data.message.id |
sender_id | data.sender.id,即原訊息作者 |
emoji | 所選表情;移除時為空字串 |
群組對話中,對話識別群組,發送者識別成員。不要因為私人對話中的值看起來相似,就將發送者當成對話目標。保留平台傳回的完整識別碼,不要用聯絡人名稱或電話號碼自行組合。
如果由 message.reaction 事件開始,data.message.id 代表回應本身,data.message.target_message_id 才指向原訊息。事件的發送者是作出回應的人,不一定是原訊息作者。應先找出已儲存的原訊息,再建立新操作。回應 webhook 處理教學處理接收及狀態投影;本文處理主動發出請求。
建立明確的新增或移除請求
以下 JavaScript 是請求建構示例,不是已執行的整合測試或完整接收器。輸入必須是已驗證簽署、持久儲存,並由獲授權操作員選取的原訊息事件。函式名稱及錯誤文字屬應用程式本身。
function buildReactionRequest(original, emoji) {
if (original.type !== 'message.received' ||
!['whatsapp', 'telegram'].includes(original.provider)) {
throw new Error('Select a supported original message');
}
const conversation = original.data?.conversation;
const message = original.data?.message;
const sender = original.data?.sender;
if (!original.account_id || !conversation?.id ||
!message?.id || !sender?.id) {
throw new Error('Original message context is incomplete');
}
if (typeof emoji !== 'string') {
throw new Error('Choose an emoji or an empty string');
}
return {
account_id: original.account_id,
conversation_id: conversation.id,
message_id: message.id,
sender_id: sender.id,
emoji
};
}
傳入 "👍" 請求新增回應,傳入 "" 請求移除。此函式只檢查上下文及資料類型,不保證上游接受任何表情。不要以 null、省略欄位或自行新增的 remove 標記取代空字串。
由後端以 X-Api-Key 將產生的 JSON 傳至 POST /v1/messages/reaction,不要把金鑰放進瀏覽器程式碼。發送前確認操作員對訊息帳戶及訊息的存取權,並固定所選目標,避免新訊息到達後改變操作對象。
如果需要的是引用原訊息的一句回覆,而非表情回應,應使用獨立的 WhatsApp 引用回覆流程。其不透明 reply_token 並非回應識別碼。
按操作能力啟用按鈕,不要只看事件支援
目前的平台操作矩陣及 webhook 事件矩陣描述不同能力:
| 平台 | 透過此 API 發送回應 | 回應事件映射 |
|---|---|---|
whatsapp | 支援 | 支援 |
telegram | 支援 | 支援 |
line | 不支援 | 支援 |
twitter、zalo、tiktok、whatsapp-protocol | 不支援 | 不支援 |
這些是文件列明的介接映射,不保證每個帳戶或上游情況下均可使用。LINE 收件匣可以顯示傳入回應,但不代表可以啟用發送回應按鈕。不支援的組合會傳回 501 unsupported_by_provider;重複呼叫不會增加功能。
UnifyPort 為已連接帳戶提供非官方接口。Telegram 官方 Bot API另有供機械人使用的 setMessageReaction。需要機械人身分時,請使用對應原生規格;不要把其請求結構貼進此端點,亦不要直接以其限制定義 UnifyPort 的行為。
分開記錄意圖、請求結果及觀察狀態
端點文件展示 200 OK 成功回應,內含 data.ok: true。記錄實際 HTTP 結果及傳回的 request_id,不要將它當成其他人已看見回應的證據。
建議應用程式採用以下流程:
- 同一帳戶、同一目標訊息的操作依次執行,避免舊的新增工作在較新的移除之後執行。
- 發送前記錄期望表情,另行保存 HTTP 結果。
- 遇到
react_message_failed,檢查錯誤及原目標。逾時則維持結果不確定,不要自動執行相反操作作補償。 - 收到相符回應事件後,以冪等方式更新觀察狀態。不要假定每次請求必有回調,或回調必定按序到達。
接收端設定 signing_secret 並遵循投遞文件:以時間戳、句點及原始請求內容驗證 HMAC-SHA256,檢查時間是否過舊,持久儲存後才確認投遞。收到 webhook 不等於獲准自動發起新操作。
驗收檢查及常見問題
啟用前測試收到的私人訊息、其他群組成員的訊息、帳戶自行發送的訊息、空字串移除、不支援的平台,以及結果不確定的網絡請求。確認新訊息不會改變所選目標。這是建議測試清單,並非已完成的測試結果。
sender_id 可以指定由誰作出回應嗎?
不可以。它指定被回應訊息的作者。執行操作的是已連接帳戶,不能藉此冒充其他回應者。
再發送相同表情便可移除嗎?
文件規定以 emoji: "" 移除,不應假設存在切換行為。
為甚麼能接收 LINE 回應,卻不能發送?
入站事件解析與出站操作有不同的支援矩陣。目前出站回應操作只映射至 Telegram 及 WhatsApp。
下一步及參考資料
先按訊息回應 API實作目標檢查,再加入收件匣控制項。證據不足時保留未確定狀態,不要虛構回應查詢 API 或保證重播功能。
核對日期:2026-10-16。
令訊息接入變成一條穩定嘅產品管線。
先用統一嘅 API 跑通發送,再用標準事件將所有入站訊息接返去業務系統。