https://developers.facebook.com/docs/messenger-platform/getting-started/app-setup
You'll need the first three things, which will be self-explanatory.
- Facebook Page: A Facebook Page will be used as the identity of your Messenger experience. When people chat with your app, they will see the Page name and the Page profile picture. To create a new Page, visit https://www.facebook.com/pages/create
- Facebook Developer Account: Your developer account is required to create new apps, which are the core of any Facebook integration. You can create a new developer account by going to the Facebook Developers website and clicking the 'Get Started' button.
- Facebook App: The Facebook app contains the settings for your Messenger experience, including access tokens. To create a new app, visit your app dashboard
The fourth, we'll set up here.
The first step is to just simply create and deploy something to the internet, that returns "Hello World". In the next step, we will make it respond correctly to Facebook's webhooks.
We'll use two services here, ngrok and Vercel to aid us in our mission. We'll start by installing Vercel - detailed instructions here.
npm i -g vercel
api
and a file called hello.js
.npm init -y
mkdir api
touch api/hello.js
As mentioned above, we'll simply return "Hello World".
This is using Vercel's serverless Node runtime, which is based off of Express / NodeJS. You can find documentation here. If you aren't familiar with Express, don't worry, we won't use any advanced features of the framework here. But if you're curious you can explore express documentation here.
Make sure you're in the root directory (not in /api
):
The basic settings should be fine:
You can now go to the URL, in my case:
https://msngr-hl-wrld.vercel.app/api/hello
This is important to get a real address on the internet, because Facebook needs to be able to call our bot, so "localhost" won't be sufficient. We could stop here and keep uploading each time (npx vercel
will deploy a new version) but this is pretty inconvenient, because it's quite slow to deploy each time.
This may not seem like a big deal but over time this will be super frustrating and slow us down too much.
Instead, let's develop on localhost. First step is to run vercel in development mode, by typing:
This starts at a local port, 3000. But now we need a way for Facebook to reach our local port, 3000.
There are many options here, but let's start with a service called https://ngrok.com/. You'll want to sign up (don't worry, we'll stay on free tier) and https://dashboard.ngrok.com/get-started/setup.
You'll download this, and then you'll unzip it - it's just an executable. After you download it, you just need to run:
This will give you an externally available address that forwards to your local computer:
Verify that going to your ngrok URL successfully returns "Hello World".
Now we can go to the next steps in the Facebook setup: https://developers.facebook.com/docs/messenger-platform/getting-started/app-setup.
Add Webhooks and Messenger to your Facebook App, and you'll be prompted for a callback URL. Use your ngrok from the previous step. NOTE: every time you restart ngrok, you'll need to update this URL because your ngrok url will change. (In production, you can point it at your Vercel production instance.)
You can set the Verify Token to whatever you like. It is your personal password, and just remember it.
Your callback url needs to come back with the right parameters - if you haven't coded your server correctly (which we haven't), when you try to put "Verify and Save", you'll get an error like this:
or possibly like this:
We actually need to fix two things - our path, and our code.
webhook.js
.That file looks like this:
Note that I wrote ToiYeuDevC
; that can be anything (but just make it the same as what you put in the Facebook dialog).
Now change your url to xxx.ngrok.io/api/webhook
, and then clicking "Verify and Save" will succeed and you've made it to the next step!
Now click on the Messenger Tab and make sure to subscribe to messages
and messaging_postbacks
.
The verifyWebhook
code is just to let Facebook know that our server is indeed, the right one (so nobody else can take over our chatbot). The real magic happens in handlePost
; that's where our subscriptions will trigger.
Here, we'll share code that's a highly simplified version of the official facebook samples at https://github.com/fbsamples/messenger-platform-samples/tree/master/quick-start and https://github.com/fbsamples/original-coast-clothing. Please read those! But I think you'll find that CoderSchool's version is simpler ;).
For handlePost
:
Now send your bot a message. You won't see a response, but you will see something pop up in your local terminal (where you ran vercel dev
).
Hooray, messages are getting through to your program.
Now it's time to make your robot come to life. We'll need to reply to the post
requests. To make things easier, let's install the popular axios
library that makes HTTP requests easier:
Now we'll need At the top of webhook.js
Now, in the handlePost, after the console.log
s of the previous step:
You'll see we need a token. Where did this come from? Well, it comes from your "Page access tokens" on Facebook settings.
Click the generate token, and you'll get a token. Replace <YOUR TOKEN HERE>
with your token. Make sure you keep this token secret (don't upload it into git). For full credit, you should set this as an environment variable - you can consult vercel documentation here but we won't cover that here.
Now we've set up our "parrot" bot, which will repeat what you say.
Plain text responses already open up a lot of possibilities, but here's one more: using what's called a "message template". Instead of simply replying with {text: blahblah}
we can respond with a "structured" message, with buttons.
Create a message:
Now, from the previous step, replace sending
with:
and you should get something like this:
Note that responding to the message doesn't do anything. Buttons come in the form of messaging_postbacks
, which we subscribed to earlier. To handle this, let's refactor our code to read the postback
field, and separate our handling.
Copy the previous code into handleMessage. Let's now implement handlePostback
. We will read the payload
we specified above:
NOTE: It looks like the user is just typing "Yes!" but it's from clicking on the button.
Let's do a little refactoring on the axios.post
and everything, so here's the cleaner final code: