TeamSpirit Developer Blog

チームスピリット開発者のブログ

Amazon Echo から Salesforce へ繋げてみた

こんにちは。
株式会社チームスピリットの古川(id:furukawa-hisakatsu)です。

Amazonにて発売されましたスマートスピーカー「Amazon Echo」が11月に日本に上陸しました。
私自身も11月末にAmazon Echoが届きましたので試しにSalesforceに繋げてみました。

f:id:furukawa-hisakatsu:20171222194712p:plain

(可愛いやつです)

後、この記事はチームスピリット Advent Calendar 2017の21日目です。(遅刻) adventar.org

概要

今回はAmazon Echoと接続する音声サービス「Amazon Alexa」からAccount Link機能とAPI Gatewayを使用してSalesforceと接続し、
Lambdaから未承認レコードの件数の取得を行うカスタム音声サービス「Alexa Skills Kit」を作成します。
お試しまでとなりますので公開用の設定ではありません。

必要なアカウント

Alexaからのリクエスト処理をLambdaで作成

Alexaからのリクエストを受付し、Salesforceに接続、その後Alexaに件数を発言するレスポンスを返す処理を作成します。 ソースコードは下記URLから参照して下さい。

github.com

  • AWSにログインし、「Lambda」を選択し、関数の作成をクリックします。

f:id:furukawa-hisakatsu:20171222160507p:plain

  • 次に「一から作成」を選択し、名前を適当に入力し、ランタイムは「Node.js 6.10」を選択し、ロールは既存のままで選択して保存します。

f:id:furukawa-hisakatsu:20171222160634p:plain

  • 関数の詳細画面が表示されましたら、「関数コード」の「コード エントリ タイプ」に「.ZIP ファイルをアップロード」を選択し、こちらをダウンロードしてアップロードします。

f:id:furukawa-hisakatsu:20171222162847p:plain

  • 表示している関数がAlexa Skills Kitから呼び出されるトリガーを設定するため、「Designer」のサイドメニューから「Alexa Skills Kit」を選択し、「トリガーの設定」から「追加」をクリックします。

f:id:furukawa-hisakatsu:20171222163241p:plain

  • 最後に右上の「保存」をクリックし、Lambdaの設定は完了です。

f:id:furukawa-hisakatsu:20171222163308p:plain

  • 後のスキル設定で使用するため、右上の「ARN」を何処かに退避します。

f:id:furukawa-hisakatsu:20171222180221p:plain

トークン取得時のレスポンスを工夫するためAPI Gatewayを作成する

Salesforceからのアクセストークン取得を行うためにAPI Gatewayを作成します。

  • AWSにログインし、「API Gateway」を選択し、「APIの作成」をクリックします。

f:id:furukawa-hisakatsu:20171222164535p:plain

  • 「Swagger からインポート」選択し、下記コードを入力して、「インポート」をクリックします。
    (名称変更したい場合は、下記コードの「title」属性の値を変更してください。)
{
  "swagger": "2.0",
  "info": {
    "title": "SalesforceProxy"
  },
  "schemes": [
    "https"
  ],
  "paths": {
    "/": {
      "post": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "#set($params = $input.path('$'))\n{\n#foreach($paramName in $params.keySet())\n    #if($paramName == \"access_token\")\n    \"expires_in\": 3600,\n    #end\n    \"$paramName\": \"$params.get($paramName)\"\n    #if($foreach.hasNext)\n    ,\n    #end\n#end\n}\n"
              }
            }
          },
          "requestParameters": {
            "integration.request.header.Accept": "'application/json'",
            "integration.request.header.Content-Type": "method.request.header.Content-Type"
          },
          "uri": "https://login.salesforce.com/services/oauth2/token",
          "passthroughBehavior": "when_no_templates",
          "httpMethod": "POST",
          "type": "http"
        }
      }
    }
  },
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}

f:id:furukawa-hisakatsu:20171222170333p:plain

  • これだけではまだ使用できないため、作成に成功しましたら「アクション」をクリックして、「API のデプロイ」をクリックします。

f:id:furukawa-hisakatsu:20171222170441p:plain

  • 「デプロイされるステージ」に「[新しいステージ]」を選択しステージ名等を適当に入力して「デプロイ」をクリックします。

f:id:furukawa-hisakatsu:20171222170509p:plain

  • 成功しますとステージエディタが表示されるので、「URLの呼び出し」を何処かに退避します。(これもスキル設定で使いますよ)

f:id:furukawa-hisakatsu:20171222170914p:plain

余談

OAuth認証処理を行ったことある人は(あれ?)と思われますが、 本来、「https://login.salesforce.com/services/oauth2/token」に通信してアクセストークンを取得するのがSalesforceの認証となりますが、 Amazon AlexaのAccount Link機能でアクセストークンを取得する際、初回時は問題ないのですが、 アクセストークンが時間切れとなり再度取得が必要となった場合、 Amazon Alexaはアクセストークン取得のレスポンスに含まれている「expires_in」(有効時間)が過ぎているかを判定し再度取得する仕組みと思われます。 ですが、Salesforceからのアクセストークン取得時には「expires_in」が含まれていないため、これを含ませるためにAPI Gatewayを作成します。

Salesforceのセッション時間は設定による可変式でありますが、これを検出する手段がないため、今回は固定で1時間を指定しております。

Alexaのスキルを作成しよう

AWS側の設定が終わりました。Alexaスキルを作成しましょう!

  • Amazon Developerにログインし、「Alexa」をクリックし、「Alexa Skills Kit」の「始める」をクリックします。

f:id:furukawa-hisakatsu:20171222171221p:plain

  • Alexa スキル一覧の画面が表示されましたら、「新しいスキルを追加する」をクリックします。

f:id:furukawa-hisakatsu:20171222171812p:plain

  • スキル情報を設定する画面が表示されるため、下記設定を行い、「保存」をクリックします。
    • スキルの種別:カスタム対話モデル
    • 言語:Japanese
    • スキル名:適当に入力して下さい
    • 呼び出し名:こちらも適当に入力してください。

f:id:furukawa-hisakatsu:20171222172057p:plain

  • 「対話モデル」を選択し、「インテントスキーマ」及び「サンプル発話」に下記コードを入力し、「保存」をクリックします。

    インテントスキーマ

{
  "intents": [
    {
      "intent": "SalesforceIntent"
    }
  ]
}

f:id:furukawa-hisakatsu:20171222173646p:plain

サンプル発話

SalesforceIntent 未承認個数を教えて

f:id:furukawa-hisakatsu:20171222173708p:plain

  • 次のSalesforceの設定のため、「設定」をクリックし、「アカウントリンク」の「ユーザーにアカウントの作成や既存のアカウントへのリンクを許可しますか?」に「はい」を選択して、
    「リダイレクトURL」を何処かに退避しておきます。

f:id:furukawa-hisakatsu:20171222174755p:plain

(まだ設定しますので画面はそのまま)

Salesforceに繋ぐための設定をする

スキルの設定を一旦中断し、AlexaからSalesforceに接続するための設定をしましょう!

  • Salesforceにログインし、右上の歯車をクリックし、「設定」をクリックします。

f:id:furukawa-hisakatsu:20171222174320p:plain

  • 設定画面が開きましたら「アプリケーション」から「アプリケーションマネージャ」をクリックし、「新規接続アプリケーション」をクリックします。

f:id:furukawa-hisakatsu:20171222174500p:plain

  • 「接続アプリケーション名」や「API 参照名」、「取引先責任者 メール」を適当に設定しましょう。

f:id:furukawa-hisakatsu:20171222174914p:plain

  • 「OAuth 設定の有効化」にチェックを入れ、下記設定を行い、「保存」をクリックします。
    • コールバックURL:先程退避したリダイレクトURLを貼り付けましょう
    • 選択したOAuth範囲:「データへのアクセスと管理(api)」、「ユーザに代わっていつでも要求を実行(refresh_token, offline_access)」、「基本設定へのアクセス(id, profile, email ,address, phone)」を右に追加します。

f:id:furukawa-hisakatsu:20171222175245p:plain

  • 「次へ」をクリックし、設定完了!

f:id:furukawa-hisakatsu:20171222175319p:plain

  • 画面が切り替わりましたら「コンシューマ鍵」と「コンシューマの秘密」を退避しておきましょう。次に使いますよ!

f:id:furukawa-hisakatsu:20171222175618p:plain

AlexaとSalesforceが繋がる時です

Alexaのスキル設定を再開し、Salesforceの接続設定をしましょう!

  • Amazon Developerのスキル設定画面に戻って「設定」をクリックします。(もう開いているかもしれません)

f:id:furukawa-hisakatsu:20171222180045p:plain

  • 「サービスエンドポイントのタイプ」に「AWS Lambda の ARN (Amazonリソースネーム)」を選択し、「デフォルト」に先程退避したLambdaの「ARN」を貼り付けます。

f:id:furukawa-hisakatsu:20171222180722p:plain

  • 「アカウントリンク」から「ユーザーにアカウントの作成や既存のアカウントへのリンクを許可しますか?」に「はい」を入れ(もう入れてるかもしれません)、下記設定を行います。
    • 認証 URL:「https://login.salesforce.com/https://login.salesforce.com/services/oauth2/authorize
    • クライアント ID:退避したSalesforceの「コンシューマ鍵」
    • 認可の承諾タイプ:「Auth Code Grant」
    • アクセストークンURL:退避したAPI Gatewayの「URLの呼び出し」
    • クライアントシークレット:退避したSalesforceの「コンシューマの秘密」
    • クライアント認証スキーム:「リクエストボディの資格情報」

f:id:furukawa-hisakatsu:20171222181415p:plain

  • 最後の「プライバシーポリシー URL」は適当に入力しましょう。(本当は個人情報の取扱が記載されているURLが必要ですよ)

f:id:furukawa-hisakatsu:20171222181654p:plain

  • 「保存」をクリックして「次へ」をクリックします。
    (このあたりでエラーが起きやすいですね、エラーが起きたら手順を再確認してみましょう)

さぁテストの時間だ!

面倒な設定作業を終え、ついにAlexaの言葉を聞く時が来ました。

Amazon Echo等を持っていない方向け

なんとAmazon Echoのシミュレータがあるのでログインして許可してみましょう。

echosim.io

Salesforceの認証が必要です

まだ声を聴くのは早かったですね、Salesforceの認証をしましょう

  • お手持ちのスマートフォンにAmazon Alexaをインストールするか、もしくは http://https:/alexa.amazon.co.jp からログインします。
    (スキル開発したアカウントでログインしてください)

  • 「スキル」を選択して「有効なスキル」をクリックします。(Amazon Echo等が設定済みか上のシミュレータ連携されていないと開けないかもしれません)

f:id:furukawa-hisakatsu:20171222183300p:plain

  • 先程登録したスキルが表示されているのでクリックします。
    (表示されていなかったらログインするユーザが異なっているか、スキルの設定が途中かもしれません)

f:id:furukawa-hisakatsu:20171222183656p:plain

  • 「設定」をクリックし、「アカウントのリンク」をクリックしてSalesforceにログインします。
    (Salesforceのログイン時にこのアプリケーション許可するとウィンドウが出ると思いますが、「許可」するをクリックして下さい)

f:id:furukawa-hisakatsu:20171222183756p:plain

  • アカウントのリンクに成功しているはずです!
    (成功していなかったらスキル設定やSalesforceの設定を再確認!)

f:id:furukawa-hisakatsu:20171222184202p:plain

声を聞きましょう

youtu.be

(なかなか通じない場合は単語分割していってみるのもいいかもしれません)

締め

今回Alexaにてスキルを実装してみましたが、アカウント管理や認証処理をAlexa側に一任できるのは大きく、
わざわざユーザを特定したり、データベースを用意したりする必要もないのは魅力的であり、
開発自体もsdkが用意されていたりと特に詳しく勉強しなくても開発できるのはいいですね。

皆様も是非仕事役に立つような、あるいはちょっと役に立つような、はたまた面白いようなスキルを開発してみて下さい!

公式でのSalesforceとの接続はAlexa for Businessでなにか来るみたいですけど日本にくるのでしょうか?