Explorar no Dialogflow
Clique em Continue para importar a amostra de Notifications para o Dialogflow. Depois, siga as etapas abaixo para implantar e testar a amostra:
- Digite um nome de agente e crie um novo agente do Dialogflow para a amostra.
- Depois que a importação do agente terminar, clique em Go to agent.
- No menu de navegação principal, acesse Fulfillment.
- Ative o Editor in-line e clique em Implantar. O editor contém a amostra o código-fonte.
- No menu de navegação principal, acesse Integrações e clique em Google Google Assistente.
- Na janela modal exibida, ative a opção Mudanças na visualização automática e clique em Testar. para abrir o simulador do Actions.
- No simulador, insira
Talk to my test app
para testar a amostra.
Sua Ação pode enviar notificações push para os usuários sempre que relevante, por exemplo, um lembrete quando a data de conclusão de uma tarefa estiver próxima.
Neste guia, usamos o exemplo de dicas do Actions on Google. como referência para mostrar como configurar notificações push para uma ação. Quando os usuários invocam essa ação, ela pergunta se eles querem ouvir uma gorjeta sobre como desenvolver ações próprias. Os usuários podem escolher uma categoria específica ou selecionada aleatoriamente para a gorjeta, ou é possível optar por ouvir a dica mais recente.
Plataformas compatíveis
As notificações push estão disponíveis em dispositivos Android e iOS (dispositivos iOS devem ter o app Google Assistente instalado para receber notificações push). Eles não são atualmente compatíveis com alto-falantes ativados por voz, smart displays ou outras superfícies.
Pré-requisitos
Pelo menos uma das ações no seu projeto precisa ser configurada como de acionamento de uma intent, que será invocada quando o usuário tocar em uma notificação recebida do o Assistente.
Não é possível configurar suas ações para acionar a intent de boas-vindas padrão em uma notificação push.
Configuração do console
Para adicionar suporte a notificações push à sua Ação:
Acesse o Console do Actions e navegue Criar > Ações.
Clique na ação que corresponde à intent de acionamento adicional que você quer ativar as notificações push.
Para o exemplo de dicas do Actions on Google, selecione "tell_latest_tip".
Role para baixo até a seção Engajamento do usuário e ative Você quer enviar notificações push.
Digite um Título do conteúdo.
No exemplo de dicas do Actions on Google, o título pode ser "Nova dica adicionada".
Clique em Salvar.
Importações
Para os fins das próximas seções, no código de atendimento, você precisará declarar as seguintes importações:
const { dialogflow, UpdatePermission, Suggestions, } = require('actions-on-google');
const { actionssdk, UpdatePermission, Suggestions, } = require('actions-on-google');
Usuários que aceitaram participar
Antes de enviar notificações push aos usuários, você precisa solicitar a ativação delas. Para fazer isso, mostre um chip de sugestão para pedir permissão. Quando a pessoa dá permissão, você recebe um ID do usuário de atualização para enviar notificações push para esse usuário.
Mostrar ícones de sugestão para ativação
Antes que os usuários possam receber notificações push da sua Ação, você precisa mostrar uma ícone de sugestão de resposta para convidá-los a ativar as notificações push.
O snippet de código a seguir envia ao usuário um aviso "Alertar-me sobre novas dicas" sugestão ícone ao lado de uma resposta de texto.
conv.ask('I can send you push notifications. Would you like that?'); conv.ask(new Suggestions('Send notifications'));
conv.ask(' I can send you push notifications. Would you like that?'); conv.ask(new Suggestions('Send notifications'));
responseBuilder .add("I can send you push notifications. Would you like that?") .addSuggestions(new String[] { "Send notifications" });
responseBuilder .add("I can send you push notifications. Would you like that?") .addSuggestions(new String[] { "Send notifications" });
O JSON abaixo descreve uma resposta do 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" } ] } } } }
O JSON abaixo descreve uma resposta do 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" } ] } } } ] }
Depois de tocar no ícone, você precisa pedir a permissão UPDATE
.
O código abaixo mostra como fazer isso com o askForUpdatePermission
.
da biblioteca de cliente Node.js.
- Abra seu agente no console do Dialogflow e selecione a intent que você está configurando para atualizações.
- Role para baixo até Resposta e abra a guia Google Assistente.
- Clique em Adicionar conteúdo da mensagem e selecione Ícones de sugestão.
- Defina o texto do ícone como algo que convide o usuário a aceitar. Na No exemplo de dicas do Actions on Google, configuramos o ícone como Alert me of new Tips (Alertar-me sobre novas dicas).
- Adicione outro intent do Dialogflow, chamado, por exemplo, setup_push. defina uma ação correspondente, por exemplo, setup.push. A expressão do usuário dessa intent precisa corresponder ao texto do ícone de ativação. no exemplo Alertar-me sobre novas dicas.
app.intent('Subscribe to Notifications', (conv) => { conv.ask(new UpdatePermission({ intent: 'Notification', })); });
Configure sua solução PLN para acionar uma função que solicita permissão se a expressão do usuário corresponder ao valor das notificações push solicitação de aceitação. Veja um exemplo muito básico com base na correspondência de string:
conv.ask(new UpdatePermission({ intent: 'Notification', }));
- Abra seu agente no console do Dialogflow e selecione a intent que você está configurando para atualizações.
- Role para baixo até Resposta e abra a guia Google Assistente.
- Clique em Adicionar conteúdo da mensagem e selecione Ícones de sugestão.
- Defina o texto do ícone como algo que convide o usuário a aceitar. Na No exemplo de dicas do Actions on Google, configuramos o ícone como Alert me of new Tips (Alertar-me sobre novas dicas).
- Adicione outro intent do Dialogflow, chamado, por exemplo, setup_push. defina uma ação correspondente, por exemplo, setup.push. A expressão do usuário dessa intent precisa corresponder ao texto do ícone de ativação. no exemplo Alertar-me sobre novas dicas.
@ForIntent("Subscribe to Notifications") public ActionResponse subscribeToNotifications(ActionRequest request) { ResponseBuilder responseBuilder = getResponseBuilder(request); responseBuilder.add(new UpdatePermission().setIntent("Notification")); return responseBuilder.build(); }
Configure sua solução PLN para acionar uma função que solicita permissão se a expressão do usuário corresponder ao valor das notificações push solicitação de aceitação. Veja um exemplo muito básico com base na correspondência de string:
ResponseBuilder responseBuilder = getResponseBuilder(request); responseBuilder.add(new UpdatePermission().setIntent("Notification")); return responseBuilder.build();
Observe que o JSON abaixo descreve uma resposta de webhook usando o 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" } } } } } }
O JSON abaixo descreve uma resposta de webhook usando o SDK do 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" } } } ] } ] }
Finalizar a assinatura
Para finalizar a assinatura do webhook Node.js, você precisa salvar o o ID de notificações do usuário e a intent que ele selecionou. Ambos são transmitidos como se o usuário conceder a permissão.
Se sua ação for criada com o Dialogflow, você precisará:
- Adicione uma intent que gerencie o
actions_intent_PERMISSION
. - Especifique o nome da Action da intent para algo que seu webhook possa filtrar para mais tarde.
O código a seguir mostra como processar uma intent do Dialogflow com uma intent
chamado finish_push_setup
com o nome da ação finish.push.setup
:
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.`); } });
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.`); } });
@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(); }
@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(); }
Observe que o JSON abaixo descreve uma solicitação para o 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" }
Observe que o JSON abaixo descreve uma solicitação para o 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" } ] } ] }
Envie notificações
É possível enviar notificações push aos usuários usando a API Actions. Para usar essa API, você precisa ativar a API no seu projeto do Google Cloud, configurar e fazer o download Chave da conta de serviço JSON. Consulte a etapa 8 nas instruções neste exemplo de código.
Depois, você pode usar a biblioteca de cliente do Google OAuth2 para trocar a chave da conta de serviço. para receber um token de acesso e usá-lo para autenticar suas solicitações à API Actions.
Gerar uma chave da conta de serviço
- Acesse este URL, substituindo "example-project-1" no final pelo ID do projeto no Console do Actions: https://console.developers.google.com/apis/api/actions.googleapis.com/overview?project=example-project-1
- Se houver um botão Ativar, clique nele. Caso contrário, avance para a etapa 3.
- Acesse este URL, substituindo "example-project-1" no final pelo ID do projeto no Console do Actions: https://console.developers.google.com/apis/credentials?project=example-project-1
- Clique em Criar credenciais > Chave da conta de serviço.
- Clique na caixa Selecionar em Conta de serviço e em Novo serviço Google.
- Dê um nome à conta de serviço, como "notificações" e o Papel de Proprietário do projeto.
- Selecione o tipo de chave JSON e clique em Criar. Uma chave de conta de serviço JSON transferidos por download para sua máquina local.
Trocar a chave por um token de acesso e enviar uma notificação
Para enviar uma notificação pela API Actions, você precisa trocar a chave da conta de serviço para um token de acesso. Recomendamos usar um cliente de API do Google para isso. Na série de snippets de código a seguir, estamos usando biblioteca de cliente Node.js da API do Google.
- Instale a biblioteca de cliente da API do Google e solicite:
npm install googleapis request --save
- Use o código a seguir para receber um token de acesso da chave da conta de serviço e envie uma notificação push:
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}`); }); } });
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}`); }); } });
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); }
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); }