Upgrade to Pro — share decks privately, control downloads, hide ads and more …

フロントエンドに優しいスマートスピーカースキルの作り方 #ゆるWeb札幌

フロントエンドに優しいスマートスピーカースキルの作り方 #ゆるWeb札幌

フロントエンド・Web技術をベースに作れる、スマートスピーカースキル (Google Nest Hub 向け) の導入の話。
https://mild-web-sap.connpass.com/event/147756/

Kihara, Takuya

October 26, 2019
Tweet

More Decks by Kihara, Takuya

Other Decks in Technology

Transcript

  1. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ ୭ • ໊લ tacck / ໦ݪ ୎໵ •

    ॴଐ גࣜձࣾϊʔεσΟςʔϧ • ओ࠵ • ΏΔWebษڧձ@ࡳຈ • εϚʔτεϐʔΧʔͰ༡΅͏ձ@ࡳຈ • ޷͖ͳϑΟΪϡΞεέʔτͷٕ εϓϨουɾΠʔάϧ
  2. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ εϚʔτεϐʔΧʔ ɹΤϯδϯ Ϋϥ΢υ্ ௨৴ ϚΠΫ εϐʔΧʔ Ի੠ೝࣝ จষղੳ

    Ի੠ೝࣝ ର࿩࡞੒ Ի੠߹੒ "MFYB ࠓͷ࣌ؒ͸ ʮ"MFYBʯͱ ݺͼ͔͚ΒΕͨ ͜ͱΛೝࣝ
  3. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ εϚʔτεϐʔΧʔ ɹΤϯδϯ Ϋϥ΢υ্ ௨৴ ϚΠΫ εϐʔΧʔ Ի੠ೝࣝ จষղੳ

    Ի੠ೝࣝ ର࿩࡞੒ Ի੠߹੒ "MFYB ࠓͷ࣌ؒ͸ ʮࠓʯͷʮ࣌ؒʯ ˠݱࡏ࣌ࠁΛਘͶΒΕ͍ͯΔ ͱཧղ
  4. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ εϚʔτεϐʔΧʔ ɹΤϯδϯ Ϋϥ΢υ্ ௨৴ ϚΠΫ εϐʔΧʔ Ի੠ೝࣝ จষղੳ

    Ի੠ೝࣝ ର࿩࡞੒ Ի੠߹੒ "MFYB ࠓͷ࣌ؒ͸ ճ౴จΛ Ի੠ʹม׵ͯ͠
 εϐʔΧʔ΁ฦ٫
  5. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ εϚʔτεϐʔΧʔ ɹΤϯδϯ Ϋϥ΢υ্ ௨৴ ϚΠΫ εϐʔΧʔ Ի੠ೝࣝ จষղੳ

    Ի੠ೝࣝ ର࿩࡞੒ Ի੠߹੒ "MFYB ࠓͷ࣌ؒ͸ ड৴ͨ͠Ի੠Λ
 ࠶ੜ ൃ࿩ ޕޙ࣌ ෼Ͱ͢
  6. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ جຊతͳߟ͑ํ • Ϣʔβʔ͸εϚʔτεϐʔΧʔ΁ʮݺͼ͔͚ʯʮ࣭໰ʯΛߦͳ͏ • εϚʔτεϐʔΧʔ͸ͦΕʹԠͨ͡ʮ౴͑ʯΛฦ͢ • ݺͼ͔͚࣌ͷݴ༿͔ΒʮҙਤʯΛͲΕ͚ͩर͑Δ͔͕ΧΪ •

    Intent (ର࿩ҙਤ) • ʮͲ͏͍͏ҙਤΛ࣋ͬͨݺͼ͔͚͔ʯͱ͍͏ɺ
 ର࿩ͷछྨΛද͢΋ͷɻ
 • Slot (ύϥϝʔλ) • ݺͼ͔͚ͷதͷʮ೔෇ʯ΍ʮ਺ྔʯͱ͍ͬͨɺ
 มԽ͢Δ৔ॴΛද͢΋ͷɻ
  7. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ ఱؾ༧ใͷ৔߹ • ʮ10݄17೔ʯ͕೔࣌Λද͢ Slot • ʮ౦ژʯ͕৔ॴΛද͢ Slot •

    ʮఱؾΛڭ͑ͯʯ͕ձ࿩ͷྲྀΕΛܾΊΔ Intent Ϣʔβʔ 10݄17೔ͷ౦ژͷఱؾΛڭ͑ͯɻ ໌೔ͷ౦ژͷఱؾ͸ಶΓͷ༧ใͰ͢ɻ εϚʔτ
 εϐʔΧʔ
  8. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ ఱؾ༧ใͷ৔߹ • ʮ10݄17೔ʯ͕೔࣌Λද͢ Slot • ʮ౦ژʯ͕৔ॴΛද͢ Slot •

    ʮ࠷ߴؾԹΛڭ͑ͯʯ͕ձ࿩ͷྲྀΕΛܾΊΔ Intent Ϣʔβʔ 10݄17೔ͷ౦ژͷ࠷ߴؾԹΛڭ͑ͯɻ ໌೔ͷ౦ژͷ༧૝࠷ߴؾԹ͸20℃Ͱ͢ɻ εϚʔτ
 εϐʔΧʔ
  9. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ ఱؾ༧ใͷ৔߹ • ʮࠓ೔ʯ͕೔࣌Λද͢ Slot • ʮఱؾΛڭ͑ͯʯ͕ձ࿩ͷྲྀΕΛܾΊΔ Intent Ϣʔβʔ

    ࠓ೔ͷఱؾΛڭ͑ͯɻ
 (ݱࡏҐஔ͸ࡳຈͰొ࿥ࡁΈ) ࠓ೔ͷࡳຈͷఱؾ͸੖ΕͰ͢ɻ εϚʔτ
 εϐʔΧʔ
  10. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ Ͳ͏͍͏ड͚౴͑ʹ͢Δ͔ • Ϣʔβʔͷ஌Γ͍ͨ͜ͱʹର͠ɺձ࿩ͷྲྀΕΛߟ͑Δɻ • ձ࿩ͷྲྀΕͷத͔Β Intent (ҙਤ) Λݟ͚ͭΔɻ

    • Intent ͝ͱʹɺ۩ମతͳฦ౴ͷϓϩάϥϜΛॻ͍͍ͯ͘ɻ ࠓ೔ͷఱؾ͸? ࡳຈͷࠓ೔ͷఱؾ͸ɺ
 ͘΋Γ ͷͪ ੖Ε Ͱ͢ɻ
  11. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ ը໘෇͖σόΠε ը໘දࣔͷ࢓૊Έ ɹɹɹɹɹɹɹAmazon Echo Show Echo Show 5

    Echo Spot APL ɹɹɹɹɹɹɹGoogle Google Nest Hub Interactive Canvas
 (Web) ɹɹɹɹɹɹɹLINE Clova Desk ඇެ։
  12. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ mounted: async function () { // Callback Ͱ

    ΧʔυҠಈͷॲཧΛ࣮૷ window.interactiveCanvas.ready({ onUpdate: async data => { let cardId = '' let cardNumber = -1 if ('cardId' in data) { cardId = data.cardId cardNumber = this.list.findIndex(element => { return element.id === cardId }) } else if ('cardNumber' in data) { cardNumber = data.cardNumber - 1 const card = this.list[cardNumber] cardId = card.id } else { // ߋ৽ෆཁͳͷͰऴྃ return } await axios.put( `https://api.trello.com/1/cards/${cardId}?idList=${this.finishedListId}&key=${this.apiKey} &token=${this.apiToken}&pos=bottom` ) this.list.splice(cardNumber, 1) }, onTtsMark: markName => {} })
  13. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ mounted: async function () { // Callback Ͱ

    ΧʔυҠಈͷॲཧΛ࣮૷ window.interactiveCanvas.ready({ onUpdate: async data => { let cardId = '' let cardNumber = -1 if ('cardId' in data) { cardId = data.cardId cardNumber = this.list.findIndex(element => { return element.id === cardId }) } else if ('cardNumber' in data) { cardNumber = data.cardNumber - 1 const card = this.list[cardNumber] cardId = card.id } else { // ߋ৽ෆཁͳͷͰऴྃ return } await axios.put( `https://api.trello.com/1/cards/${cardId}?idList=${this.finishedListId}&key=${this.apiKey} &token=${this.apiToken}&pos=bottom` ) this.list.splice(cardNumber, 1) }, onTtsMark: markName => {} }) εϚʔτεϐʔΧΒͷ
 Πϕϯτड͚औΓ λοϓͷ৔߹ ੠ͷ৔߹ λοϓ͞ΕͨΧʔυΛ
 ׬ྃࡁΈϦετ΁Ҡಈ Ϧετ͔ΒΞΠςϜ࡟আ
  14. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ const response = await axios.get( `https://api.trello.com/1/lists/${this.listId}/cards?fields=all&key=${this.apiKey}&token=$ {this.apiToken}` )

    this.list = response.data }, methods: { finish: function (id) { window.interactiveCanvas.sendTextQuery(`finishedTask-${id}`) } }
  15. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ const response = await axios.get( `https://api.trello.com/1/lists/${this.listId}/cards?fields=all&key=${this.apiKey}&token=$ {this.apiToken}` )

    this.list = response.data }, methods: { finish: function (id) { window.interactiveCanvas.sendTextQuery(`finishedTask-${id}`) } } TrelloͷಛఆͷList͔Β
 CardҰཡΛऔಘ Card ͕λοϓ͞ΕͨΒ Intent ૹ৴
  16. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ 'use strict'; const axios = require('axios'); const {

    dialogflow, HtmlResponse } = require('actions-on-google'); const app = dialogflow({ debug: false }); const tasksUrl = 'https://show-today-tasks.netlify.com' const currentListId = process.env.CURRENT_LIST_ID const finishedListId = process.env.FINISHED_LIST_ID const apiKey = process.env.API_KEY const apiToken = process.env.API_TOKEN // ىಈ࣌Intent app.intent('welcome', (conv) => { conv.ask('ࠓ೔ͷλεΫҰཡͰ͢ɻ֬ೝ͠·͠ΐ͏ɻ'); conv.ask(new HtmlResponse({ url: `${tasksUrl}/?listId=${currentListId}&apiKey=${apiKey} &apiToken=${apiToken}`, suppress: true }));
  17. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ 'use strict'; const axios = require('axios'); const {

    dialogflow, HtmlResponse } = require('actions-on-google'); const app = dialogflow({ debug: false }); const tasksUrl = 'https://show-today-tasks.netlify.com' const currentListId = process.env.CURRENT_LIST_ID const finishedListId = process.env.FINISHED_LIST_ID const apiKey = process.env.API_KEY const apiToken = process.env.API_TOKEN // ىಈ࣌Intent app.intent('welcome', (conv) => { conv.ask('ࠓ೔ͷλεΫҰཡͰ͢ɻ֬ೝ͠·͠ΐ͏ɻ'); conv.ask(new HtmlResponse({ url: `${tasksUrl}/?listId=${currentListId}&apiKey=${apiKey} &apiToken=${apiToken}`, suppress: true })); දࣔίϯςϯπ͕
 ը໘ʹग़ΔΑ͏ʹࢦఆ
  18. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ app.intent('finishedTaskByVoice', async (conv, { cardNumber }) => {

    // ੠Ͱ׬ྃʹ͢Δ conv.ask('ΧʔυΛ׬ྃʹ͠·ͨ͠ɻ') conv.ask( new HtmlResponse({ url: `${tasksUrl}/?listId=${currentListId}&finishedListId=$ {finishedListId}&apiKey=${apiKey}&apiToken=${apiToken}`, suppress: true, data: { cardNumber: cardNumber } }) ) })
  19. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ app.intent('finishedTaskByVoice', async (conv, { cardNumber }) => {

    // ੠Ͱ׬ྃʹ͢Δ conv.ask('ΧʔυΛ׬ྃʹ͠·ͨ͠ɻ') conv.ask( new HtmlResponse({ url: `${tasksUrl}/?listId=${currentListId}&finishedListId=$ {finishedListId}&apiKey=${apiKey}&apiToken=${apiToken}`, suppress: true, data: { cardNumber: cardNumber } }) ) }) ੠Ͱࢦఆ͞Εͨ ΧʔυͷදࣔॱΛऔಘ ίϯςϯπଆʹ
 ΧʔυͷදࣔॱΛૹ৴
  20. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ app.intent('finishedTask', async (conv, { cardId }) => {

    // λοϓͰ׬ྃʹ͢Δ conv.ask('ΧʔυΛ׬ྃʹ͠·ͨ͠ɻ') conv.ask( new HtmlResponse({ url: `${tasksUrl}/?listId=${currentListId}&finishedListId=$ {finishedListId}&apiKey=${apiKey}&apiToken=${apiToken}`, suppress: true, data: { cardId: cardId } }) ) })
  21. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ app.intent('finishedTask', async (conv, { cardId }) => {

    // λοϓͰ׬ྃʹ͢Δ conv.ask('ΧʔυΛ׬ྃʹ͠·ͨ͠ɻ') conv.ask( new HtmlResponse({ url: `${tasksUrl}/?listId=${currentListId}&finishedListId=$ {finishedListId}&apiKey=${apiKey}&apiToken=${apiToken}`, suppress: true, data: { cardId: cardId } }) ) }) λοϓ͞ΕͨΧʔυͷ
 IDΛऔಘ ίϯςϯπଆʹ
 CardId Λૹ৴
  22. !UBDDL ΏΔ8FCษڧձ!ࡳຈΏΔ8FCࡳຈ ͦΕͧΕͷಛ௃ • Echo • γϦʔζల։͕๛෋ɾຊؾग़͢ͱʮεϚʔτϗʔϜʯԽՄೳ • ը໘෇͖ͷ “Echo

    Show 5” ͕͓खࠒ (¥9,980) • Google Home • Android ΋ؚΊͨڧΈ • ը໘෇͖ͷ “Google Nest Hub” Λ࣠ʹࠓޙల։ͷํ޲ • LINE Clova • LINE ΍ LINE Bot ͱͷ࿈ܞ͕ڧ͍(ϝοηʔδ࢖͏ͳΒ͜Ε) • ࠓޙͷల։͸ɾɾɾΧʔφϏ?