Botões de link do WhatsApp
Um botão de link coloca um botão clicável abaixo de uma mensagem do WhatsApp que abre uma URL no navegador do destinatário. Use-o quando o próximo passo está na web, como uma página de checkout ou uma lista de datas de workshop, e não no próprio chat. Para uma escolha que o destinatário responde dentro do WhatsApp, use botões de resposta ou menus de lista.
Enviar um botão de link
Defina interactive.type como cta_url, com um objeto body_text e um objeto cta_url contendo o text e o url do botão:
const msg = await bird.whatsapp.send({
to: "+16505551234",
from: "+13124495648",
interactive: {
type: "cta_url",
body_text: "Tap the button below to see the available dates.",
cta_url: { text: "See dates", url: "https://example.com/workshops?click_id=a1b2c3" },
},
});
console.log(msg.id, msg.status);msg = client.whatsapp.send(
to="+16505551234",
from_="+13124495648",
interactive={
"type": "cta_url",
"body_text": "Tap the button below to see the available dates.",
"cta_url": {"text": "See dates", "url": "https://example.com/workshops?click_id=a1b2c3"},
},
)
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: "cta_url",
BodyText: "Tap the button below to see the available dates.",
CtaUrl: &bird.WhatsAppInteractiveCtaUrlSend{Text: "See dates", Url: "https://example.com/workshops?click_id=a1b2c3"},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}$interactive = (new WhatsAppMessageSendRequestInteractive())
->setType('cta_url')
->setBodyText('Tap the button below to see the available dates.')
->setCtaUrl(
(new WhatsAppInteractiveSendCtaUrl())
->setText('See dates')
->setUrl('https://example.com/workshops?click_id=a1b2c3'),
);
$message = $bird->whatsapp->send(
to: '+16505551234',
from: '+13124495648',
interactive: $interactive,
);
echo $message->getId(), ' ', $message->getStatus();bird whatsapp send \
--from +13124495648 \
--interactive '{"body_text":"Tap the button below to see the available dates.","cta_url":{"text":"See dates","url":"https://example.com/workshops?click_id=a1b2c3"},"type":"cta_url"}' \
--to +16505551234{
"name": "whatsapp_send",
"arguments": {
"from": "+13124495648",
"interactive": {
"body_text": "Tap the button below to see the available dates.",
"cta_url": {
"text": "See dates",
"url": "https://example.com/workshops?click_id=a1b2c3"
},
"type": "cta_url"
},
"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": "cta_url",
"body_text": "Tap the button below to see the available dates.",
"cta_url": {
"text": "See dates",
"url": "https://example.com/workshops?click_id=a1b2c3"
}
}
}'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 header opcional, um footer e a citação de uma mensagem anterior:
Exemplo de código
{
"to": "+16505551234",
"from": "+13124495648",
"in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
"interactive": {
"type": "cta_url",
"header": {
"type": "image",
"url": "https://cdn.example.com/banners/workshop.png"
},
"body_text": "Tap the button below to see the available dates.",
"footer_text": "Dates are subject to change.",
"cta_url": {
"text": "See dates",
"url": "https://example.com/workshops?click_id=a1b2c3"
}
},
"tags": [{ "name": "campaign", "value": "autumn-workshops" }],
"metadata": { "order_id": "A-4192" }
}in_reply_to_message_id cita uma mensagem anterior na mesma conversa. Consulte a seção citação de mensagem para correlacionar uma resposta do hub para saber como a resolução funciona e o que ela pode perder.
Esse tipo envia exatamente um botão cta_url e não pode incluir buttons, list ou cards junto. Consulte a seção buttons do hub para ver a forma compartilhada de botão, que o botão de link de um card de carrossel também reutiliza.
Headers e footers
Um header é opcional e pode ter uma de quatro formas:
Exemplo de código
"header": { "type": "text", "text": "New workshop dates" }
"header": { "type": "image", "url": "https://cdn.example.com/a.png" }
"header": { "type": "video", "url": "https://cdn.example.com/a.mp4" }
"header": { "type": "document", "url": "https://cdn.example.com/a.pdf" }Um header de mídia (image, video ou document) carrega seu arquivo como uma URL https pública que o WhatsApp busca no momento do envio, em vez de um handle de mídia enviado por upload. footer_text é opcional e adiciona uma linha abaixo do botão.
Limites
| Campo | Limite |
|---|---|
| Botões cta_url | exatamente um |
| cta_url.text (label) | obrigatório, 1 a 20 caracteres |
| cta_url.url | obrigatório, 1 a 2.000 caracteres |
| body_text | obrigatório, 1 a 1.024 caracteres |
| footer_text | opcional, 1 a 60 caracteres |
| header.text | 1 a 60 caracteres |
O limite de 2.000 caracteres em url é do próprio Bird: a Meta não publica limite de tamanho para esse campo. url também exige format: uri, um endereço absoluto com esquema, mas Bird não verifica qual esquema: um endereço http:// passa na validação do Bird, e a Meta é a única juíza de se ele será entregue.
O que um clique reporta
Um toque abre o endereço no navegador do destinatário e nada retorna para você pela API. O toque em um botão de link não é um interactive_reply: o mapeador de entrada que produz interactive_reply processa apenas toques em botões de resposta e em linhas de lista, e um link cta_url não tem formato de entrada equivalente. O que você vê é o ciclo de vida de saída normal, os status sent, delivered e read da mensagem, mas read_at indica que a mensagem foi aberta, não que o botão foi tocado. Não há evento de clique, nem timestamp, nem sinal de toque por destinatário vindo do WhatsApp ou do Bird.
Duas formas de obter atribuição, já que o envio em si não a fornece:
- Instrumente a página de destino. A única evidência de clique disponível está no seu próprio servidor de destino, a partir da URL que você forneceu.
- Varie a URL você mesmo, por destinatário. A url que você envia é uma string literal: o Bird a armazena e a repassa para a Meta sem alteração, sem substituição e sem sintaxe de variável. Ela é idêntica para todos os destinatários de um envio, então atribuição por destinatário significa gerar seu próprio parâmetro de query, como ?click_id=<value>, e fazer uma chamada POST /v1/whatsapp/messages por destinatário. O endpoint já aceita um único to por chamada, então isso é controle do seu lado, não uma funcionalidade ausente do API.
Uma terceira opção existe fora desse tipo: um template com uma variável de botão url é personalizado por destinatário pelo próprio WhatsApp, fornecido através do componente button do envio. Essa variável precisa ficar no final do endereço, escrita como {{1}}, então ela pode variar um segmento de caminho final ou valor de query, mas nunca o host ou o meio da URL. A troca: um template oferece URLs por destinatário e entrega fora da janela de atendimento ao cliente, ao custo da revisão da Meta e de um formato aprovado fixo, enquanto um envio cta_url oferece envio livre de formato e de revisão dentro de uma janela aberta, com uma URL que você varia por conta própria.
Limites e casos especiais
- A janela de atendimento ao cliente precisa estar aberta. Um botão de link é uma mensagem de serviço, entregável apenas dentro de uma janela aberta; consulte a seção janela de atendimento ao cliente do hub. A verificação de janela falha de forma permissiva, então um 202 não é prova de que a janela estava realmente aberta no momento do envio.
- from deve ser um número que o seu espaço de trabalho possui. Omiti-lo, ou informar um número que não é um remetente conectado, é rejeitado antes de o envio ser criado.
- A URL é estática para todo o envio e idêntica para todos os destinatários. Não há variável por destinatário nesse tipo. Consulte O que um clique reporta para saber como atribuir cliques mesmo assim.
- Nenhum sinal de toque, nunca. O toque em um botão de link não produz mensagem de entrada nem evento de webhook. Não construa uma funcionalidade que prometa métricas de clique apenas com esse tipo.
- Bird verifica a forma da URL, não o esquema. url deve ser um endereço absoluto com esquema, mas Bird não exige https, e a Meta também não publica restrição de esquema. Compare com o url de um header de mídia, que é documentado como exigindo https.
- Uma URL de header de mídia que o WhatsApp não consegue buscar falha após o envio ser aceito. O WhatsApp busca o recurso do header no momento do envio e o armazena em cache por 10 minutos; uma URL assinada precisa durar mais que o envio, e uma URL inacessível falha de forma assíncrona, com media_rejected no last_error da mensagem.
Nenhuma das verificações de forma que a tabela de erros do hub lista pode disparar nesse tipo: elas inspecionam linhas de uma lista, um array buttons ou cards de um carrossel, e uma mensagem cta_url não tem nenhum dos três. Um erro de forma, como um label text com mais de 20 caracteres, retorna como um erro genérico de validação de solicitação em vez de um desses códigos. Uma citação que não resolve falha a solicitação antes de qualquer coisa ser criada ou cobrada: 404 E15071 quando o id não corresponde a nenhuma mensagem que esse espaço de trabalho possui, 422 E15072 quando corresponde a uma que não pode ser citada. Para os erros que qualquer envio WhatsApp pode encontrar, como janela fechada, remetente ausente ou inválido, ou destinatário inválido, consulte a seção de erros do hub e Enviando mensagens WhatsApp.
Próximos passos
- Mensagens interativas do WhatsApp: o que os seis tipos interativos compartilham
- Templates do WhatsApp: para uma variável de botão url que o WhatsApp personaliza por destinatário
- Enviando mensagens WhatsApp: o envelope de solicitação, o modelo 202 e novas 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