Menerima kartu kontak WhatsApp
contact_cards adalah satu-satunya arm yang membawa field yang sama di kedua arah. Kontak dapat membagikan kartu dari buku alamat mereka, dan ketukan pada contact info request yang Anda kirim juga masuk di sini, membawa nomor yang mereka pilih untuk diungkapkan.
Apa yang dibawa kartu kontak masuk
contact_cards selalu berupa array, dan origin menunjukkan cara kartu tersebut masuk:
Contoh kode
{
"id": "wam_01kyg9v3timy1w7n0r4cbh9ukf",
"direction": "inbound",
"from": { "phone_number": "+14155550100" },
"to": { "phone_number": "+13124495569" },
"status": "received",
"contact_cards": [
{
"origin": "contact_request",
"phone_numbers": [{ "phone_number": "+14155550100", "type": "cell" }]
}
],
"created_at": "2026-08-25T09:27:45Z"
}| origin | Cara kartu masuk |
|---|---|
| contact_request | Kontak mengetuk tombol yang Anda kirim untuk meminta nomor mereka |
| other | Kontak membagikan kartu di chat tanpa diminta |
Periksa origin sebelum memperlakukan kartu sebagai jawaban atas permintaan Anda. Ini satu-satunya sinyal yang membedakan keduanya, dan kartu yang dibagikan tanpa diminta bisa saja berisi data pihak ketiga sepenuhnya, bukan data kontak itu sendiri. Daftar nilai bersifat terbuka, jadi perlakukan nilai yang tidak Anda kenali sebagai cara berbagi lain yang ditambahkan kemudian.
Kartu yang dikirim oleh workspace ini terbaca kembali tanpa origin sama sekali, dan inilah cara membedakan kartu keluar dari kartu masuk pada field yang sama.
Apa yang dibawa ketukan, dan apa yang dibawa kartu yang dibagikan
Keduanya masuk dengan jumlah detail yang berbeda, dan tidak ada field pada kartu yang wajib: WhatsApp mengirimkan bagian yang ada di kartu dan mengabaikan sisanya, sehingga kartu yang hanya berisi origin tetap masuk dan tidak dibuang.
| Field | Pada ketukan tombol | Pada kartu yang dibagikan di chat |
|---|---|---|
| phone_numbers[].phone_number, type | Nomor yang dipilih kontak untuk diungkapkan | Nomor apa pun yang ada di kartu |
| vcard | Tidak ada; ketukan hanya membawa nomor | Kartu dalam format vCard |
| name, org, birthday, emails, urls, addresses | Apa pun yang dikirim WhatsApp, biasanya kosong | Ada jika kartu memuatnya |
Contoh kode
{
"contact_cards": [
{
"origin": "other",
"vcard": "BEGIN:VCARD\nVERSION:3.0\nN:Johnson;Barbara;;;\nTEL;type=CELL:+16505551234\nEND:VCARD\n",
"name": {
"formatted_name": "Barbara J. Johnson",
"first_name": "Barbara",
"last_name": "Johnson"
},
"org": { "company": "Northside Plumbing" },
"phone_numbers": [{ "phone_number": "+16505551234", "type": "cell" }]
}
]
}Dua field perlu perhatian saat Anda mem-parse. phone_number dinormalisasi ke E.164 jika bisa di-parse, dan diteruskan persis seperti yang disimpan perangkat kontak jika tidak bisa, termasuk ekstensi, jadi parse secara defensif dan jangan mengasumsikan E.164. birthday datang dari perangkat tersebut tanpa divalidasi dan diteruskan sebagai teks dalam bentuk YYYY-MM-DD, bukan sebagai tipe tanggal, jadi jangan asumsikan bisa di-parse. Label type pada kartu yang diterima di-lowercase-kan, dan WhatsApp tidak mendefinisikan kosakata untuk itu, jadi cocokkan secara case-insensitive dan jangan gunakan pencocokan persis pada CELL.
Nomor telepon yang diungkapkan kontak
Kontak yang sudah menggunakan username WhatsApp menghubungi Anda melalui business-scoped user ID tanpa nomor telepon di from. Contact info request adalah cara Anda meminta nomor tersebut, dan arm ini adalah tempat jawaban masuk, dengan origin: "contact_request" dan nomor di phone_numbers.
Nomor yang diungkapkan tidak dijamin sama dengan nomor yang mereka gunakan untuk chat: Meta memperingatkan bahwa identifier dan nomor telepon pengguna mungkin tidak selalu cocok, jadi simpan nomor yang diungkapkan sebagai data tersendiri dan jangan menimpa identitas di from.
Payload webhook
whatsapp.received membawa array contact_cards pada event envelope:
Contoh kode
{
"type": "whatsapp.received",
"timestamp": "2026-08-25T09:27:45.019Z",
"data": {
"whatsapp_id": "wam_01kyg9v3timy1w7n0r4cbh9ukf",
"workspace_id": "ws_01ky7m235keycbnwyajabe1a6b",
"direction": "inbound",
"from": { "phone_number": "+14155550100", "bsuid": "US.13491208655302741918" },
"to": { "phone_number": "+13124495569" },
"contact_cards": [
{
"origin": "contact_request",
"phone_numbers": [{ "phone_number": "+14155550100", "type": "cell" }]
}
],
"tags": null,
"metadata": null
}
}Hal yang perlu diperhatikan
- Permintaan yang ditolak tidak menghasilkan apa pun. WhatsApp menampilkan share sheet kepada kontak, dan menutupnya tidak mengirim pesan maupun memicu webhook, jadi alur yang menunggu nomor perlu timeout sendiri, bukan menunggu event penolakan.
- Dua permintaan yang belum dijawab tidak bisa dibedakan. Kartu yang menjawab contact info request tidak membawa in_reply_to_message_id, jadi permintaan kedua yang dikirim sebelum yang pertama dijawab tidak bisa dicocokkan dengan jawabannya sendiri.
- Array bisa berisi beberapa kartu. Kontak yang membagikan beberapa kartu dalam satu pesan mengisi beberapa entri, masing-masing dengan origin sendiri.
- Kartu adalah data kontak yang tidak Anda kumpulkan sendiri. Kartu bisa berisi nama, nomor, dan tanggal lahir pihak ketiga, jadi terapkan aturan retensi dan persetujuan yang sama seperti pada data pribadi lainnya sebelum menyimpannya.
Langkah selanjutnya
- Cara kerja penerimaan: envelope masuk, pengambilan media, dan webhook whatsapp.received
- Kartu kontak WhatsApp: sisi pengiriman dari arm yang sama
- Business-scoped user ID: mengapa kontak masuk tanpa nomor telepon, dan bagaimana permintaan ini cocok dalam percakapan
- Contact info request WhatsApp: tombol yang meminta nomor
Sumber daya terkait
Lanjutkan dengan dokumentasi, panduan, dan contoh untuk topik ini. Sumber daya tersedia dalam bahasa Inggris.
Tonton panduannyaConnecting WhatsApp to Bird: from buying a number to a live channelPahami konsepnyaWhat is the 24-hour customer service window on WhatsApp?Gunakan alatnyaWhatsApp message builderJelajahi kemampuannyaWhatsApp
Coba praktiknya dan dapatkan ringkasan implementasi