Solicitudes de información de contacto de WhatsApp
Una solicitud de información de contacto coloca un botón debajo de un mensaje de WhatsApp que pide al destinatario compartir un número de teléfono. Úsala cuando necesitas un número para contactar a alguien, como una devolución de llamada o una confirmación de reserva, en lugar de una dirección guardada. Para una ubicación, usa solicitudes de ubicación.
Enviar una solicitud de información de contacto
Configura interactive.type como request_contact_info, con un body_text y nada más. WhatsApp renderiza el botón en sí, así que no hay nada con qué etiquetarlo:
const msg = await bird.whatsapp.send({
to: "+16505551234",
from: "+13124495648",
interactive: {
type: "request_contact_info",
body_text:
"To confirm your booking we need a number to reach you on. Tap below to share yours.",
},
});
console.log(msg.id, msg.status);msg = client.whatsapp.send(
to="+16505551234",
from_="+13124495648",
interactive={
"type": "request_contact_info",
"body_text": "To confirm your booking we need a number to reach you on. Tap below to share yours.",
},
)
print(msg.id, msg.status)package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
To: "+16505551234",
From: "+13124495648",
Interactive: &bird.WhatsAppInteractiveSend{
Type: "request_contact_info",
BodyText: "To confirm your booking we need a number to reach you on. Tap below to share yours.",
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}$interactive = (new WhatsAppMessageSendRequestInteractive())
->setType('request_contact_info')
->setBodyText('To confirm your booking we need a number to reach you on. Tap below to share yours.');
$message = $bird->whatsapp->send(
to: '+16505551234',
from: '+13124495648',
interactive: $interactive,
);
echo $message->getId(), ' ', $message->getStatus();bird whatsapp send \
--from +13124495648 \
--interactive '{"body_text":"To confirm your booking we need a number to reach you on. Tap below to share yours.","type":"request_contact_info"}' \
--to +16505551234{
"name": "whatsapp_send",
"arguments": {
"from": "+13124495648",
"interactive": {
"body_text": "To confirm your booking we need a number to reach you on. Tap below to share yours.",
"type": "request_contact_info"
},
"to": "+16505551234"
}
}curl -X POST "https://{region}.platform.bird.com/v1/whatsapp/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "+16505551234",
"from": "+13124495648",
"interactive": {
"type": "request_contact_info",
"body_text": "To confirm your booking we need a number to reach you on. Tap below to share yours."
}
}'from es obligatorio en cada mensaje de servicio: un número que tu espacio de trabajo posee, no uno administrado por Bird. Este tipo no nombra ningún campo propio, y el esquema prohíbe un header, un footer_text y todos los campos de los demás tipos (buttons, list, cta_url, cards) directamente, así que body_text es el mensaje completo, con un máximo de 1024 caracteres. Meta no indica un límite de longitud del cuerpo para este tipo; Bird aplica el límite de 1024 caracteres que tienen todos los demás tipos interactivos excepto un menú de lista.
in_reply_to_message_id sigue funcionando en este tipo, para citar un mensaje anterior en la misma conversación. Consulta en el hub citar un mensaje para correlacionar una respuesta para ver cómo funciona la resolución y qué puede omitir.
Leer el contacto compartido
Un toque no produce un interactive_reply. Llega como un mensaje entrante ordinario con un array contact_cards:
Ejemplo de código
{
"id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
"direction": "inbound",
"from": { "phone_number": "+16505551234", "bsuid": "US.13491208655302741918" },
"to": { "phone_number": "+13124495648" },
"status": "received",
"contact_cards": [
{
"origin": "contact_request",
"phone_numbers": [{ "phone_number": "+14155550829", "type": "cell" }]
}
],
"created_at": "2026-08-26T10:00:00Z"
}contact_cards es un array, y un mensaje contacts que no llevaba ninguna tarjeta se lee como [] en lugar de como un campo ausente. El mismo campo lleva una tarjeta que tú envías, así que una tarjeta que responde a esta solicitud se distingue por origin, no por el campo en el que llega. Comprobar origin es obligatorio antes de tratar una tarjeta como tu respuesta. origin es contact_request cuando la tarjeta responde a esta solicitud, o other cuando el contacto compartió una tarjeta sin que se la pidieran, que puede nombrar a un tercero completamente y no al contacto en sí. Un toque lleva solo phone_numbers[].{phone_number, type} y omite vcard; el objeto de contacto completo, con name, org, birthday y el resto, llega solo en origin: "other". Ves esta respuesta a través de la lista de mensajes o GET /v1/whatsapp/messages/{id}; consulta en el hub leer una respuesta para ese flujo completo.
Correlacionar la respuesta con la pregunta
A diferencia de una solicitud de ubicación, Meta no incluye un context en la respuesta de este tipo, así que in_reply_to_message_id se omite en lugar de resolverse. Correlaciona con from más un envío reciente tuyo, o acepta que no puedes. Dos solicitudes pendientes al mismo contacto son indistinguibles: nada en la respuesta indica a cuál solicitud responde, así que un espacio de trabajo que envía una segunda solicitud de información de contacto antes de que se responda la primera no puede saber qué tarjeta corresponde a cuál.
Este es el contraste deliberado con las solicitudes de ubicación: la respuesta de ese tipo lleva el propio context de Meta, así que in_reply_to_message_id se resuelve y el mecanismo del hub de citar un mensaje para correlacionar una respuesta vincula la respuesta automáticamente. La respuesta de una solicitud de información de contacto no tiene ese mecanismo en el que apoyarse.
Preguntar dentro de una plantilla en su lugar
El mensaje interactivo request_contact_info es la contraparte de formato libre del botón de plantilla REQUEST_CONTACT_INFO, que solicita la misma tarjeta de contacto pero puede alcanzar a un destinatario cuya ventana de servicio al cliente está cerrada. Usa el mensaje interactivo cuando el destinatario te escribió recientemente y quieres redactar la solicitud para esta conversación; usa el botón de plantilla cuando la ventana esté cerrada, o cuando la solicitud va en un mensaje que ya envías como plantilla. Consulta plantillas de WhatsApp para enviar con una plantilla.
Aspectos a tener en cuenta
- La ventana de servicio al cliente tiene que estar abierta. Una solicitud de información de contacto es un mensaje de servicio, entregable solo dentro de una ventana abierta; consulta en el hub la ventana de servicio al cliente. La verificación de la ventana falla en abierto, así que un 202 no es prueba de que la ventana estuviera realmente abierta cuando se realiza el envío.
- from debe ser un número que tu espacio de trabajo posea, y la ventana que necesita abierta está asociada a ese número, no a tu espacio de trabajo en su conjunto.
- La respuesta no se puede vincular a la solicitud por id. La ausencia de context del lado de Meta significa que in_reply_to_message_id se omite en la respuesta; correlaciona con from más un envío reciente tuyo.
- Un rechazo es silencioso. WhatsApp muestra al destinatario una hoja para compartir, y descartarla no produce ningún mensaje ni ningún webhook. La ausencia de un mensaje contact_cards es la única señal, así que cualquier flujo que espere una respuesta necesita su propio tiempo de espera en lugar de un evento de rechazo que vigilar.
- Sin encabezado, sin pie y sin etiqueta de botón. El esquema prohíbe un header y footer_text en este tipo directamente, y no hay campo con el que etiquetar el botón. Todo lo que el destinatario lee tiene que estar en body_text.
- No se garantiza que el número compartido sea con el que el contacto chatea. Meta advierte que el ID y el número de teléfono de un usuario pueden no coincidir siempre, así que no asumas que el número compartido es igual a from.phone_number. Tampoco se garantiza que sea E.164: Bird lo normaliza cuando es analizable y lo pasa tal cual cuando no lo es.
- La respuesta es un mensaje contact_cards, no un interactive_reply. Una integración que solo vigila interactive_reply en busca de un toque no detectará este tipo en absoluto, y tampoco una que solo vigile location entrantes para el otro tipo de solicitud.
Todo lo que el esquema puede expresar aquí, un body_text demasiado largo, un header, un footer_text, o cualquiera de buttons, list, cta_url, cards, es un fallo de validación de solicitud simple sin código de catálogo. Una cita que no se resuelve hace fallar la solicitud antes de que se cree o cobre nada: 404 E15071 cuando el id no nombra ningún mensaje que este espacio de trabajo tenga, 422 E15072 cuando nombra uno que no se puede citar. Consulta en el hub los errores para la tabla completa de errores interactivos y Enviar mensajes de WhatsApp para los errores que cualquier envío de WhatsApp puede encontrar.
Próximos pasos
- Mensajes interactivos de WhatsApp: lo que comparten los seis tipos interactivos
- Solicitudes de ubicación: pide una ubicación en lugar de un número de teléfono
- Plantillas de WhatsApp: alcanza a un destinatario cuya ventana de servicio al cliente está cerrada
- Enviar mensajes de WhatsApp: el sobre de la solicitud, el modelo 202 y reintentos seguros
Recursos relacionados
Continúa con la documentación, guías y ejemplos sobre este tema. Los recursos están en inglés.
Ver la guíaConnecting WhatsApp to Bird: from buying a number to a live channelComprender el conceptoWhat is the 24-hour customer service window on WhatsApp?Usar la herramientaWhatsApp message builderExplorar la funcionalidadWhatsApp
Prueba el ejercicio y obtén un resumen de implementación