Skip to content

Commit

Permalink
Update to use Cloud Functions for Firebase
Browse files Browse the repository at this point in the history
Change-Id: I5734a8bd83f5e7194d68d5f3ab43f025b503237a
  • Loading branch information
Matt Carroll committed Sep 7, 2017
1 parent 7ede7d2 commit 45bffa4
Show file tree
Hide file tree
Showing 9 changed files with 421 additions and 320 deletions.
32 changes: 2 additions & 30 deletions .gitignore
@@ -1,31 +1,3 @@
### Node template
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
.firebaserc
node_modules

# Created by .ignore support plugin (hsz.mobi)
firebase-debug.log
373 changes: 192 additions & 181 deletions LICENSE

Large diffs are not rendered by default.

50 changes: 35 additions & 15 deletions README.md
@@ -1,23 +1,43 @@
# Api.ai - sample webhook implementation.

This is a really simple webhook implementation that gets Api.ai classification JSON (i.e. a JSON output of Api.ai /query endpoint) and returns a fulfillment response.

More info about Api.ai webhooks could be found here:
[Api.ai Webhook](https://docs.api.ai/docs/webhook)

# Deploy to:
[![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)

# What does the service do?
It's a simple echo service that takes `resolvedQuery` and `action` fields from the Api.ai JSON reponse and echoes them back in into `speech` and `displayTest` fields in the fulfillment JSON.
# Actions on Google: Webhook Template using Node.js and Cloud Functions for Firebase

This webhook template sets up everything you need to build your fulfillment
business logic for your Assistant app built on API.AI.

## Setup Instructions

### Steps
1. Use the [Actions on Google Console](https://console.actions.google.com) to add a new project with a name of your choosing.
1. Click *Use API.AI* and then *Create Actions on API.AI*.
1. Click *Save* to save the project.
1. Deploy the fulfillment webhook provided in the functions folder using [Google Cloud Functions for Firebase](https://firebase.google.com/docs/functions/):
1. Follow the instructions to [set up and initialize Firebase SDK for Cloud Functions](https://firebase.google.com/docs/functions/get-started#set_up_and_initialize_functions_sdk). Make sure to select the project that you have previously generated in the Actions on Google Console and to reply `N` when asked to overwrite existing files by the Firebase CLI.
1. Run `firebase deploy --only functions` and take note of the endpoint where the fulfillment webhook has been published. It should look like `Function URL (yourAction): https://${REGION}-${PROJECT}.cloudfunctions.net/yourAction`
1. Go back to the API.AI console and select *Fulfillment* from the left navigation menu.
1. Enable *Webhook*, set the value of *URL* to the `Function URL` from the previous step, then click *Save*.
1. Select *Intents* from the left navigation menu. Select the `Default Welcome Intent` intent, scroll down to the end of the page and click *Fulfillment*, check *Use webhook* and then click *Save*. This will allow you to have the welcome intent be a basic webhook intent to test.
1. Build out your agent and business logic by adding function handlers for API.AI actions.
1. For each API.AI action, set a new key/value pair on the actionMap, reflecting
the action name and corresponding function handler on the actionMap in **index.js**.
1. Open API.AI's *Integrations* page, open the *Settings* menu for *Actions on Google*, click *Authorize* if needed, then click *Test*.
1. Click *View* to open the Actions on Google simulator.
1. Type `Talk to my test app` in the simulator, or say `OK Google, talk to my test app` to any Actions on Google enabled device signed into your developer account.

For more detailed information on deployment, see the [documentation](https://developers.google.com/actions/samples/).

## References and How to report bugs
* Actions on Google documentation: [https://developers.google.com/actions/](https://developers.google.com/actions/).
* If you find any issues, please open a bug here on GitHub.
* Questions are answered on [StackOverflow](https://stackoverflow.com/questions/tagged/actions-on-google).

## How to make contributions?
Please read and follow the steps in the [CONTRIBUTING.md](CONTRIBUTING.md).
Please read and follow the steps in the CONTRIBUTING.md.

## License
See [LICENSE](LICENSE).
See LICENSE.md.

## Terms
Your use of this sample is subject to, and by using or downloading the sample files you agree to comply with, the [Google APIs Terms of Service](https://developers.google.com/terms/).

This is not an official Google product.
## Google+
Actions on Google Developers Community on Google+ [https://g.co/actionsdev](https://g.co/actionsdev).

7 changes: 0 additions & 7 deletions app.json

This file was deleted.

1 change: 1 addition & 0 deletions firebase.json
@@ -0,0 +1 @@
{}
170 changes: 170 additions & 0 deletions functions/index.js
@@ -0,0 +1,170 @@
// Copyright 2017, Google, Inc.
// Licensed under the Apache License, Version 2.0 (the 'License');
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const functions = require('firebase-functions');

// Default Action names for API.AI's welcome and fallback intents.
const WELCOME_ACTION = 'input.welcome';
const FALLBACK_ACTION = 'input.unknown';
const DEFAULT_ACTION = 'default';

exports.apiaiFirebaseFulfillment = functions.https.onRequest((request, response) => {
// Log the request header and body coming from API.AI to help debug issues.
// See https://api.ai/docs/fulfillment#request for more.
console.log('Request headers: ' + JSON.stringify(request.headers));
console.log('Request body: ' + JSON.stringify(request.body));

// An action is a string used to identify what tasks needs to be done
// in fulfillment usally based on the corresponding intent.
// See https://api.ai/docs/actions-and-parameters for more.
let action = request.body.result.action;

// Parameters are any entites that API.AI has extracted from the request.
// See https://api.ai/docs/actions-and-parameters for more.
const parameters = request.body.result.parameters;

// Contexts are objects used to track and store conversation state and are identified by strings.
// See https://api.ai/docs/contexts for more.
const contexts = request.body.result.contexts;

// Initialize JSON we will use to respond to API.AI.
let responseJson = {};

// Create a handler for each action defined in API.AI
// and a default action handler for unknown actions
const actionHandlers = {
WELCOME_ACTION: () => {
// The default welcome intent has been matched, Welcome the user.
// Define the response users will hear
responseJson.speech = 'Hello, welcome to my API.AI agent';
// Define the response users will see
responseJson.displayText = 'Hello! Welcome to my API.AI agent :-)';
// Send the response to API.AI
response.json(responseJson);
},
FALLBACK_ACTION: () => {
// The default fallback intent has been matched, try to recover.
// Define the response users will hear
responseJson.speech = 'I\'m having trouble, can you try that again?';
// Define the response users will see
responseJson.displayText = 'I\'m having trouble :-/ can you try that again?';
// Send the response to API.AI
response.json(responseJson);
},
DEFAULT_ACTION: () => {
// This is executed if the action hasn't been defined.
// Add a new case with your action to respond to your users' intent!
responseJson.speech = 'This message is from API.AI\'s Cloud Functions for Firebase editor!';
responseJson.displayText = 'This is from API.AI\'s Cloud Functions for Firebase editor!';

// Optional: add rich messages for Google Assistant, Facebook and Slack defined below.
// Uncomment next line to enable. See https://api.ai/docs/rich-messages for more.
//responseJson.data = richResponses;

// Optional: add outgoing context(s) for conversation branching and flow control.
// Uncomment next 2 lines to enable. See https://api.ai/docs/contexts for more.
//let outgoingContexts = [{"name":"weather", "lifespan":2, "parameters":{"city":"Rome"}}];
//responseJson.contextOut = outgoingContexts;

// Send the response to API.AI
response.json(responseJson);
}
};

// If the action is not handled by one of our defined action handlers
// use the default action handler
if (!actionHandlers[action]) {
action = DEFAULT_ACTION;
}

// Map the action name to the correct action handler function and run the function
actionHandlers[action]();
});

// JSON for Rich responses for Google Assistant, Facebook and Slack
const richResponses = {
'google': {
'expectUserResponse': true,
'isSsml': false,
'noInputPrompts': [],
'richResponse': {
'items': [
{
'simpleResponse': {
'textToSpeech': 'This is a simple speech response for Actions on Google.',
'displayText': 'This is a simple display text response for Action on Google.'
}
},
{
'basicCard': {
'title': 'Title: this is a title',
'subtitle': 'This is a subtitle',
'formattedText': 'This is a basic card. Text in a basic card can include \'quotes\' and most other unicode characters including emoji 📱. Basi cards also support some markdown formatting like *emphasis* or _italics_, **strong** or __bold__, and ***bold itallic*** or ___strong emphasis___ as well as other things like line \nbreaks',
'image': {
'url': 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
'accessibilityText': 'Image alternate text'
},
'buttons': [
{
'title': 'This is a button',
'openUrlAction': {
'url': 'https://assistant.google.com/'
}
}
]
}
}
]
}
},
'slack': {
'text': 'This is a text response for Slack.',
'attachments': [
{
'title': 'Title: this is a title',
'title_link': 'https://assistant.google.com/',
'text': 'This is an attachment. Text in attachments can include \'quotes\' and most other unicode characters including emoji 📱. Attachments also upport line\nbreaks.',
'image_url': 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
'fallback': 'This is a fallback.'
}
]
},
'facebook': {
'attachment': {
'type': 'template',
'payload': {
'template_type': 'generic',
'elements': [
{
'title': 'Title: this is a title',
'image_url': 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
'subtitle': 'This is a subtitle',
'default_action': {
'type': 'web_url',
'url': 'https://assistant.google.com/'
},
'buttons': [
{
'type': 'web_url',
'url': 'https://assistant.google.com/',
'title': 'This is a button'
}
]
}
]
}
}
}
};
21 changes: 21 additions & 0 deletions functions/package.json
@@ -0,0 +1,21 @@
{
"name": "apiaiFirebaseFulfillment",
"description": "This is the default fulfillment for a API.AI agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "~6.0"
},
"scripts": {
"start": "firebase serve --only functions:apiaiFirebaseFulfillment",
"deploy": "firebase deploy --only functions:apiaiFirebaseFulfillment"
},
"dependencies": {
"actions-on-google": "^1.0.0",
"firebase-admin": "^4.2.1",
"firebase-functions": "^0.5.7",
"apiai": "^4.0.3"
}
}
71 changes: 0 additions & 71 deletions index.js

This file was deleted.

16 changes: 0 additions & 16 deletions package.json

This file was deleted.

0 comments on commit 45bffa4

Please sign in to comment.