Build your conversational Action

Fulfillment is code deployed as a webhook that lets your Action call your business logic. Fulfillment tells your Action what to do when user requests are made. With Interactive Canvas, your fulfillment also tells the Assistant to render the web app you created and provides updates to state, which your web app custom logic uses to make changes to your web app.

Immersive Responses

The method for communicating your web app URL and state is to send an ImmersiveResponse through your webhook. When you send an ImmersiveResponse, the following steps are executed:

  • The fulfillment of the matched intent sends an ImmersiveResponse to the device.
  • The device uses the URL in the ImmersiveResponse to load the web app.
  • The state JSON payload is passed to the web app in a callback.
  • Your conversational Action sends a new ImmersiveResponse to send updates or load new states.

An ImmersiveResponse is included in your intent-specific fulfillment and updates the state of variables within your web app's custom logic.

Sample fulfillment

ImmersiveResponse in our sample fulfillment code looks like this:

const functions = require('firebase-functions');
const {dialogflow, ImmersiveResponse} = require('actions-on-google');

const app = dialogflow({debug: true});
app.intent('welcome', (conv) => {
  conv.ask('Welcome! Do you want me to change color or pause spinning?');
  conv.ask(new ImmersiveResponse({
    url: 'https://your-web-app.com',
  }));
});

// map of human speakable colors to color values
const tints = {
  red: 0xFF0000,
  green: 0x00FF00,
  blue: 0x0000FF,
};
app.intent('color', (conv, {color}) => {
  if (color in tints) {
    conv.ask(`Ok, I changed my color to ${color}. What else?`);
    conv.ask(new ImmersiveResponse({
      state: {
        tint: tints[color],
      },
    }));
    return;
  }
  conv.ask(`Sorry, I don't know that color. What else?`);
  conv.ask(new ImmersiveResponse({
    state: {
      query: conv.query,
    },
  }));
});
app.intent('start', (conv) => {
  conv.ask(`Ok, I'm spinning. What else?`);
  conv.ask(new ImmersiveResponse({
    state: {
      spin: true,
    },
  }));
});

app.intent('pause', (conv) => {
  conv.ask(`Ok, I paused spinning. What else?`);
  conv.ask(new ImmersiveResponse({
    state: {
      spin: false,
    },
  }));
});

exports.conversation = functions.https.onRequest(app);

welcome intent

In the sample above, the fulfillment for the welcome intent sends an ImmersiveResponse with the URL for the web app. The Assistant receives this and loads the HTML and JavaScript at that address.

...
app.intent('welcome', (conv) => {
  conv.ask('Welcome! Do you want me to change color or pause spinning?');
  conv.ask(new ImmersiveResponse({
    url: 'https://your-web-app.com',
  }));
});
...

Other intents

The ImmersiveResponse in the fulfillment for all other intents pass variable values (tint or spin in the sample) to the web app. The custom logic for the web app then uses these values to update elements (animations, color, etc).

...
app.intent('start', (conv) => {
  conv.ask(`Ok, I'm spinning. What else?`);
  conv.ask(new ImmersiveResponse({
    state: {
      spin: true,
    },
  }));
});
...