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

Alexaの通知について考える / Retaining users with Alexa's ...

Alexaの通知について考える / Retaining users with Alexa's Notification

【大阪】スマートスピーカーミーティング 2019/07/25 のLTの資料です。AlexaのリマインダーAPIを使ってユーザとの関係性を高めようという話をしてきました。もちろんVocieflowの場合もありますよ!

https://osaka-driven-dev.connpass.com/event/134869/

Kuniaki Shimizu

July 25, 2019
Tweet

More Decks by Kuniaki Shimizu

Other Decks in Technology

Transcript

  1. My Skills & Actions 5 - Alexa (JP): 11→12(予定) -

    Google: 1 - Clova: 1 #スキル開発100チャレンジ - Alexa (US): 1
  2. こんな経験ないですか? 9 • 利用者側 ◦ 有効にしたスキルの呼び出し名を間違える・ 思い出せない ◦ スキル一覧を見て、有効にしたことを覚えて いないスキルがある

    • 開発者側 ◦ スキルの利用者が増えない ◦ スキルが継続的に利用されない、一定期間経つ と利用されなくなる
  3. スキルが利用されない理由 10 • スキル名を覚えれない ◦ VUIではそもそも覚えることが難しい • 使うことを忘れる ◦ トリガーは常にユーザ

    • 視覚的な補助がない ◦ 音声で簡単に有効化できてしまう ◦ ホーム画面のようなものが存在しない ◦ メラビアンの法則(55%は視覚から) • 他の接点を作るのが面倒(メールとか) ユーザとの日常的な接点が非常に少ない
  4. Alexaの通知機能 • 以下の2種類 13 リマインダーAPI プロアクティブイベントAPI タイミングの決定 ユーザがスキル内で選択 外部から自由なタイミング で通知可能

    選択可能な 通知タイミング • 相対指定(現在からn秒後) • 絶対指定 ◦ ◦年◦月◦日◦時◦分◦秒 ◦ 繰り返し(毎日・毎週) 通知内容の柔軟性 ある程度柔軟に設定可能 ※ただしルールはいろいろある 決められたフォーマットから選択 ※フォーマットが合うか次第 実装範囲 スキルのみでOK ※外部から更新・削除は可能 イベントを送るエンドポイントが必要 (Lambdaでないとだめっぽい?) 実装方法 ask-sdk v2のServiceClientFactory 経由 or リマインダーAPI プロアクティブイベントAPI アクセス許可 リマインダ権限+ユーザ確認 通知権限(SMAPIで有効化)
  5. Alexaの通知機能 • 以下の2種類 14 リマインダーAPI プロアクティブイベントAPI タイミングの決定 ユーザがスキル内で選択 外部から自由なタイミング で通知可能

    選択可能な 通知タイミング • 相対指定(現在からn秒後) • 絶対指定 ◦ ◦年◦月◦日◦時◦分◦秒 ◦ 繰り返し(毎日・毎週) 通知内容の柔軟性 ある程度柔軟に設定可能 ※ただしルールはいろいろある 決められたフォーマットから選択 ※フォーマットが合うか次第 実装範囲 スキルのみでOK ※外部から更新・削除は可能 イベントを送るエンドポイントが必要 (Lambdaでないとだめっぽい?) 実装方法 ask-sdk v2のServiceClientFactory 経由 or リマインダーAPI プロアクティブイベントAPI アクセス許可 リマインダ権限+ユーザ確認 通知権限(SMAPIで有効化) 今回はこっち
  6. Alexaの通知機能 • 以下の2種類 15 リマインダーAPI プロアクティブイベントAPI タイミングの決定 ユーザがスキル内で選択 外部から自由なタイミング で通知可能

    選択可能な 通知タイミング • 相対指定(現在からn秒後) • 絶対指定 ◦ ◦年◦月◦日◦時◦分◦秒 ◦ 繰り返し(毎日・毎週) 通知内容の柔軟性 ある程度柔軟に設定可能 ※ただしルールはいろいろある 決められたフォーマットから選択 ※フォーマットが合うか次第 実装範囲 スキルのみでOK ※外部から更新・削除は可能 イベントを送るエンドポイントが必要 (Lambdaでないとだめっぽい?) 実装方法 ask-sdk v2のServiceClientFactory 経由 or リマインダーAPI プロアクティブイベントAPI アクセス許可 リマインダ権限+ユーザ確認 通知権限(SMAPIで有効化) 今回はこっち 今回はこっち ※相対指定の事例は多いが  こっちは少ない これを使う
  7. Alexaの通知機能 • 以下の2種類 19 リマインダーAPI プロアクティブイベントAPI タイミングの決定 ユーザがスキル内で選択 外部から自由なタイミング で通知可能

    選択可能な 通知タイミング • 相対指定(現在からn秒後) • 絶対指定 ◦ ◦年◦月◦日◦時◦分◦秒 ◦ 繰り返し(毎日・毎週) 通知内容の柔軟性 ある程度柔軟に設定可能 ※ただしルールはいろいろある 決められたフォーマットから選択 ※フォーマットが合うか次第 実装範囲 スキルのみでOK ※外部から更新・削除は可能 イベントを送るエンドポイントが必要 (Lambdaでないとだめっぽい?) 実装方法 ask-sdk v2のServiceClientFactory 経由 or リマインダーAPI プロアクティブイベントAPI アクセス許可 リマインダ権限+ユーザ確認 通知権限(SMAPIで有効化) 再 掲
  8. ServiceClientFactoryを使う 22 exports.handler = Alexa.SkillBuilders.custom() .addRequestHandlers( ・・・) .addErrorHandlers( ErrorHandler) .withApiClient(new

    Alexa.DefaultApiClient()) .lambda(); • ServiceClientFactory ◦ Alexaの各種APIサービスへアクセスするための ask-sdk-v2のサービスクライアント ◦ リスト、デバイスアドレス、リマインダー、プログレッシブ応 答、スキル内課金などなど ◦ 上記API叩くのに必要な処理をよしなにやってくれる • custom()の場合は要初期化、standard()の場合は初期化不要 以前の再 掲
  9. 権限と確認① 23 const ReminderIntentHandler = {  ・・・ }, async handle(handlerInput)

    { const hhmm = handlerInput.requestEnvelope.request.intent.slots.hour.value; let hh, mm = hhmm.split(":"); const consentToken = handlerInput.requestEnvelope.context.System.apiAccessToken; switch (handlerInput.requestEnvelope.request.intent.confirmationStatus) { case 'CONFIRMED': break; case 'DENIED': return handlerInput.responseBuilder .speak(`わかりました。リマインドはしないでおきますね。`) .getResponse(); case 'NONE': default: console.log('NONE....'); return handlerInput.responseBuilder .addDelegateDirective() .getResponse(); } ・・・ スキルのアクセス権 とは別に、明示的な 確認を取る。 この例ではスロット の確認を使っている。
  10. 権限と確認② 24 if (!consentToken) { const speechText = 'ごめんなさい、このスキルでは、リマインダーへのアクセス権が’ +

    ‘必要になります。Alexaアプリのアクティビティーをご確認ください。'; return handlerInput.responseBuilder .speak(speechText) .withAskForPermissionsConsentCard(PERMISSIONS) .getResponse(); } スキルのアクセス権。カードを 表示して、ユーザに アクセス権許可を促す handlerInput.requestEnvelope.context.System.apiAccessTo kenをAlexaの各種アクセス権許可の判断にしている例をよくみ るけど、単にAPIアクセストークンだから毎回飛んでくるし実際に はアクセス権許可の判断にはならないと思うんだよな・・・ 最低限必要だとしても、APIレスポンスの結果からの判断は必要 だし、もっとかんたんに権限チェックできる方法はないものか ・・・・
  11. リマインダー設定(基本の流れ) 25 ・・・ try { const client = handlerInput.serviceClientFactory.getReminderManagementServiceClient(); 〜〜〜リマインダーリクエストオブジェクトを作るための前処理〜〜〜

    const reminderRequest = {      〜〜〜リマインダーリクエストオブジェクトの組み立て〜〜〜 }; const reminderResponse = await client.createReminder(reminderRequest); } catch (error) { if (error.name !== 'ServiceError') { console.log(`error: ${error.stack}`); const response = responseBuilder.speak(`ごめんなさい、エラーが発生しました。`).getResponse(); return response; } throw error; } return handlerInput.responseBuilder .speak(`毎日 ${hhmm} にリマインドを設定しました。`) .getResponse(); }, };
  12. リマインダーオブジェクトの組み立て 26 const remindTime = moment({ hours: hh, minutes: mm}).add(1,

    'minutes'); const timeFormat = 'YYYY-MM-DDTHH:mm:ss.SSS'; console.log('REQUEST_TIME: ' + moment().format(timeFormat)); console.log('REMIND_TIME: ' + remindTime.format(timeFormat)); const reminderRequest = { requestTime: moment().format(timeFormat), trigger: { type: 'SCHEDULED_ABSOLUTE', scheduledTime: remindTime.format(timeFormat), timeZoneId: 'Asia/Tokyo', recurrence: { freq: 'DAILY' }, }, alertInfo: { spokenInfo: { content: [{ locale: "ja-JP", text: "リマインダーテストの時間" }] } }, pushNotification: { status: 'ENABLED' } } SCHEDULED_ABSOLUTE で絶対指定 未来であればOK(繰り返し の場合は意味はない) タイムゾーン指定すれば 時間処理側では意識しなく て良い recurrenceで繰り返し “DAILY” or ”Weekly” “Weekly”は曜日も指定 リマインドされる文字列 ※色々要件あり
  13. リマインダーのUXについて(成功例①) 29 • アクセス権をチェックして表現を変える アレクサ、「〇〇〇」をひらいて
 「〇〇〇」へようこそ。このスキルでは・・・ 
 (リマインダーチェック) (アクセス権がない場合)
 あと、このスキルでは、次回に向けてリマインダーを設定できます。

    詳細はAlexaアプリをご確認ください。 
 (アクセス権がある場合)
 次回に向けてリマインダーを設定できます。毎日何時にセット 
 しますか?
 ReminderManagementServiceClient.getReminders()あた りを使うのがよい(と思われるが、良い実装求む・・・)
  14. まとめ • リマインダーでスキルの利用を促進 ◦ ユーザ・開発者の両方にメリット ◦ 画面付きなら告知効果高い • 注意点いろいろ ◦

    習慣的な利用が前提のスキルであること! ◦ きちんと確認を得る、その他文言等の制限 ◦ 相対指定は簡単、絶対指定少し面倒だけどニーズ高い、 ぜひトライ! • UXを損ねないように会話フローに留意 ◦ 一通りの会話後に権限ないよ?だとやる気なくなる ◦ 可能ならなるべく初期段階。必須 or オプションでも考慮 • Voiceflowでも(ちょっと制限あるかもだけど)できるよ! 42 積極的に使ってエンゲージメント高めていこう!