สำรวจใน Dialogflow
คลิกต่อไปเพื่อนำเข้าตัวอย่างการแจ้งเตือนใน Dialogflow จากนั้นทำตามขั้นตอนด้านล่างเพื่อทำให้ใช้งานได้และทดสอบตัวอย่าง
- ป้อนชื่อตัวแทนและสร้าง Agent ใหม่ใน Dialogflow สำหรับตัวอย่าง
- หลังจากนำเข้า Agent เสร็จแล้ว ให้คลิกไปที่ Agent
- จากเมนูการนำทางหลัก ให้ไปที่การดำเนินการคำสั่งซื้อ
- เปิดใช้ตัวแก้ไขในบรรทัด แล้วคลิกทำให้ใช้งานได้ ซึ่งตัวแก้ไขจะมีโค้ดตัวอย่าง
- จากเมนูการนําทางหลัก ให้ไปที่ Integrations แล้วคลิก Google Assistant
- ในหน้าต่างโมดัลที่ปรากฏ ให้เปิดใช้แสดงตัวอย่างการเปลี่ยนแปลงอัตโนมัติ และคลิกทดสอบเพื่อเปิดเครื่องจำลองการดำเนินการ
- ในเครื่องจำลอง ให้ป้อน
Talk to my test app
เพื่อทดสอบตัวอย่าง
การดำเนินการของคุณสามารถส่งข้อความ Push ไปยังผู้ใช้ได้ทุกเมื่อที่เกี่ยวข้อง เช่น การส่งการช่วยเตือนเมื่อวันที่ครบกำหนดของงานอยู่ใกล้
ในคู่มือนี้ เราจะใช้ตัวอย่างเคล็ดลับเกี่ยวกับ Actions on Google เป็นข้อมูลอ้างอิงเพื่อแสดงวิธีตั้งค่าข้อความ Push สำหรับ Action ของคุณ เมื่อผู้ใช้เรียกใช้การดำเนินการนี้ ระบบจะถามว่าต้องการฟังเคล็ดลับเกี่ยวกับการพัฒนาการดำเนินการของตนหรือไม่ ผู้ใช้จะเลือกหมวดหมู่สำหรับเคล็ดลับที่เจาะจงหรือสุ่มเลือกก็ได้ หรือจะเลือกฟังเคล็ดลับล่าสุดก็ได้
แพลตฟอร์มที่รองรับ
ข้อความ Push มีให้ใช้งานในอุปกรณ์ Android และ iOS (อุปกรณ์ iOS ต้องติดตั้งแอป Assistant จึงจะรับข้อความ Push ได้) แต่ขณะนี้ยังไม่รองรับในลำโพงที่สั่งงานด้วยเสียง จออัจฉริยะ หรือแพลตฟอร์มอื่นๆ
ข้อกำหนดเบื้องต้น
ต้องมีการกำหนดค่าการดำเนินการอย่างน้อย 1 รายการในโปรเจ็กต์ Actions เป็น Intent ที่ทริกเกอร์ ซึ่งจะเรียกใช้เมื่อผู้ใช้แตะการแจ้งเตือนที่ได้รับจาก Assistant
ไม่สามารถกำหนดค่าการดำเนินการของคุณให้ทริกเกอร์ความตั้งใจต้อนรับเริ่มต้นจากข้อความ Push ได้
การตั้งค่าคอนโซล
วิธีเพิ่มการสนับสนุนข้อความ Push ไปยังการดำเนินการ
ไปที่คอนโซล Actions แล้วไปที่สร้าง > การดําเนินการ
คลิกการดำเนินการที่ตรงกับจุดประสงค์ในการทริกเกอร์เพิ่มเติมที่คุณต้องการเปิดใช้ข้อความ Push
สำหรับตัวอย่างเคล็ดลับของ Actions on Google คุณจะต้องเลือก "tell_latest_Tip"
เลื่อนลงไปที่ส่วนการมีส่วนร่วมของผู้ใช้ แล้วเปิดคุณต้องการส่งข้อความ Push ไหม
ป้อนชื่อเนื้อหา
สําหรับตัวอย่างเคล็ดลับของ Actions on Google ชื่ออาจเป็น "เพิ่มเคล็ดลับใหม่"
คลิกบันทึก
การนำเข้า
คุณจะต้องประกาศการนำเข้าต่อไปนี้ในโค้ด Fulfillment เพื่อวัตถุประสงค์ของส่วนถัดไป
const { dialogflow, UpdatePermission, Suggestions, } = require('actions-on-google');
const { actionssdk, UpdatePermission, Suggestions, } = require('actions-on-google');
ผู้ใช้ที่เลือกรับ
ก่อนจะส่งข้อความ Push ไปยังผู้ใช้ คุณต้องขอให้ผู้ใช้เลือกรับอีเมล ซึ่งทำได้โดยแสดงชิปคำแนะนำเพื่อขอสิทธิ์ เมื่อมีการให้สิทธิ์ คุณจะได้รับ User-ID ที่อัปเดตเพื่อส่งข้อความ Push ไปยังผู้ใช้รายนั้น
แสดงชิปคำแนะนำสำหรับการเลือกใช้
ก่อนที่ผู้ใช้จะรับข้อความ Push จากการดำเนินการได้ คุณต้องแสดงชิปคำแนะนำแก่ผู้ใช้เพื่อเชิญให้ผู้ใช้เลือกรับข้อความ Push
ข้อมูลโค้ดต่อไปนี้จะส่งชิปคำแนะนำ "แจ้งเตือนฉันเกี่ยวกับเคล็ดลับใหม่" ไปพร้อมกับการตอบกลับข้อความ
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
- เปิด Agent ในคอนโซล Dialogflow แล้วเลือก Intent ที่ต้องการกำหนดค่าสำหรับการอัปเดต
- เลื่อนลงไปที่การตอบกลับ แล้วเปิดแท็บ Google Assistant
- คลิกเพิ่มเนื้อหาข้อความ แล้วเลือกชิปคำแนะนำ
- ตั้งค่าข้อความชิปให้เป็นข้อความที่เชิญชวนให้ผู้ใช้เลือกใช้ ในตัวอย่างเคล็ดลับของ Actions on Google เราได้ตั้งค่าชิปเป็นแจ้งเตือนฉันเมื่อมีเคล็ดลับใหม่
- เพิ่ม Intent ของ Dialogflow อีกรายการหนึ่ง เช่น setup_push และตั้งค่าการดำเนินการที่เกี่ยวข้อง เช่น setup.push นิพจน์ผู้ใช้ใน Intent นี้ต้องตรงกับข้อความของชิปการเลือกใช้ในตัวอย่าง Alert me of new tips
app.intent('Subscribe to Notifications', (conv) => { conv.ask(new UpdatePermission({ intent: 'Notification', })); });
คุณควรกำหนดค่าโซลูชัน NLU เพื่อทริกเกอร์ฟังก์ชันที่ขอสิทธิ์หากนิพจน์ของผู้ใช้ตรงกับค่าของข้อความแจ้งให้เลือกใช้ข้อความ Push ต่อไปนี้เป็นตัวอย่างพื้นฐานที่อิงตามการจับคู่สตริง
conv.ask(new UpdatePermission({ intent: 'Notification', }));
- เปิด Agent ในคอนโซล Dialogflow แล้วเลือก Intent ที่ต้องการกำหนดค่าสำหรับการอัปเดต
- เลื่อนลงไปที่การตอบกลับ แล้วเปิดแท็บ Google Assistant
- คลิกเพิ่มเนื้อหาข้อความ แล้วเลือกชิปคำแนะนำ
- ตั้งค่าข้อความชิปให้เป็นข้อความที่เชิญชวนให้ผู้ใช้เลือกใช้ ในตัวอย่างเคล็ดลับของ Actions on Google เราได้ตั้งค่าชิปเป็นแจ้งเตือนฉันเมื่อมีเคล็ดลับใหม่
- เพิ่ม Intent ของ Dialogflow อีกรายการหนึ่ง เช่น setup_push และตั้งค่าการดำเนินการที่เกี่ยวข้อง เช่น setup.push นิพจน์ผู้ใช้ใน Intent นี้ต้องตรงกับข้อความของชิปการเลือกใช้ในตัวอย่าง Alert me of new tips
@ForIntent("Subscribe to Notifications") public ActionResponse subscribeToNotifications(ActionRequest request) { ResponseBuilder responseBuilder = getResponseBuilder(request); responseBuilder.add(new UpdatePermission().setIntent("Notification")); return responseBuilder.build(); }
คุณควรกำหนดค่าโซลูชัน NLU เพื่อทริกเกอร์ฟังก์ชันที่ขอสิทธิ์หากนิพจน์ของผู้ใช้ตรงกับค่าของข้อความแจ้งให้เลือกใช้ข้อความ Push ต่อไปนี้เป็นตัวอย่างพื้นฐานที่อิงตามการจับคู่สตริง
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 คุณต้องบันทึกรหัสการแจ้งเตือนของผู้ใช้และจุดประสงค์ที่ผู้ใช้เลือก ทั้ง 2 อย่างนี้จะส่งผ่านเป็นอาร์กิวเมนต์ได้หากผู้ใช้ให้สิทธิ์
หากการดำเนินการของคุณสร้างด้วย Dialogflow คุณต้องทำดังนี้
- เพิ่ม Intent ที่จัดการ
actions_intent_PERMISSION
- ระบุชื่อการดำเนินการของ Intent เป็นชื่อที่เว็บฮุคกรองไว้ใช้ในภายหลังได้
โค้ดต่อไปนี้แสดงวิธีจัดการ Intent ของ Dialogflow ที่มี Intent ชื่อ 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 ด้านล่างอธิบายคำขอที่ส่งไปยังเว็บฮุค
{ "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 ด้านล่างอธิบายคำขอที่ส่งไปยังเว็บฮุค
{ "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" } ] } ] }
ส่งการแจ้งเตือน
คุณส่งข้อความ Push ไปยังผู้ใช้ได้โดยใช้ Actions API หากต้องการใช้ API นี้ คุณต้องเปิดใช้ API ในโปรเจ็กต์ Google Cloud จากนั้นตั้งค่าและดาวน์โหลดคีย์บัญชีบริการ JSON ดูขั้นตอนที่ 8 ในวิธีการในตัวอย่างโค้ดที่นี่
จากนั้นคุณจะใช้ไลบรารีของไคลเอ็นต์ OAuth2 ของ Google เพื่อแลกเปลี่ยนคีย์บัญชีบริการเป็นโทเค็นเพื่อการเข้าถึงและใช้โทเค็นดังกล่าวเพื่อตรวจสอบสิทธิ์คำขอที่ส่งไปยัง Actions API ได้
ดาวน์โหลดคีย์บัญชีบริการ
- ไปที่ URL นี้ โดยแทนที่ "example-project-1" ที่ตอนท้ายด้วยรหัสโปรเจ็กต์ ในคอนโซลการดำเนินการ https://console.developers.google.com/apis/api/actions.googleapis.com/overview?project=example-project-1
- หากเห็นปุ่มเปิดใช้ ให้คลิกปุ่มนั้น หรือดำเนินการต่อในขั้นตอนที่ 3
- ไปที่ URL นี้ โดยแทนที่ "example-project-1" ที่ตอนท้ายด้วยรหัสโปรเจ็กต์ในคอนโซลการดำเนินการ https://console.developers.google.com/apis/credentials?project=example-project-1
- คลิกสร้างข้อมูลเข้าสู่ระบบ > คีย์บัญชีบริการ
- คลิกช่องเลือกใต้บัญชีบริการ แล้วคลิกบัญชีบริการใหม่
- ตั้งชื่อบัญชีบริการ เช่น "การแจ้งเตือน" และบทบาทของเจ้าของโปรเจ็กต์
- เลือกประเภทคีย์ JSON แล้วคลิก Create ระบบจะดาวน์โหลดคีย์บัญชีบริการ JSON ไปยังเครื่องภายใน
แลกเปลี่ยนคีย์เป็นโทเค็นเพื่อการเข้าถึงและส่งการแจ้งเตือน
หากต้องการส่งการแจ้งเตือนผ่าน Actions API คุณต้องแลกเปลี่ยนคีย์บัญชีบริการกับโทเค็นเพื่อการเข้าถึง เราขอแนะนำให้ใช้ไลบรารีไคลเอ็นต์ Google API สำหรับขั้นตอนนี้ ในซีรีส์ข้อมูลโค้ดที่ตามมา เราจะใช้ไลบรารีของไคลเอ็นต์ Google API Node.js
- ติดตั้งไลบรารีไคลเอ็นต์ Google API และคำขอ
npm install googleapis request --save
- ใช้รหัสต่อไปนี้เพื่อรับโทเค็นเพื่อการเข้าถึงจากคีย์บัญชีบริการและส่งข้อความ 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); }