در Dialogflow کاوش کنید
برای وارد کردن نمونه اعلانهای ما در Dialogflow روی Continue کلیک کنید. سپس، مراحل زیر را برای استقرار و آزمایش نمونه دنبال کنید:
- یک نام عامل وارد کنید و یک عامل Dialogflow جدید برای نمونه ایجاد کنید.
- پس از وارد کردن عامل، روی Go to agent کلیک کنید.
- از منوی پیمایش اصلی، به Fulfillment بروید.
- ویرایشگر درون خطی را فعال کنید، سپس روی Deploy کلیک کنید. ویرایشگر حاوی کد نمونه است.
- از منوی پیمایش اصلی، به Integrations بروید، سپس روی Google Assistant کلیک کنید.
- در پنجره مدال که ظاهر میشود، پیشنمایش خودکار تغییرات را فعال کنید و روی Test کلیک کنید تا شبیهساز Actions باز شود.
- در شبیه ساز برای تست نمونه وارد
Talk to my test app
شوید!
Action شما میتواند هر زمان که مرتبط باشد، اعلانها را به کاربران ارسال کند، مانند ارسال یادآوری زمانی که موعد مقرر برای یک کار نزدیک است.
در این راهنما، ما از نمونه نکات Actions on Google به عنوان مرجع استفاده می کنیم تا به شما نشان دهیم چگونه اعلان های فشار را برای Action خود تنظیم کنید. وقتی کاربران این Action را فراخوانی میکنند، از شما میپرسد که آیا میخواهند نکتهای درباره توسعه Action خود بشنوند یا خیر. کاربران میتوانند یک دسته خاص یا بهطور تصادفی برای نکته انتخاب کنند، یا میتوانند جدیدترین نکته را بشنوند.
سطوح پشتیبانی شده
اعلانهای فشاری در دستگاههای Android و iOS در دسترس هستند (دستگاههای iOS باید برنامه Assistant را برای دریافت اعلانهای فشار نصب کرده باشند). آنها در حال حاضر در بلندگوهای فعال صوتی، نمایشگرهای هوشمند یا سطوح دیگر پشتیبانی نمیشوند.
پیش نیازها
حداقل یکی از کنشها در پروژه Actions شما باید بهعنوان یک هدف راهاندازی پیکربندی شود که وقتی کاربر روی اعلان دریافتی از دستیار ضربه میزند، احضار میشود.
کنشهای شما را نمیتوان برای راهاندازی پیشفرض پیشفرض پیشفرض از اعلان فشار پیکربندی کرد.
راه اندازی کنسول
برای افزودن پشتیبانی از اعلانهای فشاری به Action:
به کنسول Actions بروید و به Build > Actions بروید.
روی اقدامی کلیک کنید که با هدف تحریک اضافی که میخواهید اعلانهای فشار را برای آن فعال کنید مطابقت دارد.
برای نمونه نکات Actions on Google، "tell_latest_tip" را انتخاب کنید.
به سمت پایین به بخش تعامل کاربر بروید و Wid you like to send push notifications را فعال کنید.
عنوان محتوا را وارد کنید.
برای نمونه نکات مربوط به Actions on Google، عنوان می تواند "نکته جدید اضافه شده" باشد.
روی ذخیره کلیک کنید.
واردات
برای اهداف بخش های بعدی، در کد تکمیلی خود، باید واردات زیر را اعلام کنید:
const { dialogflow, UpdatePermission, Suggestions, } = require('actions-on-google');
const { actionssdk, UpdatePermission, Suggestions, } = require('actions-on-google');
کاربران فعال
قبل از اینکه بتوانید اعلانهای فشاری را برای کاربران ارسال کنید، باید از آنها بخواهید که شرکت کنند. می توانید این کار را با نشان دادن یک تراشه پیشنهادی برای درخواست اجازه از آنها انجام دهید. هنگامی که آنها اجازه می دهند، شما یک شناسه کاربری به روز دریافت می کنید تا اعلان های فشار را برای آن کاربر ارسال کنید.
نمایش تراشههای پیشنهادی برای انتخاب
قبل از اینکه کاربران بتوانند اعلانهای فشاری را از Action شما دریافت کنند، باید یک تراشه پیشنهادی به آنها نشان دهید تا از آنها دعوت کنید در اعلانهای فشاری شرکت کنند.
قطعه کد زیر یک تراشه پیشنهادی «به من از نکات جدید هشدار بده» به همراه یک پاسخ متنی برای کاربر ارسال می کند.
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" });
توجه داشته باشید که JSON زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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" } ] } } } }
توجه داشته باشید که JSON زیر یک پاسخ وب هوک را توضیح می دهد.
{ "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" } ] } } } ] }
پس از ضربه زدن روی تراشه، باید مجوز UPDATE
را بخواهید. کد زیر به شما نشان می دهد که چگونه این کار را با تابع askForUpdatePermission
کتابخانه مشتری Node.js انجام دهید.
- عامل خود را در کنسول Dialogflow باز کنید و هدفی را که برای بهروزرسانی پیکربندی میکنید انتخاب کنید.
- به پایین بروید و به Response بروید و تب Google Assistant را باز کنید.
- روی افزودن محتوای پیام کلیک کنید و تراشههای پیشنهادی را انتخاب کنید.
- متن تراشه را روی چیزی تنظیم کنید که کاربر را به شرکت در آن دعوت کند. در نمونه نکات Actions on Google، تراشه را روی Alert me of new tips قرار دادیم.
- یک هدف Dialogflow دیگر، به عنوان مثال setup_push نامیده میشود، اضافه کنید و یک عمل مربوطه را تنظیم کنید، برای مثال setup.push . بیان کاربر این هدف باید با متن تراشه انتخاب کردن مطابقت داشته باشد، در مثال ما نکات جدید به من هشدار داده شود .
app.intent('Subscribe to Notifications', (conv) => { conv.ask(new UpdatePermission({ intent: 'Notification', })); });
شما باید راه حل NLU خود را به گونه ای پیکربندی کنید که تابعی را راه اندازی کند که در صورت مطابقت عبارت کاربر با مقدار درخواست opt-in push notifications اجازه می خواهد. در اینجا یک مثال بسیار اساسی بر اساس تطبیق رشته آورده شده است:
conv.ask(new UpdatePermission({ intent: 'Notification', }));
- عامل خود را در کنسول Dialogflow باز کنید و هدفی را که برای بهروزرسانی پیکربندی میکنید انتخاب کنید.
- به پایین بروید و به Response بروید و تب Google Assistant را باز کنید.
- روی افزودن محتوای پیام کلیک کنید و تراشههای پیشنهادی را انتخاب کنید.
- متن تراشه را روی چیزی تنظیم کنید که کاربر را به شرکت در آن دعوت کند. در نمونه نکات Actions on Google، تراشه را روی Alert me of new tips قرار دادیم.
- یک هدف Dialogflow دیگر، به عنوان مثال setup_push نامیده میشود، اضافه کنید و یک عمل مربوطه را تنظیم کنید، برای مثال setup.push . بیان کاربر این هدف باید با متن تراشه انتخاب کردن مطابقت داشته باشد، در مثال ما نکات جدید به من هشدار داده شود .
@ForIntent("Subscribe to Notifications") public ActionResponse subscribeToNotifications(ActionRequest request) { ResponseBuilder responseBuilder = getResponseBuilder(request); responseBuilder.add(new UpdatePermission().setIntent("Notification")); return responseBuilder.build(); }
شما باید راه حل NLU خود را به گونه ای پیکربندی کنید که تابعی را راه اندازی کند که در صورت مطابقت عبارت کاربر با مقدار درخواست opt-in push notifications اجازه می خواهد. در اینجا یک مثال بسیار اساسی بر اساس تطبیق رشته آورده شده است:
ResponseBuilder responseBuilder = getResponseBuilder(request); responseBuilder.add(new UpdatePermission().setIntent("Notification")); return responseBuilder.build();
توجه داشته باشید که JSON زیر یک پاسخ هوک با استفاده از 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" } } } } } }
توجه داشته باشید که JSON زیر یک پاسخ هوک را با استفاده از Actions SDK توضیح میدهد.
{ "expectUserResponse": true, "expectedInputs": [ { "possibleIntents": [ { "intent": "actions.intent.PERMISSION", "inputValueData": { "@type": "type.googleapis.com/google.actions.v2.PermissionValueSpec", "permissions": [ "UPDATE" ], "updatePermissionValueSpec": { "intent": "tell_latest_tip" } } } ] } ] }
اشتراک را نهایی کنید
برای نهایی کردن اشتراک از وبهوک Node.js، باید شناسه اعلانهای کاربر و هدفی را که انتخاب کردهاند ذخیره کنید. اگر کاربر مجوز را بدهد، هر دو به عنوان آرگومان ارسال می شوند.
اگر Action شما با Dialogflow ساخته شده است، باید:
- یک intent اضافه کنید که
actions_intent_PERMISSION
را مدیریت کند. - نام اقدام intent را برای چیزی که وبهوک شما میتواند برای بعداً فیلتر کند، مشخص کنید.
کد زیر نحوه مدیریت یک Intent Dialogflow را با هدفی به نام finish_push_setup
با نام Action 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(); }
توجه داشته باشید که JSON زیر یک درخواست به 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" }
توجه داشته باشید که JSON زیر یک درخواست به 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" } ] } ] }
ارسال اعلان ها
می توانید با استفاده از Action API برای کاربران اعلان های فشار ارسال کنید. برای استفاده از این API، باید API را در پروژه Google Cloud خود فعال کنید و کلید حساب سرویس JSON را تنظیم و دانلود کنید. مرحله 8 را در دستورالعمل های نمونه کد اینجا ببینید.
سپس میتوانید از کتابخانه سرویس گیرنده Google OAuth2 برای مبادله کلید حساب سرویس با یک نشانه دسترسی استفاده کنید و از آن برای تأیید اعتبار درخواستهای خود در API Action استفاده کنید.
یک کلید حساب سرویس دریافت کنید
- به این URL بروید و در پایان با شناسه پروژه خود در کنسول Actions جایگزین «example-project-1» شوید: https://console.developers.google.com/apis/api/actions.googleapis.com/overview?project =example-project-1
- اگر دکمه فعال کردن را می بینید، روی آن کلیک کنید. در غیر این صورت به مرحله 3 بروید.
- به این نشانی اینترنتی بروید و در پایان با شناسه پروژه خود در کنسول Actions جایگزین «example-project-1» شوید: https://console.developers.google.com/apis/credentials?project=example-project-1
- روی ایجاد اعتبارنامه > کلید حساب سرویس کلیک کنید.
- روی کادر انتخاب در زیر حساب سرویس کلیک کنید و حساب جدید سرویس را کلیک کنید.
- به حساب سرویس نامی مانند «اعلانها» و نقش مالک پروژه بدهید.
- نوع کلید JSON را انتخاب کرده و روی Create کلیک کنید. یک کلید حساب سرویس JSON در دستگاه محلی شما دانلود می شود.
کلید را با یک نشانه دسترسی تعویض کنید و یک اعلان ارسال کنید
برای ارسال اعلان از طریق API Action، باید کلید حساب سرویس را با یک نشانه دسترسی مبادله کنید. توصیه می کنیم برای این کار از کتابخانه سرویس گیرنده Google API استفاده کنید. در سری کدهایی که در ادامه می آیند، از کتابخانه سرویس گیرنده Google API Node.js استفاده می کنیم.
- کتابخانه سرویس گیرنده Google API را نصب کنید و درخواست کنید:
npm install googleapis request --save
- از کد زیر برای دریافت رمز دسترسی از کلید حساب سرویس و ارسال اعلان فشار استفاده کنید:
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); }