JavaScript
lambda
Alexa

amazon echoで会社の受付システムを作ってみました

先日h-takaumaさんの記事を見て、自分もalexaで会社の受付システムを作ってみました
Google Homeで受付システム作ってみた

また、JavaScriptやamazon lambda触った経験が全くないので、間違いなどあればぜひ教えてください!

構成流れ

image.png

完成動画

必要なもの

  • amazon developer アカウント
  • amazon Echo
  • slack アカウント(チャンネルの権限持つ)

それでは作ってみよう!

alexa skillの簡単な動作や開発手順はここを参考にしました
https://github.com/alexa/skill-sample-nodejs-trivia/blob/ja-JP/instructions/1-voice-user-interface.md

対話モデルのIntents設定

image.png

以下のケースに対応するためのintentを追加しました
- 約束のある方
- 面接で来た方(学生)
- 配送業者
- 来客の人数

slack側のやること

チャンネルにIncoming WebHooksを作ります

QQ20171211-135530@2x.png

WorkSpaceメンバーのidを取得します

https://api.slack.com/changelog/2017-09-the-one-about-usernames
<@userID> でメンバーにメンションを飛ばすことができます。

https://api.slack.com/methods/users.list/test
ここでチャンネルのメンバーidを取得できる。
QQ20171211-142501@2x.png

amazon lambda側

name.json を作ります

担当者の名字、フルネーム両方対応できるように、両方用意します。

name.json
[
    {  "name" : "AA",  "full_name" : "AABB",  "slack_name" : "aabb"  },
   {  "name" : "CC",  "full_name" : "CCDD",  "slack_name" : "ccdd"  },
   and more...
]

index.jsを作ります

//require
var Alexa = require('alexa-sdk');
var slackjson = require('./slack.json');
var namejson = require('./name.json');
var rp = require('request-promise');

基本枠は「skill-sample-nodejs-trivia」を参照すれば良い

学生の時の例

var firstHandlers = Alexa.CreateStateHandler(STATUS.FIRSTMODE, {
    "Unhandled": function(){
        ...
    },

    "GetAnswerIntent": function (){
        ....//約束のある方
    },

    "GetAnswerFromStudentIntent": function (){
        studentRequest.call(this, false);

        rp(options).then((response) => {
            this.emit(':tell', '担当者に伝えました、少々お待ち下さい');
        }, (error) => {
            this.emit(':tell', '通信失敗しました,もう一度お願いします');
        });
    },

    "GetAnswerFromDeliveryIntent": function (){
        ....//配送業者
    }, 
    "AMAZON.StopIntent": function(){
      this.emit("stop");
    }
});

function studentRequest(frist) {
    var to_user_message = "<@slackid> 面接の学生がきました。"
    options = {
        method: 'POST',
        uri: slack_webhook,//先のslack_webhook
        body: {
            text: to_user_message
        },
        json: true
    }; 
}

slackにpostする内容は、Incoming WebHooksを設定する時のSetup Instructionsを参照すれば良い

上記の作業が終わったら、zipファイルを作成し、lambdaにアップロードしてテストclearなら完成です!

image.png

めっちゃはまった所

最初のpostの書き方:

    "GetAnswerFromStudentIntent": function () {
        studentRequest.call(this, false);
        rp(options); //ここでpost
        this.emit(':tell', '担当者に伝えました、少々お待ち下さい');
    },

この書き方だと、postのレスポンスが返る前に this.emit() を実行していて、ひどい時には前回起動したスキルのレスポンスをemitしたりしました。
検索した結果、以下のissueを見つけました。
https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/issues/44

どうやら非同期処理をしていることが原因のようでした。

まとめ

初めてJavaScriptとLambdaを触りましたが、思った以上に楽しかったです。
次の目標はslack message buttonを追加して、担当者が対応したことを確認できる感じにしたいです。
API Gatewayで作れるらしいので、調べてみます。