Cartões de contato do WhatsApp
Uma mensagem de cartão de contato compartilha um ou mais contatos: um nome que o destinatário vê no cartão e uma visualização de perfil que ele abre a partir dele, contendo números de telefone, e-mails, sites, endereços, um empregador e uma data de aniversário. Use-a para entregar a um cliente o número de um colega, de um entregador ou o seu próprio, em vez de colar dígitos em um texto que ele precisará redigitar.
Enviar um cartão de contato
contact_cards é um array. Cada cartão precisa de um name, e esse nome precisa de formatted_name mais pelo menos uma outra parte:
const msg = await bird.whatsapp.send({
to: "+16505551234",
from: "+13124495648",
contact_cards: [
{
name: {
formatted_name: "Barbara J. Johnson",
first_name: "Barbara",
last_name: "Johnson",
},
phone_numbers: [{ phone_number: "+16505559999", type: "Mobile" }],
},
],
});
console.log(msg.id, msg.status);msg = client.whatsapp.send(
to="+16505551234",
from_="+13124495648",
contact_cards=[
{
"name": {
"formatted_name": "Barbara J. Johnson",
"first_name": "Barbara",
"last_name": "Johnson",
},
"phone_numbers": [{"phone_number": "+16505559999", "type": "Mobile"}],
}
],
)
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",
ContactCards: []bird.WhatsAppContactCardSend{{
Name: bird.WhatsAppContactNameSend{
FormattedName: "Barbara J. Johnson",
FirstName: bird.String("Barbara"),
LastName: bird.String("Johnson"),
},
PhoneNumbers: &[]bird.WhatsAppContactPhoneSend{{
PhoneNumber: "+16505559999",
Type: bird.String("Mobile"),
}},
}},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}$name = (new WhatsAppContactCardSendName())
->setFormattedName('Barbara J. Johnson')
->setFirstName('Barbara')
->setLastName('Johnson');
$phone = (new WhatsAppContactPhoneSend())
->setPhoneNumber('+16505559999')
->setType('Mobile');
$card = (new WhatsAppContactCardSend())
->setName($name)
->setPhoneNumbers([$phone]);
$message = $bird->whatsapp->send(
to: '+16505551234',
from: '+13124495648',
contactCards: [$card],
);
echo $message->getId(), ' ', $message->getStatus();bird whatsapp send \
--to +16505551234 \
--from +13124495648 \
--contact-cards '[{"name":{"formatted_name":"Barbara J. Johnson","first_name":"Barbara","last_name":"Johnson"},"phone_numbers":[{"phone_number":"+16505559999","type":"Mobile"}]}]'curl -X POST "https://us1.platform.bird.com/v1/whatsapp/messages" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+16505551234",
"from": "+13124495648",
"contact_cards": [
{
"name": {
"formatted_name": "Barbara J. Johnson",
"first_name": "Barbara",
"last_name": "Johnson"
},
"phone_numbers": [
{ "phone_number": "+16505559999", "type": "Mobile" }
]
}
]
}'from é obrigatório em toda mensagem de serviço: um número que o seu espaço de trabalho possui, não um gerenciado pelo Bird.
A forma completa adiciona um empregador, uma data de aniversário e os outros arrays de detalhes de contato:
Exemplo de código
{
"to": "+16505551234",
"from": "+13124495648",
"contact_cards": [
{
"name": {
"formatted_name": "Dr. Barbara J. Johnson Esq.",
"prefix": "Dr.",
"first_name": "Barbara",
"middle_name": "Joana",
"last_name": "Johnson",
"suffix": "Esq."
},
"org": { "company": "Lucky Shrub", "department": "Legal", "title": "Lead Counsel" },
"birthday": "1999-01-23",
"phone_numbers": [
{ "phone_number": "+16505559999", "type": "Landline" },
{ "phone_number": "+19175559999", "type": "Mobile" }
],
"emails": [{ "email": "bjohnson@example.com", "type": "Work" }],
"urls": [{ "url": "https://example.com", "type": "Company" }],
"addresses": [
{
"street": "1 Lucky Shrub Way",
"city": "Menlo Park",
"state": "CA",
"zip": "94025",
"country": "United States",
"country_code": "US",
"type": "Office"
}
]
}
]
}Todo rótulo type, seja em um telefone, um e-mail, um site ou um endereço, é texto livre que você escreve, enviado exatamente como você escreveu e exibido ao lado do valor na visualização de perfil do destinatário. O WhatsApp não define vocabulário para esses rótulos, então Mobile, Landline, Pop-Up e Work (old) são todos igualmente válidos.
O que dá a um cartão um botão
Um número de telefone escrito em E.164, com o código do país e o + inicial, dá a esse cartão um botão que abre um chat do WhatsApp com o número. Um número que o Bird não consegue ler como E.164 ainda é exibido no cartão, exatamente como você o escreveu; ele apenas não ganha um botão.
Isso inclui um número escrito sem o + inicial. O Bird não vai adicionar um para você: um número em formato nacional de um país pode ser interpretado como um número válido em outro quando um + é adicionado, o que apontaria o botão para um desconhecido. Recusar-se a adivinhar custa um botão; adivinhar errado custa ao destinatário um chat com a pessoa errada.
Um cartão sem nenhum número de telefone é exibido sem botão de chat e só pode ser salvo na agenda de contatos.
Limites
| Campo | Limite | Aplicado por |
|---|---|---|
| contact_cards | 1 a 5 cartões por mensagem | Bird, no aceite (422) |
| name | obrigatório; formatted_name mais uma outra parte do nome | Bird, no aceite (422) |
| formatted_name, first_name, middle_name, last_name | até 256 caracteres | Bird, no aceite (422) |
| prefix, suffix | até 64 caracteres | Bird, no aceite (422) |
| birthday | opcional, YYYY-MM-DD, e uma data que o calendário comporta | Bird, no aceite (422) |
| phone_numbers, emails, urls, addresses | até 10 entradas cada | Bird, no aceite (422) |
| phone_number | até 32 caracteres | Bird, no aceite (422) |
| até 254 caracteres | Bird, no aceite (422) | |
| url | até 2.048 caracteres, não validado como URL | Bird, no aceite (422) |
| type em qualquer telefone, e-mail, site ou endereço | até 64 caracteres de texto livre | Bird, no aceite (422) |
| company, department, title | até 128 caracteres | Bird, no aceite (422) |
| street, city, state, zip, country, country_code | até 128 caracteres | Bird, no aceite (422) |
O limite de cinco cartões é do Bird, e está deliberadamente muito abaixo do que o WhatsApp aceita. A própria descrição publicada do API do WhatsApp declara cinco, sua documentação recomenda menos por motivos de usabilidade e feedback negativo, e uma mensagem que abre como "Contact 1 and 256 other contacts" é um vetor de spam antes de ser um recurso. Aumentar o limite depois seria uma mudança aditiva, então pergunte se cinco é pouco para o que você está construindo.
Todo limite de comprimento acima também é do Bird. O WhatsApp não aplica nenhum que valha a pena mencionar, e seu cliente não compensa: um type de 500 caracteres é exibido como dez linhas de uma mesma letra repetida, e um url de 4.000 caracteres é descartado silenciosamente, deixando a visualização de perfil em branco. Um 422 nomeando o campo infrator é melhor do que um cartão que o destinatário não consegue ler.
Duas regras que o schema não consegue expressar
Um nome precisa de uma segunda parte. formatted_name sozinho é recusado com um 422 E15061 WhatsAppContactNameIncomplete, nomeando contact_cards.<n>.name. Qualquer um entre prefix, first_name, middle_name, last_name ou suffix o satisfaz, mas um valor em branco ou contendo apenas espaços não conta, e um org não o resgata. Esse é um requisito do próprio WhatsApp, não documentado em nenhum lugar na sua referência; o Bird o captura no aceite para que você receba um erro acionável em vez de uma falha assíncrona.
Uma data de aniversário precisa ser uma data real. birthday é YYYY-MM-DD; qualquer outro formato, e qualquer data que o calendário não comporta, como 2026-02-30, é recusado com um 422 E15062 WhatsAppContactBirthdayInvalid. O próprio WhatsApp aceita 2026-02-30 e o exibe ao destinatário, o que parece um bug nos seus dados.
Lendo um cartão de volta
Um cartão que você enviou é lido de volta no mesmo campo contact_cards que um cartão recebido usa, pela lista de mensagens ou por GET /v1/whatsapp/messages/{id}:
Exemplo de código
{
"id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
"direction": "outbound",
"status": "delivered",
"contact_cards": [
{
"name": { "formatted_name": "Barbara J. Johnson", "first_name": "Barbara" },
"phone_numbers": [{ "phone_number": "+16505559999", "type": "Mobile" }]
}
]
}origin e vcard estão ausentes em um cartão que você enviou: o WhatsApp define ambos em um cartão que um contato compartilhou. Um rótulo type que você enviou é lido de volta exatamente como escrito, enquanto um rótulo em um cartão recebido fica em minúsculas. Consulte Recebendo cartões de contato do WhatsApp para o lado de entrada.
Casos especiais
- A janela de atendimento ao cliente precisa estar aberta. O envio de um cartão de contato é uma mensagem de serviço, entregável apenas dentro de uma janela aberta; consulte a janela de atendimento ao cliente do hub.
- Não existe wa_id para enviar. O WhatsApp identifica o contato de um cartão por um ID de conta; o Bird o deriva de cada phone_number E.164 em vez de aceitar um, então o botão em um cartão nunca pode apontar para algo diferente dos dígitos impressos nele.
- vcard é somente leitura. O WhatsApp o gera para um cartão que um contato compartilhou. Não há como enviar um cartão como texto vCard bruto.
- Um cartão não é um registro de contato. Enviar um compartilha detalhes em uma mensagem; ele não cria nada no seu espaço de trabalho, e o destinatário salvá-lo é uma ação dele, invisível para você.
Próximos passos
- Mensagens de serviço do WhatsApp: a janela de atendimento ao cliente e o modelo que toda mensagem de serviço compartilha
- Solicitações de informações de contato: peça a um contato o número dele em vez de enviar um
- Recebendo mensagens do WhatsApp: mensagens de entrada, mídia e o webhook whatsapp.received
- Enviando mensagens do WhatsApp: o envelope da solicitação, o modelo 202 e tentativas seguras
Recursos relacionados
Continue com a documentação, guias e exemplos sobre este tópico. Os recursos estão em inglês.
Assista ao guiaConnecting WhatsApp to Bird: from buying a number to a live channelEntenda o conceitoWhat is the 24-hour customer service window on WhatsApp?Use a ferramentaWhatsApp message builderExplore a funcionalidadeWhatsApp
Experimente na prática e obtenha um resumo de implementação