
🤖 Налаштування постійного меню та кнопок для бота 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, єдиний ендпоїнт:
1 POST 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:
1 curl -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:
1 curl -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 13 if ($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, який ви вказали. У відповіді можна привітати користувача на ім’я або показати меню з кнопок.
Без налаштованої кнопки «Почати» постійне меню не відображається — це обов’язкова вимога платформи.
Встановлення:
1 curl -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 і поверніть персоналізоване привітання.
Видалення:
1 curl -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}}. Персоналізація за іменем підвищує залученість, користувач бачить, що бот звертається саме до нього.
Встановлення:
1 curl -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.
Видалення:
1 curl -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. Це кнопки з готовими запитаннями, які з’являються до того, як користувач щось написав. Натискання надсилає текст від імені користувача та запускає діалог.
Зручно для онбордингу: замість порожнього вікна людина бачить «Що ти вмієш?», «Де моє замовлення?», «Зв’язатися з підтримкою» і починає діалог одним дотиком.
Встановлення:
1 curl -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 хвилин на сторінку. Пакетні оновлення меню для тисяч користувачів ставте в чергу із затримкою.



