Skip to content

Все для WordPress, веб-розробки — і не тільки

🤖 Налаштування постійного меню та кнопок для бота Facebook Messenger

🤖 Налаштування постійного меню та кнопок для бота Facebook Messenger

Ви запустили бота в Facebook Messenger, він відповідає на повідомлення, але чогось бракує. Користувач заходить у чат і бачить порожнє вікно. Ні меню, ні підказок, ні кнопки «Почати». Перший дотик, і тиша. Люди просто не розуміють, що ваш бот уміє.

Три компоненти перетворюють безликого бота на зрозумілий інтерфейс: постійне меню зі швидкими діями, кнопка «Почати» для першого контакту та текст вітання, який зустрічає користувача на ім’я. Раніше все це налаштовувалося через застарілий параметр thread_settings. Зараз Meta перевела керування на єдиний Messenger Profile API, і старі виклики cURL з туторіалів 2017 року просто не працюють.

У цьому гайді, актуальний підхід до налаштування постійного меню, кнопки Get Started та вітання через Messenger Profile API. З робочими прикладами cURL і PHP-обробником POSTBACK, який розрізняє натискання на пункти меню.

💡 Швидкий огляд:

  • Налаштувати постійне меню через persistent_menu у Messenger Profile API: до 20 пунктів, локалізація, вимкнення композера
  • Додати кнопку «Почати» через параметр get_started: при першому дотику Facebook повертає PSID користувача
  • Прописати текст вітання через greeting: шаблони {{user_first_name}} працюють і в 2026 році
  • Написати PHP-обробник POSTBACK: switch за payload розрізняє, на який пункт меню натиснув користувач
  • Врахувати ліміти: 10 викликів Profile API за 10 хвилин на сторінку, до 24 годин на оновлення кешу меню

Що змінилося: Thread Settings → Messenger Profile API

До 2020 року меню, кнопка «Почати» та вітання налаштовувалися окремими POST-запитами до ендпоїнта /me/thread_settings. Тип налаштування вказувався в тілі через setting_type: call_to_actions для меню, greeting для вітання. У 2026 році цей підхід не працює, ендпоїнт вилучено з документації.

Зараз усі властивості бота задаються через Messenger Profile API, єдиний ендпоїнт:

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

Тіло запиту, JSON-об’єкт із потрібними властивостями: persistent_menu для меню, get_started для кнопки «Почати», greeting для вітання, ice_breakers і whitelisted_domains. Можна передати їх разом або окремо. Профіль перезаписується, не передавайте властивість, якщо не хочете її змінювати.

Офіційна документація: Persistent Menu на Meta for Developers. Версія API оновлюється щопівроку, уточнюйте актуальну через Changelog.

Вимоги для роботи меню, актуальні на червень 2026:

  • Сторінка Facebook опублікована, бот переведений у режим «public» у налаштуваннях застосунку
  • У застосунку є дозвіл pages_messaging
  • Користувач запускає Messenger версії 106 або вище
  • Кнопка «Почати» налаштована (без неї меню не показується)
  • У вас роль адміністратора сторінки
Програмний код на екрані монітора

1. Постійне меню (persistent_menu)

Меню висить ліворуч від поля введення, користувач натискає на іконку «гамбургер» і бачить список дій. Це навігація верхнього рівня: «Допомога», «Каталог», «Підтримка». До 20 пунктів, але Meta рекомендує обмежитися п’ятьма для кращого UX.

Кожен пункт, об’єкт із type (postback або web_url), title (до 30 символів) і або payload, або url. Емодзі в заголовках працюють, копіюйте з getemoji.com.

Встановлення меню. Надішліть POST до Messenger Profile API:

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": "🆘 Помощь",
10 "payload": "HELP_PAYLOAD"
11 },
12 {
13 "type": "postback",
14 "title": "📰 Новости",
15 "payload": "LATEST_POSTS_PAYLOAD"
16 },
17 {
18 "type": "web_url",
19 "title": "🌐 Сайт",
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"

Успішна відповідь: {"result": "success"}. Меню з’явиться не одразу, кеш на стороні клієнта оновлюється до 24 годин. Під час тестування видаліть листування та почніть заново, щоб побачити зміни миттєво.

Видалення меню. DELETE із параметром fields:

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

Вимкнення композера. Якщо бот працює лише через меню та кнопки, виставте "composer_input_disabled": true. Поле введення зникне, користувач взаємодіє виключно через пункти меню та postback-кнопки. Корисно для FAQ-ботів і каталогів.

Локалізація. Додайте об’єкти з ключем locale для кожної мови. Об’єкт із "locale": "default" обов’язковий, він працює як fallback:

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}

Користувацьке меню. Через ендпоїнт /me/custom_user_settings можна перевизначити меню для конкретного користувача за PSID. Ліміт: 10 викликів на користувача за 10 хвилин. Після видалення користувацького меню відновлюється сторінкове.

2. Обробка POSTBACK у PHP

Коли користувач натискає пункт меню з type: "postback", Facebook надсилає на ваш webhook подію messaging_postbacks. У тілі запиту, об’єкт postback із полем payload, яке ви задали під час налаштування меню.

PHP-обробник читає вхідний JSON із php://input, видобуває payload і через switch визначає, яку дію виконати. Нижче, актуальний код для 2026 року з ендпоінтом v22.0:

1<?php
2// Читаем входящий запрос от Facebook
3$input = json_decode(file_get_contents('php://input'), true);
4
5// Извлекаем данные получателя и отправителя
6$page_id = $input['entry'][0]['id'];
7$sender = $input['entry'][0]['messaging'][0]['sender']['id'];
8
9// Определяем, сообщение или 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;
17 } else {
18 switch ($postback) {
19 case 'HELP_PAYLOAD':
20 $reply = 'Вы нажали кнопку «Помощь». Чем могу помочь?';
21 break;
22
23 case 'LATEST_POSTS_PAYLOAD':
24 $reply = 'Вот свежие публикации за эту неделю.';
25 break;
26
27 default:
28 $reply = 'Действие не распознано. Попробуйте ещё раз.';
29 }
30 }
31
32 // Формируем ответ
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 // Отправляем через 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}

Що змінилося. Версію API в URL піднято з v2.7 до v22.0. Замість ручного складання JSON-рядка використовується json_encode(), менше шансів зламати екранування. Додано default-блок у switch для нерозпізнаних payload. Конструкція ?? (null coalescing) чистіша за старі isset() із тернарниками.

Де розмістити. Код іде у файл, на який вказує webhook-URL застосунку Facebook. Зазвичай це webhook.php у корені сайту. Переконайтеся, що метод GET на цю саму URL-адресу обробляє верифікацію webhook через hub_challenge.

Важливо. Access token зберігайте у змінних середовища або конфігурації, не в коді. Для локальної розробки використовуйте .env-файл із PAGE_ACCESS_TOKEN=....

3. Кнопка «Почати» (get_started)

Кнопка з’являється на екрані привітання під час першого контакту користувача зі сторінкою. Після натискання Facebook надсилає messaging_postbacks із payload, який ви вказали. У відповіді можна привітати користувача на ім’я або показати меню з кнопок.

Без налаштованої кнопки «Почати» постійне меню не відображається — це обов’язкова вимога платформи.

Встановлення:

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"

Payload, довільний рядок до 1000 символів. У PHP-обробнику додайте case 'GET_STARTED_PAYLOAD' у switch і поверніть персоналізоване привітання.

Видалення:

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

4. Текст привітання (greeting)

Привітання показується в порожньому чаті до першого повідомлення. Підтримує шаблони {{user_first_name}} {{user_last_name}} і {{user_full_name}}. Персоналізація за іменем підвищує залученість, користувач бачить, що бот звертається саме до нього.

Встановлення:

1curl -X POST -H "Content-Type: application/json" -d '{
2 "greeting": [
3 {
4 "locale": "default",
5 "text": "Привет, {{user_first_name}}! Я бот-помощник. Задайте вопрос или откройте меню слева."
6 }
7 ]
8}' "https://graph.facebook.com/v22.0/me/messenger_profile?access_token=PAGE_ACCESS_TOKEN"

Текст привітання також підтримує локалізацію, додавайте об’єкти з ключем locale.

Видалення:

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

5. Ice Breakers: часті запитання до першого повідомлення

Ice Breakers, відносно нова фіча Messenger Platform. Це кнопки з готовими запитаннями, які з’являються до того, як користувач щось написав. Натискання надсилає текст від імені користувача та запускає діалог.

Зручно для онбордингу: замість порожнього вікна людина бачить «Що ти вмієш?», «Де моє замовлення?», «Зв’язатися з підтримкою» і починає діалог одним дотиком.

Встановлення:

1curl -X POST -H "Content-Type: application/json" -d '{
2 "ice_breakers": [
3 {
4 "question": "Что ты умеешь?",
5 "payload": "ICE_CAPABILITIES"
6 },
7 {
8 "question": "Где мой заказ?",
9 "payload": "ICE_ORDER_STATUS"
10 }
11 ]
12}' "https://graph.facebook.com/v22.0/me/messenger_profile?access_token=PAGE_ACCESS_TOKEN"

До 4 запитань, максимум 80 символів на запитання. Payload обробляється в тому самому PHP-обробнику через switch.

⁉️🤔 Часті запитання

Чому меню не з’являється, хоча запит повернув success?

Основні причини: не налаштована кнопка «Почати», сторінка не опублікована, застосунок у режимі розробки, користувач використовує стару версію Messenger або Facebook Mobile Browser. Меню кешується локально, оновлення на стороні клієнта триває до 24 годин. Для тесту видаліть листування з ботом і почніть заново. Якщо меню досі не видно, перевірте всі пункти: сторінка опублікована, бот публічний, дозвіл pages_messaging отримано, кнопка «Почати» налаштована.

Чи можна зробити вкладене меню?

Так, через параметр call_to_actions всередині пункту меню. Вкладеність підтримує один рівень, підменю розкривається після натискання на батьківський пункт. Формат аналогічний основному меню: масив об’єктів із type, title та payload/url. Батьківський пункт із вкладеним меню не може бути web_url, лише postback. Максимальна глибина, один рівень. Це обмеження платформи, обійти його не можна.

Чим user-level меню відрізняється від page-level?

Page-level меню, одне для всіх користувачів сторінки. User-level через /me/custom_user_settings дає змогу показувати різні пункти різним людям: новим, «Що я вмію», тим, хто повернувся,, «Історія замовлень». User-level оновлюється в реальному часі, сторінкове, із затримкою до 24 годин. Ліміт: 10 викликів на користувача за 10 хвилин. Після видалення користувацького меню автоматично відновлюється сторінкове.

Як перевірити, що webhook приймає POSTBACK?

Увімкніть режим налагодження в налаштуваннях застосунку Facebook і натисніть пункт меню в чаті з ботом. У логах з’явиться запис із полем postback.payload. Як альтернатива, додайте error_log(print_r($input, true)) на початок обробника та дивіться логи сервера. Для локальної розробки використовуйте ngrok: він прокладає публічний HTTPS-URL на ваш localhost із валідним сертифікатом.

Чи потрібно оновлювати код, якщо версія API змінюється?

Так, двічі на рік. Meta випускає нову версію API щопівроку, старі вимикає через 2 роки після виходу заміни. Стежте за Changelog Messenger Platform. У коді достатньо замінити номер версії в URL, логіка викликів змінюється рідко. Планове вимкнення: v19.0, січень 2026, v20.0, травень 2026, v21.0, жовтень 2026. Версія v22.0 активна до травня 2027. Ставте в коді змінну $api_version.

Що робити з ботом після налаштування: чек-лист

Меню, кнопка та привітання — це фундамент, а не фінал. Коли базова механіка працює, три кроки перетворюють бота з візитівки на корисний інструмент:

  • Підключіть аналітику. Facebook Messenger Insights показує відкриття, надіслані й отримані повідомлення, активні діалоги. Без цих даних ви не дізнаєтеся, якими пунктами меню реально користуються.

  • Налаштуйте fallback-відповідь. Коли користувач пише текст, не передбачений сценарієм, бот має відповідати осмислено, а не мовчати. Додайте в обробник гілку default із пропозицією відкрити меню або зв’язатися з людиною.

  • Оновлюйте меню під сезон. Акції, нові продукти, святкові розпродажі, змінюйте пункти меню протягом року. Через Messenger Profile API це робиться одним POST-запитом.

Якщо бот обробляє замовлення або збирає контакти, налаштуйте домен у whitelisted_domains для коректної роботи WebView всередині Messenger. І не забувайте про rate limits: 10 викликів Profile API за 10 хвилин на сторінку. Пакетні оновлення меню для тисяч користувачів ставте в чергу із затримкою.