Skip to content
🤖 Sette opp vedvarende meny og knapper for Facebook Messenger-bot

🤖 Sette opp vedvarende meny og knapper for Facebook Messenger-bot

Du har lansert en chatbot i Facebook Messenger, den svarer på meldinger, men noe mangler. En bruker åpner chatten og ser et tomt vindu. Ingen meny, ingen hint, ingen «Kom i gang»-knapp. Første møte, og stillhet. Folk forstår rett og slett ikke hva chatboten din kan gjøre.

Tre komponenter gjør en ansiktsløs chatbot om til et forståelig grensesnitt: en fast meny med hurtighandlinger, en «Kom i gang»-knapp for førstegangskontakt, og en velkomsttekst som hilser brukeren ved navn. Tidligere ble alt dette konfigurert via den utdaterte parameteren thread_settings. Nå har Meta flyttet kontrollen til det enhetlige Messenger Profile API-et, og gamle cURL-kall fra veiledninger fra 2017 fungerer rett og slett ikke.

I denne veiledningen ser vi på dagens tilnærming til å konfigurere fast meny, Kom i gang-knapp og velkomsthilsen via Messenger Profile API-et. Med fungerende cURL-eksempler og en PHP POSTBACK-håndterer som skiller mellom klikk på menyelementer.

💡 Hurtigoversikt:

  • Konfigurer fast meny via persistent_menu i Messenger Profile API: opptil 20 elementer, lokalisering, deaktivering av skrivefelt
  • Legg til «Kom i gang»-knapp via parameteren get_started: ved første berøring returnerer Facebook brukerens PSID
  • Sett opp velkomsttekst via greeting: {{user_first_name}}-maler fungerer fortsatt i 2026
  • Skriv en PHP POSTBACK-håndterer: en switch på payload skiller hvilket menyelement brukeren klikket på
  • Vær oppmerksom på begrensninger: 10 Profile API-kall per 10 minutter per side, opptil 24 timer for oppdatering av menybuffer

Hva som er endret: Thread Settings → Messenger Profile API

Før 2020 ble meny, «Kom i gang»-knapp og velkomsthilsen konfigurert med separate POST-forespørsler til endepunktet /me/thread_settings. Innstillingstypen ble angitt i brødteksten via setting_type: call_to_actions for meny, greeting for hilsen. I 2026 fungerer ikke denne tilnærmingen, endepunktet er fjernet fra dokumentasjonen.

Nå settes alle chatbot-egenskaper via Messenger Profile API, et enhetlig endepunkt:

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

Forespørselsbrødteksten er et JSON-objekt med de nødvendige egenskapene: persistent_menu for meny, get_started for «Kom i gang»-knapp, greeting for hilsen, ice_breakers og whitelisted_domains. Du kan sende dem samlet eller hver for seg. Profilen overskrives, så ikke send med en egenskap hvis du ikke vil endre den.

Offisiell dokumentasjon: Persistent Menu på Meta for Developers. API-versjonen oppdateres hvert halvår, sjekk gjeldende versjon via Changelog.

Krav for at menyen skal fungere, gjeldende per juni 2026:

  • Facebook-siden er publisert, chatboten satt til «offentlig» modus i app-innstillingene
  • Appen har tillatelsen pages_messaging
  • Brukeren kjører Messenger versjon 106 eller høyere
  • «Kom i gang»-knappen er konfigurert (uten den vises ikke menyen)
  • Du har administratorrollen for siden
Programkode på en dataskjerm

1. Fast meny (persistent_menu)

Menyen ligger til venstre for inntastingsfeltet, brukeren klikker på «hamburger»-ikonet og ser en liste med handlinger. Dette er navigasjon på toppnivå: «Hjelp», «Katalog», «Support». Opptil 20 elementer, men Meta anbefaler å begrense til fem for bedre brukeropplevelse.

Hvert element er et objekt med type (postback eller web_url), title (opptil 30 tegn) og enten payload eller url. Emoji i titler fungerer, kopier fra getemoji.com.

Sette opp meny. Send POST til 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"

Vellykket respons: {"result": "success"}. Menyen vises ikke umiddelbart, klientbufferen oppdateres i opptil 24 timer. Når du tester, slett samtalen og start på nytt for å se endringer øyeblikkelig.

Fjerne meny. DELETE med parameteren fields:

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

Deaktivere skrivefelt. Hvis chatboten bare fungerer via meny og knapper, sett "composer_input_disabled": true. Inntastingsfeltet forsvinner, og brukeren samhandler utelukkende via menyelementer og postback-knapper. Nyttig for FAQ-chatboter og kataloger.

Lokalisering. Legg til objekter med nøkkelen locale for hvert språk. Objektet med "locale": "default" er obligatorisk og fungerer som tilbakefall:

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}

Tilpasset meny. Via endepunktet /me/custom_user_settings kan du overstyre menyen for en spesifikk bruker med PSID. Begrensning: 10 kall per bruker per 10 minutter. Etter fjerning av tilpasset meny, gjenopprettes sidens meny.

2. Håndtering av POSTBACK i PHP

Når en bruker klikker på et menyelement med type: "postback", sender Facebook en messaging_postbacks-hendelse til din webhook. I forespørselsbrødteksten ligger et postback-objekt med et payload-felt som du satte da du konfigurerte menyen.

PHP-behandleren leser innkommende JSON fra php://input, henter ut payload og avgjør via switch hvilken handling som skal utføres. Under finner du gjeldende kode for 2026 med v22.0-endepunkt:

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}

Hva som er endret. API-versjon i URL er økt fra v2.7 til v22.0. I stedet for manuell bygging av JSON-strenger brukes json_encode(), noe som gir mindre risiko for feil i escaping. Det er lagt til en default-blokk i switch for ugjenkjent payload. Konstruksjonen ?? (null coalescing) er ryddigere enn gammel isset() med ternære operatorer.

Hvor koden plasseres. Koden legges i filen som Facebook-appens webhook-URL peker til. Vanligvis er dette webhook.php i nettstedets rotmappe. Sørg for at GET-metoden på samme URL håndterer webhook-verifisering via hub_challenge.

Viktig. Oppbevar tilgangstoken i miljøvariabler eller konfigurasjon, ikke i koden. For lokal utvikling bruker du en .env-fil med PAGE_ACCESS_TOKEN=....

3. Kom i gang-knapp (get_started)

Knappen vises på velkomstskjermen ved første kontakt med siden. Etter klikk sender Facebook messaging_postbacks med payloaden du spesifiserte. Som svar kan du hilse på brukeren med navn eller vise en meny med knapper.

Uten en konfigurert «Kom i gang»-knapp vises ikke den vedvarende menyen, dette er et obligatorisk plattformkrav.

Oppsett:

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 er en vilkårlig streng på opptil 1000 tegn. I PHP-behandleren legger du til case 'GET_STARTED_PAYLOAD' i switch og returnerer en personlig hilsen.

Fjerning:

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

4. Hilsningstekst (greeting)

Hilsningen vises i en tom chat før den første meldingen. Støtter malene {{user_first_name}} {{user_last_name}} og {{user_full_name}}. Personalisering med navn øker engasjementet, brukeren ser at boten henvender seg direkte til dem.

Oppsett:

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"

Hilsningstekst støtter også lokalisering, legg til objekter med locale-nøkkel.

Fjerning:

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

5. Isbrytere: vanlige spørsmål før første melding

Isbrytere er en relativt ny funksjon i Messenger-plattformen. Dette er knapper med ferdige spørsmål som vises før brukeren har skrevet noe. Et klikk sender teksten på vegne av brukeren og starter dialogen.

Praktisk for onboarding: i stedet for et tomt vindu ser personen «Hva kan du gjøre?», «Hvor er bestillingen min?», «Kontakt kundestøtte» og starter dialogen med ett trykk.

Oppsett:

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"

Opptil 4 spørsmål, maksimalt 80 tegn per spørsmål. Payload håndteres i samme PHP-behandler via switch.

⁉️🤔 Ofte stilte spørsmål

Hvorfor vises ikke menyen selv om forespørselen returnerte suksess?

Hovedårsaker: «Kom i gang»-knappen er ikke konfigurert, siden er ikke publisert, appen er i utviklingsmodus, brukeren bruker en gammel Messenger-versjon eller Facebooks mobilnettleser. Menyen mellomlagres lokalt, og klientoppdateringen kan ta opptil 24 timer. For testing, slett samtalen med boten og start på nytt. Hvis menyen fortsatt ikke er synlig, sjekk alle punkter: siden publisert, boten offentlig, tillatelsen pages_messaging innhentet, «Kom i gang»-knappen konfigurert.

Kan man lage en nestet meny?

Ja, via parameteren call_to_actions inne i et menyelement. Nesting støtter ett nivå, undermenyen utvides når man klikker på overordnet element. Formatet ligner hovedmenyen: en matrise med objekter med type, title og payload/url. Overordnet element med nestet meny kan ikke være web_url, kun postback. Maksimal dybde er ett nivå. Dette er en plattformbegrensning som ikke kan omgås.

Hvordan skiller meny på brukernivå seg fra sidenivå?

Meny på sidenivå er én for alle sidebrukere. Brukernivå via /me/custom_user_settings gjør det mulig å vise ulike elementer til ulike personer: nye brukere får «Hva jeg kan gjøre», tilbakevendende brukere får «Ordrehistorikk». Brukernivå oppdateres i sanntid, sidenivå med en forsinkelse på opptil 24 timer. Begrensning: 10 kall per bruker per 10 minutter. Etter fjerning av tilpasset meny gjenopprettes sidemenyen automatisk.

Hvordan sjekker man at webhook mottar POSTBACK?

Aktiver feilsøkingsmodus i Facebook-appinnstillingene og klikk på et menyelement i chat med boten. Logger vil vise en oppføring med feltet postback.payload. Alternativt kan du legge til error_log(print_r($input, true)) i starten av handleren og sjekke serverloggene. For lokal utvikling, bruk ngrok: det tunnelerer en offentlig HTTPS-URL til din localhost med et gyldig sertifikat.

Må man oppdatere koden hvis API-versjonen endres?

Ja, to ganger i året. Meta lanserer en ny API-versjon hver sjette måned og deaktiverer gamle to år etter at erstatningen er utgitt. Følg Changelog Messenger Platform. I koden er det bare å erstatte versjonsnummeret i URL-en, kallogikken endres sjelden. Planlagt utfasing: v19.0, januar 2026, v20.0, mai 2026, v21.0, oktober 2026. Versjon v22.0 er aktiv til mai 2027. Sett variabelen $api_version i koden.

Hva du gjør med boten etter oppsett: sjekkliste

Meny, knapp og velkomsthilsen er grunnmuren, ikke målstreken. Når grunnleggende mekanikk fungerer, gjør tre steg boten fra et visittkort til et nyttig verktøy:

  • Koble til analyse. Facebook Messenger Insights viser åpninger, sendte og mottatte meldinger, aktive dialoger. Uten disse dataene vet du ikke hvilke menyelementer som faktisk brukes.

  • Konfigurer reserverespons. Når en bruker skriver tekst som ikke er forutsett i scenarioet, bør boten svare meningsfylt, ikke være stille. Legg til en standardgren i handleren med et tilbud om å åpne menyen eller kontakte et menneske.

  • Oppdater menyen sesongbasert. Kampanjer, nye produkter, høytidssalg, endre menyelementer gjennom året. Via Messenger Profile API gjøres dette med én POST-forespørsel.

Hvis boten håndterer bestillinger eller samler inn kontakter, konfigurer domene i whitelisted_domains for korrekt WebView-drift inne i Messenger. Og ikke glem ratebegrensninger: 10 Profile API-kall per 10 minutter per side. Sett menyoppdateringer i kø for tusenvis av brukere med forsinkelser.