Skip to content

Allt om WordPress, webbutveckling — och mer därtill

🤖 Konfigurera beständig meny och knappar för Facebook Messenger-bot

🤖 Konfigurera beständig meny och knappar för Facebook Messenger-bot

Du har lanserat en bot i Facebook Messenger, den svarar på meddelanden, men något saknas. En användare öppnar chatten och ser ett tomt fönster. Ingen meny, inga ledtrådar, ingen "Kom igång"-knapp. Första kontakten, och tystnad. Folk förstår helt enkelt inte vad din bot kan göra.

Tre komponenter förvandlar en ansiktslös bot till ett begripligt gränssnitt: en fast meny med snabbåtgärder, en "Kom igång"-knapp för första kontakten och en hälsningstext som välkomnar användaren med namn. Tidigare konfigurerades allt detta via den numera föråldrade parametern thread_settings. Nu har Meta flyttat kontrollen till det enhetliga Messenger Profile API:t, och gamla cURL-anrop från guider från 2017 fungerar helt enkelt inte.

I den här guiden går vi igenom det aktuella tillvägagångssättet för att konfigurera den fasta menyn, Kom igång-knappen och hälsningen via Messenger Profile API. Med fungerande cURL-exempel och en PHP POSTBACK-hanterare som särskiljer klick på menyalternativ.

💡 Snabb översikt:

  • Konfigurera fast meny via persistent_menu i Messenger Profile API: upp till 20 alternativ, lokalisering, inaktivering av textinmatning
  • Lägg till "Kom igång"-knapp via parametern get_started: vid första kontakten returnerar Facebook användarens PSID
  • Ställ in hälsningstext via greeting: mallar med {{user_first_name}} fungerar fortfarande 2026
  • Skriv en PHP POSTBACK-hanterare: en switch på payload särskiljer vilket menyalternativ användaren klickade på
  • Tänk på begränsningar: 10 Profile API-anrop per 10 minuter per sida, upp till 24 timmar för uppdatering av meny-cache

Vad som ändrades: Thread Settings → Messenger Profile API

Före 2020 konfigurerades meny, "Kom igång"-knapp och hälsning med separata POST-anrop till ändpunkten /me/thread_settings. Inställningstypen angavs i bodyn via setting_type: call_to_actions för meny, greeting för hälsning. År 2026 fungerar inte detta tillvägagångssätt, ändpunkten har tagits bort från dokumentationen.

Nu sätts alla bot-egenskaper via Messenger Profile API, en enhetlig ändpunkt:

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

Anropsbodyn är ett JSON-objekt med de egenskaper som behövs: persistent_menu för meny, get_started för "Kom igång"-knapp, greeting för hälsning, ice_breakers och whitelisted_domains. Du kan skicka dem tillsammans eller separat. Profilen skrivs över, så skicka inte med en egenskap om du inte vill ändra den.

Officiell dokumentation: Persistent Menu på Meta for Developers. API-versionen uppdateras var sjätte månad, kontrollera den aktuella via Changelog.

Krav för att menyn ska fungera, aktuella per juni 2026:

  • Facebook-sidan är publicerad, boten är satt till "public" i appinställningarna
  • Appen har behörigheten pages_messaging
  • Användaren kör Messenger version 106 eller högre
  • "Kom igång"-knappen är konfigurerad (utan den visas inte menyn)
  • Du har administratörsroll för sidan
Programkod på en bildskärm

1. Fast meny (persistent_menu)

Menyn hänger till vänster om inmatningsfältet, användaren klickar på "hamburgar"-ikonen och ser en lista med åtgärder. Detta är toppnavigering: "Hjälp", "Katalog", "Support". Upp till 20 alternativ, men Meta rekommenderar att man begränsar till fem för bättre UX.

Varje alternativ är ett objekt med type (postback eller web_url), title (upp till 30 tecken) och antingen payload eller url. Emoji i titlar fungerar, kopiera från getemoji.com.

Konfigurera meny. Skicka POST till 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": "🆘 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"

Lyckat svar: {"result": "success"}. Menyn visas inte omedelbart, klient-sidans cache uppdateras inom upp till 24 timmar. När du testar, ta bort konversationen och börja om för att se ändringar direkt.

Ta bort meny. DELETE med parametern fields:

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

Inaktivera textinmatning. Om boten bara fungerar via meny och knappar, sätt "composer_input_disabled": true. Inmatningsfältet försvinner, användaren interagerar uteslutande via menyalternativ och postback-knappar. Användbart för FAQ-botar och kataloger.

Lokalisering. Lägg till objekt med nyckeln locale för varje språk. Objektet med "locale": "default" är obligatoriskt, det fungerar som 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}

Anpassad meny. Via ändpunkten /me/custom_user_settings kan du åsidosätta menyn för en specifik användare med PSID. Begränsning: 10 anrop per användare per 10 minuter. Efter borttagning av anpassad meny återställs sidans meny.

2. Hantera POSTBACK i PHP

När en användare klickar på ett menyval med type: "postback" skickar Facebook en messaging_postbacks-händelse till din webhook. I request body finns ett postback-objekt med ett payload-fält som du sätter när du konfigurerar menyn.

PHP-hanteraren läser inkommande JSON från php://input, extraherar payload och avgör via switch vilken åtgärd som ska utföras. Nedan finns aktuell kod för 2026 med v22.0-endpoint:

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}

Vad som har ändrats. API-versionen i URL:en höjdes från v2.7 till v22.0. Istället för manuell JSON-stränghantering används json_encode(), vilket minskar risken för felaktig escaping. Ett default-block lades till i switch för okänd payload. Konstruktionen ?? (null coalescing) är renare än den gamla isset() med ternära operatorer.

Var koden ska placeras. Koden läggs i filen som Facebook-appens webhook-URL pekar på. Vanligtvis är detta webhook.php i webbplatsens rot. Se till att GET-metoden på samma URL hanterar webhook-verifiering via hub_challenge.

Viktigt. Lagra access token i miljövariabler eller config, inte i koden. För lokal utveckling använd en .env-fil med PAGE_ACCESS_TOKEN=....

3. Kom igång-knapp (get_started)

Knappen visas på välkomstskärmen vid första kontakten med sidan. Efter klick skickar Facebook messaging_postbacks med den payload du angav. Som svar kan du hälsa användaren med namn eller visa en meny med knappar.

Utan en konfigurerad "Kom igång"-knapp visas inte den beständiga menyn, detta är ett obligatoriskt plattformskrav.

Konfiguration:

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 är en godtycklig sträng på upp till 1000 tecken. I PHP-hanteraren lägger du till case 'GET_STARTED_PAYLOAD' i switch och returnerar en personlig hälsning.

Borttagning:

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

4. Hälsningstext (greeting)

Hälsningen visas i en tom chatt före det första meddelandet. Stöder mallarna {{user_first_name}} {{user_last_name}} och {{user_full_name}}. Personlig anpassning med namn ökar engagemanget, användaren ser att botten tilltalar just dem.

Konfiguration:

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"

Hälsningstexten stöder också lokalisering, lägg till objekt med locale-nyckel.

Borttagning:

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

5. Ice Breakers: vanliga frågor före första meddelandet

Ice Breakers är en relativt ny funktion i Messenger Platform. Det är knappar med färdiga frågor som visas innan användaren har skrivit något. Ett klick skickar texten för användarens räkning och startar dialogen.

Praktiskt för onboarding: istället för ett tomt fönster ser personen "Vad kan du göra?", "Var är min order?", "Kontakta support" och startar dialogen med en knapptryckning.

Konfiguration:

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"

Upp till 4 frågor, max 80 tecken per fråga. Payload hanteras i samma PHP-hanterare via switch.

⁉️🤔 Vanliga frågor

Varför visas inte menyn trots att förfrågan returnerade success?

Huvudorsaker: "Kom igång"-knappen är inte konfigurerad, sidan är inte publicerad, appen är i utvecklingsläge, användaren har en gammal Messenger-version eller Facebooks mobilwebbläsare. Menyn cachas lokalt, uppdatering på klientsidan kan ta upp till 24 timmar. För testning, radera konversationen med botten och börja om. Om menyn fortfarande inte syns, kontrollera alla punkter: sidan publicerad, botten publik, behörigheten pages_messaging erhållen, "Kom igång"-knappen konfigurerad.

Kan man skapa en nästlad meny?

Ja, via parametern call_to_actions inuti ett menyalternativ. Nästling stöder en nivå, undermenyn expanderar när man klickar på det överordnade alternativet. Formatet liknar huvudmenyn: array av objekt med type, title och payload/url. Överordnat alternativ med nästlad meny kan inte vara web_url, endast postback. Maximalt djup är en nivå. Detta är en plattformsbegränsning och kan inte kringgås.

Hur skiljer sig meny på användarnivå från sidnivå?

Meny på sidnivå är en för alla sidans användare. Användarnivå via /me/custom_user_settings gör det möjligt att visa olika alternativ för olika personer: nya användare får "Vad jag kan göra", återkommande användare får "Orderhistorik". Användarnivå uppdateras i realtid, sidnivå med upp till 24 timmars fördröjning. Gräns: 10 anrop per användare per 10 minuter. Efter borttagning av anpassad meny återställs sidmenyn automatiskt.

Hur kontrollerar man att webhook tar emot POSTBACK?

Aktivera felsökningsläge i Facebooks appinställningar och klicka på ett menyalternativ i chatten med botten. Loggarna visar en post med fältet postback.payload. Alternativt lägg till error_log(print_r($input, true)) i början av hanteraren och kontrollera serverloggarna. För lokal utveckling använd ngrok: det tunnlar en publik HTTPS-URL till din localhost med ett giltigt certifikat.

Behöver man uppdatera koden om API-versionen ändras?

Ja, två gånger per år. Meta släpper en ny API-version var sjätte månad och inaktiverar gamla 2 år efter att ersättningsversionen släppts. Följ Changelog Messenger Platform. I koden byter du bara versionsnumret i URL:en, anropslogiken ändras sällan. Planerad utfasning: v19.0, januari 2026, v20.0, maj 2026, v21.0, oktober 2026. Version v22.0 aktiv till maj 2027. Sätt variabeln $api_version i koden.

Vad du ska göra med botten efter installation: checklista

Meny, knapp och hälsning är grunden, inte målet. När den grundläggande mekaniken fungerar förvandlar tre steg botten från ett visitkort till ett användbart verktyg:

  • Koppla upp analys. Facebook Messenger Insights visar öppningar, skickade och mottagna meddelanden, aktiva dialoger. Utan denna data vet du inte vilka menyalternativ som faktiskt används.

  • Konfigurera reservsvar. När en användare skriver text som inte finns med i scenariot ska botten svara meningsfullt, inte vara tyst. Lägg till en standardgren i hanteraren med ett erbjudande om att öppna menyn eller kontakta en människa.

  • Uppdatera menyn säsongsvis. Kampanjer, nya produkter, högtidsreor, ändra menyalternativ under året. Via Messenger Profile API görs detta med en POST-förfrågan.

Om botten hanterar beställningar eller samlar in kontakter, konfigurera domän i whitelisted_domains för korrekt WebView-funktion inuti Messenger. Och glöm inte hastighetsbegränsningarna: 10 Profile API-anrop per 10 minuter per sida. Köa batchuppdateringar av menyer för tusentals användare med fördröjningar.