Skill Connections やってみた / Introduction to Alexa Skill Connections

Skill Connections やってみた / Introduction to Alexa Skill Connections

【AAJUG大阪】VoiceConJapan2020直前企画!Alexaスキル開発ごった煮トーク でお話したSkill ConnectionsのLT資料です。某所でLTしたものと同じですが、少しブラッシュアップしました。サンプルコードあります。

https://aajug.connpass.com/event/161436/

5caee8d2ccdb42a940545c47c6c01373?s=128

Kuniaki Shimizu

February 09, 2020
Tweet

Transcript

  1. Skill Connectionsやってみた AAJUG Osaka 2020/2/9

  2. About Myself 1

  3. Kuniaki Shimizu (@kun432) - シナジーマーケティング株式会社 - インフラエンジニア - Twitter/Facebook/Github/Hatena/Alexa -

    ポートフォリオ: https:/ /kun432.github.io/ - AWS認定Alexaスキルビルダー - Voiceflow Global Ambassador - Voiceflow Growth Award 2019 3 Hello!
  4. My Skills & Actions 4 - Alexa (JP): 12 -

    Google: 1 - Clova: 1 #スキル開発100チャレンジ - Alexa (US): 1
  5. • 本資料内における意見・発言等は個人の 見解であり、所属する組織・団体の見解 を代表するものでは、ありません • 某所でLTしたものと基本的に同じ内容 ですので、あしからず • 今日はVoiceflowの話はしません •

    ちょっとポエム風味・・・ 5 Disclaimer
  6. Skill Connections やってみた 2

  7. 某所でのアンケートの結果 7

  8. 8

  9. めっちゃマイナー 9

  10. Skill Connectionsおさらい 10 • 単純にいうと、スキル間連携 • スキルAから、スキルBの機能を呼び出す • スキルBの処理が終わるとスキルAに戻る •

    用語 ◦ リクエスタ(上で言うA) ▪ 他のスキルの機能を呼び出す ◦ プロバイダ(上で言うB) ▪ 他のスキルへ機能を提供する
  11. 11 連携 開始 連携中 連携後 印刷インテントトリガー ディレクティブ送信 (StartConnection) 印刷インテントハンドラ レスポンスハンドラ

    (SessionResumedRequest) 処理を続ける • リクエスタはconnectionエンドポイントに要求を投げる • プロバイダはAlexaが決めて、要求を受け渡す • プロバイダの実行結果をAlexaから受け取って処理を継続 Skill Connectionsの仕組み セッション切断 A B A 処理結果
  12. 今回はプリンタスキルと連携する リクエスタやってみた ※プロバイダだと両方作らないといけない ※プロバイダ側は特別な審査が必要らしい 12

  13. 13

  14. 14 リクエスタの実装 const continueIntentHandler = { ・・・ handle(handlerInput) { const

    speakOutput = 'それではプリンタスキルを呼び出して印刷します。'; return handlerInput.responseBuilder .speak(speakOutput) .addDirective({ 'type': 'Connections.StartConnection', 'uri': 'connection://AMAZON.PrintPDF/1', 'input': { '@type': 'PrintPDFRequest', '@version': '1', 'title': 'サンプルのPDF', 'description': 'スキルコネクションズのサンプルのPDFです。', 'url': 'https://******.s3-ap-northeast-1.amazonaws.com/sample1.pdf' }, 'token': 'none' }) .getResponse();
  15. 15 const ConnectionsResponseHandler = { canHandle(handlerInput) { const request =

    handlerInput.requestEnvelope.request; return request.type === 'SessionResumedRequest'; }, handle(handlerInput) { const statusCode = handlerInput.requestEnvelope.request.cause.status.code; const statusMessage = handlerInput.requestEnvelope.request.cause.status.message; console.log(`SessionResumedRequest: code: ${statusCode}, msg: ${statusMessage}`; let speechText;  switch (statusCode) { case “200”: // 購入した speechText = "印刷が終わりました。ご利用ありがとうございました。"; break; case “204”: // ユーザキャンセル speechText = "またご利用くださいね。"; Break; ・・・ Default: // その他エラー speechText = "ごめんなさい、うまく行かなかったようです。"; break;  } return handlerInput.responseBuilder.speak(speechText).getResponse(); }, };
  16. 16 ん?なんかこれ 見たことない?

  17. 17 課金 処理前 課金 処理中 課金 処理後 購入インテントトリガー ディレクティブ送信 (type=Connections.SendRequest)

    購入インテントハンドラ レスポンスハンドラ (type=Connections.Response) getResponseで会話フロー をつなげる 商品・料金説明、 同意確認 認証コード確認 課金処理 • スキル側でやるのは購入処理の手前と後だけ • 購入処理も一連のやり取りもAlexa⇔ユーザでやってくれる スキル内課金のやりとり セッション切断
  18. 18 MonetizationServiceClient • 購入をMonetizationServiceClientにリクエスト const BuyEnglishPackIntentHandler = { ・・・ handle(handlerInput)

    { const locale = handlerInput.requestEnvelope.request.locale; const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient(); return ms.getInSkillProduct(locale, ENGLISH_PACK_ID).then(function (product) { if (product.entitled === "ENTITLED") { const speechText = `既に${product.name} を購入しています。続けますか?`; const repromptText = `続けますか?`; return handlerInput.responseBuilder .speak(speechText) .reprompt(repromptText) .getResponse(); } else { return handlerInput.responseBuilder .addDirective({ type: 'Connections.SendRequest', name: 'Buy', payload: { InSkillProduct: { productId: ENGLISH_PACK_ID } }, token: 'correlationToken' }) .getResponse(); } }); } };
  19. 19 .getResponse(); } else { return handlerInput.responseBuilder .addDirective({ type: 'Connections.SendRequest',

    name: 'Buy', payload: { InSkillProduct: { productId: ENGLISH_PACK_ID } }, token: 'correlationToken' }) .getResponse(); } });
  20. 20 MonetizationServiceClient • 購入処理結果を受けるハンドラ const BuyResponseHandler = { canHandle(handlerInput) {

    return handlerInput.requestEnvelope.request.type === 'Connections.Response' && ・・・ }, handle(handlerInput) { const locale = handlerInput.requestEnvelope.request.locale; const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient(); return ms.getInSkillProduct(locale, ENGLISH_PACK_ID).then(function (product) { if (handlerInput.requestEnvelope.request.status.code === '200') { let speechText = product.summary; const repromptText = '続けますか?'; switch (handlerInput.requestEnvelope.request.payload.purchaseResult) { case 'ACCEPTED': // 購入した speechText = product.summary + repromptText; break; case 'DECLINED': // 購入しなかった speechText = repromptText; break; case 'ALREADY_PURCHASED': // 既に購入済 speechText = product.summary + repromptText; break; Default: // その他のERROR speechText = `うまく行かなかったようです。${repromptText}`; break; } ・・・続く・・・
  21. 21 ISPも内部的にはConnections ※そしてAmazon Payも同じ

  22. Skill Connections: Pros 22 • ISPやってれば実装そんなに難しくない。 ◦ プロバイダ側への受け渡し部分とプロバイダ側 処理は勝手にやってくれる ◦

    リクエスタは所定のフォーマットで投げて、 結果に応じて続けるだけ。 • 自分で実装しなくて良いのはやっぱり楽 ▪ ハードウェア連携は特に ▪ プロバイダが増えれば機能を増やせる ▪ プロバイダもAlexaがよしなに選んでくれる
  23. Skill Connections: Cons① 23 • ISPと同じで会話の流れがつかみにくい ◦ リクエスタとプロバイダが両方しゃべる。 ◦ 受け渡し時のAlexa側の発話もある。

    ◦ テスト用のタスク(AMAZON.TestStatusCode) を使って確認 ◦ プロバイダ側独自のステータスコードも。 ◦ 実際にテストしながら発話の自然さをチェック。 • 連携時は、セッション切れるので要対応 ◦ Persistent Attribute 良くも悪くもISPと同じ
  24. いろいろしゃべる 24

  25. いろいろしゃべる 25 リクエスタ側 プロバイダ側 ASK側

  26. Skill Connections: Cons② 26 少なすぎる・・・ • 現在対応しているタスク ◦ 印刷系 ▪

    AMAZON.PrintImage ▪ AMAZON.PrintPDF ▪ AMAZON.PrintWebPage ◦ 予約系 ▪ AMAZON.ScheduleTaxiReservation ▪ AMAZON.ScheduleFoodEstablishmentRes ervation
  27. Skill Connections対応スキル 27

  28. Skill Connections対応スキル 28

  29. Skill Connections対応スキル 29

  30. 30 その他つまづいたところ • 利用開始までのプロセスが長い(プリンタの場合) ◦ プリンタのWiFi接続設定 ◦ プリンタ側のアカウント登録 ◦ アカウントリンク

    ◦ スキル有効化までのハードルが高い、ここでくじける人 が一定数いるはず • 情報がない・・・ ◦ DevSummit以来、特に話がない ◦ ドキュメントが少なすぎるし、サンプルも微妙 ◦ Githubのサンプルコード欲しい
  31. 31 モチベーションが・・・

  32. 32 なんで今日この話?

  33. 33 https://developer.amazon.com/en-US/blogs/alexa/alexa-skills-kit/2019/12/Create-Custom-Connected-Skill-Experiences-with-Tasks-and-Direct-Skill-Connections

  34. 34 Custom Tasks & Direct Connections • Custom Tasks ◦

    プロバイダのタスクを自由に定義できるようになる? ◦ “ask api search-task/get-task” でタスクを探して使う • Direct Connections ◦ Skill Connectionsでは、Amazon定義のプロバイダが 自動的に選択される ◦ Direct Connectionsでは、リクエスタがプロバイダを 選択可能に? プロバイダの数・種類の増加に期待 さらにプロバイダ開発も
  35. 35 そして

  36. 36 Alexa Conversations https://robotstart.info/2019/06/06/alexa-cross-skill-conversations.html

  37. 37 Alexa Conversations https://robotstart.info/2019/06/06/alexa-cross-skill-conversations.html

  38. 38 Alexa Conversations • Alexa側でユーザの要望に合わせたスキルを チョイスしてくれる ◦ 呼び出し名がいらない(canFulfillIntentと同じ) • ユーザの要望に関連するスキルを連携して呼び出す

    ◦ ユーザの要望を先回りする
  39. 39 スキルが呼び出すのはユーザだけではなく Alexaや他のスキルから呼び出される

  40. まとめ 3

  41. 41 まとめ • Skill Connectionsの実装はISPと似てる。ISP やってれば難しくない • 現状は限定的なユースケースのみ • 今後、Custom

    Tasks & Direct Connectionsが出て きたら可能性が広がるかも • AlexaConversation含めて、ユーザ「以外」から起動され る・他のスキルから連携されやすい、単機能を きちんとこなすスキル企画・開発へ? スキル開発の別の形になるかも?ど
  42. 42 知らんけど

  43. 43 今日のサンプル https://github.com/kun432/alexa-skill-connections-sample

  44. お知らせ 4

  45. 45 2/29 技術書典8 (Day1あ09) • 豪華執筆陣!CEOの前書き! • 165P、1000円(予定)

  46. 46 3/21 Voice Con Japan 2020

  47. Thanks! Any questions?