Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Messenger Bot With DialogFlow and Golang

DZone's Guide to

Messenger Bot With DialogFlow and Golang

Learn how to create a Messenger Bot in Golang with DialogFlow (formerly API.AI) that can show a list of movies playing today.

· AI Zone ·
Free Resource

Learn how integrating security into DevOps to deliver "DevSecOps" requires changing mindsets, processes and technology.

This post is part of series on ChatOps. In this part, I will show you how to create a Messenger Bot in Golang with DialogFlow (formerly API.AI) to show a list of movies playing today.

Note: All the code used in this demo can be found on my GitHub.

Start with an HTTP server exposing two endpoints.

package main

import (
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/webhook", VerificationEndPoint).Methods("GET")
	r.HandleFunc("/webhook", MessagesEndPoint).Methods("POST")
	log.Fatal(http.ListenAndServe(":8080", r))
}

GET /webhook: Handles Facebook challenge verification. It simply looks for the Verify Token and responds with the challenge sent in the verification request.

func VerificationEndPoint(w http.ResponseWriter, r *http.Request) {
	challenge := r.URL.Query().Get("hub.challenge")
	mode := r.URL.Query().Get("hub.mode")
	token := r.URL.Query().Get("hub.verify_token")
	if mode != "" && token == os.Getenv("VERIFY_TOKEN") {
		w.WriteHeader(200)
		w.Write([]byte(challenge))
	} else {
		w.WriteHeader(404)
		w.Write([]byte("Error, wrong validation token"))
	}
}

POST /webhookHandles messages coming from Messenger:

func MessagesEndPoint(w http.ResponseWriter, r *http.Request) {
	var callback Callback
	json.NewDecoder(r.Body).Decode(&callback)
	if callback.Object == "page" {
		for _, entry := range callback.Entry {
			for _, event := range entry.Messaging {
				if !reflect.DeepEqual(event.Message, Message{}) && event.Message.Text != "" {
					ProcessMessage(event)
				}
			}
		}
		w.WriteHeader(200)
		w.Write([]byte("Got your message"))
	} else {
		w.WriteHeader(404)
		w.Write([]byte("Message not supported"))
	}
}

It calls the ProcessMessage method, which uses Facebook Graph API to send a GIF image to the user:

func ProcessMessage(event Messaging) {
	client := &http.Client{}
  response = Response{
    Recipient: User{
      ID: event.Sender.ID,
    },
    Message: Message{
      Attachment: &Attachment{
        Type: "image",
        Payload: Payload{
          URL: IMAGE,
        },
      }
    },
  }
 
	body := new(bytes.Buffer)
	json.NewEncoder(body).Encode(&response)
 
	url := fmt.Sprintf(FACEBOOK_API, os.Getenv("PAGE_ACCESS_TOKEN"))
	req, err := http.NewRequest("POST", url, body)
	req.Header.Add("Content-Type", "application/json")
	if err != nil {
		log.Fatal(err)
	}
 
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
}

Note: For more in-depth details, check my tutorial Build a Facebook Messenger Bot With Go and Messenger API.

Create a Facebook page. It will be the identity of your bot:

Then, create a Facebook application. It will be the middleware that connects the server and your public page.

Click Add Product from the left menu, then choose Messenger:

At Token Generation, choose the page you just created from the drop-down menu, and it will generate a token:

Once you've gotten your PAGE_ACCESS_TOKEN and VERIFY_TOKEN, make sure you add those two as environment variables for the server:

export PAGE_ACCESS_TOKEN="YOUR PAGE ACCESS TOKEN"
export VERIFY_TOKEN="YOUR SECRET"

In a new terminal session, issue the following command to start the HTTP server:

go run *.go

In order to make our server publically accessible, I will use a tool called ngrok. It basically creates a secure tunnel on your local machine along with a public URL you can use for browsing your local server.

Note: Keep in mind, to use your bot in production, you need to use a:

  • IaaS like AWS, GCP, Azure...

  • PaaS like Heroku, Clever Cloud...

Then, at the Webhooks section, click the Setup Webhooks button:

After you've configured your webhook, you will need to subscribe to the page you created earlier:

Go to the Facebook page you created and click Message next to the Like button near the top of the page. Start sending your Page messages and the bot should reply with a GIF!

By default, the bot should respond to everything with a GIF image.

Now, let's make it smarter. We will use an NLP (natural language processing) backend like DialogFlow (formerly API.AI):

So after signing up to DialogFow, create a new Agent:

Give it a name and fill out the required fields:

Once created, let's use the Small Talk feature of DialogFlow to give our bot the ability to have simple conversations:

Enable the Small Talk checkbox. With this feature enabled, we imported a lot of predefined answers for simple questions and phrases. You can easily change the responses to the questions if you don't like them:

To test it out, you can use the Console on the right-hand side:

Now, let's use this feature in out bot. DialogFlow offers many SDKs in different programming languages:

But unfortunately, there's no SDK for Golang:

But don't be sad, I made an SDK to integrate DialogFlow with Golang:

So, install DialogFlow Golang library:

go get github.com/mlabouardy/dialogflow-go-client

Go back to DialogFlow dashboard and copy the Client Access Token:

Set it as an environment variable:

export DIALOG_FLOW_TOKEN="YOUR TOKEN"

Create a new function that takes the message sent from a user via Messenger as an argument, and pass it to DialogFlow Client to get the appropriate response:

func GetResponse(input string) apiai.Result {
	err, client := NewDialogFlowClient(apiai.Options{
		AccessToken: os.Getenv("DIALOG_FLOW_TOKEN"),
	})
	if err != nil {
		log.Fatal(err)
	}
 
	query := apiai.Query{
		Query: input,
	}
	resp, err := client.QueryFindRequest(query)
	if err != nil {
		log.Fatal(err)
	}
	return resp.Result
}

Go to the Facebook page and click on Message to start chatting:

But that's not enough. Let's take this further and make our bot tell us about the movies playing today in cinema and series airing today on TV.

Create an entity to store the type of the show (movie or series) the user is asking about:

Then, create a new intent that represents a mapping between what a user says and what action should be taken:

Create some more questions:

Finally, update the ProcessMessage method to respond with a list of shows if the intent name is shows. The method is using the moviedb library to get the list of shows.

Let's test the bot from Messenger:

Wow! You have created your first chatbot in Golang with DialogFlow! It was easy, wasn't it?

In the upcoming tutorial, I will show you how to create a ServerlessMessengerBot with Lambda and API Gateway.

Learn how enterprises are using tools to automate security in their DevOps toolchain with these DevSecOps Reference Architectures.

Topics:
ai ,dialogflow ,golang ,bot development ,chatbot ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}