Boutons de lien WhatsApp
Un bouton de lien place un bouton cliquable sous un message WhatsApp qui ouvre une URL dans le navigateur du destinataire. Utilisez-le lorsque l'étape suivante se trouve sur le web, comme une page de paiement ou une liste de dates d'atelier, plutôt que dans la conversation elle-même. Pour un choix auquel le destinataire répond dans WhatsApp, utilisez les boutons de réponse ou les menus de liste à la place.
Envoyer un bouton de lien
Définissez interactive.type à cta_url, avec un objet body_text et un objet cta_url portant les propriétés text et url du bouton :
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 est requis pour chaque message de service : un numéro appartenant à votre espace de travail, et non un numéro géré par Bird. La structure complète ajoute un en-tête optionnel, un pied de page et une citation d'un message précédent :
Exemple de code
{
"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 cite un message précédent dans la même conversation. Consultez la section citer un message pour corréler une réponse du hub pour comprendre comment la résolution fonctionne et ce qu'elle peut manquer.
Ce type envoie exactement un bouton cta_url et ne peut pas contenir buttons, list ou cards en même temps. Consultez la section boutons du hub pour la structure de bouton partagée, que le bouton de lien d'une carte de carrousel réutilise également.
En-têtes et pieds de page
Un en-tête est optionnel et prend l'une de quatre formes :
Exemple de code
"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" }Un en-tête média (image, video ou document) transporte son fichier sous forme d'URL https publique que WhatsApp récupère au moment de l'envoi, plutôt qu'un identifiant de média téléversé. footer_text est optionnel et ajoute une ligne sous le bouton.
Limites
| Champ | Limite |
|---|---|
| Boutons cta_url | exactement un |
| cta_url.text (libellé) | requis, 1 à 20 caractères |
| cta_url.url | requis, 1 à 2 000 caractères |
| body_text | requis, 1 à 1 024 caractères |
| footer_text | optionnel, 1 à 60 caractères |
| header.text | 1 à 60 caractères |
La limite de 2 000 caractères sur url est propre à Bird : Meta ne publie aucune limite de longueur pour ce champ. url impose également format: uri, une adresse absolue avec un schéma, mais Bird ne vérifie pas quel schéma : une adresse http:// passe la validation de Bird, et Meta est le seul juge de la livraison effective.
Ce que signale un clic
Un appui ouvre l'adresse dans le navigateur du destinataire et rien ne vous revient via le API. L'appui sur un bouton de lien n'est pas un interactive_reply : le mappeur entrant qui produit les interactive_reply ne gère que l'appui sur un bouton de réponse et l'appui sur une ligne de liste, et un lien cta_url n'a pas de forme entrante équivalente. Ce que vous voyez, c'est le cycle de vie sortant ordinaire, les statuts sent, delivered et read du message, mais read_at vous indique que le message a été ouvert, pas que le bouton a été appuyé. Il n'y a pas d'événement de clic, pas d'horodatage et pas de signal d'appui par destinataire provenant de WhatsApp ou de Bird.
Deux façons de récupérer l'attribution, puisque l'envoi lui-même ne vous la fournira pas :
- Instrumentez la page de destination. La seule preuve de clic disponible se trouve sur votre propre serveur de destination, à partir de l'URL que vous avez distribuée.
- Variez l'URL vous-même, par destinataire. Le url que vous envoyez est une chaîne littérale : Bird la stocke et la transmet à Meta telle quelle, sans substitution ni syntaxe de variable. Elle est identique pour chaque destinataire d'un même envoi, donc l'attribution par destinataire implique de générer votre propre paramètre de requête, tel que ?click_id=<value>, et d'émettre un appel POST /v1/whatsapp/messages par destinataire. Le point d'entrée accepte déjà un seul to par appel, c'est donc de la comptabilité de votre côté plutôt qu'une fonctionnalité API manquante.
Une troisième option existe en dehors de ce type : un template avec une variable de bouton url est personnalisé par destinataire par WhatsApp lui-même, fourni via le composant button de l'envoi. Cette variable doit se trouver à la fin de l'adresse, écrite sous la forme {{1}}, de sorte qu'elle peut varier un segment de chemin final ou une valeur de requête, mais jamais l'hôte ni le milieu de l'URL. Le compromis : un template offre des URL par destinataire et la livraison en dehors de la fenêtre de service client, au prix de la revue de Meta et d'une forme approuvée fixe, tandis qu'un envoi cta_url offre un envoi libre, sans revue, dans une fenêtre ouverte avec une URL que vous variez vous-même.
Limites et cas particuliers
- La fenêtre de service client doit être ouverte. Un bouton de lien est un message de service, livrable uniquement dans une fenêtre ouverte ; consultez la section fenêtre de service client du hub. La vérification de la fenêtre échoue de manière permissive, donc un 202 ne prouve pas que la fenêtre était réellement ouverte au moment de l'envoi.
- from doit être un numéro appartenant à votre espace de travail. L'omettre ou nommer un numéro qui n'est pas un expéditeur connecté est rejeté avant la création de l'envoi.
- L'URL est statique pour l'ensemble de l'envoi et identique pour chaque destinataire. Il n'y a pas de variable par destinataire sur ce type. Consultez Ce que signale un clic pour savoir comment attribuer les clics malgré tout.
- Aucun signal d'appui, jamais. L'appui sur un bouton de lien ne produit aucun message entrant ni aucun événement webhook. Ne construisez pas une fonctionnalité qui promet des métriques de clic à partir de ce type seul.
- Bird vérifie la forme de l'URL, pas son schéma. url doit être une adresse absolue avec un schéma, mais Bird n'exige pas https, et Meta ne publie aucune restriction de schéma non plus. En comparaison, le url d'un en-tête média est documenté comme exigeant https.
- Une URL d'en-tête média que WhatsApp ne peut pas récupérer échoue après l'acceptation de l'envoi. WhatsApp récupère la ressource d'en-tête au moment de l'envoi et la met en cache pendant 10 minutes ; une URL signée doit survivre à l'envoi, et une URL inaccessible échoue de manière asynchrone, avec media_rejected sur le last_error du message.
Aucune des vérifications de forme listées dans le tableau d'erreurs du hub ne peut se déclencher sur ce type : elles inspectent les lignes d'une liste, un tableau buttons ou les cartes d'un carrousel, et un message cta_url ne possède aucun des trois. Une erreur de forme, comme un libellé text de plus de 20 caractères, revient sous forme d'erreur générique de validation de requête plutôt que l'un de ces codes. Une citation qui ne se résout pas fait échouer la requête avant que quoi que ce soit ne soit créé ou facturé : 404 E15071 lorsque l'id ne désigne aucun message détenu par cet espace de travail, 422 E15072 lorsqu'il désigne un message qui ne peut pas être cité. Pour les erreurs que tout envoi WhatsApp peut rencontrer, une fenêtre fermée, un expéditeur manquant ou invalide, ou un destinataire invalide, consultez les sections erreurs et Envoi de messages WhatsApp du hub.
Étapes suivantes
- Messages interactifs WhatsApp : ce que les six types interactifs ont en commun
- Templates WhatsApp : pour une variable de bouton url que WhatsApp personnalise par destinataire
- Envoi de messages WhatsApp : l'enveloppe de requête, le modèle 202 et les réessais sûrs
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet. Les ressources sont en anglais.
Regarder le guideConnecting WhatsApp to Bird: from buying a number to a live channelComprendre le conceptWhat is the 24-hour customer service window on WhatsApp?Utiliser l'outilWhatsApp message builderExplorer la fonctionnalitéWhatsApp
Essayez la pratique et obtenez un guide d'implémentation