How to use Actions on Google Client Library on Azure Functions Node.js

Yoichiro Tanaka
Google Developer Experts
4 min readJan 4, 2019

If you are a developer who is usually using Azure Functions Node.js, you can build your actions for Google Assistant with Azure Functions Node.js. Google has been providing Actions on Google Client Library for Node.js.

You can implement your fulfillment code with the client library on Azure Functions. But, you need to use some tricks. In this story, I intend to introduce how to use the Actions on Google Client Library on Azure Functions Node.js environment.

Architecture

I assume that you want to implement your fulfillment code on Azure Functions to handle requests from Dialogflow as like the following:

Unfortunately, Azure Functions Node.js doesn’t have a compatibility with express. It is necessary to use some bridge between express and Actions on Google Client Library. But, I can provide a good news for you. You can use an azure-function-express library to bridge them.

Prerequisite

You need to prepare the following:

  • You have already registered your account on Azure.
  • You have already installed Azure CLI and signed in to the Azure.
  • You have already installed Azure Functions Core Tools.
  • You have already understood how to build actions for Google Assistant on Google Cloud Platform or Amazon Web Services.
  • You already have your Actions on Google project and your Dialogflow agent that has already been connected to the AoG project.

If you don’t know how to build actions, you can study it with codelabs:

Create Your Function

Let’s get started to create your function on Azure. If you don’t have your resource group and your storage account, please create them using the following commands:

$ az group create --name <RESOURCE_GROUP_NAME> --location <LOCATION_NAME>
$ az storage account create --name <STORAGE_ACCOUNT_NAME> --resource-group <RESOURCE_GROUP_NAME> --location <LOCATION_NAME> --sku Standard_LRS

Next, create your function with the commands below:

$ az functionapp create --resource-group <RESOURCE_GROUP_NAME> --consumption-plan-location <LOCATION_NAME> --name <FUNCTION_NAME> --storage-account <STORAGE_ACCOUNT_NAME> --runtime node
$ func init <FUNCTIONAPP_NAME>
$ cd <FUNCTIONAPP_NAME>
$ func new --name <FUNCTION_NAME> --template "HttpTrigger"

Install Dependencies

After creating your function, execute the following command to create your package.json file:

$ cd <FUNCTION_NAME>
$ npm init

You will ask some questions from the command, but basically you can answer to press ENTER key for all questions. Then, install dependencies by the following command:

$ npm install --save actions-on-google express azure-function-express

The node_modules will be created and dependencies will be installed into the directory.

Write Fulfillment Code

By the commands above, the index.js file has already been created in the <FUNCTION_NAME> directory. Replace the content of the index.js file with the following code:

const {dialogflow} = require('actions-on-google');
const express = require('express');
const {createHandler} = require('azure-function-express');
const app = dialogflow();app.intent('Default Welcome Intent', conv => {
conv.close('Hello, Azure!');
});
// Put other intent handlers here.const expressApp = express();
expressApp.post('/api/<FUNCTION_NAME>', app);
module.exports = createHandler(expressApp);

Also, you need to change the authentication mode to anonymous for testing. Replace the authLevel value with anonymous in the function.json file.

{
...
"bindings": [
{
"authLevel": "anonymous",
...
}
]
}

Set Proxy to Avoid an Issue

Unfortunately, there is an issue on current Azure Functions about handling a charset. Therefore, the code above does not work.

As the workaround against the issue above, set a proxy to override an Accept-Charset request header forcibly. To do that, create a new proxies.json file in the <FUNCTIONAPP_NAME> directory and write the following code in the file:

{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"proxy1": {
"matchCondition": {
"methods": [
"POST"
],
"route": "/api/<FUNCTION_NAME>"
},
"backendUri": "https://localhost/api/<FUNCTION_NAME>",
"requestOverrides": {
"backend.request.headers.Accept-Charset": "utf-8"
}
}
}
}

This proxy overrides the Accept-Charset request header value to “utf-8” only. As the result, your function can return the response as UTF-8 string.

Of course, if the issue will be fixed, this proxy will be unnecessary.

Deploy and Test

Last, deploy your fulfillment to the Azure using the following command:

$ func azure functionapp publish <FUNCTIONAPP_NAME>

After deploying, the command displays the endpoint URL of your function. Register the URL as the fulfillment webhook URL on your Dialogflow agent. Then, invoke your action on the Actions simulator.

Conclusion

In this story, I introduced how to use Actions on Google Client Library on Azure Functions Node.js. Unfortunately, there is the issue, and you need to avoid the issue with the workaround (that is, using the proxy). But, you will be able to remove the proxy after fixing the issue simply.

If you are using Azure Functions, try to build your action for Google Assistant on Azure!

--

--