Notifications push (Dialogflow)

Explorer dans Dialogflow

Cliquez sur Continue (Continuer) pour importer notre exemple de notifications dans Dialogflow. Suivez ensuite les procédez comme suit pour déployer et tester l'exemple:

  1. Saisissez un nom d'agent et créez un agent Dialogflow pour l'exemple.
  2. Une fois l'importation de l'agent terminée, cliquez sur Accéder à l'agent.
  3. Dans le menu de navigation principal, accédez à Fulfillment.
  4. Activez l'éditeur intégré, puis cliquez sur Déployer. L'éditeur contient l'exemple du code source.
  5. Dans le menu de navigation principal, accédez à Integrations (Intégrations), puis cliquez sur Google l'Assistant Google.
  6. Dans la fenêtre modale qui s'affiche, activez Auto-preview changes (Prévisualisation automatique des modifications), puis cliquez sur Test (Tester). pour ouvrir le simulateur d'actions.
  7. Dans le simulateur, saisissez Talk to my test app pour tester l'échantillon.
<ph type="x-smartling-placeholder"></ph> Continuer

Votre action peut envoyer des notifications push aux utilisateurs chaque fois que cela est pertinent, par exemple en envoyant des notifications un rappel lorsque la date d’échéance d’une tâche est proche.

Dans ce guide, nous utilisons l'exemple de conseils Actions on Google. pour vous montrer comment configurer les notifications push pour votre action. Lorsque les utilisateurs appellent cette action, il leur est demandé s'ils veulent entendre un conseil à développer leur propre action. Les utilisateurs peuvent choisir une catégorie spécifique ou sélectionnée de manière aléatoire pour le pourboire, choisissez d'écouter le conseil le plus récent.

Surfaces compatibles

Les notifications push sont disponibles sur les appareils Android et iOS (les appareils iOS doivent installer l'application Assistant pour recevoir des notifications push). Ce n'est pas le cas actuellement compatible avec les enceintes à commande vocale, les écrans connectés ou d'autres surfaces.

Prérequis

Au moins une des actions de votre projet Actions doit être configurée en tant que d'intent qui est appelé lorsque l'utilisateur appuie sur une notification reçue de l'Assistant.

Vos actions ne peuvent pas être configurées pour déclencher l'intent d'accueil par défaut à partir d'une notification push.

Configuration de la console

Pour ajouter la prise en charge des notifications push à votre action:

  1. Accédez à la console Actions et naviguez pour Créer > les actions.

  2. Cliquez sur l'action correspondant à l'intent de déclenchement supplémentaire que vous souhaitez activer les notifications push.

    Pour l'exemple de conseils Actions on Google, vous devez sélectionner "tell_latest_tip".

  3. Faites défiler la page jusqu'à la section Engagement utilisateur, puis activez Souhaitez-vous envoyer des notifications push ?

  4. Saisissez le titre du contenu.

    Pour l'exemple de conseils Actions on Google, le titre pourrait être "Nouveau conseil ajouté".

  5. Cliquez sur Enregistrer.

Importations

Pour les besoins des sections suivantes, dans votre code de fulfillment, vous allez déclarer les importations suivantes:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Dialogflow
const {
  dialogflow,
  UpdatePermission,
  Suggestions,
} = require('actions-on-google');
<ph type="x-smartling-placeholder">
</ph>
SDK Actions
const {
  actionssdk,
  UpdatePermission,
  Suggestions,
} = require('actions-on-google');

Utilisateurs ayant accepté la demande

Avant de pouvoir envoyer des notifications push aux utilisateurs, vous devez leur demander d'accepter les notifications. Pour ce faire, vous pouvez leur montrer un chip de suggestion pour demander leur autorisation. Lorsqu'ils accordent l'autorisation, vous recevez un identifiant utilisateur de mise à jour à envoyer des notifications push à cet utilisateur.

Afficher les chips de suggestion pour l'activation

Pour que les utilisateurs puissent recevoir des notifications push de votre action, vous devez leur montrer un un chip de suggestion pour les inviter à activer les notifications push.

L'extrait de code suivant envoie une alerte de nouveaux conseils à l'utilisateur. suggestion à côté d'une réponse textuelle.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Dialogflow Node.js
conv.ask('I can send you push notifications. Would you like that?');
conv.ask(new Suggestions('Send notifications'));
<ph type="x-smartling-placeholder">
</ph>
SDK Actions Node.js
conv.ask(' I can send you push notifications. Would you like that?');
conv.ask(new Suggestions('Send notifications'));
<ph type="x-smartling-placeholder">
</ph>
Dialogflow Java
responseBuilder
    .add("I can send you push notifications. Would you like that?")
    .addSuggestions(new String[] {
        "Send notifications"
    });
<ph type="x-smartling-placeholder">
</ph>
SDK Actions Java
responseBuilder
    .add("I can send you push notifications. Would you like that?")
    .addSuggestions(new String[] {
        "Send notifications"
    });
<ph type="x-smartling-placeholder">
</ph>
JSON Dialogflow

Notez que le code JSON ci-dessous décrit une réponse webhook.

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Hi! Welcome to Push Notifications!"
            }
          },
          {
            "simpleResponse": {
              "textToSpeech": "I can send you push notifications. Would you like that?"
            }
          }
        ],
        "suggestions": [
          {
            "title": "Send notifications"
          }
        ]
      }
    }
  }
}
<ph type="x-smartling-placeholder">
</ph>
JSON SDK Actions

Notez que le code JSON ci-dessous décrit une réponse webhook.

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Hi! Welcome to Push Notifications!"
              }
            },
            {
              "simpleResponse": {
                "textToSpeech": " I can send you push notifications. Would you like that?"
              }
            }
          ],
          "suggestions": [
            {
              "title": "Send notifications"
            }
          ]
        }
      }
    }
  ]
}

Après que l'utilisateur appuie sur le chip, vous devez lui demander l'autorisation UPDATE. Le code suivant vous montre comment procéder avec askForUpdatePermission. de la bibliothèque cliente Node.js.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Dialogflow Node.js
  1. Ouvrez votre agent dans la console Dialogflow et sélectionnez l'intent que vous configurez pour les mises à jour.
  2. Faites défiler l'écran vers le bas jusqu'à Réponse, puis ouvrez l'onglet Assistant Google.
  3. Cliquez sur Ajouter le contenu du message, puis sélectionnez Chips de suggestion.
  4. Définissez le texte du chip afin d'inviter l'utilisateur à accepter l'invitation. Dans Exemple de conseils Actions on Google, nous avons défini le chip sur M'avertir en cas de nouveaux conseils.
  5. Ajouter un autre intent Dialogflow, appelé par exemple setup_push, Définissez une action correspondante, par exemple setup.push. L'expression utilisateur de cet intent doit correspondre au texte du chip d'activation, dans notre exemple, Recevoir les nouveaux conseils.
L'extrait de code suivant montre comment demander l'autorisation à l'aide des actions sur la bibliothèque cliente Google pour Node.js:
app.intent('Subscribe to Notifications', (conv) => {
  conv.ask(new UpdatePermission({
    intent: 'Notification',
  }));
});
<ph type="x-smartling-placeholder">
</ph>
SDK Actions Node.js

Vous devez configurer votre solution NLU pour déclencher une fonction qui demande au autorisation si l'expression utilisateur correspond à la valeur des notifications push invite d'activation. Voici un exemple très basique basé sur la correspondance de chaînes:

conv.ask(new UpdatePermission({
  intent: 'Notification',
}));
<ph type="x-smartling-placeholder">
</ph>
Dialogflow Java
  1. Ouvrez votre agent dans la console Dialogflow et sélectionnez l'intent que vous configurez pour les mises à jour.
  2. Faites défiler l'écran vers le bas jusqu'à Réponse, puis ouvrez l'onglet Assistant Google.
  3. Cliquez sur Ajouter le contenu du message, puis sélectionnez Chips de suggestion.
  4. Définissez le texte du chip afin d'inviter l'utilisateur à accepter l'invitation. Dans Exemple de conseils Actions on Google, nous avons défini le chip sur M'avertir en cas de nouveaux conseils.
  5. Ajouter un autre intent Dialogflow, appelé par exemple setup_push, Définissez une action correspondante, par exemple setup.push. L'expression utilisateur de cet intent doit correspondre au texte du chip d'activation, dans notre exemple, Recevoir les nouveaux conseils.
L'extrait de code suivant montre comment demander l'autorisation à l'aide des actions dans la bibliothèque cliente Google Java/Kotlin:
@ForIntent("Subscribe to Notifications")
public ActionResponse subscribeToNotifications(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  responseBuilder.add(new UpdatePermission().setIntent("Notification"));
  return responseBuilder.build();
}
<ph type="x-smartling-placeholder">
</ph>
SDK Actions Java

Vous devez configurer votre solution NLU pour déclencher une fonction qui demande au autorisation si l'expression utilisateur correspond à la valeur des notifications push invite d'activation. Voici un exemple très basique basé sur la correspondance de chaînes:

ResponseBuilder responseBuilder = getResponseBuilder(request);
responseBuilder.add(new UpdatePermission().setIntent("Notification"));
return responseBuilder.build();
<ph type="x-smartling-placeholder">
</ph>
JSON Dialogflow

Notez que le code JSON ci-dessous décrit une réponse webhook à l'aide de Dialogflow.

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.PERMISSION",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
          "permissions": [
            "UPDATE"
          ],
          "updatePermissionValueSpec": {
            "intent": "tell_latest_tip"
          }
        }
      }
    }
  }
}
<ph type="x-smartling-placeholder">
</ph>
JSON SDK Actions

Notez que le fichier JSON ci-dessous décrit une réponse webhook à l'aide du SDK Actions.

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.PERMISSION",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
            "permissions": [
              "UPDATE"
            ],
            "updatePermissionValueSpec": {
              "intent": "tell_latest_tip"
            }
          }
        }
      ]
    }
  ]
}
.

Finaliser l'abonnement

Pour finaliser l'abonnement à partir de votre webhook Node.js, vous devez enregistrer le l'ID de notification de l'utilisateur et l'intent qu'il a sélectionné. Les deux sont transmis en tant que arguments si l'utilisateur accorde l'autorisation.

Si votre action est créée avec Dialogflow, vous devez:

  • Ajoutez un intent qui gère actions_intent_PERMISSION.
  • Spécifiez le nom de l'action de l'intent en indiquant un élément que votre webhook peut filtrer pour plus tard.

Le code suivant montre comment gérer un intent Dialogflow avec un intent nommé finish_push_setup avec le nom d'action finish.push.setup:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Dialogflow Node.js
app.intent('Confirm Notifications Subscription', (conv) => {
  if (conv.arguments.get('PERMISSION')) {
    const updatesUserId = conv.arguments.get('UPDATES_USER_ID');
    // Store user ID in database for later use
    conv.close(`Ok, I'll start alerting you.`);
  } else {
    conv.close(`Ok, I won't alert you.`);
  }
});
<ph type="x-smartling-placeholder">
</ph>
SDK Actions Node.js
app.intent('actions.intent.PERMISSION', (conv) => {
  if (conv.arguments.get('PERMISSION')) {
    const updatesUserId = conv.arguments.get('UPDATES_USER_ID');
    // Store user ID in database for later use
    conv.close(`Ok, I'll start alerting you.`);
  } else {
    conv.close(`Ok, I won't alert you.`);
  }
});
<ph type="x-smartling-placeholder">
</ph>
Dialogflow Java
@ForIntent("Confirm Notifications Subscription")
public ActionResponse confirmNotificationsSubscription(ActionRequest request) {
  // Verify the user has subscribed for push notifications
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (request.isPermissionGranted()) {
    Argument userId = request.getArgument(ConstantsKt.ARG_UPDATES_USER_ID);
    if (userId != null) {
      // Store the user's ID in the database
    }
    responseBuilder.add("Ok, I'll start alerting you.");
  } else {
    responseBuilder.add("Ok, I won't alert you.");
  }
  responseBuilder.endConversation();
  return responseBuilder.build();
}
<ph type="x-smartling-placeholder">
</ph>
SDK Actions Java
@ForIntent("actions.intent.PERMISSION")
public ActionResponse confirmNotificationsSubscription(ActionRequest request) {
  // Verify the user has subscribed for push notifications
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (request.isPermissionGranted()) {
    Argument userId = request.getArgument(ConstantsKt.ARG_UPDATES_USER_ID);
    if (userId != null) {
      // Store the user's ID in the database
    }
    responseBuilder.add("Ok, I'll start alerting you.");
  } else {
    responseBuilder.add("Ok, I won't alert you.");
  }
  responseBuilder.endConversation();
  return responseBuilder.build();
}
<ph type="x-smartling-placeholder">
</ph>
JSON Dialogflow

Notez que le code JSON ci-dessous décrit une requête envoyée au webhook.

{
  "responseId": "ee9e7ed5-fa1a-48c6-aac7-f9fbe94f1f58-712767ed",
  "queryResult": {
    "queryText": "actions_intent_PERMISSION",
    "action": "confirm.subscription",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            ""
          ]
        }
      }
    ],
    "outputContexts": [
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_screen_output"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_account_linking"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_media_response_audio"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_audio_output"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_capability_web_browser"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/google_assistant_input_type_keyboard"
      },
      {
        "name": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k/contexts/actions_intent_permission",
        "parameters": {
          "PERMISSION": true,
          "text": "yes",
          "UPDATES_USER_ID": "ABwppHHssyPbvEBF1mgN7Ddwb7mkhiVohW9PZ--I_svqy7zFElA4DHkf9pn04UBd5gwZo26_RfXCQ8otcztyIfe6MCQ"
        }
      }
    ],
    "intent": {
      "name": "projects/PROJECT_ID/agent/intents/c7f7b30b-5b88-4bb5-b0b8-1cd0862d1dd2",
      "displayName": "Confirm Notifications Subscription"
    },
    "intentDetectionConfidence": 1,
    "languageCode": "en"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "user": {
        "permissions": [
          "UPDATE"
        ],
        "locale": "en-US",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k",
        "type": "ACTIVE",
        "conversationToken": "[]"
      },
      "inputs": [
        {
          "intent": "actions.intent.PERMISSION",
          "rawInputs": [
            {
              "inputType": "KEYBOARD",
              "query": "yes"
            }
          ],
          "arguments": [
            {
              "name": "PERMISSION",
              "boolValue": true,
              "textValue": "true"
            },
            {
              "name": "text",
              "rawText": "yes",
              "textValue": "yes"
            },
            {
              "name": "UPDATES_USER_ID",
              "textValue": "ABwppHHssyPbvEBF1mgN7Ddwb7mkhiVohW9PZ--I_svqy7zFElA4DHkf9pn04UBd5gwZo26_RfXCQ8otcztyIfe6MCQ"
            }
          ]
        }
      ],
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.ACCOUNT_LINKING"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": "projects/PROJECT_ID/agent/sessions/ABwppHGIgmmU3zBcYMF_vWoHaM4JUo3wniYBHdbUF25l63G7EQWjRnlne8Ar7AOcRHWn1lrEKGy8qdP0UXLcWDBq93k"
}
<ph type="x-smartling-placeholder">
</ph>
JSON SDK Actions

Notez que le code JSON ci-dessous décrit une requête envoyée au webhook.

{
  "user": {
    "permissions": [
      "UPDATE"
    ],
    "locale": "en-US",
    "userVerificationStatus": "VERIFIED"
  },
  "conversation": {
    "conversationId": "ABwppHEP6OAFZHkSGEiZ5HYM9qrlk8YtIH1DQmJ52cxXELSPvM-kSc_tMJ_5O6ITbgVJlY9i2FIsKWjE_HXLke48",
    "type": "NEW"
  },
  "inputs": [
    {
      "intent": "actions.intent.PERMISSION",
      "rawInputs": [
        {
          "inputType": "KEYBOARD",
          "query": "yes"
        }
      ],
      "arguments": [
        {
          "name": "PERMISSION",
          "boolValue": true,
          "textValue": "true"
        },
        {
          "name": "text",
          "rawText": "yes",
          "textValue": "yes"
        },
        {
          "name": "UPDATES_USER_ID",
          "textValue": "ABwppHFvBKC-tMYUsUjJkm3YECgZvd6A3sOc7KuQvO4ZdQX3bGLmyoQ41dh4Zmtlzv_kaOKBt1Sf6eRpNbayynrl"
        }
      ]
    }
  ],
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      },
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.ACCOUNT_LINKING"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      }
    ]
  },
  "availableSurfaces": [
    {
      "capabilities": [
        {
          "name": "actions.capability.AUDIO_OUTPUT"
        },
        {
          "name": "actions.capability.SCREEN_OUTPUT"
        },
        {
          "name": "actions.capability.WEB_BROWSER"
        }
      ]
    }
  ]
}

Envoyer des notifications

Vous pouvez envoyer des notifications push aux utilisateurs à l'aide de l'API Actions. Pour utiliser cette API, vous devez activer l'API dans votre projet Google Cloud, et configurer et télécharger un Clé de compte de service JSON. Reportez-vous à l'étape 8 des instructions dans l'exemple de code disponible ici.

Vous pourrez ensuite utiliser la bibliothèque cliente Google OAuth2 pour échanger la clé du compte de service. un jeton d'accès et l'utiliser pour authentifier vos requêtes auprès de l'API Actions.

Obtenir une clé de compte de service

  1. Accédez à cette URL en remplaçant "exemple-projet-1" à la fin par l'ID de votre projet ; dans la console Actions: https://console.developers.google.com/apis/api/actions.googleapis.com/overview?project=example-project-1
  2. Si un bouton Activer s'affiche, cliquez dessus. Sinon, passez à l'étape 3.
  3. Accédez à cette URL en remplaçant "exemple-projet-1" à la fin par l'ID de votre projet ; dans la console Actions: https://console.developers.google.com/apis/credentials?project=example-project-1
  4. Cliquez sur Créer des identifiants > Clé de compte de service :
  5. Cochez la case Sélectionner sous Compte de service, puis cliquez sur Nouveau service. Compte.
  6. Donnez un nom au compte de service, tel que "notifications". et le rôle Propriétaire du projet :
  7. Sélectionnez le type de clé JSON, puis cliquez sur Créer. Une clé de compte de service JSON téléchargée sur votre ordinateur local.

Échanger la clé contre un jeton d'accès et envoyer une notification

Pour envoyer une notification via l'API Actions, vous devez échanger la clé du compte de service pour un jeton d'accès. Nous vous recommandons d'utiliser un client API Google pour cela. Dans la série d'extraits de code qui suit, nous utilisons le module Bibliothèque cliente des API Google pour Node.js.

  1. Installez la bibliothèque cliente des API Google et exécutez la requête suivante: npm install googleapis request --save
  2. Utilisez le code suivant pour obtenir un jeton d'accès à partir de la clé du compte de service et envoyez une notification push:
<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Dialogflow Node.js
const {google} = require('googleapis');
const request = require('request');

const jwtClient = new google.auth.JWT(
  serviceAccount.client_email, null, serviceAccount.private_key,
  ['https://www.googleapis.com/auth/actions.fulfillment.conversation'],
  null
);

jwtClient.authorize((err, tokens) => {
  if (!err) {
    request.post('https://actions.googleapis.com/v2/conversations:send', {
      auth: {
        bearer: tokens.access_token,
      },
      json: true,
      body: {
        customPushMessage: {
          userNotification: {
            title: 'Push Notification Title',
          },
          target: {
            userId: '<UPDATES_USER_ID>',
            intent: 'Notification Intent',
          },
        },
        isInSandbox: true,
      },
    }, (err, httpResponse, body) => {
      console.log(`${httpResponse.statusCode}: ${httpResponse.statusMessage}`);
    });
  }
});
<ph type="x-smartling-placeholder">
</ph>
SDK Actions Node.js
const {google} = require('googleapis');
const request = require('request');

const jwtClient = new google.auth.JWT(
  serviceAccount.client_email, null, serviceAccount.private_key,
  ['https://www.googleapis.com/auth/actions.fulfillment.conversation'],
  null
);

jwtClient.authorize((err, tokens) => {
  if (!err) {
    request.post('https://actions.googleapis.com/v2/conversations:send', {
      auth: {
        bearer: tokens.access_token,
      },
      json: true,
      body: {
        customPushMessage: {
          userNotification: {
            title: 'Push Notification Title',
          },
          target: {
            userId: '<UPDATES_ORDER_ID>',
            intent: 'Notification Intent',
          },
        },
        isInSandbox: true,
      },
    }, (err, httpResponse, body) => {
      console.log(`${httpResponse.statusCode}: ${httpResponse.statusMessage}`);
    });
  }
});
<ph type="x-smartling-placeholder">
</ph>
Dialogflow Java
final class Notification {

  private final String title;

  Notification(String title) {
    this.title = title;
  }

  String getTitle() {
    return title;
  }
}

final class Target {

  private final String userId;
  private final String intent;
  private final String locale;

  Target(String userId, String intent, String locale) {
    this.userId = userId;
    this.intent = intent;
    this.locale = locale;
  }

  String getUserId() {
    return userId;
  }

  String getIntent() {
    return intent;
  }

  String getLocale() {
    return locale;
  }
}

final class PushMessage {

  private final Notification userNotification;
  private final Target target;

  PushMessage(Notification userNotification, Target target) {
    this.userNotification = userNotification;
    this.target = target;
  }

  Notification getUserNotification() {
    return userNotification;
  }

  Target getTarget() {
    return target;
  }
}

final class PushNotification {

  private final PushMessage customPushMessage;
  private boolean isInSandbox;

  PushNotification(PushMessage customPushMessage, boolean isInSandbox) {
    this.customPushMessage = customPushMessage;
    this.isInSandbox = isInSandbox;
  }

  PushMessage getCustomPushMessage() {
    return customPushMessage;
  }

  boolean getIsInSandbox() {
    return isInSandbox;
  }
}

private PushNotification createNotification(String title, String userId, String intent, String locale) {
  Notification notification = new Notification(title);
  Target target = new Target(userId, intent, locale);
  PushMessage message = new PushMessage(notification, target);
  boolean isInSandbox = true;
  return new PushNotification(message, isInSandbox);
}

private ServiceAccountCredentials loadCredentials() throws IOException {
  String actionsApiServiceAccountFile =
      this.getClass().getClassLoader().getResource("service-account.json").getFile();
  InputStream actionsApiServiceAccount = new FileInputStream(actionsApiServiceAccountFile);
  ServiceAccountCredentials serviceAccountCredentials =
      ServiceAccountCredentials.fromStream(actionsApiServiceAccount);
  return (ServiceAccountCredentials)
      serviceAccountCredentials.createScoped(
          Collections.singleton(
              "https://www.googleapis.com/auth/actions.fulfillment.conversation"));
}

private String getAccessToken() throws IOException {
  AccessToken token = loadCredentials().refreshAccessToken();
  return token.getTokenValue();
}

public void sendNotification(String title, String userId, String intent, String locale) throws IOException {
  Preconditions.checkNotNull(title, "title cannot be null.");
  Preconditions.checkNotNull(userId, "userId cannot be null.");
  Preconditions.checkNotNull(intent, "intent cannot be null.");
  Preconditions.checkNotNull(locale, "locale cannot be null");
  PushNotification notification = createNotification(title, userId, intent, locale);

  HttpPost request = new HttpPost("https://actions.googleapis.com/v2/conversations:send");

  String token = getAccessToken();

  request.setHeader("Content-type", "application/json");
  request.setHeader("Authorization", "Bearer " + token);

  StringEntity entity = new StringEntity(new Gson().toJson(notification));
  entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
  request.setEntity(entity);
  HttpClient httpClient = HttpClientBuilder.create().build();
  httpClient.execute(request);
}
<ph type="x-smartling-placeholder">
</ph>
SDK Actions Java
final class Notification {

  private final String title;

  Notification(String title) {
    this.title = title;
  }

  String getTitle() {
    return title;
  }
}

final class Target {

  private final String userId;
  private final String intent;

  Target(String userId, String intent) {
    this.userId = userId;
    this.intent = intent;
  }

  String getUserId() {
    return userId;
  }

  String getIntent() {
    return intent;
  }
}

final class PushMessage {

  private final Notification userNotification;
  private final Target target;

  PushMessage(Notification userNotification, Target target) {
    this.userNotification = userNotification;
    this.target = target;
  }

  Notification getUserNotification() {
    return userNotification;
  }

  Target getTarget() {
    return target;
  }
}

final class PushNotification {

  private final PushMessage customPushMessage;
  private boolean isInSandbox;

  PushNotification(PushMessage customPushMessage, boolean isInSandbox) {
    this.customPushMessage = customPushMessage;
    this.isInSandbox = isInSandbox;
  }

  PushMessage getCustomPushMessage() {
    return customPushMessage;
  }

  boolean getIsInSandbox() {
    return isInSandbox;
  }
}

private PushNotification createNotification(String title, String userId, String intent) {
  Notification notification = new Notification(title);
  Target target = new Target(userId, intent);
  PushMessage message = new PushMessage(notification, target);
  boolean isInSandbox = true;
  return new PushNotification(message, isInSandbox);
}

private ServiceAccountCredentials loadCredentials() throws IOException {
  String actionsApiServiceAccountFile =
      this.getClass().getClassLoader().getResource("service-account.json").getFile();
  InputStream actionsApiServiceAccount = new FileInputStream(actionsApiServiceAccountFile);
  ServiceAccountCredentials serviceAccountCredentials =
      ServiceAccountCredentials.fromStream(actionsApiServiceAccount);
  return (ServiceAccountCredentials)
      serviceAccountCredentials.createScoped(
          Collections.singleton(
              "https://www.googleapis.com/auth/actions.fulfillment.conversation"));
}

private String getAccessToken() throws IOException {
  AccessToken token = loadCredentials().refreshAccessToken();
  return token.getTokenValue();
}

public void sendNotification(String title, String userId, String intent) throws IOException {
  Preconditions.checkNotNull(title, "title cannot be null.");
  Preconditions.checkNotNull(userId, "userId cannot be null.");
  Preconditions.checkNotNull(intent, "intent cannot be null.");
  PushNotification notification = createNotification(title, userId, intent);

  HttpPost request = new HttpPost("https://actions.googleapis.com/v2/conversations:send");

  String token = getAccessToken();

  request.setHeader("Content-type", "application/json");
  request.setHeader("Authorization", "Bearer " + token);

  StringEntity entity = new StringEntity(new Gson().toJson(notification));
  entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
  request.setEntity(entity);
  HttpClient httpClient = HttpClientBuilder.create().build();
  httpClient.execute(request);
}