透過 API 檢查 WhatsApp 聯絡人是否已儲存
要檢查某人是否已儲存至已連線 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 |
| 對方是否儲存了我們的號碼? | 此端點不提供答案 |
| 此人是否遭封鎖? | 獨立的封鎖清單流程 |
| 是否有聊天,或有人分享過名片? | 獨立的對話或訊息證據 |
| 應用程式能否主動聯絡此人? | 另外確認的授權與溝通規範 |
關於通訊錄寫入和資料分享的差別,請參閱新增聯絡人與傳送 vCard 的比較。不要為了方便檢查而先呼叫新增端點,否則查詢之前就改變了原本要觀察的狀態。
準備帳號與實際回傳的 LID
UnifyPort 為已連線的訊息帳號提供非官方介面;這不是 WhatsApp Cloud API 端點。目前渠道動作支援文件將聯絡人歸屬查詢對應至 whatsapp,不包括 LINE、Telegram、Zalo 或獨立的 whatsapp-protocol 渠道。
請一起保留所選帳號與聯絡人。聯絡人物件的 id、provider_user_id 和 conversation_id 可能不同。本操作要求使用聯絡人 API 以 conversation_id 回傳的 LID。從合法的既有聯絡人流程保存此值,不要在電話號碼後加上 @lid 就當成正確識別碼。
若應用程式只有電話號碼,沒有已確認的回傳 LID,應先顯示無法查詢,待身分對應完成後再操作。此端點並未定義為任意電話號碼查詢服務。
以下為示意請求,本文未實際執行。環境變數應取自後端選定的帳號與已儲存的聯絡人對應;API Key 不應出現在瀏覽器端:
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。
呈現三種結果,不要只用一個核取方塊
常見錯誤是把所有假值或缺漏值轉為「未儲存」。如此一來,逾時、不支援的渠道或異常回應都會變成錯誤的否定結論。
以下 JavaScript 範例僅解讀已取得的 HTTP 狀態與已解析 JSON,不會發出網路請求:
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 與應用程式記錄的檢查時間。不同訊息帳號不要共用同一筆快取結果。操作人員切換聯絡人後,應忽略上一個請求延遲抵達的結果,也不要把舊觀察呈現為永久保證。
後續操作應保持獨立
否定結果不等於寫入許可。操作人員確實要儲存此人時,再使用新增聯絡人 API,保存回傳識別碼,並在需要最新確認時重新查詢歸屬。
「未儲存」也不是「已封鎖」。靜音與封鎖比較說明了這些獨立控制。不要因為顯示通訊錄狀態,就自動解除封鎖、傳送測試訊息或修改通訊錄。
失敗時保留 HTTP 狀態及可取得的 request_id,不要記錄 API Key 或完整聯絡人資料。應用程式也應限制哪些操作人員能檢視各帳號的通訊錄。
常見問題
可以判斷對方是否儲存了我的號碼嗎?
不行。此 API 檢查已連線帳號的聯絡人清單,不讀取對方通訊錄。
is_in_contacts: false 是錯誤嗎?
若來自成功的 200 回應,它就是正常的否定結果。缺少資料或請求失敗應歸為無法確認,而不是 false。
能用電話號碼 JID 代替 LID 嗎?
WhatsApp 的文件要求輸入聯絡人 API 以 conversation_id 回傳的 LID。請使用該值,不要猜測識別碼。
收到聯絡人名片就代表已儲存嗎?
不是。聯絡人訊息與通訊錄操作是兩件事,需要確認時應查詢歸屬。
下一步與參考資料
依據檢查聯絡人歸屬文件建立唯讀控制項。上線前測試 true、false、缺少資料、不支援的渠道、逾時,以及請求待處理期間切換聯絡人。這是建議測試項目,並非已執行的測試結果。
資料核對日期:2026-10-31。
讓訊息接入變成一條穩定的產品管線。
先用統一 API 跑通傳送,再用標準事件把所有入站訊息接回業務系統。