Lien wa.me et QR code WhatsApp : faire écrire à votre agent IA

Créez un lien wa.me avec un message prérempli, transformez-le en QR code WhatsApp et reconnaissez l'utilisateur qui a écrit, avec du TypeScript fonctionnel et l'API whasp.

Un motif abstrait de carreaux verts qui projettent de la lumière vers l'écran d'un téléphone.

L’essentiel

  • Un lien wa.me se compose de https://wa.me/ suivi du numéro complet au format international, sans signe plus, zéros, parenthèses ni tirets, et ?text= ajoute un message encodé en URL qui apparaît dans la zone de saisie de l'utilisateur.
  • L'utilisateur doit toujours appuyer sur envoyer et peut modifier le texte prérempli : un code placé dedans est une déclaration à rapprocher de vos données, pas une preuve d'identité.
  • Avec whasp, GET /v1/numbers/pick renvoie le numéro qui a le plus de marge et un wa_link prêt à l'emploi : chaque conversation commence donc par un message de l'utilisateur.
  • Un QR code est le même lien, encodé, et tout ce que vous imprimez doit encoder l'URL de votre propre redirection, car les numéros se remplissent et peuvent être remplacés.

Un lien wa.me est l’URL « click to chat » de WhatsApp. Son format est https://wa.me/<numéro>, où le numéro est au format international complet, sans signe plus, zéros, parenthèses ni tirets, et ?text= ajoute un premier message encodé en URL. Toucher le lien ouvre une conversation avec le numéro de votre agent : l’utilisateur écrit en premier et votre agent peut répondre.

Quel est le format exact d’un lien wa.me ?

La page d’aide click to chat de WhatsApp documente trois formes :

https://wa.me/15555550100
https://wa.me/15555550100?text=Salut%20Ava
https://wa.me/?text=Salut%20Ava

Le premier ouvre une conversation avec ce numéro. Le deuxième place en plus le texte dans la zone de message. Le troisième n’a pas de numéro : WhatsApp affiche une liste de contacts à qui envoyer le message, il sert donc à partager, pas à lancer une conversation avec votre agent.

Pour le numéro, la page demande « un numéro de téléphone complet au format international », sans zéros, parenthèses ni tirets. Son exemple de ce qu’il ne faut pas faire est https://wa.me/+001-(XXX)XXXXXXX. whasp renvoie les numéros au format E.164 (+15555550100) : retirez donc le signe plus.

Trois comportements à connaître :

  • Le lien fonctionne sur téléphone et sur WhatsApp Web.
  • Il fonctionne pour un numéro absent du carnet d’adresses de l’utilisateur, à condition que ce numéro ait un compte WhatsApp actif.
  • Le texte prérempli arrive dans la zone de saisie. Il n’est pas envoyé. L’utilisateur appuie sur envoyer, et peut d’abord modifier ou supprimer le texte.

Comment construire le lien en code ?

Retirez tout caractère non numérique du numéro E.164, puis encodez le texte en URL. Ne collez jamais du texte brut dans l’URL : un & termine le paramètre trop tôt et un # ouvre un fragment. encodeURIComponent gère les deux.

export function waLink(e164: string, text?: string): string {
  const digits = e164.replace(/\D/g, "").replace(/^0+/, ""); // "+1 555 555 0100" -> "15555550100"
  return `https://wa.me/${digits}` + (text ? `?text=${encodeURIComponent(text)}` : "");
}

Quatre erreurs à éviter :

  • Garder le signe plus, un 00 en tête ou des espaces dans le numéro. La page de WhatsApp demande de les retirer.
  • Sauter l’encodage : un & dans le message coupe alors le texte.
  • Construire le lien une fois et le mettre en cache. Les numéros se remplissent et sont remplacés.
  • Prendre le message prérempli pour un message envoyé. Il reste dans la zone de saisie tant que l’utilisateur n’appuie pas sur envoyer.

Gardez le texte prérempli court et simple. La page de WhatsApp n’indique aucune limite de longueur, mais Meta plafonne le texte prérempli à 140 caractères sur ses propres QR codes et liens courts, ce qui est un plafond raisonnable pour tout message d’accueil.

Évitez les emoji dans ce texte. Le 19 octobre 2026, nous avons demandé des liens wa.me avec des emoji dans ?text=, et la redirection vers api.whatsapp.com/send est revenue avec les emoji remplacés par le caractère de remplacement Unicode (%EF%BF%BD). Les lettres latines accentuées sont passées intactes, et le même texte envoyé directement à api.whatsapp.com/send a gardé les emoji. Vous pouvez refaire la vérification :

curl -sI "https://wa.me/15555550100?text=Salut%20%F0%9F%91%8B" | grep -i location

WhatsApp peut changer ce comportement : testez sur de vrais téléphones avant de vous appuyer sur l’un ou l’autre.

Comment faire un QR code pour un lien wa.me ?

Un QR code click to chat est le lien lui-même, encodé. Générez-le à partir de l’URL complète avec n’importe quelle bibliothèque de QR code, et affichez-le sur les pages pour ordinateur, là où l’utilisateur ne tient pas son téléphone. L’appareil photo d’un téléphone lit un QR code qui contient une URL et propose de l’ouvrir, puis wa.me confie la conversation à WhatsApp. La documentation de Meta décrit le même parcours (scanner avec l’appareil photo) pour ses propres QR codes.

import QRCode from "qrcode";

const link = waLink("+15555550100", "Salut Ava");
const svg = await QRCode.toString(link, { type: "svg", margin: 2, errorCorrectionLevel: "M" });
await QRCode.toFile("ava.png", link, { width: 512, margin: 2 });

Il s’agit du paquet qrcode. Utilisez le SVG pour l’impression, car il se redimensionne sans flou (la documentation des QR codes de Meta fait la même recommandation), et le PNG pour les écrans. Une URL plus courte donne un code plus simple, qui se scanne plus facilement. Testez le code imprimé à sa taille finale, sur deux ou trois téléphones différents, avant de commander mille autocollants.

Ne le confondez pas avec les QR codes et liens courts de Meta. Cette fonction relève de la WhatsApp Business Platform : jusqu’à 2 000 par numéro de téléphone professionnel, texte prérempli jusqu’à 140 caractères, aucune statistique de scan, gestion via la Business Management API. Un numéro whasp est un compte WhatsApp personnel : vous utilisez donc de simples liens wa.me.

Comment votre agent sait-il qui vient d’écrire ?

Un événement message.received contient le numéro de téléphone de l’expéditeur (chat), son nom WhatsApp (sender_name) et le texte. Il ne contient pas votre identifiant utilisateur. Si la personne a cliqué sur un bouton dans votre application, vous voulez relier les deux. Placez un code à usage unique dans le texte prérempli.

import { randomBytes } from "node:crypto";

const API = "https://api.whasp.ai/v1";
const pending = new Map<string, { userId: string; expires: number }>(); // utilisez votre base de données

export async function startChat(userId: string) {
  const code = randomBytes(3).toString("hex"); // par ex. "9f3a1c"
  pending.set(code, { userId, expires: Date.now() + 24 * 60 * 60 * 1000 });

  const text = `Salut Ava, mon code est ${code}`;
  const res = await fetch(`${API}/numbers/pick?text=${encodeURIComponent(text)}`, {
    headers: { Authorization: `Bearer ${process.env.WHASP_API_KEY}` },
  });
  if (res.status === 409) return null; // no_capacity: tous les numéros sont pleins, hors ligne ou en mauvaise santé
  if (!res.ok) throw new Error(`whasp answered ${res.status}`);
  return (await res.json()) as { number: string; wa_link: string };
}

// Dans votre gestionnaire message.received: qui est-ce ?
export function claimCode(text: string): string | null {
  const code = /mon code est ([0-9a-f]{6})\b/i.exec(text)?.[1]?.toLowerCase();
  const hit = code ? pending.get(code) : undefined;
  if (!code || !hit || hit.expires < Date.now()) return null;
  pending.delete(code); // usage unique
  return hit.userId;
}

Quand claimCode renvoie un identifiant utilisateur, enregistrez le trio : le chat de l’expéditeur, le number qui a reçu le message, et votre utilisateur. Ensuite, reconnaissez cette personne par son numéro de téléphone. La gestion du webhook elle-même (vérification de la signature, dédoublonnage sur l’identifiant d’événement) est décrite dans Webhook WhatsApp : signature, nouvelles tentatives, doublons.

Le code est une déclaration, pas une preuve. L’utilisateur peut modifier le texte, et quiconque reçoit le lien peut l’envoyer. Gardez-le à usage unique et de courte durée, rendez-le opaque (jamais une adresse e-mail ni un token), et ne mettez jamais de secret dans un lien qui finit dans l’historique du navigateur et dans une conversation.

Comment whasp choisit-il le numéro du lien ?

GET /v1/numbers/pick renvoie le numéro sain et en ligne qui a le plus de marge pour un nouvel utilisateur, avec un wa_link dont le text est prérempli. Il répond 409 no_capacity quand tous les numéros sont pleins, hors ligne ou en mauvaise santé. Un numéro accepte jusqu’à 100 conversations actives sur 30 jours et 40 nouvelles conversations en 24 heures, puis il sort de pick (les messages entrants continuent d’arriver). Appelez pick quand l’utilisateur demande la conversation, pas au moment du build ni une seule fois pour toute une campagne.

Les utilisateurs qui reviennent doivent retrouver le même numéro. L’événement message.received inclut le number qui l’a reçu, et un envoi sans from part du numéro auquel la personne a écrit en dernier. Stockez-le avec l’utilisateur et construisez son prochain lien avec waLink(number, text).

Les numéros changent aussi. Si WhatsApp en bannit un, whasp le retire et vous donne un remplaçant. Les conversations ne suivent pas, et le nouveau numéro ne peut pas écrire en premier : un lien qui pointe vers l’ancien numéro est donc mort. Générez les liens à la demande et lisez Numéro WhatsApp banni : migrer vos utilisateurs vers un nouveau pour la marche à suivre complète. Combien de numéros WhatsApp pour un agent IA : la formule traite de la capacité.

Pourquoi est-ce utile que les utilisateurs écrivent en premier ?

Un numéro whasp ne peut pas ouvrir une conversation : un envoi vers quelqu’un qui n’a jamais écrit renvoie 409 chat_not_open. Le lien et le QR code sont la porte d’entrée. Ils protègent aussi la santé du numéro. Des développeurs qui utilisent des bibliothèques non officielles signalent l’erreur 463, le « reachout timelock », depuis mars 2026 au moins, et l’hypothèse courante la relie au fait d’écrire à des gens qui n’avaient jamais écrit. Erreur WhatsApp 463 : le reachout timelock expliqué sépare ce qui est confirmé de ce qui relève de la théorie. Avec click to chat, chaque conversation commence par un message entrant, et un message prérempli donne tout de suite sa première entrée à votre agent.

Où placer le lien et le QR code ?

Où Quoi afficher Pourquoi
Page de succès d’inscription, sur téléphone Un bouton avec le lien propre à chaque utilisateur Un seul geste, code inclus
Même page, dans un navigateur sur ordinateur Un QR code de ce lien, à côté du bouton L’appareil photo du téléphone fait le relais
E-mail de bienvenue Un bouton qui pointe vers votre propre URL Le lien est construit au clic : il n’expire jamais et ne pointe jamais vers un numéro retiré
Impression, emballages, profils sociaux Un QR code de votre propre URL, pas du lien wa.me Vous pouvez changer le numéro derrière sans réimprimer

Pour les deux dernières lignes, pointez vers une redirection sur votre domaine, qui demande à whasp un numéro disponible et y envoie le visiteur :

import { createServer } from "node:http";

createServer(async (req, res) => {
  if (req.url !== "/chat") return void res.writeHead(404).end();
  const pick = await fetch(`https://api.whasp.ai/v1/numbers/pick?text=${encodeURIComponent("Salut Ava")}`, {
    headers: { Authorization: `Bearer ${process.env.WHASP_API_KEY}` },
  });
  if (pick.ok) {
    const { wa_link } = (await pick.json()) as { wa_link: string };
    res.writeHead(302, { Location: wa_link }).end();
  } else {
    res.writeHead(503).end("Toutes nos lignes sont prises. Revenez dans quelques minutes.");
  }
}).listen(3000);

Un visiteur anonyme n’a pas de code : laissez l’agent demander ce dont il a besoin une fois la conversation ouverte. Pour un utilisateur connu, comme dans la ligne de l’e-mail, faites appeler startChat(userId) (vu plus haut) par la redirection au lieu d’utiliser un texte fixe. WhatsApp publie aussi un bouton officiel « Chat on WhatsApp » en vert et blanc, et sa page d’aide demande de l’utiliser tel quel.

Que faire ensuite ?

Créez un numéro dans le tableau de bord, puis suivez le quickstart pour recevoir le premier événement message.received. Ajoutez la redirection ci-dessus à votre site, placez son URL derrière un bouton et un QR code, et vérifiez le parcours complet sur un iPhone et sur un téléphone Android. Si vous construisez un compagnon, Lancer un compagnon IA sur WhatsApp en 2026 : le guide montre où ce lien s’insère dans l’onboarding.

Questions

Comment créer un lien WhatsApp avec un message prérempli ?

Utilisez https://wa.me/<numéro>?text=<texte encodé en URL>, où le numéro est au format international complet. En code, construisez la partie texte avec encodeURIComponent. Le message apparaît dans la zone de saisie et l'utilisateur appuie sur envoyer.

Un lien wa.me fonctionne-t-il si le numéro n'est pas dans les contacts de l'utilisateur ?

Oui. La page d'aide de WhatsApp indique que click to chat ouvre une conversation sans que le numéro soit enregistré dans le carnet d'adresses, à condition que ce numéro ait un compte WhatsApp actif. Cela marche sur téléphone et sur WhatsApp Web.

Comment transformer un lien wa.me en QR code ?

Un QR code click to chat n'est que l'URL encodée. Passez le lien wa.me complet à n'importe quelle bibliothèque de QR code, par exemple le paquet qrcode pour Node, et exportez en SVG pour l'impression ou en PNG pour les écrans.

Peut-on mettre des emoji dans un message prérempli wa.me ?

Testez d'abord. Lors de notre vérification du 19 octobre 2026, wa.me remplaçait les emoji du texte par un caractère de remplacement, alors que les lettres latines accentuées passaient. Le texte simple est le choix sûr.

Mon agent whasp peut-il écrire à un utilisateur avant qu'il ne m'écrive ?

Non. Un numéro whasp ne peut pas ouvrir une conversation à froid et l'API répond 409 chat_not_open. L'utilisateur écrit en premier, et un lien wa.me ou un QR code est le moyen de l'y amener.

Tous les articles