1. WhatsApp Web guide
  2. Menu bot setup guide

About this site

Menu bot setup guide

For buyers of the menu bot: every step, in plain words. About one hour, two free accounts, no programming. Stuck? Support is included for 30 days.

Is your bot hosted by us? Then you skip everything about Cloudflare. You only do the Meta part: step 3 (create your Meta app), step 4 (connect your number), step 5 (permanent access token and app secret) and step 9 (go live). Then log in to the customer portal and paste the app ID, app secret, token, phone number ID and WhatsApp Business Account ID under your purchase. We connect the webhook for you.

You are about to run a menu bot that belongs to you. It lives in your Cloudflare account, talks to WhatsApp through your Meta app, and nobody else, including us, can see your messages or your access token. Set aside 45 to 60 minutes. You need no programming knowledge, only patience with two dashboards.

Included: 30 days of setup help. Stuck? First open your bot's /check page (step 7). It tests every setting and tells you in plain words what to fix. Still stuck: mail info@airtimemedia.eu with a screenshot of that page and we answer within two working days. Want your menu changed? Mail us what should be different and we send you the new menu to paste in. If we cannot get your bot running within 30 days of purchase, you get your money back.

Before you start: three things to know

  1. The bot needs a phone number that is not in use in the WhatsApp or WhatsApp Business app. A number connected directly to the WhatsApp Business Platform cannot be open in the phone app at the same time. Most owners use a second number for the bot (a spare SIM, a landline or a virtual number that can receive one SMS or call) and keep their existing number in the app for talking to people. The bot hands customers over to that number with a link.
  2. What it costs to run. Cloudflare's free plan is enough for roughly 300 to 400 customer messages a day. Meta charges nothing for the first 1,000 replies per month per number (rule from 1 October 2026; before that date replies are free without a limit). Beyond that, Meta charges a small fee per reply and asks for a payment method on your WhatsApp Business Account. The optional notification template (step 8) is charged per message from the first one.
  3. What the bot does. It answers people who write to you: menu, replies, questions, a summary to you. It never starts conversations and never sends marketing, so it needs no opt-in list.

1. Your menu is already inside

This download was built for you: the menu you made and tried on webonwhatsapp.com is written into worker.js. There is nothing to copy. menu.json in this folder is the same menu, for your own records.

Not happy with a text or an option? For 30 days after your purchase you can change the menu as often as you like: see "Changing the menu later" at the end of this guide.

2. Create the bot on Cloudflare

  1. Create a free account at dash.cloudflare.com.
  2. Workers & Pages → Create → Worker → start from "Hello World" → name it (for example menubot) → Deploy.
  3. Edit code, delete everything in the editor, paste the whole of worker.js → Deploy.
  4. Note the address of your Worker: https://menubot.YOUR-NAME.workers.dev. This is your callback URL.
  5. Storage & Databases → KV → Create a namespace called menubot-state.
  6. Back in the Worker: Settings → Bindings → Add → KV namespace → variable name STATE (exactly, in capitals) → choose menubot-state → Deploy.

3. Create your Meta app

  1. Go to developers.facebook.com, log in with your Facebook account and register as a developer.
  2. My Apps → Create App → use case "Connect with customers through WhatsApp" → choose or create your business portfolio → finish.
  3. In the app, open WhatsApp → API Setup. Meta gives you a test number to try things with. Under "To", add your own mobile number as a recipient and confirm the code: while the app is in development mode the bot can only answer numbers on this list.
  4. Note the Phone number ID shown on this page (a long number, not the phone number itself).

4. Connect your real number (can also be done after testing)

On the same page choose Add phone number, enter your business name and the number from "Before you start", and confirm it by SMS or call. Meta reviews the display name. Use the Phone number ID of this number from now on.

5. Get a permanent access token

The token on the API Setup page expires after 24 hours. For a bot you need one that does not:

  1. business.facebook.com → Settings → Users → System users → Add → name menubot, role Admin.
  2. Assign assets: your app (full control) and your WhatsApp account (full control).
  3. Generate token → select your app → expiration Never → tick whatsapp_business_messaging and whatsapp_business_management → copy the token. It is shown once.
  4. In your Meta app: App settings → Basic → App secret → Show → copy it.

6. Give the bot its settings

In Cloudflare: Worker → Settings → Variables and Secrets → Add. Use type Secret where marked.

Name Type Value
PHONE_NUMBER_ID Text from step 3 or 4
WHATSAPP_TOKEN Secret the permanent token from step 5
APP_SECRET Secret the app secret from step 5
VERIFY_TOKEN Secret any phrase you make up, e.g. blue-kettle-42
CHECK_KEY Secret another phrase you make up; it opens your check page
OWNER_NUMBER Text, optional your own WhatsApp number with country code; completed requests are sent there
NOTIFY_URL Text, optional a web address (Zapier, Make, Google Sheets script) that receives each request

Press Deploy after adding them.

7. Connect WhatsApp to the bot, and check

  1. Meta app → WhatsApp → Configuration → Webhook → Edit: callback URL = your Worker address from step 2, verify token = the VERIFY_TOKEN phrase → Verify and save.
  2. Under Webhook fields, subscribe to messages.
  3. Open https://menubot.YOUR-NAME.workers.dev/check?key=YOUR_CHECK_KEY. Every line should say OK. A line that says FIX tells you what to change.
  4. From your mobile, send "hi" to the bot's number. The menu should answer within a second or two. Reload the check page: "Messages arriving from Meta" now shows the time.

If "hi" gets no answer and the check page still says no messages arrived, your app is most likely not subscribed to your WhatsApp Business Account. Meta verifies the webhook and even shows your message under Check test webhooks in the dashboard, but it only delivers to apps that are subscribed to the account - and on a new app often only Meta's own dashboard app is. To subscribe yours, once:

  1. Open the Graph API Explorer: developers.facebook.com/tools/explorer
  2. Top right, pick your app, and paste your access token into the token field.
  3. Set the method to POST and the path to YOUR_WHATSAPP_BUSINESS_ACCOUNT_ID/subscribed_apps (the account ID is on the API Setup page, next to the phone number ID). Click Submit.
  4. The answer is {"success": true}. Send "hi" again.

Argentina and Mexico: a number that writes to the bot as 549... (Argentina) or 521... (Mexico) is sometimes only reachable in another form - Meta then refuses the reply with error 131030 or 131026. The bot handles this itself: it tries the other forms once, remembers the one that works, and uses it from then on. Nothing to set up.

8. Notifications that always arrive (recommended)

The bot sends each completed request to OWNER_NUMBER as a normal message. WhatsApp only allows that within 24 hours of your last message to the bot. Two ways to deal with it:

  • Simple: send the bot any message from your own WhatsApp once a day. It answers "Notifications are on".
  • Reliable: Meta app → WhatsApp → Message templates → create a Utility template named new_request, language English (US), body New request: {{1}}. Once approved, add the variable NOTIFY_TEMPLATE = new_request. The bot uses it automatically whenever your 24 hours have run out.

9. Go live

In the Meta app, switch App mode from Development to Live (Meta asks for a privacy policy URL; your website's policy is fine). From now on the bot answers everyone, not only the numbers on your test list. Put the bot's number on your website with a chat button or link from webonwhatsapp.com/tools/.

Changing the menu later

Within 30 days of your purchase: make the new menu in the generator on webonwhatsapp.com, choose "I already bought" under the price, and enter the licence key from your Gumroad receipt. You get a fresh download with the new menu inside. In Cloudflare, open your Worker, Edit code, replace everything with the new worker.js, Deploy. Your settings stay as they are.

At any time, by hand: open menu.json, change the texts, and paste the whole content into a new variable called MENU_JSON (type Text) under Settings → Variables and Secrets, then Deploy. A MENU_JSON variable always wins over the menu inside the file.

Opening hours (optional). By default the bot always sends your greeting. To send the away message outside your hours, use the MENU_JSON way above and replace "schedule": null with your times (24-hour clock, your time zone):

"schedule": { "tz": "Europe/London", "days": { "mon": ["09:00", "17:30"], "tue": ["09:00", "17:30"], "wed": ["09:00", "17:30"], "thu": ["09:00", "17:30"], "fri": ["09:00", "17:30"] } }

Days you leave out are closed.

How the bot behaves

You can try all of this before you install anything: the chat in step 2 of the generator runs the same logic as your bot.

  • First message from a customer → your greeting with the menu (or the away message when you are closed). If that first message already says what they want ("do you have a table tonight?"), the bot answers it directly instead.
  • A number, letter or keyword → that option's reply. The bot also understands plain questions: "what time are you open?", "how much is it?", "can I book?" find the matching option.
  • If the option has questions, the bot asks them one by one, then sends your closing line and notifies you with the answers and a link to reply to the customer.
  • Inside those questions a customer is never trapped: CANCEL stops, MENU starts over, and a question ("how much is a pizza?") pauses the request and gets answered instead of being saved as an answer.
  • If the option books a time, the bot offers the times you are still free as numbers, writes the booking down and gives the customer a code to cancel with. See Your agenda below.
  • "Hi" shows the menu again, "thanks" gets a thank-you. Neither counts as a mistake.
  • "Talk to a person", or two replies in a row the bot does not understand → your handover message and a notification to you. After that the customer is never met with silence: a menu choice, a greeting or MENU wakes the bot again, and anything else is passed on to you and acknowledged to the customer.
  • You reply to customers from your own WhatsApp (the notification contains a link that opens the chat). The bot's number has no phone app, which is why the staff number in your menu matters.

Your agenda: letting customers book a time

Bookings are part of the assistant, the version we set up and run for you; the download you bought is the menu bot, and its menu.json says "booking": { "enabled": false .... Everything the agenda needs is nevertheless inside your bot, so if you want to run it yourself, set "enabled": true and fill in the days below - it is your file. What follows is how it then behaves. There is nothing to connect and no account to link: the bot works out which times are still free, offers three of them as numbered choices, and writes the booking down in its own storage.

A booking looks like this to your customer:

1. Wednesday 23 September, 10:00
2. Wednesday 23 September, 11:00
3. Thursday 24 September, 09:00
4. Other times

They reply 2. The bot answers any questions you set for that option, confirms the time and gives them a six-character code. Sending that code back cancels their booking and puts the time back on offer. Nobody else's code works, and a time that is booked is never offered again (unless you set "how many at the same time" higher than one).

You get the booking twice. The notification on your own WhatsApp says the time, the customer's details and their number — and carries a link ending in /ics/CODE.ics. Opening it on your phone offers to put that appointment straight into your calendar app. Nothing of ours sits in between.

Your whole agenda as a calendar you can subscribe to:

https://menubot.YOUR-NAME.workers.dev/calendar.ics?key=YOUR_CHECK_KEY
  • Google Calendar: Other calendars → + → From URL → paste → Add calendar
  • Outlook: Add calendar → Subscribe from web → paste → Import
  • Apple Calendar: File → New Calendar Subscription → paste

Both Google and Outlook refresh a subscribed calendar on their own schedule, which can take several hours — that is their choice, not a setting in the bot. The link in each notification is the one to use when you want the appointment in your calendar now. Treat the address like a password: anyone who has it can read your bookings. If you ever want to cut it off, change CHECK_KEY in your Worker's settings.

Times you took yourself. The bot only knows the bookings it made. If someone books by phone or walks in, send a message to your own bot from your own WhatsApp, pick that time the way a customer would, and it is blocked for everyone else. The code it gives you frees it again.

What the bot keeps. Everything still to come, plus the last seven days. Older bookings are cleared away by themselves, so your calendar stays the agenda and not an archive.

Changing your hours later. The quickest way is the generator: make the change, use "I already bought" with your licence key, and replace worker.js with the new download. By hand, the agenda sits in menu.json under "booking" — the days work exactly like the schedule example above, and slotMinutes, capacity, leadHours and daysAhead are what they say.

If something does not work

What you see Usual cause
Check page: token invalid or expired You used the 24-hour token from API Setup. Make the permanent one (step 5).
Check page: recipient not on the allowed list App still in development mode and your phone is not under "To" (step 3), or go live (step 9).
Check page: no messages arriving Webhook not verified, or the messages field not subscribed (step 7).
"Verify and save" fails in Meta The verify token differs from VERIFY_TOKEN, or you forgot to Deploy after adding it.
Bot answers you with "Notifications are on" You are writing from OWNER_NUMBER. Send MENU to try the menu, or test from another phone.
A customer's messages arrive as "Message for the team" A handover happened: the bot passes their messages on to you until they send MENU, a greeting or a menu choice.

Questions about a step: info@airtimemedia.eu, with a screenshot of where you are.