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

先日h-takaumaさんの記事を見て、自分もalexaで会社の受付システムを作ってみました
[Google Homeで受付システム作ってみた
](https://qiita.com/h-takauma/items/4ecc3421f2995b207284)
また、JavaScriptやamazon lambda触った経験が全くないので、間違いなどあればぜひ教えてください！

# 構成流れ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/165424/91d68ac7-92c1-42ad-8d9c-bfc9b3128819.png)

# 完成動画

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">amazon echoで受付システムを作ってみた <a href="https://t.co/q0c6rbKtUK">pic.twitter.com/q0c6rbKtUK</a></p>&mdash; 豚んでチハヤ＠キュアチャイナ (@ikarosu_tsubasa) <a href="https://twitter.com/ikarosu_tsubasa/status/940189443985629186?ref_src=twsrc%5Etfw">2017年12月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# 必要なもの
- 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](https://qiita-image-store.s3.amazonaws.com/0/165424/fe191685-bafa-3efd-a1d7-f6f72f20185e.png)

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

## slack側のやること
### チャンネルにIncoming WebHooksを作ります
<img width="466" alt="QQ20171211-135530@2x.png" src="https://qiita-image-store.s3.amazonaws.com/0/165424/a487d737-69c4-e60f-aa23-3837bf957b64.png">

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

https://api.slack.com/methods/users.list/test
ここでチャンネルのメンバーidを取得できる。
<img width="358" alt="QQ20171211-142501@2x.png" src="https://qiita-image-store.s3.amazonaws.com/0/165424/5b97ff61-0f94-20ac-5af3-3c2f166fc04d.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」を参照すれば良い

学生の時の例

```js
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](https://qiita-image-store.s3.amazonaws.com/0/165424/d7d6d696-3196-6b58-fd92-c91569954c94.png)


##めっちゃはまった所

最初のpostの書き方：

```js
    "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で作れるらしいので、調べてみます。