← 所有文章
指南

X Chat 私訊故障排查:登入狀態、金鑰版本與訊息簽署

X 帳戶登入到,不等於每個加密對話都可以正常使用。帳戶存取權、正確的對話金鑰,以及有效的訊息簽署,是不同條件。排查時,先分清問題出在驗證、準備加密訊息、傳送請求,還是訊息送到業務系統的一段。只見到「傳送失敗」,未足以判斷是簽署錯誤、流量限制或帳戶受限。

先查清楚四件事

  • 是單一對話有問題,還是整個帳戶都受影響?傳送、接收,抑或兩邊都失敗?
  • 加密訊息要用對應版本的對話金鑰,不能只看快取內有沒有金鑰。
  • X Chat 訊息簽署與 UnifyPort Webhook 驗證是兩回事。
  • 重試或更改帳戶連線之前,先記錄請求識別碼和時間。

帳戶連線與聊天金鑰,各有不同職責

X 官方加密介紹分開說明身分金鑰、簽署金鑰和帶版本的對話金鑰。排查可以按以下分工進行:

材料用途要確認甚麼
帳戶工作階段存取帳戶是否正確的帳戶,工作階段是否仍可用?
身分私密金鑰解開分發給該用戶的對話金鑰有沒有相符的身分金鑰材料?
簽署私密金鑰簽署訊息及支援的狀態變更是否選對簽署金鑰及版本?
對話金鑰加密或解密對話內容有沒有這則訊息所需版本的金鑰?

不同層要查的資料不同。使用託管連接器的應用開發者,一般先看公開帳戶狀態及錯誤回應,再交由連接器維護者檢查協定層金鑰。API 驗證成功,未足以證明其餘條件都已經滿足。

恢復聊天金鑰所用的 Chat 通行碼,也不同於 API key 或帳戶登入憑證。恢復失敗時,應沿用帳戶持有人原有的 Chat 設定,不要將重設通行碼當成普通重試。X 的 Chat 說明列明了無法取得通行碼時,恢復加密歷史紀錄的限制。

改設定之前,先收窄問題範圍

保留一次失敗請求,跟已知正常的操作比較。例如,用戶資料查詢正常,但一個對話傳送失敗,應先查該對話,不能直接認定整個服務連不上。比較只幫助定位範圍,並非根因證據。

症狀要保留的資料下一步
帳戶無法存取驗證回應、帳戶與執行狀態按現行授權文件處理存取問題。
單一對話傳送失敗請求 ID、對話 ID、準確錯誤類別請維護者查對話狀態、金鑰版本、token 和簽署輸入。
部分訊息無法解密受影響訊息 ID,以及可取得的金鑰版本確認所需的歷史版本金鑰是否存在。
不肯定是否已傳送請求時間、回應或逾時、接收方結果核對這次操作後才決定重發;逾時可能代表結果未明。
X 收到訊息,業務系統沒收到Webhook 設定、傳送嘗試及接收端回應將事件傳送和 Chat 加密分開排查。

直接使用 X Chat SDK 的開發者,可查閱 X 官方故障排查,內容包括金鑰初始化、缺少對話金鑰、解密與簽署失敗。當中的 SDK 方法和錯誤訊息,並不是 UnifyPort 公開 API 的契約。

缺少金鑰後,要有明確的恢復決策

連接器可以採用以下恢復流程:

  1. 確認對話,以及事件要求的準確金鑰版本。
  2. 查找該版本的快取。
  3. 透過整合方案支援的恢復途徑取得封裝金鑰材料。
  4. 驗證材料,以相應的身分私密金鑰解開,再儲存版本紀錄。
  5. 重新讀取快取,在有限的重試策略內繼續原有操作。

這是設計方法,不代表每個已連接帳戶都可以恢復所有歷史訊息。如果請求成功但目標金鑰仍不存在,就不算恢復完成。同一金鑰的並行請求可以共用恢復工作,但每則訊息的處理結果仍要分開記錄。舊金鑰可保留來讀取歷史訊息,同時不應蓋過較新的預設金鑰。

接收和傳送的失敗處理也要分開。接收端應在支援的重試期限內保留原始事件,不能把密文當成解密完成的訊息。傳送端要明確決定:恢復失敗時回報錯誤,還是容許現有替代路徑。如果替代路徑改變了加密屬性,就不能當作等效的加密傳送。兩種情況都不應無限重試。

簽署錯誤要有對應證據

只有當上游回應確實指出簽署失敗,維護者才應針對金鑰選擇、傳送者身分、金鑰版本,以及參與簽署的實際位元組作檢查。重複提交相同的無效內容,不會修正輸入;停用簽署驗證亦不能解決根因。

單靠 HTTP 錯誤或籠統的 Provider 錯誤,不能證明簽署失敗。同樣,連接器修正簽署實作,不代表 X 改了推薦演算法,也不能據此認定 X 最近更新了協定。

用 UnifyPort 公開 API 排查

UnifyPort 為已連接的訊息帳戶提供非官方介面。先核對現行 X 授權指南,再檢查 GET /v1/accounts/{account_id}/authGET /v1/accounts/{account_id}。驗證狀態與 runtime_status 用來判斷連線狀態,並不是逐個對話的加密健康檢查。

對於已有的 POST /v1/messages 操作,可以保留簡短診斷摘要。以下函式接收已取得的 Response,本身不會傳送或重試訊息:

async function recordMessageAttempt(response) {
  const body = await response.clone().json().catch(() => null);
  console.info({
    observed_at: new Date().toISOString(),
    http_status: response.status,
    request_id: body?.request_id ?? response.headers.get('X-Request-Id'),
    code: body?.error?.code,
    numeric_code: body?.error?.numeric_code,
  });
}

訊息帳戶 ID、相關對話和訊息 ID,應放在限制存取的事故紀錄內。公開 codenumeric_code 的定義,以錯誤參考為準。provider_unavailable 這類概括回應並不揭示個別 X 簽署錯誤,也不能自行將內部錯誤逐一對應到公開錯誤碼。

函式刻意不記錄訊息內容、cookies、工作階段 URL、PIN 或金鑰。若連 HTTP 回應都沒有收到,應記錄客戶端錯誤、操作和時間;當時未必有伺服器請求 ID。不要自行產生 ID,再當成伺服器證據。

Webhook 簽署保護另一段連線

簽署驗證對象排查位置
X Chat 訊息簽署已簽署的 Chat 事件X Chat 客戶端或連接器協定實作
X-Device-SignatureUnifyPort 傳到接收端的請求Webhook 接收端及其 signing_secret

後者使用 HMAC-SHA256 計算「時間戳記、一個句點、原始請求內容」,詳見 Webhook 傳送文件。修正 HMAC 驗證不會補回 X 對話金鑰;HMAC 驗證成功,也不代表對方收到某則傳出訊息。

可按 Webhook 優先的接入清單檢查接收設定,下游應用則可參考 X 私訊及提及監聽器實作。驗證收到的事件後,先儲存,再做較慢的路由工作。

常見問題

重新登入一定會補回缺少的金鑰嗎?

不一定。更新工作階段不代表指定身分金鑰或對話金鑰版本已經可用。先找出缺少的材料,再決定是否重做帳戶設定。

金鑰恢復成功,是否等於訊息送達?

不是。金鑰可用、提交獲接納、接收方收到訊息,以及 Webhook 服務完成處理,是不同的觀察結果。要確認工作流程真正需要的結果。

可以呼叫 UnifyPort 公開端點恢復 Chat 金鑰嗎?

本文沒有新增這類公開端點。請用文件列出的公開 API,並向支援團隊提供診斷識別碼。內部連接器操作不能直接當成公開 API 路由。

所有 X 私訊都是加密訊息嗎?

不是。X 的 Chat 文件列出了未加密訊息請求的情況。應先確認實際對話與傳送路徑,再說明加密屬性。

下一步

測試需要的訊息類型前,先看現行訊息支援矩陣。如果直接串接 X 官方 Chat API,請使用其 SDK 和恢復文件;它的驗證方式和事件契約與 UnifyPort 不同。

一手資料來源

核對日期:2026 年 9 月 10 日。

UnifyPort API

令訊息接入變成一條穩定嘅產品管線。

先用統一嘅 API 跑通發送,再用標準事件將所有入站訊息接返去業務系統。