[Alexa] Login with Amazon との Account Linking で名前を呼びかける挨拶とかメールを送信するスキルを作ってみました

alexa-eyecatch

1 はじめに

Amazon Alexa(以下、Alexa)のスキルには、Account Linkingという機能があり、他サービスの機能を利用することができます。

参考
Amazon AlexaのAccount Linkingを使ってAmazon EchoからTwitterに書き込ませてみる
[Alexa] Account Linking を使用してスキルからFacebookに投稿してみました

Account Linkingは、OAuth2で利用可能ですが、今回は、 Login with Amazon (以下、LWA)とのリンクを試してみました。

下記の動画は、LWAからプロファイル(名前とメールアドレス)を取得して、名前を呼びかける挨拶とメール送信をしてみたものです。

今回は、このようなスキルの作成方法について紹介させて下さい。

2 LWAにおけるSecurity Profileの作成

LWAAccount Linkingするためには、そのEndpointとして、Security Profileを作成する必要があります。

Security Profileの作成要領は、以下のとおりです。

  • セキュリティプロファイルの作成
  • リダイレクトURLの設定

(1) セキュリティプロファイルの作成

Amazonの開発者コンソールから、「アプリ&サービス」> 「Amazonでログイン」とたどり、「Create a aNew Security Profile」を選択します。

001

名前、説明、ポリシーのURL等を入力して、Saveボタンを押します。

002

作成が完了したら、後ほど使用するので、Client ID及び、Client Secretをコピーしておきます。

003

(2) リダイレクトURLの設定

右端にある歯車アイコンをクリックして、Web Settingsを選択します。

004

Editボタンを押して、Allowed Return URLsにリダイレクトURLを設定します。

005

リダイレクトURLは、スキルの設定でAccount LinkingYesにすると、Redirect URLsに生成されますので、これをコピーします。URLは2つ生成されていますが、どちらが使用されるかは、Alexaが決めることなので両方とも設定しておく必要があります。

006 007

3 Account Linkingの設定

Account Linkingの設定は以下のとおりです。

  • Authorization URL 「https://www.amazon.com/ap/oa」 (LWA固定)
  • Client Id LWAの「Client ID」です。
  • Scope 「profile」 指定できるscopeについては、Customer Profileをご参照ください
  • Authorization Grant Type 「Auth Code Grant」
  • Access Token URI 「https://api.amazon.com/auth/o2/token」 (LWA固定)
  • Client Secret LWAの「Client Secret」です。
  • Client Authentication Scheme 「HTTP Basic (Recommended)」

008

4 ユーザーの誘導

Account Linkingでは、スキルが呼び出される際にアクセストークンが送られてきますが、まだ、ユーザーが許可をしていない場合、それは空となります。

このため、スキルでは、アクセストークンが空の場合に、ユーザーにリンクをしてもらうよう誘導するコードが必要です。

下記のコードは、session.user.accessTokenundefinedの時に、ユーザーを誘導するコードです。

let accessToken = this.event.session.user.accessToken;
if (accessToken == undefined) {
    this.emit(':tellWithLinkAccountCard','to start using this skill, please use the companion app to authenticate on Amazon');
    return;
}

5 ユーザによるアカウントリンク

Account Linkingを許可していない状態でスキルを使用した場合、先のコードにより、許可を促す発話と、Alexaアプリへのメッセージが表示されます。

009

ここで、ユーザーがLink Accountを選択すると、LWAへの認証と、プロフィールの利用を許可するページが表示されます。

010

ユーザーが許可すると、Alexaは必要なアクセストークを取得できるようになり、下記のメッセージが表示されます。

011

6 LWAからのプロフィール取得とメール送信

アクセストークンを使用して、ユーザーのプロフィールを取得し、挨拶とメール送信を行なっているコード(抜粋)は、下記のとおりです。

メールの送信は、Amazon SESを使用しています。

var request = require('request');
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});

//・・・省略・・・

const handlers = {
  'Unhandled': function () {
    this.emit('WelcomeIntent');
  },
  'WelcomeIntent': function () {
    // アクセストークンのコピー
    let accessToken = this.event.session.user.accessToken;
    if (accessToken == undefined) {
      // トークンが空の場合は、ユーザーに許可を促す
      this.emit(':tellWithLinkAccountCard','to start using this skill, please use the companion app to authenticate on Amazon');
      return;
    }
    // LWAからプロファイルを取得する
    var url = 'https://api.amazon.com/user/profile?access_token=' + accessToken;
    let self = this;
    request(url, function(error, response, body) {
      if (response.statusCode == 200) {
        // プロファイルから名前とメールアドレを取り出し、セッション情報で記憶する
        let name = JSON.parse(body).name;
        let email = JSON.parse(body).email;
        self.attributes['name'] = name;
        self.attributes['email'] = email;
        self.emit(':ask', 'Hello ' + name + '. May I send you a test mail?');
      } else {6
        self.emit(':tell', "Hello, unfortunately I do not know my name.");
      }
    });
  },
  'YesIntent': function () {
    // ユーザーがYESと答えた場合は、メールを送信する
    // 名前及びメールアドレスは、セッション情報から取得する
    let name = this.attributes['name'];
    let email = this.attributes['email'];
    this.emit('SendMail', name, email);
  },
  'NoIntent': function () {
    // ユーザーがNOと答えた場合は、スキルを終了する
    self.emit(':tell', "good-by.");
  },
  'SendMail':function (name, email) {
    // SESによるメール送信
    let self = this;    
    let ses = new AWS.SES();
    let params = {
      Destination: {
        ToAddresses: [ email ]
      },
      Message: {
         Body: {
           Text: {
             Data: ''
           }
        },
        Subject: {
          Data: 'This is test mail from Alexa'
        }
      },
      Source: 'sin@sapporoworks.ne.jp' 
    };
    ses.sendEmail(params, function(err, data) {
      if (err) {
        console.log(err, err.stack);
        self.emit(':tell', "e-mail transmission failed.")
      } else {
        self.emit(':tell', 'OK. I sent an e-mail');
      }
    });
  }

//・・・省略・・・

7 最後に

今回は、LWAでのAccount Linkingを試してみました。

スキルでメールアドレスが必要となった場合、それを音声で入力させるのは、ちょっと厄介です。LWAでは、有効なメールアドレスが必ず入っているはずなので、それを必要とする場合は、結構有効な手段となるかも知れません。

8 参考リンク


Login with Amazon
Customer Profile
Login with Amazon
How Account Linking Works
Alexa Account Linking: 5 Steps to Seamlessly Link Your Alexa Skill with Login with Amazon
[Alexa] Account Linking を使用してスキルからFacebookに投稿してみました

AWS Cloud Roadshow 2017 福岡