Getting Started for Google Home Actions

Botmetrics: Analytics for Google Home Actions

Botmetrics: Analytics for Google Home Actions

botmetrics makes it simple to get instant analytics and gives you levers to increase engagement with your Google Home Actions without additional engineering work.

We’ll show you how to get started collecting metrics in 3 easy steps:

Set Up A Google Home Bot on Botmetrics

Set up a Google Home Action on Botmetrics

Install the Botmetrics SDK in your project

Install the Botmetrics SDK and import it via var Botmetrics = require('botmetrics');

Update your Action's Webhook Handler

Add a Botmetrics.track() API to your action's webhook handler.

Actions SDK Sample Code

const ActionsSdkAssistant = require('actions-on-google').ActionsSdkAssistant;
const Eliza = require('elizabot');
const express = require('express');
const bodyParser = require('body-parser');

// Make sure you set BOTMETRICS_API_KEY and BOTMETRICS_BOT_ID in your environment
const Botmetrics = require('botmetrics');
let _request = {};

const app = express();
app.set('port', (process.env.PORT || 8080));
app.use(bodyParser.json({type: 'application/json'}));

/**
 * Handles the main intent coming from Assistant, when the user first engages with the action,
 * asking for an initial prompt from Eliza.
 */
const mainIntentHandler = (assistant) => {
  console.log('Main intent triggered.');
  const eliza = new Eliza();

  _request.bot_response = eliza.getInitial();
  Botmetrics.track(_request);
  assistant.ask(eliza.getInitial(), {elizaInstance: eliza});
};

/**
 * Handles the intent where the user sends a query to be handled by Eliza.
 *
 * This intent is triggered inside the dialogs when the user already has a conversation going on
 * with Eliza, or when the user 'deep links' into the action by calling Eliza and already sending an
 * initial prompt.
 */
const rawIntentHandler = (assistant) => {
  console.log('Raw input intent triggered.');
  const eliza = new Eliza();

  // Reloads the previous instance of Eliza in case this is an ongoing conversation
  const previousEliza = assistant.getDialogState().elizaInstance;
  if (previousEliza) {
    eliza.quit = previousEliza.quit;
    eliza.mem = previousEliza.mem;
    eliza.lastChoice = previousEliza.lastChoice;
  }

  const elizaReply = eliza.transform(assistant.getRawInput());
  if (eliza.quit) {
    _request.bot_response = eliza.getFinal();
    Botmetrics.track(_request);
    assistant.tell(eliza.getFinal());
  } else {
    _request.bot_response = elizaReply;
    Botmetrics.track(_request);
    assistant.ask(elizaReply, {elizaInstance: eliza});
  }
};

// Map that contains the intents and respective handlers to be used by the actions client library
const actionMap = new Map();

// Intent constants
const RAW_INTENT = 'raw.input';

/**
 * Configures the post request handler by setting the intent map to the right functions.
 */
actionMap.set(new ActionsSdkAssistant().StandardIntents.MAIN, mainIntentHandler);
actionMap.set(RAW_INTENT, rawIntentHandler);
actionMap.set(new ActionsSdkAssistant().StandardIntents.TEXT, rawIntentHandler);

/**
 * Handles the post request incoming from Assistant.
 */
app.post('/', (request, response) => {
  console.log('Incoming post request...');
  const assistant = new ActionsSdkAssistant({request: request, response: response});
  _request = request.body;
  assistant.handleRequest(actionMap);
});

// Start the server
const server = app.listen(app.get('port'), () => {
  console.log('Eliza endpoint listening on port %s', server.address().port);
  console.log('Press Ctrl+C to quit.');
});

API.AI Sample Code

// Copyright 2016, 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';

process.env.DEBUG = 'actions-on-google:*';
let Assistant = require('actions-on-google').ApiAiAssistant;
let Botmetrics = require('botmetrics');
let express = require('express');
let bodyParser = require('body-parser');

let app = express();
app.use(bodyParser.json({type: 'application/json'}));

const NAME_ACTION = 'make_name';
const WELCOME_ACTION = 'input.welcome';
const COLOR_ARGUMENT = 'color';
const NUMBER_ARGUMENT = 'number';

// [START SillyNameMaker]
app.post('/', function (req, res) {
  const assistant = new Assistant({request: req, response: res});
  console.log('Request body: ' + JSON.stringify(req.body));

  // Make a silly name
  function makeName (assistant) {
    let number = assistant.getArgument(NUMBER_ARGUMENT);
    let color = assistant.getArgument(COLOR_ARGUMENT);
    // If we set up webhooks for slot filling
    // we need to make sure that we respond only
    // with the results if both slots are filled
    if(number && color) {
      let response = 'Alright, your silly name is ' +
        color + ' ' + number +
        '! I hope you like it. See you next time.';

      // Set Bot answer to request body
      req.body.result.fulfillment.speech = response
      assistant.tell(response);
    }

    Botmetrics.track(req.body, function(err, response) {
      console.log("botmetrics error", err);
    });
  }

  //You should make handlers for all intents even if some of them are handling by api.ai
  //This needed for tracking
  function welcome (assistant) {
    Botmetrics.track(req.body, function(err, response) {
      console.log("botmetrics error", err);
    });
  }

  let actionMap = new Map();
  actionMap.set(NAME_ACTION, makeName);
  actionMap.set(WELCOME_ACTION, welcome);

  assistant.handleRequest(actionMap);
});
// [END SillyNameMaker]

if (module === require.main) {
  // [START server]
  // Start the server
  let server = app.listen(process.env.PORT || 8080, function () {
    let port = server.address().port;
    console.log('App listening on port %s', port);
  });
  // [END server]
}

module.exports = app;