【AAJUG大阪】VoiceConJapan2020直前企画!Alexaスキル開発ごった煮トーク でお話したSkill ConnectionsのLT資料です。某所でLTしたものと同じですが、少しブラッシュアップしました。サンプルコードあります。
https://aajug.connpass.com/event/161436/
Skill ConnectionsやってみたAAJUG Osaka 2020/2/9
View Slide
About Myself1
Kuniaki Shimizu (@kun432)- シナジーマーケティング株式会社- インフラエンジニア- Twitter/Facebook/Github/Hatena/Alexa- ポートフォリオ: https://kun432.github.io/- AWS認定Alexaスキルビルダー- Voiceflow Global Ambassador- Voiceflow Growth Award 20193Hello!
My Skills & Actions4- Alexa (JP): 12- Google: 1 - Clova: 1#スキル開発100チャレンジ- Alexa (US): 1
● 本資料内における意見・発言等は個人の見解であり、所属する組織・団体の見解を代表するものでは、ありません● 某所でLTしたものと基本的に同じ内容ですので、あしからず● 今日はVoiceflowの話はしません● ちょっとポエム風味・・・5Disclaimer
Skill Connectionsやってみた2
某所でのアンケートの結果7
8
めっちゃマイナー9
Skill Connectionsおさらい10● 単純にいうと、スキル間連携● スキルAから、スキルBの機能を呼び出す● スキルBの処理が終わるとスキルAに戻る● 用語○ リクエスタ(上で言うA)■ 他のスキルの機能を呼び出す○ プロバイダ(上で言うB)■ 他のスキルへ機能を提供する
11連携開始連携中連携後印刷インテントトリガーディレクティブ送信(StartConnection)印刷インテントハンドラレスポンスハンドラ(SessionResumedRequest)処理を続ける● リクエスタはconnectionエンドポイントに要求を投げる● プロバイダはAlexaが決めて、要求を受け渡す● プロバイダの実行結果をAlexaから受け取って処理を継続Skill Connectionsの仕組みセッション切断ABA処理結果
今回はプリンタスキルと連携するリクエスタやってみた※プロバイダだと両方作らないといけない※プロバイダ側は特別な審査が必要らしい12
13
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();
15const 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ん?なんかこれ見たことない?
17課金処理前課金処理中課金処理後購入インテントトリガーディレクティブ送信(type=Connections.SendRequest)購入インテントハンドラレスポンスハンドラ(type=Connections.Response)getResponseで会話フローをつなげる商品・料金説明、同意確認認証コード確認課金処理● スキル側でやるのは購入処理の手前と後だけ● 購入処理も一連のやり取りもAlexa⇔ユーザでやってくれるスキル内課金のやりとりセッション切断
18MonetizationServiceClient● 購入を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.getResponse();} else {return handlerInput.responseBuilder.addDirective({type: 'Connections.SendRequest',name: 'Buy',payload: { InSkillProduct:{ productId: ENGLISH_PACK_ID } },token: 'correlationToken'}).getResponse();}});
20MonetizationServiceClient● 購入処理結果を受けるハンドラ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: // その他のERRORspeechText = `うまく行かなかったようです。${repromptText}`;break;} ・・・続く・・・
21ISPも内部的にはConnections※そしてAmazon Payも同じ
Skill Connections: Pros22● ISPやってれば実装そんなに難しくない。○ プロバイダ側への受け渡し部分とプロバイダ側処理は勝手にやってくれる○ リクエスタは所定のフォーマットで投げて、結果に応じて続けるだけ。● 自分で実装しなくて良いのはやっぱり楽■ ハードウェア連携は特に■ プロバイダが増えれば機能を増やせる■ プロバイダもAlexaがよしなに選んでくれる
Skill Connections: Cons①23● ISPと同じで会話の流れがつかみにくい○ リクエスタとプロバイダが両方しゃべる。○ 受け渡し時のAlexa側の発話もある。○ テスト用のタスク(AMAZON.TestStatusCode)を使って確認○ プロバイダ側独自のステータスコードも。○ 実際にテストしながら発話の自然さをチェック。● 連携時は、セッション切れるので要対応○ Persistent Attribute良くも悪くもISPと同じ
いろいろしゃべる24
いろいろしゃべる25リクエスタ側プロバイダ側ASK側
Skill Connections: Cons②26少なすぎる・・・● 現在対応しているタスク○ 印刷系■ AMAZON.PrintImage■ AMAZON.PrintPDF■ AMAZON.PrintWebPage○ 予約系■ AMAZON.ScheduleTaxiReservation■ AMAZON.ScheduleFoodEstablishmentReservation
Skill Connections対応スキル27
Skill Connections対応スキル28
Skill Connections対応スキル29
30その他つまづいたところ● 利用開始までのプロセスが長い(プリンタの場合)○ プリンタのWiFi接続設定○ プリンタ側のアカウント登録○ アカウントリンク○ スキル有効化までのハードルが高い、ここでくじける人が一定数いるはず● 情報がない・・・○ DevSummit以来、特に話がない○ ドキュメントが少なすぎるし、サンプルも微妙○ Githubのサンプルコード欲しい
31モチベーションが・・・
32なんで今日この話?
33https://developer.amazon.com/en-US/blogs/alexa/alexa-skills-kit/2019/12/Create-Custom-Connected-Skill-Experiences-with-Tasks-and-Direct-Skill-Connections
34Custom Tasks & Direct Connections● Custom Tasks○ プロバイダのタスクを自由に定義できるようになる?○ “ask api search-task/get-task” でタスクを探して使う● Direct Connections○ Skill Connectionsでは、Amazon定義のプロバイダが自動的に選択される○ Direct Connectionsでは、リクエスタがプロバイダを選択可能に?プロバイダの数・種類の増加に期待さらにプロバイダ開発も
35そして
36Alexa Conversationshttps://robotstart.info/2019/06/06/alexa-cross-skill-conversations.html
37Alexa Conversationshttps://robotstart.info/2019/06/06/alexa-cross-skill-conversations.html
38Alexa Conversations● Alexa側でユーザの要望に合わせたスキルをチョイスしてくれる○ 呼び出し名がいらない(canFulfillIntentと同じ)● ユーザの要望に関連するスキルを連携して呼び出す○ ユーザの要望を先回りする
39スキルが呼び出すのはユーザだけではなくAlexaや他のスキルから呼び出される
まとめ3
41まとめ● Skill Connectionsの実装はISPと似てる。ISPやってれば難しくない● 現状は限定的なユースケースのみ● 今後、Custom Tasks & Direct Connectionsが出てきたら可能性が広がるかも● AlexaConversation含めて、ユーザ「以外」から起動される・他のスキルから連携されやすい、単機能をきちんとこなすスキル企画・開発へ?スキル開発の別の形になるかも?ど
42知らんけど
43今日のサンプルhttps://github.com/kun432/alexa-skill-connections-sample
お知らせ4
452/29 技術書典8 (Day1あ09)● 豪華執筆陣!CEOの前書き!● 165P、1000円(予定)
463/21 Voice Con Japan 2020
Thanks!Any questions?