X ChatのDMトラブル対策:ログイン状態・鍵のバージョン・署名を確認する
Xにログインできても、すべての暗号化された会話を利用できるとは限りません。アカウントへのアクセス、正しい会話鍵、有効なメッセージ署名は、それぞれ別の条件です。まず、認証、暗号化メッセージの準備、送信リクエスト、アプリへの配信のどこで失敗したかを特定します。「送信失敗」という表示だけでは、署名エラー、レート制限、アカウント制限のどれかは判断できません。
最初に確認すること
- 特定の会話だけか、アカウント全体か。送信・受信のどちらで発生しているか。
- 暗号化メッセージが要求する会話鍵のバージョンがあるか。何らかの鍵がキャッシュされているだけでは不十分です。
- X Chatの署名とUnifyPortのWebhook署名検証を混同していないか。
- 再試行や接続変更の前に、リクエストIDと発生時刻を保存したか。
ログインとチャットの鍵は役割が違う
X公式の暗号化解説は、ID鍵、署名鍵、バージョン付きの会話鍵を区別しています。調査では次のように整理できます。
| 情報 | 役割 | 調査する点 |
|---|---|---|
| アカウントセッション | アカウントへのアクセス | 想定したアカウントで、セッションが利用可能か |
| ID秘密鍵 | ユーザー宛てに保護された会話鍵を取り出す | 対応するID鍵の情報があるか |
| 署名秘密鍵 | メッセージや対応する状態変更に署名する | 正しい署名鍵とバージョンを選んでいるか |
| 会話鍵 | 会話の内容を暗号化・復号する | そのメッセージに必要なバージョンがあるか |
確認する担当も異なります。マネージドコネクターを利用するアプリ開発者は公開のアカウント状態とエラーレスポンスを調べ、プロトコルの鍵はコネクターの保守担当が調査します。API認証に成功しても、後続の条件を満たしたことにはなりません。
Chatの鍵を復元するパスコードも、API keyやアカウントのログイン認証情報とは別物です。復元に失敗したら、アカウント所有者の既存のChat設定を確認してください。パスコードのリセットは単なる再試行ではありません。XのChatヘルプには、パスコードを利用できない場合の暗号化履歴の復元制限が説明されています。
設定変更の前に、失敗の範囲を絞る
失敗した1回のリクエストを保存し、正常に動く操作と比較します。プロフィールの取得は成功し、ある会話への送信だけが失敗するなら、まずその会話を調べます。サービス全体に接続できないと決めつけないでください。この比較は調査範囲を狭めますが、原因の確定ではありません。
| 症状 | 集める証跡 | 次の対応 |
|---|---|---|
| アカウントにアクセスできない | 認証レスポンス、アカウント・ランタイム状態 | 現行の認証手順でアクセスを修復する |
| 1つの会話だけ送信できない | リクエストID、会話ID、正確なエラー分類 | 保守担当が会話状態、鍵のバージョン、token、署名入力を確認する |
| 一部のメッセージを復号できない | 対象メッセージIDと、取得可能なら鍵のバージョン | 必要な過去の鍵が残っているか確認する |
| 送信結果が不明 | リクエスト時刻、レスポンスまたはタイムアウト、受信側の結果 | 再送前に結果を照合する。タイムアウトでは結果が不明なことがある |
| Xには届いたがアプリに届かない | Webhook設定、配信試行、受信サーバーの応答 | Chat暗号化とは別にイベント配信を調べる |
X Chat SDKを直接使う場合は、鍵の初期化、会話鍵の欠落、復号、署名についてのX公式トラブルシューティングを参照します。そこで紹介されるSDKメソッドとエラーは、UnifyPortの公開API契約とは異なります。
鍵の欠落には復元と失敗時の方針が必要
コネクター実装では、次の復元手順が考えられます。
- 会話と、イベントが要求する正確な鍵のバージョンを特定する。
- そのバージョンのキャッシュを調べる。
- 利用中の統合方式が対応する復元経路から、保護された鍵情報を取得する。
- 内容を検証し、対応するID秘密鍵で会話鍵を取り出して、バージョン別に保存する。
- キャッシュを再読込し、上限のある再試行方針に従って元の処理を続ける。
これは設計パターンであり、接続済みの全アカウントで全履歴が復元できるという保証ではありません。復元リクエストが成功しても、必要な鍵がなければ完了とは言えません。同じ鍵の並行リクエストは復元処理を共有できますが、メッセージごとの結果は別に管理します。過去の鍵は履歴用に保持し、新しい既定の鍵を上書きしない設計が必要です。
受信と送信では失敗時の判断が異なります。受信では、対応する再試行期間中は元のイベントを保持し、暗号文を復号済みメッセージとして扱わないこと。送信では、エラーを返すか、既存の代替経路を許可するかを明確にします。代替経路で暗号化の性質が変わるなら、同等の暗号化配信とは説明できません。どちらも無限に再試行するべきではありません。
署名エラーは署名層の証跡で判断する
上流の応答が実際に署名失敗を示した場合、保守担当は鍵の選択、送信者ID、鍵のバージョン、署名対象の正確なバイト列を確認します。同じ無効なデータを再送しても入力は直りません。検証を無効にしても原因は解消しません。
HTTPエラーや大まかなProviderエラーだけで、署名失敗と判断しないでください。また、コネクターの署名修正はその実装が変わった証拠であって、Xの推薦アルゴリズムや直近のプロトコル変更の証拠ではありません。
UnifyPortの公開APIで確認する
UnifyPortは接続したメッセージアカウント向けの非公式インターフェースです。現在のX認証ガイドを確認し、GET /v1/accounts/{account_id}/auth と GET /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は、アクセスを制限した調査記録に保存します。公開 code と numeric_code はエラーリファレンスに従って解釈してください。provider_unavailable のような広いエラーから、特定のX署名失敗は分かりません。内部エラーと公開エラーコードの一対一対応を独自に仮定しないでください。
この関数は本文、cookies、セッションURL、PIN、鍵情報を記録しません。HTTP応答自体がなければ、クライアント側の失敗、操作、時刻を記録します。その場合、サーバーのリクエストIDがないこともあります。自分で生成したIDをサーバーの証跡として扱ってはいけません。
Webhook署名が保護するのは別の接続
| 署名 | 認証する対象 | 調査場所 |
|---|---|---|
| X Chatメッセージ署名 | 署名されたChatイベント | X Chatクライアント、コネクターのプロトコル処理 |
X-Device-Signature | UnifyPortから受信サーバーへの配信 | Webhook受信処理と signing_secret |
後者はタイムスタンプ、ピリオド、生のリクエストボディを結合した値のHMAC-SHA256です。Webhook配信リファレンスを参照してください。この検証を修正してもXの会話鍵は補充されません。HMAC検証成功も、送信メッセージが相手に届いたことを保証しません。
受信設定はWebhookを先に準備する統合チェックリストで確認できます。下流アプリの構成例はXのDM・メンション監視の実装例を参照してください。検証済みの受信イベントを保存してから、時間のかかる振り分け処理を行います。
よくある質問
再ログインすれば不足する鍵はすべて取得できますか?
保証できません。セッション更新だけでは、必要なID鍵や会話鍵のバージョンが使えると確認できません。再設定の前に不足する情報を特定します。
鍵の復元成功はメッセージ到着の証明ですか?
いいえ。鍵が使えること、送信受付、相手への到着、Webhook受信処理の完了は別の観測結果です。業務で必要な段階を確認してください。
UnifyPortの公開エンドポイントからChatの鍵を復元できますか?
この記事はそのような公開エンドポイントを追加するものではありません。公開APIを利用し、調査用の識別子をサポートに渡してください。内部コネクターの操作は公開APIルートと同じではありません。
Xの私信はすべて暗号化されていますか?
いいえ。Xは暗号化されないメッセージリクエストのケースも説明しています。実際の会話と送信経路を確認したうえで暗号化について説明してください。
次のステップ
必要なペイロードを試す前に、現在のメッセージ対応表を確認します。X公式Chat APIを直接使う場合は、そちらのSDKと復元ドキュメントに従ってください。認証方法とイベント契約はUnifyPortとは異なります。
参考資料
確認日:2026年9月10日。
メッセージ連携を安定したプロダクトパイプラインへ。
まずは 1 つの API で送信を始め、標準イベントですべての inbound メッセージを業務システムへ戻しましょう。