透過 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 跑通發送,再用標準事件將所有入站訊息接返去業務系統。