אפשרויות נוספות ב-Dialogflow
אפשר ללחוץ על המשך כדי לייבא את דוגמת ההתראות מ-Dialogflow. לאחר מכן, מבצעים את הפעולות הבאות כדי לפרוס את הדוגמה ולבדוק אותה:
- צריך להזין שם נציג וליצור נציג חדש ב-Dialogflow לדוגמה.
- כשמסיימים לייבא את הנציג, לוחצים על מעבר לנציג.
- מתפריט הניווט הראשי, עוברים אל מילוי הזמנה.
- מפעילים את עורך מוטבע ולוחצים על פריסה. העורך מכיל את הקוד לדוגמה.
- בתפריט הניווט הראשי, נכנסים אל Integrations (שילובים) ולוחצים על Google Assistant.
- בחלון החלון הקופץ, מפעילים את האפשרות שינויים בתצוגה מקדימה אוטומטית ולוחצים על בדיקה כדי לפתוח את סימולטור הפעולות.
- בסימולטור, מזינים
Talk to my test app
כדי לבדוק את הטעימה!
הפעולה יכולה לשלוח התראות למשתמשים בכל פעם שהדבר רלוונטי, למשל שליחת תזכורת כשתאריך היעד של המשימה מתקרב.
במדריך הזה אנחנו משתמשים בדוגמה לטיפים בנושא פעולות ב-Google כדי להראות לכם איך להגדיר התראות על פעולה מסוימת. כשהמשתמשים מפעילים את הפעולה, השאלה אם הם רוצים לשמוע טיפ על פיתוח פעולה משלהם. המשתמשים יכולים לבחור לטיפ קטגוריה ספציפית או אקראית, או לשמוע את הטיפ העדכני ביותר.
פלטפורמות נתמכות
ההתראות זמינות במכשירי Android ו-iOS (כדי לקבל התראות, אפליקציית Assistant צריכה להיות מותקנת במכשירי iOS). הם לא נתמכים כרגע ברמקולים עם הפעלה קולית, במסכים חכמים או בפלטפורמות אחרות.
דרישות מוקדמות
צריך להגדיר לפחות אחת מהפעולות בפרויקט הפעולות כ-Intent הפעלה, שיופעל כשהמשתמש יקיש על התראה שמתקבלת מ-Assistant.
לא ניתן להגדיר את הפעולות כך שיפעילו את Intent קבלת הפנים שמוגדר כברירת מחדל מהתראה.
הגדרת מסוף
כדי להוסיף לפעולה תמיכה בהתראות:
נכנסים ל-Actions Console ולוחצים על Build > Actions (בנייה > פעולות).
לוחצים על הפעולה שתואמת ל-Intent הטריגר הנוסף שעבורו רוצים להפעיל התראות.
כדי לראות את הדוגמה לטיפים של Actions on Google, עליך לבחור באפשרות "tell_minute_tip".
גוללים למטה לקטע User engagement ומפעילים את האפשרות רוצה לשלוח התראות?.
מזינים את שם התוכן.
בדוגמה של הטיפים ל-Actions on Google, הכותרת יכולה להיות "נוסף טיפ חדש".
לוחצים על שמירה.
יבוא
לצורך הסעיפים הבאים, צריך להצהיר על פעולות הייבוא הבאות בקוד ההפצה:
const { dialogflow, UpdatePermission, Suggestions, } = require('actions-on-google');
const { actionssdk, UpdatePermission, Suggestions, } = require('actions-on-google');
צירוף משתמשים
לפני שתוכלו לשלוח התראות למשתמשים, עליכם לבקש מהם להביע הסכמה. כדי לעשות את זה, אפשר להציג להם צ'יפ של הצעה ולבקש את רשותם. כשהוא מעניק הרשאה, אתם מקבלים מזהה משתמש מעודכן לשליחת התראות למשתמש הזה.
הצגת צ'יפים של הצעות להצטרפות
כדי שהמשתמשים יוכלו לקבל התראות מהפעולה, עליכם להציג להם צ'יפ הצעה שבאמצעותו הם יוכלו להביע הסכמה לקבלת התראות.
קטע הקוד הבא שולח למשתמש את צ'יפ ההצעות 'התרעה על טיפים חדשים' לצד תשובת טקסט.
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 שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (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" } ] } } } }
שימו לב: קובץ ה-JSON שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (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" } ] } } } ] }
אחרי שהמשתמש מקיש על הצ'יפ, עליך לבקש את ההרשאה UPDATE
.
כאן מוסבר איך לעשות זאת באמצעות הפונקציה askForUpdatePermission
בספריית הלקוח של Node.js.
- פותחים את הנציג במסוף Dialogflow ובוחרים את הכוונה שרוצים להגדיר לעדכונים.
- גוללים למטה אל תגובה ופותחים את הכרטיסייה Google Assistant.
- לוחצים על הוספת תוכן ההודעה ובוחרים באפשרות צ'יפים של הצעות.
- מגדירים את הטקסט של הצ'יפ לטקסט שמזמין את המשתמש להביע הסכמה. בדוגמת הטיפים של Actions on Google, הגדרנו את הצ'יפ אני רוצה לקבל התראות על טיפים חדשים.
- אפשר להוסיף עוד Intent ב-Dialogflow, שנקרא לדוגמה setup_push, ולהגדיר פעולה תואמת, כמו setup.push. הביטוי של Intent זה חייב להיות זהה לטקסט של צ'יפ ההסכמה, בדוגמה שלנו בנושא התראת אזהרה לגבי טיפים חדשים.
app.intent('Subscribe to Notifications', (conv) => { conv.ask(new UpdatePermission({ intent: 'Notification', })); });
צריך להגדיר את הפתרון של NLU כך שיפעיל פונקציה שמבקשת את ההרשאה אם ביטוי המשתמש תואם לערך של בקשת ההצטרפות להתראות שנשלחות מהאפליקציה. לפניכם דוגמה בסיסית מאוד המבוססת על התאמת מחרוזות:
conv.ask(new UpdatePermission({ intent: 'Notification', }));
- פותחים את הנציג במסוף Dialogflow ובוחרים את הכוונה שרוצים להגדיר לעדכונים.
- גוללים למטה אל תגובה ופותחים את הכרטיסייה Google Assistant.
- לוחצים על הוספת תוכן ההודעה ובוחרים באפשרות צ'יפים של הצעות.
- מגדירים את הטקסט של הצ'יפ לטקסט שמזמין את המשתמש להביע הסכמה. בדוגמת הטיפים של Actions on Google, הגדרנו את הצ'יפ אני רוצה לקבל התראות על טיפים חדשים.
- אפשר להוסיף עוד Intent ב-Dialogflow, שנקרא לדוגמה setup_push, ולהגדיר פעולה תואמת, כמו setup.push. הביטוי של Intent זה חייב להיות זהה לטקסט של צ'יפ ההסכמה, בדוגמה שלנו בנושא התראת אזהרה לגבי טיפים חדשים.
@ForIntent("Subscribe to Notifications") public ActionResponse subscribeToNotifications(ActionRequest request) { ResponseBuilder responseBuilder = getResponseBuilder(request); responseBuilder.add(new UpdatePermission().setIntent("Notification")); return responseBuilder.build(); }
צריך להגדיר את הפתרון של NLU כך שיפעיל פונקציה שמבקשת את ההרשאה אם ביטוי המשתמש תואם לערך של בקשת ההצטרפות להתראות שנשלחות מהאפליקציה. לפניכם דוגמה בסיסית מאוד המבוססת על התאמת מחרוזות:
ResponseBuilder responseBuilder = getResponseBuilder(request); responseBuilder.add(new UpdatePermission().setIntent("Notification")); return responseBuilder.build();
הערה: בקובץ ה-JSON שמוצג בהמשך מתוארת תגובה של תגובה לפעולה מאתר אחר (webhook) באמצעות 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 שמוצג בהמשך מתאר תגובה של תגובה לפעולה מאתר אחר (webhook) באמצעות 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 webhook, צריך לשמור את מזהה ההתראות של המשתמש ואת הכוונה שהוא בחר. שניהם מועברים כארגומנטים אם המשתמש מעניק את ההרשאה.
אם הפעולה נוצרה באמצעות Dialogflow, צריך:
- יש להוסיף Intent שמטפל ב-
actions_intent_PERMISSION
. - צריך לציין את שם ה-Action של ה-Intent בשביל משהו שהתגובה לפעולה מאתר אחר (webhook) יכולה לסנן אותו למועד מאוחר יותר.
בקוד הבא מוסבר איך מטפלים באובייקטים מסוג Intent ב-Dialogflow עם אובייקט
בשם finish_push_setup
, עם שם הפעולה 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" } ] } ] }
שליחת התראות
אפשר לשלוח התראות למשתמשים באמצעות Actions API. כדי להשתמש ב-API הזה, צריך להפעיל את ה-API בפרויקט ב-Google Cloud, להגדיר ולהוריד מפתח חשבון שירות מסוג JSON. אתם יכולים לעיין בשלב 8 בהוראות שמפורטות כאן בדוגמת הקוד.
לאחר מכן תוכלו להשתמש בספריית הלקוח של Google OAuth2 כדי להמיר את המפתח של חשבון השירות באסימון גישה, ולהשתמש באסימון כדי לאמת את הבקשות שלכם ל-Actions API.
קבלת מפתח לחשבון שירות
- עוברים לכתובת ה-URL הזו ומחליפים את "example-project-1" במזהה הפרויקט במסוף Actions: https://console.developers.google.com/apis/api/actions.googleapis.com/overview?project=example-project-1
- אם מופיע הלחצן הפעלה, לוחצים עליו. אם לא, ממשיכים לשלב 3.
- עוברים לכתובת ה-URL הזו ומחליפים את "example-project-1" במזהה הפרויקט במסוף Actions: https://console.developers.google.com/apis/credentials?project=example-project-1
- לוחצים על Create credentials > Service Account Key.
- לוחצים על התיבה Select בקטע Service Account ולוחצים על New Service Account.
- נותנים לחשבון השירות שם כמו "התראות" והתפקיד של בעלי הפרויקט.
- בוחרים את סוג המפתח של JSON ולוחצים על יצירה. מורידים למחשב המקומי מפתח של חשבון שירות מסוג JSON.
להחליף את המפתח באסימון גישה ולשלוח התראה
כדי לשלוח התראה דרך Actions API, צריך להמיר את המפתח של חשבון השירות באסימון גישה. לשם כך מומלץ להשתמש בספריית לקוח של 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); }