Push-Benachrichtigungen (Dialogflow)

In Dialogflow ansehen

Klicken Sie auf Continue (Weiter), um unser Notifications-Beispiel in Dialogflow zu importieren. Führen Sie dann die folgenden Schritte aus, um das Beispiel bereitzustellen und zu testen:

  1. Geben Sie einen Agent-Namen ein und erstellen Sie einen neuen Dialogflow-Agent für das Beispiel.
  2. Nachdem der Agent importiert wurde, klicken Sie auf Zum Agent.
  3. Klicken Sie im Hauptnavigationsmenü auf Fulfillment (Auftragsausführung).
  4. Aktivieren Sie den Inline-Editor und klicken Sie dann auf Bereitstellen. Der Editor enthält den Beispielcode.
  5. Klicken Sie im Hauptnavigationsmenü auf Integrations (Integrationen) und dann auf Google Assistant.
  6. Aktivieren Sie im angezeigten modalen Fenster die Option Änderungen automatisch in der Vorschau anzeigen und klicken Sie auf Testen, um den Actions-Simulator zu öffnen.
  7. Geben Sie im Simulator Talk to my test app ein, um das Beispiel zu testen.
Weiter

Deine Aktion kann Nutzern bei Bedarf Benachrichtigungen senden, z. B. eine Erinnerung senden, wenn das Fälligkeitsdatum einer Aufgabe näher rückt.

In diesem Leitfaden zeigen wir dir anhand des Beispiels für Actions on Google-Tipps, wie du Push-Benachrichtigungen für deine Aktion einrichtest. Wenn Nutzer diese Aktion aufrufen, werden sie gefragt, ob sie einen Tipp zur Entwicklung ihrer eigenen Aktion hören möchten. Nutzer können entweder eine bestimmte oder zufällig ausgewählte Kategorie für den Tipp auswählen oder sich den neuesten Tipp anhören.

Unterstützte Oberflächen

Push-Benachrichtigungen sind auf Android- und iOS-Geräten verfügbar. Auf iOS-Geräten muss die Assistant App installiert sein, um Push-Benachrichtigungen zu erhalten. Auf Lautsprechern mit Sprachsteuerung, Smart Displays und anderen Oberflächen werden sie derzeit nicht unterstützt.

Voraussetzungen

Mindestens eine der Aktionen in Ihrem Actions-Projekt muss als auslösender Intent konfiguriert sein, der aufgerufen wird, wenn der Nutzer auf eine Benachrichtigung von Assistant tippt.

Ihre Aktionen können nicht so konfiguriert werden, dass der Standard-Begrüßungs-Intent über eine Push-Benachrichtigung ausgelöst wird.

Konsole einrichten

So fügst du deiner Aktion Unterstützung für Push-Benachrichtigungen hinzu:

  1. Rufen Sie die Actions Console auf und rufen Sie Build > Actions (Build > Aktionen) auf.

  2. Klicken Sie auf die Aktion, die dem zusätzlichen Trigger-Intent entspricht, für den Sie Push-Benachrichtigungen aktivieren möchten.

    Für das Beispiel „Actions on Google“-Tipps würden Sie „tell_latest_tip“ auswählen.

  3. Scrollen Sie nach unten zum Abschnitt Nutzerinteraktion und aktivieren Sie Möchten Sie Push-Benachrichtigungen senden.

  4. Geben Sie einen Inhaltstitel ein.

    Im Beispiel für Actions on Google-Tipps könnte der Titel „Neuer Tipp hinzugefügt“ lauten.

  5. Klicken Sie auf Speichern.

Importe

Für die nächsten Abschnitte müssen Sie in Ihrem Auftragsausführungscode die folgenden Importe deklarieren:

Dialogflow
const {
  dialogflow,
  UpdatePermission,
  Suggestions,
} = require('actions-on-google');
Actions SDK
const {
  actionssdk,
  UpdatePermission,
  Suggestions,
} = require('actions-on-google');

Nutzer aktivieren

Bevor Sie Push-Benachrichtigungen an Nutzer senden können, müssen Sie sie um Zustimmung bitten. Dazu können Sie ihnen einen Vorschlags-Chip anzeigen, in dem sie um ihre Zustimmung gebeten werden. Wenn er die Berechtigung erteilt, erhalten Sie eine aktualisierte Nutzer-ID, damit Sie Push-Benachrichtigungen an diesen Nutzer senden können.

Vorschlags-Chips für Aktivierung anzeigen

Bevor Nutzer Push-Benachrichtigungen von deiner Aktion erhalten können, musst du ihnen einen Vorschlags-Chip anzeigen, über den sie sich für Push-Benachrichtigungen anmelden können.

Mit dem folgenden Code-Snippet wird dem Nutzer ein Vorschlags-Chip „Benachrichtigung über neue Tipps“ zusammen mit einer Textantwort gesendet.

Dialogflow Node.js
conv.ask('I can send you push notifications. Would you like that?');
conv.ask(new Suggestions('Send notifications'));
Actions SDK – Node.js
conv.ask(' I can send you push notifications. Would you like that?');
conv.ask(new Suggestions('Send notifications'));
Dialogflow Java
responseBuilder
    .add("I can send you push notifications. Would you like that?")
    .addSuggestions(new String[] {
        "Send notifications"
    });
Actions SDK Java
responseBuilder
    .add("I can send you push notifications. Would you like that?")
    .addSuggestions(new String[] {
        "Send notifications"
    });
Dialogflow JSON

Beachten Sie, dass der folgende JSON-Code eine Webhook-Antwort beschreibt.

{
  "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"
          }
        ]
      }
    }
  }
}
Actions SDK-JSON

Beachten Sie, dass der folgende JSON-Code eine Webhook-Antwort beschreibt.

{
  "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"
            }
          ]
        }
      }
    }
  ]
}

Nachdem Ihr Kind auf den Chip getippt hat, müssen Sie die Berechtigung „UPDATE“ anfordern. Im folgenden Codebeispiel wird gezeigt, wie Sie dies mit der Funktion askForUpdatePermission der Node.js-Clientbibliothek tun.

Dialogflow Node.js
  1. Öffnen Sie den Agent in der Dialogflow-Konsole und wählen Sie den Intent aus, den Sie für Updates konfigurieren möchten.
  2. Scrollen Sie nach unten zu Antwort und öffnen Sie den Tab Google Assistant.
  3. Klicken Sie auf Inhalt der Nachricht hinzufügen und wählen Sie Vorschlag-Chips aus.
  4. Geben Sie als Text für den Chip einen Text ein, der den Nutzer zur Aktivierung einlädt. Im Actions on Google-Beispiel haben wir den Chip auf Benachrichtigung über neue Tipps gesetzt.
  5. Fügen Sie einen weiteren Dialogflow-Intent hinzu, z. B. setup_push, und legen Sie eine entsprechende Aktion fest, z. B. setup.push. Der Nutzerausdruck dieses Intents muss mit dem Text des Opt-in-Chips übereinstimmen, in unserem Beispiel Benachrichtigung über neue Tipps.
Das folgende Snippet zeigt, wie die Berechtigung mithilfe der Actions on Google-Clientbibliothek für Node.js angefordert wird:
app.intent('Subscribe to Notifications', (conv) => {
  conv.ask(new UpdatePermission({
    intent: 'Notification',
  }));
});
Actions SDK Node.js

Sie sollten Ihre NLU-Lösung so konfigurieren, dass eine Funktion ausgelöst wird, die die Berechtigung anfordert, wenn der Nutzerausdruck mit dem Wert der Aufforderung zur Aktivierung von Push-Benachrichtigungen übereinstimmt. Hier ist ein sehr einfaches Beispiel, das auf einem Stringabgleich basiert:

conv.ask(new UpdatePermission({
  intent: 'Notification',
}));
Dialogflow Java
  1. Öffnen Sie den Agent in der Dialogflow-Konsole und wählen Sie den Intent aus, den Sie für Updates konfigurieren möchten.
  2. Scrollen Sie nach unten zu Antwort und öffnen Sie den Tab Google Assistant.
  3. Klicken Sie auf Inhalt der Nachricht hinzufügen und wählen Sie Vorschlag-Chips aus.
  4. Geben Sie als Text für den Chip einen Text ein, der den Nutzer zur Aktivierung einlädt. Im Actions on Google-Beispiel haben wir den Chip auf Benachrichtigung über neue Tipps gesetzt.
  5. Fügen Sie einen weiteren Dialogflow-Intent hinzu, z. B. setup_push, und legen Sie eine entsprechende Aktion fest, z. B. setup.push. Der Nutzerausdruck dieses Intents muss mit dem Text des Opt-in-Chips übereinstimmen, in unserem Beispiel Benachrichtigung über neue Tipps.
Das folgende Snippet zeigt, wie die Berechtigung mithilfe der Actions on Google-Clientbibliothek für Java/Kotlin angefordert wird:
@ForIntent("Subscribe to Notifications")
public ActionResponse subscribeToNotifications(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  responseBuilder.add(new UpdatePermission().setIntent("Notification"));
  return responseBuilder.build();
}
Actions SDK Java

Sie sollten Ihre NLU-Lösung so konfigurieren, dass eine Funktion ausgelöst wird, die die Berechtigung anfordert, wenn der Nutzerausdruck mit dem Wert der Aufforderung zur Aktivierung von Push-Benachrichtigungen übereinstimmt. Hier ist ein sehr einfaches Beispiel, das auf einem Stringabgleich basiert:

ResponseBuilder responseBuilder = getResponseBuilder(request);
responseBuilder.add(new UpdatePermission().setIntent("Notification"));
return responseBuilder.build();
Dialogflow JSON

Beachten Sie, dass der folgende JSON-Code eine Webhook-Antwort mit Dialogflow beschreibt.

{
  "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"
          }
        }
      }
    }
  }
}
Actions SDK-JSON

Im folgenden JSON-Code wird eine Webhook-Antwort mit dem Actions SDK beschrieben.

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

Abo abschließen

Um das Abo über Ihren Node.js-Webhook abzuschließen, müssen Sie die Benachrichtigungs-ID des Nutzers und den ausgewählten Intent speichern. Beide werden als Argumente übergeben, wenn der Nutzer die Berechtigung erteilt.

Wenn Ihre Aktion mit Dialogflow erstellt wurde, müssen Sie Folgendes tun:

  • Fügen Sie einen Intent hinzu, der das actions_intent_PERMISSION verarbeitet.
  • Geben Sie für den Action-Namen des Intents einen Namen an, nach dem der Webhook später filtern kann.

Der folgende Code zeigt, wie ein Dialogflow-Intent mit einem Intent namens finish_push_setup und dem Aktionsnamen finish.push.setup verarbeitet wird:

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.`);
  }
});
Actions SDK – 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.`);
  }
});
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();
}
Actions SDK 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();
}
Dialogflow JSON

Der folgende JSON-Code beschreibt eine Anfrage an den 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"
}
Actions SDK-JSON

Der folgende JSON-Code beschreibt eine Anfrage an den 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"
        }
      ]
    }
  ]
}

Benachrichtigungen senden

Mithilfe der Actions API können Sie Push-Benachrichtigungen an Nutzer senden. Wenn Sie diese API verwenden möchten, müssen Sie sie in Ihrem Google Cloud-Projekt aktivieren, einen JSON-Dienstkontoschlüssel einrichten und herunterladen. Weitere Informationen finden Sie unter Schritt 8 in der Anleitung im hier aufgeführten Codebeispiel.

Anschließend kannst du mithilfe der Google OAuth2-Clientbibliothek den Dienstkontoschlüssel gegen ein Zugriffstoken austauschen und dieses zur Authentifizierung deiner Anfragen an die Actions API verwenden.

Schlüssel für Dienstkonto abrufen

  1. Rufen Sie diese URL auf und ersetzen Sie in der Actions Console „example-project-1“ durch Ihre Projekt-ID: https://console.developers.google.com/apis/api/actions.googleapis.com/overview?project=example-project-1
  2. Wenn die Schaltfläche Aktivieren angezeigt wird, klicken Sie darauf. Fahren Sie andernfalls mit Schritt 3 fort.
  3. Rufen Sie diese URL auf und ersetzen Sie in der Actions Console „example-project-1“ am Ende durch Ihre Projekt-ID: https://console.developers.google.com/apis/credentials?project=example-project-1.
  4. Klicken Sie auf Anmeldedaten erstellen > Dienstkontoschlüssel.
  5. Klicken Sie unter Dienstkonto auf das Feld Auswählen und dann auf Neues Dienstkonto.
  6. Geben Sie dem Dienstkonto einen Namen wie „notifications“ und die RolleProject Owner“.
  7. Wählen Sie den JSON-Schlüsseltyp aus und klicken Sie auf Erstellen. Ein JSON-Dienstkontoschlüssel wird auf Ihren lokalen Computer heruntergeladen.

Schlüssel gegen ein Zugriffstoken eintauschen und eine Benachrichtigung senden

Um eine Benachrichtigung über die Actions API zu senden, musst du den Dienstkontoschlüssel gegen ein Zugriffstoken eintauschen. Wir empfehlen die Verwendung einer Google API-Clientbibliothek. In den folgenden Code-Snippets wird die Google API-Clientbibliothek für Node.js verwendet.

  1. Installieren Sie die Google API-Clientbibliothek und fragen Sie Folgendes an: npm install googleapis request --save
  2. Verwenden Sie den folgenden Code, um ein Zugriffstoken vom Dienstkontoschlüssel abzurufen und eine Push-Benachrichtigung zu senden:
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}`);
    });
  }
});
Actions SDK – 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}`);
    });
  }
});
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);
}
Actions SDK 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);
}