WhatsAppの連絡先が保存済みかAPIで確認する
接続中のWhatsAppアカウントの連絡先リストに相手が保存されているかを調べるには、UnifyPortの GET /v1/accounts/{account_id}/contacts/membership を使い、連絡先APIが返したLIDを contact_id に指定します。成功レスポンスの data.is_in_contacts: false は未保存を意味し、リクエスト失敗ではありません。相手が自分の電話番号を保存しているかは分かりません。
要点
- 連絡先APIが
conversation_idとして返すLIDを使い、電話番号から生成しない。 - アプリ側で「保存済み」「未保存」「確認不能」を区別する。
- 連絡先への登録、チャット履歴、ブロック状態、販促連絡の許可は別の情報。
- 照会は読み取り専用。連絡先の追加は明示的な別操作にする。
保存済みという結果で何が分かるか
WhatsAppの公式連絡先ガイドでは、連絡先を削除してもチャット履歴は削除されないと説明されています。チャット一覧に相手がいるだけでは、今も連絡先に保存されている証拠にはなりません。また、共有された連絡先を受信した人は、それを連絡先に追加するか、直接メッセージを送るかを選べます。情報の共有と保存は別操作です。
UnifyPortの連絡先登録確認リファレンスが答えるのは、「この相手が接続中のアカウントの連絡先リストに含まれているか」という限定的な問いです。
| 確認したいこと | 必要な根拠 |
|---|---|
| 接続中のアカウントが相手を保存しているか | 成功レスポンスと is_in_contacts |
| 相手がこちらの番号を保存しているか | このAPIでは確認できない |
| 相手をブロックしているか | 別のブロックリスト確認 |
| チャットや連絡先カードの共有があったか | 会話またはメッセージの記録 |
| アプリから連絡してよいか | 別途確認した同意とコミュニケーション方針 |
書き込みと共有の違いは連絡先追加とvCard送信の比較を参照してください。確認を簡単にするために先に追加APIを呼ぶと、調べたかった状態を自分で変えてしまいます。
アカウントと返されたLIDを準備する
UnifyPortは接続済みメッセージングアカウント向けの非公式インターフェースです。このエンドポイントはWhatsApp Cloud APIではありません。現在のチャネル別アクション対応表では、この照会は whatsapp に対応し、LINE、Telegram、Zalo、別プロバイダーの whatsapp-protocol は対象外です。LINEも扱う共通管理画面では、同じボタンを全チャネルに表示しないようにします。
選択したアカウントと連絡先を組にして保持してください。連絡先オブジェクトの id、provider_user_id、conversation_id は異なる場合があります。この操作で指定するのは、連絡先APIが conversation_id として返したLIDです。正当な既存の連絡先処理で取得した値を保存し、電話番号に @lid を付けて代用しないでください。
電話番号しかなく、返されたLIDを確認できていない場合は、識別子の対応が解決するまで照会不可とします。このAPIは任意の電話番号を検索する機能としては定義されていません。
次は説明用のリクエストで、ここでは実行していません。環境変数にはバックエンドで選択したアカウントと保存済みの対応情報を設定し、APIキーはブラウザーに渡さないでください。
curl --get \
"https://api.unifyport.ai/v1/accounts/${UNIFYPORT_ACCOUNT_ID}/contacts/membership" \
-H "X-Api-Key: ${UNIFYPORT_API_KEY}" \
--data-urlencode "contact_id=${WHATSAPP_CONTACT_LID}"
クエリをエンコードすることで、@ を含む識別子を適切に送信できます。成功レスポンスには data.contact_id と真偽値の data.is_in_contacts が含まれます。
チェックボックスではなく3つの結果を表示する
値が偽と評価される場合や欠落している場合をすべて「未保存」に変換すると、タイムアウトや非対応プロバイダー、不正なレスポンスまで否定結果になってしまいます。
以下は取得済みHTTPステータスと解析済みJSONを分類するJavaScriptの例です。ネットワーク通信は行いません。
function classifyMembership(httpStatus, body) {
if (httpStatus !== 200) return 'unknown';
const value = body?.data?.is_in_contacts;
if (value === true) return 'saved';
if (value === false) return 'not_saved';
return 'unknown';
}
返す文字列はアプリ独自のラベルであり、APIの追加フィールドではありません。通信失敗やJSON以外のレスポンスは、この関数に渡す前に確認不能として扱います。
| 観測結果 | 表示 | 次の対応 |
|---|---|---|
200 と真偽値 true | 保存済み | 確認時刻を表示 |
200 と真偽値 false | 未保存 | 必要な場合だけ、権限確認付きの独立した追加操作を提示 |
501 unsupported_by_provider | 非対応/確認不能 | プロバイダーを確認し、自動追加しない |
| タイムアウト、失敗、真偽値の欠落 | 確認不能 | 診断情報を残して調査または再照会 |
観測結果にはアカウント、LID、アプリ側の確認時刻を紐付けます。複数アカウントで1つのキャッシュ結果を共有しないでください。担当者が別の連絡先へ切り替えた後に届いた古いレスポンスは表示に反映せず、過去の結果を恒久的な保証として扱わないようにします。
後続操作は独立させる
未保存という結果は書き込みの許可ではありません。担当者が本当に保存を希望した場合にだけ、連絡先追加APIを使います。返された識別子を保持し、最新状態の確認が必要なら改めて照会してください。
未保存とブロック済みも異なります。ミュートとブロックの比較でそれぞれの役割を確認してください。登録状態を表示するだけの処理で、ブロック解除、テストメッセージ送信、連絡先変更を実行してはいけません。
失敗時にはHTTPステータスと取得できた request_id を残し、APIキーや連絡先レコード全体はログに出さないでください。アプリ側でもアカウントごとの閲覧権限を制御します。
よくある質問
相手が自分の番号を保存したか分かりますか?
いいえ。確認対象は接続中のアカウントの連絡先リストで、相手のアドレス帳ではありません。
is_in_contacts: false はエラーですか?
成功した 200 レスポンスなら正常な否定結果です。データ欠落や失敗はfalseではなく確認不能です。
LIDの代わりに電話番号形式のJIDを指定できますか?
文書化されたWhatsAppの入力は、連絡先APIが conversation_id として返すLIDです。推測した識別子ではなく、その値を使います。
連絡先カードを受信すれば保存済みですか?
いいえ。連絡先メッセージとアドレス帳の操作は別です。必要なときに登録状態を確認してください。
次のステップと出典
連絡先登録確認リファレンスを基に、読み取り専用のUIを実装します。公開前にtrue、false、データ欠落、非対応プロバイダー、タイムアウト、処理中の連絡先切り替えをテストしてください。これは推奨テスト項目であり、実施結果の報告ではありません。
確認日:2026-10-31。
メッセージ連携を安定したプロダクトパイプラインへ。
まずは 1 つの API で送信を始め、標準イベントですべての inbound メッセージを業務システムへ戻しましょう。