Skip to content

Tout pour WordPress, le développement web — et plus encore

🤖 Configuration du menu persistant et des boutons pour un bot Facebook Messenger

🤖 Configuration du menu persistant et des boutons pour un bot Facebook Messenger

Vous avez lancé un bot dans Facebook Messenger, il répond aux messages, mais il manque quelque chose. Un utilisateur ouvre la conversation et voit une fenêtre vide. Pas de menu, pas d’indice, pas de bouton « Commencer ». Premier contact, et c’est le silence. Les gens ne comprennent tout simplement pas ce que votre bot peut faire.

Trois composants transforment un bot sans visage en une interface compréhensible : un menu persistant avec des actions rapides, un bouton « Commencer » pour le premier contact et un texte d’accueil qui salue l’utilisateur par son prénom. Auparavant, tout cela se configurait via le paramètre obsolète thread_settings. Désormais, Meta a transféré le contrôle vers l’API unifiée Messenger Profile, et les anciens appels cURL issus des tutoriels de 2017 ne fonctionnent tout simplement plus.

Dans ce guide, nous abordons l’approche actuelle pour configurer le menu persistant, le bouton « Commencer » et le message d’accueil via l’API Messenger Profile. Avec des exemples cURL fonctionnels et un gestionnaire PHP de POSTBACK qui distingue les clics sur les éléments du menu.

💡 Aperçu rapide :

  • Configurer le menu persistant via persistent_menu dans l’API Messenger Profile : jusqu’à 20 éléments, localisation, désactivation du champ de saisie
  • Ajouter le bouton « Commencer » via le paramètre get_started : au premier contact, Facebook renvoie le PSID de l’utilisateur
  • Définir le texte d’accueil via greeting : les templates {{user_first_name}} fonctionnent encore en 2026
  • Écrire un gestionnaire PHP de POSTBACK : un switch sur le payload permet de distinguer quel élément du menu a été cliqué
  • Tenir compte des limites : 10 appels à l’API Profile toutes les 10 minutes par page, jusqu’à 24 heures pour la mise à jour du cache du menu

Ce qui a changé : Thread Settings → Messenger Profile API

Avant 2020, le menu, le bouton « Commencer » et le message d’accueil se configuraient avec des requêtes POST distinctes vers l’endpoint /me/thread_settings. Le type de paramètre était spécifié dans le corps via setting_type : call_to_actions pour le menu, greeting pour l’accueil. En 2026, cette approche ne fonctionne plus, l’endpoint a été retiré de la documentation.

Désormais, toutes les propriétés du bot sont définies via l’API Messenger Profile, un endpoint unifié :

1POST https://graph.facebook.com/v22.0/me/messenger_profile?access_token=PAGE_ACCESS_TOKEN

Le corps de la requête est un objet JSON contenant les propriétés nécessaires : persistent_menu pour le menu, get_started pour le bouton « Commencer », greeting pour l’accueil, ice_breakers et whitelisted_domains. Vous pouvez les transmettre ensemble ou séparément. Le profil est écrasé : ne transmettez pas une propriété si vous ne souhaitez pas la modifier.

Documentation officielle : Persistent Menu sur Meta for Developers. La version de l’API est mise à jour tous les six mois, vérifiez la version actuelle via le Changelog.

Prérequis pour que le menu fonctionne, à jour en juin 2026 :

  • La page Facebook est publiée, le bot est passé en mode « public » dans les paramètres de l’application
  • L’application dispose de la permission pages_messaging
  • L’utilisateur utilise Messenger version 106 ou supérieure
  • Le bouton « Commencer » est configuré (sans lui, le menu ne s’affiche pas)
  • Vous avez le rôle d’administrateur de la page
Code de programme sur un écran d'ordinateur

1. Menu persistant (persistent_menu)

Le menu est accroché à gauche du champ de saisie, l’utilisateur clique sur l’icône « hamburger » et voit une liste d’actions. C’est la navigation de premier niveau : « Aide », « Catalogue », « Support ». Jusqu’à 20 éléments, mais Meta recommande de se limiter à cinq pour une meilleure expérience utilisateur.

Chaque élément est un objet avec type (postback ou web_url), title (jusqu’à 30 caractères) et soit payload, soit url. Les emojis dans les titres fonctionnent, vous pouvez les copier depuis getemoji.com.

Mise en place du menu. Envoyez une requête POST à l’API Messenger Profile :

1curl -X POST -H "Content-Type: application/json" -d '{
2 "persistent_menu": [
3 {
4 "locale": "default",
5 "composer_input_disabled": false,
6 "call_to_actions": [
7 {
8 "type": "postback",
9 "title": "🆘 Help",
10 "payload": "HELP_PAYLOAD"
11 },
12 {
13 "type": "postback",
14 "title": "📰 News",
15 "payload": "LATEST_POSTS_PAYLOAD"
16 },
17 {
18 "type": "web_url",
19 "title": "🌐 Website",
20 "url": "https://yoursite.com/",
21 "webview_height_ratio": "full"
22 }
23 ]
24 }
25 ]
26}' "https://graph.facebook.com/v22.0/me/messenger_profile?access_token=PAGE_ACCESS_TOKEN"

Réponse en cas de succès : {"result": "success"}. Le menu n’apparaît pas immédiatement, le cache côté client se met à jour dans un délai pouvant aller jusqu’à 24 heures. Lors de vos tests, supprimez la conversation et démarrez-en une nouvelle pour voir les changements instantanément.

Suppression du menu. Utilisez DELETE avec le paramètre fields :

1curl -X DELETE "https://graph.facebook.com/v22.0/me/messenger_profile?fields=persistent_menu&access_token=PAGE_ACCESS_TOKEN"

Désactivation du champ de saisie. Si le bot fonctionne uniquement via le menu et les boutons, définissez "composer_input_disabled": true. Le champ de saisie disparaîtra, l’utilisateur interagira exclusivement via les éléments du menu et les boutons de postback. Utile pour les bots de FAQ et les catalogues.

Localisation. Ajoutez des objets avec la clé locale pour chaque langue. L’objet avec "locale": "default" est obligatoire, il sert de solution de repli :

1{
2 "persistent_menu": [
3 {
4 "locale": "default",
5 "call_to_actions": [...]
6 },
7 {
8 "locale": "ru_RU",
9 "call_to_actions": [...]
10 }
11 ]
12}

Menu personnalisé. Via l’endpoint /me/custom_user_settings, vous pouvez remplacer le menu pour un utilisateur spécifique par son PSID. Limite : 10 appels par utilisateur toutes les 10 minutes. Après suppression du menu personnalisé, le menu de la page est rétabli.

2. Gérer le POSTBACK en PHP

Lorsqu’un utilisateur clique sur un élément de menu avec type: "postback", Facebook envoie un événement messaging_postbacks à votre webhook. Dans le corps de la requête, un objet postback contient un champ payload que vous avez défini lors de la configuration du menu.

Le gestionnaire PHP lit le JSON entrant depuis php://input, extrait le payload et, via un switch, détermine l’action à exécuter. Voici le code actuel pour 2026 avec l’endpoint v22.0:

1<?php
2// Read incoming request from Facebook
3$input = json_decode(file_get_contents('php://input'), true);
4
5// Extract recipient and sender data
6$page_id = $input['entry'][0]['id'];
7$sender = $input['entry'][0]['messaging'][0]['sender']['id'];
8
9// Determine whether message or postback
10$message = $input['entry'][0]['messaging'][0]['message']['text'] ?? '';
11$postback = $input['entry'][0]['messaging'][0]['postback']['payload'] ?? '';
12
13if ($message || $postback) {
14
15 if ($message) {
16 $reply = 'Message received: ' . $message;
17 } else {
18 switch ($postback) {
19 case 'HELP_PAYLOAD':
20 $reply = 'You clicked the "Help" button. How can I help?';
21 break;
22
23 case 'LATEST_POSTS_PAYLOAD':
24 $reply = 'Here are fresh posts from this week.';
25 break;
26
27 default:
28 $reply = 'Action not recognized. Try again.';
29 }
30 }
31
32 // Form response
33 $responseJSON = json_encode([
34 'recipient' => ['id' => $sender],
35 'message' => ['text' => $reply],
36 ]);
37
38 $access_token = 'YOUR_PAGE_ACCESS_TOKEN';
39 $url = 'https://graph.facebook.com/v22.0/me/messages?access_token=' . $access_token;
40
41 // Send via cURL
42 $ch = curl_init($url);
43 curl_setopt($ch, CURLOPT_POST, 1);
44 curl_setopt($ch, CURLOPT_POSTFIELDS, $responseJSON);
45 curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
46 $result = curl_exec($ch);
47 curl_close($ch);
48}

Ce qui a changé. La version de l’API dans l’URL est passée de v2.7 à v22.0. Au lieu d’assembler manuellement une chaîne JSON, on utilise json_encode(), ce qui réduit le risque de casser l’échappement. Ajout d’un bloc default dans le switch pour les payloads non reconnus. La construction ?? (coalescence nulle) est plus propre que l’ancien isset() avec des ternaires.

Où placer ce code. Le code se place dans le fichier pointé par l’URL du webhook de l’application Facebook. Il s’agit généralement de webhook.php à la racine du site. Assurez-vous que la méthode GET sur la même URL gère la vérification du webhook via hub_challenge.

Important. Stockez le jeton d’accès dans des variables d’environnement ou un fichier de configuration, pas dans le code. Pour le développement local, utilisez un fichier .env avec PAGE_ACCESS_TOKEN=....

2. Bouton «Commencer» (get_started)

Le bouton apparaît sur l’écran d’accueil lors du premier contact avec la page. Après un clic, Facebook envoie un messaging_postbacks avec le payload que vous avez spécifié. En réponse, vous pouvez saluer l’utilisateur par son prénom ou afficher un menu de boutons.

Sans un bouton «Commencer» configuré, le menu persistant ne s’affiche pas, c’est une exigence obligatoire de la plateforme.

Mise en place:

1curl -X POST -H "Content-Type: application/json" -d '{
2 "get_started": {
3 "payload": "GET_STARTED_PAYLOAD"
4 }
5}' "https://graph.facebook.com/v22.0/me/messenger_profile?access_token=PAGE_ACCESS_TOKEN"

Le payload est une chaîne arbitraire pouvant aller jusqu’à 1000 caractères. Dans le gestionnaire PHP, ajoutez case 'GET_STARTED_PAYLOAD' dans le switch et renvoyez un message de bienvenue personnalisé.

Suppression:

1curl -X DELETE "https://graph.facebook.com/v22.0/me/messenger_profile?fields=get_started&access_token=PAGE_ACCESS_TOKEN"

3. Texte d’accueil (greeting)

Le message d’accueil s’affiche dans une conversation vide, avant le premier message. Il prend en charge les templates {{user_first_name}}, {{user_last_name}} et {{user_full_name}}. La personnalisation par le prénom augmente l’engagement, l’utilisateur voit que le bot s’adresse spécifiquement à lui.

Mise en place:

1curl -X POST -H "Content-Type: application/json" -d '{
2 "greeting": [
3 {
4 "locale": "default",
5 "text": "Hi, {{user_first_name}}! I am a helper bot. Ask a question or open the menu on the left."
6 }
7 ]
8}' "https://graph.facebook.com/v22.0/me/messenger_profile?access_token=PAGE_ACCESS_TOKEN"

Le texte d’accueil prend également en charge la localisation: ajoutez des objets avec une clé locale.

Suppression:

1curl -X DELETE "https://graph.facebook.com/v22.0/me/messenger_profile?fields=greeting&access_token=PAGE_ACCESS_TOKEN"

4. Ice Breakers: questions fréquentes avant le premier message

Les Ice Breakers sont une fonctionnalité relativement récente de la Messenger Platform. Il s’agit de boutons avec des questions toutes prêtes qui apparaissent avant que l’utilisateur n’ait écrit quoi que ce soit. Un clic envoie le texte au nom de l’utilisateur et lance le dialogue.

Pratique pour l’intégration: au lieu d’une fenêtre vide, la personne voit «Que savez-vous faire?», «Où est ma commande?», «Contacter le support» et démarre le dialogue en une seule touche.

Mise en place:

1curl -X POST -H "Content-Type: application/json" -d '{
2 "ice_breakers": [
3 {
4 "question": "What can you do?",
5 "payload": "ICE_CAPABILITIES"
6 },
7 {
8 "question": "Where is my order?",
9 "payload": "ICE_ORDER_STATUS"
10 }
11 ]
12}' "https://graph.facebook.com/v22.0/me/messenger_profile?access_token=PAGE_ACCESS_TOKEN"

Jusqu’à 4 questions, maximum 80 caractères par question. Le payload est traité dans le même gestionnaire PHP via le switch.

⁉️🤔 Foire aux questions

Pourquoi le menu n’apparaît-il pas alors que la requête a renvoyé un succès?

Principales raisons: bouton «Get Started» non configuré, page non publiée, application en mode développement, utilisateur sur une ancienne version de Messenger ou sur le navigateur mobile Facebook. Le menu est mis en cache localement, la mise à jour côté client peut prendre jusqu’à 24 heures. Pour tester, supprimez la conversation avec le bot et démarrez-en une nouvelle. Si le menu reste invisible, vérifiez tous les points: page publiée, bot public, permission pages_messaging obtenue, bouton «Get Started» configuré.

Peut-on créer un menu imbriqué?

Oui, via le paramètre call_to_actions à l’intérieur d’un élément de menu. L’imbrication prend en charge un seul niveau, le sous-menu se déploie au clic sur l’élément parent. Le format est similaire à celui du menu principal: un tableau d’objets avec type, title et payload/url. Un élément parent avec un sous-menu ne peut pas être de type web_url, uniquement postback. La profondeur maximale est d’un niveau. Il s’agit d’une limitation de la plateforme, impossible à contourner.

En quoi le menu au niveau utilisateur diffère-t-il du menu au niveau page?

Le menu au niveau page est unique pour tous les utilisateurs de la page. Le menu au niveau utilisateur, via /me/custom_user_settings, permet d’afficher des éléments différents selon les personnes: les nouveaux utilisateurs voient «Ce que je peux faire», les utilisateurs récurrents voient «Historique des commandes». La mise à jour au niveau utilisateur est en temps réel, celle au niveau page peut prendre jusqu’à 24 heures. Limite: 10 appels par utilisateur toutes les 10 minutes. Après suppression du menu personnalisé, le menu de la page est automatiquement rétabli.

Comment vérifier que le webhook reçoit bien les POSTBACK?

Activez le mode débogage dans les paramètres de l’application Facebook et cliquez sur un élément du menu dans la conversation avec le bot. Les logs afficheront une entrée avec le champ postback.payload. Vous pouvez aussi ajouter error_log(print_r($input, true)) au début du gestionnaire et consulter les logs du serveur. Pour le développement en local, utilisez ngrok: il crée un tunnel vers une URL HTTPS publique pointant sur votre localhost avec un certificat valide.

Faut-il mettre à jour le code en cas de changement de version de l’API?

Oui, deux fois par an. Meta publie une nouvelle version de l’API tous les six mois et désactive les anciennes deux ans après la sortie de leur remplacement. Consultez le Changelog Messenger Platform. Dans le code, il suffit de remplacer le numéro de version dans l’URL, la logique d’appel change rarement. Dépréciations planifiées: v19.0, janvier 2026, v20.0, mai 2026, v21.0, octobre 2026. La version v22.0 reste active jusqu’en mai 2027. Définissez une variable $api_version dans votre code.

Que faire du bot après la configuration: checklist

Le menu, le bouton et le message d’accueil sont la base, pas l’aboutissement. Une fois que les mécaniques de base fonctionnent, trois étapes transforment le bot d’une simple carte de visite en un outil utile:

  • Connecter l’analytique. Facebook Messenger Insights indique les ouvertures, les messages envoyés et reçus, les dialogues actifs. Sans ces données, vous ne saurez pas quels éléments du menu sont réellement utilisés.

  • Configurer une réponse de repli. Lorsqu’un utilisateur écrit un texte non prévu dans le scénario, le bot doit répondre de manière pertinente, pas rester silencieux. Ajoutez une branche par défaut au gestionnaire avec une proposition d’ouvrir le menu ou de contacter un humain.

  • Mettre à jour le menu de façon saisonnière. Promotions, nouveaux produits, ventes spéciales pour les fêtes: faites évoluer les éléments du menu tout au long de l’année. Via l’API Messenger Profile, cela se fait en une seule requête POST.

Si le bot prend des commandes ou collecte des contacts, configurez le domaine dans whitelisted_domains pour un fonctionnement correct de la WebView dans Messenger. Et n’oubliez pas les limites de débit: 10 appels à l’API Profile toutes les 10 minutes par page. Planifiez les mises à jour groupées du menu pour des milliers d’utilisateurs en y intégrant des délais.