Send surveys to track user satisfaction

A customized survey in a Business Messages conversation.

To make sure that users have satisfying interactions with your agent, Google sends surveys to users after they've finished conversations with your agent. If you want to collect data with different timing, such as at the end of a conversation, you can send surveys within the context of a conversation. Surveys display in the conversation and allow users to provide feedback with a variety of feedback options depending on the question.

The timing of Google-triggered surveys depends on the agent's messaging availability:

Availability Survey timing
Bot-only 30 minutes after the last message
Human-only 12 hours after the last message
Bot and human 12 hours after the last message

You can send one survey per conversation every 24 hours. If you send a survey in a conversation before Google, Google doesn't send a survey to that conversation.

The next time a user begins a conversation with your agent after completing a survey, the agent displays a welcome message. If a user doesn't respond to a survey, the survey expires after 7 days, and the user sees a welcome message in their next conversation after the survey expiration.

If a user sends a message unrelated to a survey while a survey is active in the conversation, Business Messages cancels the survey and sends the user's message to the agent's webhook.

If you don't send surveys to users, your agent still receives the results of Google's surveys at your webhook and should accept and process them accordingly.

Questions

Surveys can include up to five questions, split into three categories: required, template, and custom. A survey always includes the required question, then displays up to two template questions, and then displays up to two custom questions.

Required question

The required question is localized across all locales that Business Messages supports. Users can respond with a thumbs up or thumbs down.

The required question: "Did this messaging service address your needs with AGENT_NAME?"

Template questions

Template questions are optional, Google-defined questions that are localized across all locales that Business Messages supports. A survey can include up to two template questions. User response formats vary by question.

To see a list of all available template questions,

  1. Open the Business Communications Developer Console and sign in with your Business Messages Google account.
  2. Choose your agent.
  3. In the left navigation, click Survey.

Custom questions

A survey can include up to two custom questions. If you specify a custom question, include versions of the question for each locale that your agent supports. You must specify a version of each question for your default locale.If a user receives a survey but is in a locale that doesn't have a specified version of a custom question, the question displays as it's defined in the agent's default locale.

Responses to custom questions support separate text and postback data, similar to suggested replies.

Customize a survey

To customize the survey for an agent,

  1. Open the Business Communications Developer Console and sign in with your Business Messages Google account.
  2. Choose your agent.
  3. In the left navigation, click Survey.
  4. Add up to two available template questions to the survey.
  5. Click Create a custom question to add custom questions to your survey.

For formatting and value options, see surveyConfig.

Send a survey

To send a survey, run the following command. Replace CONVERSATION_ID with the identifier of the conversation you want to send the survey to and SURVEY_ID with a unique identifier for the survey.

cURL

curl -X POST "https://businessmessages.googleapis.com/v1/conversations/CONVERSATION_ID/surveys?surveyId=SURVEY_ID" \
-H "Content-Type: application/json" \
-H "User-Agent: curl/business-messages" \
-H "`oauth2l header --json PATH_TO_SERVICE_ACCOUNT_KEY businessmessages`"

Node.js

const businessmessages = require('businessmessages');
const uuidv4 = require('uuid/v4');
const {google} = require('googleapis');

// Initialize the Business Messages API
let bmApi = new businessmessages.businessmessages_v1.Businessmessages({});

// Set the scope that we need for the Business Messages API
const scopes = [
  'https://www.googleapis.com/auth/businessmessages',
];

// Set the private key to the service account file
const privatekey = require('PATH_TO_SERVICE_ACCOUNT_KEY');

/**
 * Initializes the Google credentials for calling the
 * Business Messages API.
 */
async function initCredentials() {
  // configure a JWT auth client
  let authClient = new google.auth.JWT(
      privatekey.client_email,
      null,
      privatekey.private_key,
      scopes,
  );

  return new Promise(function(resolve, reject) {
    // authenticate request
    authClient.authorize(function(err, tokens) {
      if (err) {
        reject(false);
      } else {
        resolve(authClient);
      }
    });
  });
}

/**
 * Creates a new survey to send to a user.
 *
 * @param {string} conversationId The unique id for this user and agent.
 */
async function sendSurvey(conversationId) {
  let authClient = await initCredentials();

  // Create the payload for creating a new survey
  let apiParams = {
    auth: authClient,
    parent: 'conversations/' + conversationId,
    surveyId: uuidv4(),
    resource: {}
  };

  // Call the message create function using the
  // Business Messages client library
  bmApi.conversations.surveys.create(apiParams,
    {auth: authClient}, (err, response) => {
    console.log(err);
    console.log(response);
  });
}

sendSurvey('CONVERSATION_ID');
This code is based on the Node.js Business Messages client library.

Java

import com.google.api.client.googleapis.services.AbstractGoogleClientRequest;
import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.businessmessages.v1.Businessmessages;
import com.google.api.services.businessmessages.v1.model.*;
import java.io.FileInputStream;
import java.util.Arrays;
import java.util.UUID;

class Main {
  /**
   * Initializes credentials used by the Business Messages API.
   */
  private static Businessmessages.Builder getBusinessMessagesBuilder() {
    Businessmessages.Builder builder = null;
    try {
      GoogleCredential credential = GoogleCredential
            .fromStream(new FileInputStream("PATH_TO_SERVICE_ACCOUNT_KEY"));

      credential = credential.createScoped(Arrays.asList(
            "https://www.googleapis.com/auth/businessmessages"));

      credential.refreshToken();

      HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
      JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();

      // Create instance of the Business Messages API
      builder = new Businessmessages
        .Builder(httpTransport, jsonFactory, null)
        .setApplicationName("Sample Application");

      // Set the API credentials and endpoint
      builder.setHttpRequestInitializer(credential);
    } catch (Exception e) {
      e.printStackTrace();
    }

    return builder;
  }

  public static void main(String args[]) {
    try {
      String conversationId = "CONVERSATION_ID";

      // Create client library reference
      Businessmessages.Builder builder = getBusinessMessagesBuilder();

      // Create a new survey to send to the user associated with the conversationId
      Businessmessages.Conversations.Surveys.Create request
          = bmBuilder.build().conversations().surveys()
          .create("conversations/" + conversationId,
              new BusinessMessagesSurvey());

      request.setSurveyId(UUID.randomUUID().toString());

      // Setup retries with exponential backoff
      HttpRequest httpRequest =
          ((AbstractGoogleClientRequest) request).buildHttpRequest();

      httpRequest.setUnsuccessfulResponseHandler(new
          HttpBackOffUnsuccessfulResponseHandler(
          new ExponentialBackOff()));

      // Execute request
      httpRequest.execute();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
This code is based on the Java Business Messages client library.

Python

import json
import uuid
from oauth2client.service_account import ServiceAccountCredentials
from businessmessages import businessmessages_v1_client as bm_client
from businessmessages.businessmessages_v1_messages import (
    BusinessmessagesConversationsSurveysCreateRequest,
    BusinessMessagesSurvey)

credentials = ServiceAccountCredentials.from_json_keyfile_name(
    'PATH_TO_SERVICE_ACCOUNT_KEY',
    scopes=['https://www.googleapis.com/auth/businessmessages'])

client = bm_client.BusinessmessagesV1(credentials=credentials)

conversation_id = 'CONVERSATION_ID'

# Create the survey request
survey_request = BusinessmessagesConversationsSurveysCreateRequest(
    surveyId=str(uuid.uuid4().int),
    parent='conversations/' + conversation_id
    businessMessagesSurvey=BusinessMessagesSurvey())

# Send the survey
bm_client.BusinessmessagesV1.ConversationsSurveysService(
    client=client).Create(request=survey_request)
This code is based on the Python Business Messages client library.

For formatting and value options, see conversations.surveys.

Receive survey responses

When a user responds to a question in a survey, your agent receives the response at its webhook. Receive and process survey responses the same way you receive messages.

All questions in a survey have the same surveyResponse.survey value. If your survey includes multiple questions, make sure your infrastructure accepts multiple responses with the same surveyResponse.survey value and identifies individual questions by the surveyResponse.surveyQuestionId field.

Text values for survey responses appear in surveyResponse.questionResponseText. For required and template questions, Business Messages returns a thumbs up response as VERY_SATISFIED and a thumbs down response as VERY_DISSATISFIED. If a custom question response includes an emoji, it's a best practice to rely on the surveyResponse.questionResponsePostbackData rather than try to parse the Unicode value.

Survey responses have the following format.

{
  "agent": "brands/BRAND_ID/agents/AGENT_ID",
  "sendTime": "SEND_TIME",
  "conversationId": "CONVERSATION_ID",
  "requestId": "REQUEST_ID",
  "surveyResponse": {
    "survey": "conversations/CONVERSATION_ID/surveys/SURVEY_ID",
    "rating": "SURVEY_RATING",
    "createTime": "CREATE_TIME",
    "surveyQuestionId": "QUESTION_ID",
    "questionResponseText": "RESPONSE_TEXT",
    "questionResponsePostbackData": "RESPONSE_POSTBACK_DATA",
    "questionType": "QUESTION_TYPE",
    "questionIndex": QUESTION_INDEX,
    "totalQuestionCount": TOTAL_QUESTION_COUNT,
    "surveyTriggerSource": "TRIGGER_SOURCE"
  }
}

For formatting and value options, see UserMessage and SurveyResponse.