Write a simple facebook messenger bot with Go + ngrok
Messenger bots of facebook are quite long. There were many users for my facebook page. This article will guide you to write a bot that automatically responds to the pattern available with Go – for the server and ngrok – to publish localhost out.
This type:
Things you need to have:
- A facebook page
- Enough already
Facebook stuffs
First go to https://developers.facebook.com and select your app.
On the left tab of you Add Product . Select Webhooks , and New Subscription and select Page in dropdown. A popup like this will appear:
Here I only select subscription field as messages .
To be able to save this subscription again, you need a Callback URL and a Verify token
Callback URL is the place where the messenger will send data when receiving the message on the facebook page.
Here I will use Go as server, run on localhost. Then use ngrok to publish a https URL (because Callback URL facebook only accepts https)
Verify token, you enter the token that I want to verify again 1 (use in Go server to double check)
Ta da! Leave this popup, switch to writing server.
Go server
Create a main.go file .
Write the function main for it, which serves as the serve at port 8085 a webhook.
1 2 3 4 | func main () { http.HandleFunc ("/ webhook", webhookHandler) http.ListenAndServe (": 8085", nil) } |
Write webhookHandler function
1 2 3 4 5 6 7 8 | func webhookHandler (w http.ResponseWriter, r * http.Request) { if r.Method == "GET" { verifyTokenAction (w, r) } if r.Method == "POST" { webhookPostAction (w, r) } } |
Why are there two GET and POST functions here? GET will be called when you press the Verify and Save button on the popup above. And POST will be called when someone texts on the facebook page. With GET, I only check if I send the correct verificationToken , and log out.
1 2 3 4 5 6 7 8 9 | func verifyTokenAction (w http.ResponseWriter, r * http.Request) { if r.URL.Query (). Get ("hub.verify_token") == verifyToken { log.Print ("verify token success.") fmt.Fprintf (w, r.URL.Query (). Get ("hub.challenge")) } else { log.Print ("Error: verify token failed.") fmt.Fprintf (w, "Error, token validation wrong") } } |
It is important to handle the POST function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | func webhookPostAction (w http.ResponseWriter, r * http.Request) { var receivedMessage ReceivedMessage body, err: = ioutil.ReadAll (r.Body) if err! = nil { log.Print (err) } if err = json.Unmarshal (body, & receivedMessage); err! = nil { log.Print (err) } messagingEvents: = receivedMessage.Entry [0] .Messaging for _, event: = range messagingEvents { senderID: = event.Sender.ID if & event.Message! = nil && event.Message.Text! = "" { message: = getReplyMessage (event.Message.Text) sendTextMessage (senderID, message) } } fmt.Fprintf (w, "Success") } func getReplyMessage (receivedMessage string) string { var message string receivedMessage = strings.ToUpper (receivedMessage) log.Print ("Received message:" + receivedMessage) if strings.Contains (receivedMessage, "HELLO") { message = "Hi, my name is Annie. Nice to meet you" } return message } func sendTextMessage (senderID string, text string) { recipient: = new (Recipient) recipient.ID = senderID sendMessage: = new (SendMessage) sendMessage.Recipient = * recipient sendMessage.Message.Text = text sendMessageBody, err: = json.Marshal (sendMessage) if err! = nil { log.Print (err) } req, err: = http.NewRequest ("POST", FacebookEndPoint, bytes.NewBuffer (sendMessageBody)) if err! = nil { log.Print (err) } fmt.Println ("% T", req) fmt.Println ("% T", err) values: = url.Values {} values.Add ("access_token", accessToken) req.URL.RawQuery = values.Encode () req.Header.Add ("Content-Type", "application / json; charset = UTF-8") client: = & http.Client {Timeout: time.Duration (30 * time.Second)} res, err: = client.Do (req) if err! = nil { log.Print (err) } defer res.Body.Close () var result map [string] interface {} body, err: = ioutil.ReadAll (res.Body) if err! = nil { log.Print (err) } if err: = json.Unmarshal (body, & result); err! = nil { log.Print (err) } log.Print (result) } |
The above function has two functions:
- getReplyMessage : Here I only see if there is hello, I will return the corresponding greeting message. You can use other advanced techniques.
- sendTextMessage : This function will send a POST request to facebook endpoint, then facebook will send a message to the recipient (who has just chat on the facebook page).
Running servers go up by shaking main.go. We have a server running on port 8085
Ngrok
You download ngrok here https://ngrok.com/
Run:
1 | ngrok http 8085 |
Will be like this:
localhost: 8085 has been ngrok converted to https and published to the outside.
Config
Everything is almost done. You just paste the callback URL that has been forwarded by ngrok into the popup of the Facebook earlier, and the verification token is done.
So you can pm the facebook page chat try and wait for the response.
Conclusion
Above is a simple sample. Facebook messenger bots have a lot of potential in the area of sales or autoresponder. Those who are not playing can play against it.