初学者がAlexa Skills KitとAWSのLambdaを使ったシステムを作るまで（実践編）


#はじめに
今回は 全く知識のない状態から、
・Alexa Skills Kit 
・AWS の Lambda
を使って簡単なボットをつくります。





####対象
・pythonに触れたことがある
・けどサーバとかよくわからない
・Alexa使ってみたい
以上のような人を対象とします。
色々なサイトがありますが、初学者にわかりやすいサイトが少なかったのでまとめておきます。






##ゴール
・Alexaが会社の歴史を教えてくれる
・Alexa×Lambdaの超基礎的なコードの一部が理解できるようになる
実践編では、とりあえず動かすことをゴールとします。


##事前知識



###Alexa Skills Kit
**Alexa Skillは認識する文章の定義を決めるもの**です。
https://developer.amazon.com/home.html にて作成することが出来ます。
その他フローの説明はこちらが詳しいので参照ください。
https://qiita.com/ysak/items/de3e10a00cce19c48076



###AWS Lambda
AWSに関するなにかしらのイベントによって処理を実行する環境だと考えたらよいらしい。
**要はサーバサイドの処理環境**のようなものですね。

参考：https://qiita.com/s_s_k/items/b584435120e99d63975b



#事前準備
**Amazon Developerアカウント の登録（無料）**
以下からできます。簡単です。
https://developer.amazon.com/ja/

**AWS アカウント の登録（無料）**
以下からできます。クレジットカード（またはVプリカ）での登録が必要です。
（ちょっとめんどくさい、、）
https://aws.amazon.com/jp/



#開発
####スキルの開発

まずは、Alexa Developer Console を開き、「スキルの作成」ボタンを押します。

















https://developer.amazon.com/alexa/console/ask
![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/630a0e9f-aad2-8dcf-d6c6-564b9abb0596.png)
すると、上のような画面が出てきますので、
スキル名、デフォルトの言語（日本語）、モデル（カスタム）を順番に指定します。
（今回はスキル名：「HelloAlexa」としたが、適当で良い）
その後、右上の「スキルを作成」ボタンを押します。

















![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/a365c597-fa37-0ffd-0b83-89d9e58d5af1.png)
上のような画面が出たら、ここからスキルビルダーのチェックリストにしたがって進めていきます。
まずは、右にある呼び出し名をクリックします。



















![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/94444d5f-c123-8864-876e-45396e930784.png)
好きな呼び出し名（今回は「受付」とした）を入力し、「モデルを保存」を押します。
呼び出し名は、
『アレクサ、[呼び出し名]を開いて』『アレクサ、[呼び出し名]で会社の歴史を説明して』
等と呼びかける際に使用します。
その後、左側の対話モデルの中のインテントをクリックし、「インテントを追加」ボタンをクリックします。




















![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/ed8f0dbb-585c-b8de-ed61-9947243b2e62.png)
上記の画面が出たら、適当なインテント名（今回は「explain」とした）を入力し、
カスタムインテントを作成します。

















![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/13cb0aba-41bd-a915-6f12-9c2f3b4c8e0d.png)
次に、サンプル発話を追加します。「教えて」「聞かせて」「会社の歴史」「会社の歴史を教えて」「何か教えて」を登録しましょう。
登録を終えたら、「モデルの保存」→「モデルのビルド」を実行しましょう。
正常にビルドされたら、エンドポイントの設定に入ります。












![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/f5ce62ed-e9c8-c94c-4dbb-52ddb66be734.png)
AWS LambdaのARNを選択し、スキルIDをコピーしておきます。
ここで、一旦スキル作成をストップします。

####Lambda開発
次に、AWSコンソールを開き、Lambdaを探してアクセスします。見つかったら、関数のメニューから「関数の作成」をします。

















![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/f5dfd441-a527-f24a-33b3-b0d0b936533a.png)
すると上のような画面が出ると思うので、設計図を選択し、
alexa-skills-kit-color-expert-python
を選択します。
















![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/3bb5b7c7-49df-0cef-e0e4-c9f89c87924f.png)
適当な名前（今回はexplainCompany）を入力し、既存のロールから
lambda_basic_exution
を指定してください。
スキルIDの欄には、先ほどスキル作成の時にコピーしておいたIDを貼り付けましょう。
あとはいじらずに「関数の作成」をします。















![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/0db7e4ba-166b-1f7e-0b2a-d6b7e2e99776.png)
すると上のような画面に移ります。
Alexa Skills Kitの部分がない人は、左側のトリガーの追加から選択して追加しましょう。
いよいよ関数コードを編集します。
まず、ランタイムがpython2.7になっているので、python3.6に選択し直しましょう。
続いて、コードを変更します。
簡潔に理解が進むように、書いてあるコードを全て消して以下のコードを貼り付けてください。
(こちらの記事のコードをお借りして、ほんの一部変更しています：https://torina.top/detail/443/
コードの解説も非常に丁寧なのでぜひ参考にしてみてください)
その後、右上の「保存」ボタンを押して保存してください。

```python:lambda_function
class BaseSpeech:
    """シンプルな、発話するレスポンスのベース"""

    def __init__(self, speech_text, should_end_session, session_attributes=None):
        """初期化処理

        引数:
            speech_text: Alexaに喋らせたいテキスト
            should_end_session: このやり取りでスキルを終了させる場合はTrue, 続けるならFalse
            session_attributes: 引き継ぎたいデータが入った辞書
        """
        if session_attributes is None:
            session_attributes = {}

        # 最終的に返却するレスポンス内容。これを各メソッドで上書き・修正していく
        self._response = {
            'version': '1.0',
            'sessionAttributes': session_attributes,
            'response': {
                'outputSpeech': {
                    'type': 'PlainText',
                    'text': speech_text
                },
                'shouldEndSession': should_end_session,
            },
        }

        # 取り出しやすいよう、インスタンスの属性に
        self.speech_text = speech_text
        self.should_end_session = should_end_session
        self.session_attributes = session_attributes

    def simple_card(self, title, text=None):
        """シンプルなカードを追加する"""
        if text is None:
            text = self.speech_text
        card = {
            'type': 'Simple',
            'title': title,
            'content': text,
        }
        self._response['response']['card'] = card
        return self

    def build(self):
        """最後にこのメソッドを呼んでください..."""
        return self._response


class OneSpeech(BaseSpeech):
    """1度だけ発話する(ユーザーの返事は待たず、スキル終了)"""

    def __init__(self, speech_text, session_attributes=None):
        super().__init__(speech_text, True, session_attributes)


class QuestionSpeech(BaseSpeech):
    """発話し、ユーザーの返事を待つ"""

    def __init__(self, speech_text, session_attributes=None):
        super().__init__(speech_text, False, session_attributes)

    def reprompt(self, text):
        """リプロンプトを追加する"""
        reprompt = {
            'outputSpeech': {
                'type': 'PlainText',
                'text': text
            }
        }
        self._response['response']['reprompt'] = reprompt
        return self


def explain_history():
    """ハローと言っておわり"""
    return OneSpeech('この会社は1995年に設立されて、、、かくかくしかじか、、、').build()


def welcome():
    """ようこそと言って、ユーザーの返事を待つ"""
    return QuestionSpeech('ようこそ!').reprompt('よく聞こえませんでした').build()


def bye():
    """グッバーイといって終わる"""
    return OneSpeech('グッバーイ').simple_card('遊んでくれてありがとう!').build()


def lambda_handler(event, context):
    """最初に呼び出される関数"""
    # リクエストの種類を取得
    request = event['request']
    request_type = request['type']

    # LaunchRequestは、特定のインテントを提供することなく、ユーザーがスキルを呼び出すときに送信される...
    # つまり、「アレクサ、ハローワールドを開いて」のようなメッセージ
    # 「アレクサ、ハローワールドで挨拶しろ」と言うとこれはインテントを含むので、IntentRequestになる
    if request_type == 'LaunchRequest':
        return welcome()

    # 何らかのインテントだった場合
    elif request_type == 'IntentRequest':
        intent_name = request['intent']['name']

        # 「会社の歴史を教えて」「聞かせて」等で呼ばれる。サンプル発話に書いた部分
        if intent_name == 'Explain':
            return explain_history()

        # 「ヘルプ」「どうすればいいの」「使い方を教えて」で呼ばれる、組み込みインテント
        elif intent_name == 'AMAZON.HelpIntent':
            return welcome()

        # 「キャンセル」「取り消し」「やっぱりやめる」等で呼び出される。組み込みのインテント
        elif intent_name == 'AMAZON.CancelIntent' or intent_name == 'AMAZON.StopIntent':
            return bye()
```

####接続＆テスト
ここまでできたら、右上にある「ARN- arn:.....」のarn：.....の部分をコピーしてください。
次に、Alexa Developer Consoleをもう一度開きます。
もう一度エンドポイントのページを開き、デフォルトの地域の欄に先ほどコピーしたものを貼り付けましょう。
その後、「左上のエンドポイントを保存」ボタンをおします。

これで全ての準備が整いました！
アレクサのシュミレータを使ってテストしてみたいと思います。
上のタブにある「テスト」を選択してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/c5e8108e-bb7b-6323-60c7-a2b1a24e9e52.png)

上記の画面がでてきたら　、テストを有効に切り替えてください。
その後、アレクサシミュレータに、「アレクサ、受付を開いて」と入力してください。
返事が返ってきたら、次に「会社の歴史を教えて」と入力してみてください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/271486/ea3baf9c-663a-cd6f-b56e-5f28ba29a54b.png)
上の様な返答がきたら成功です！

時間があったらコード解説編も書こうと思います。


#参考URL
AWS超入門
https://qiita.com/s_s_k/items/b584435120e99d63975b
0から始めるAlexa入門
https://qiita.com/ysak/items/de3e10a00cce19c48076
Alexa Skills Kit入門シリーズ(Python、AWS Lambda使用)
https://torina.top/detail/443/
↑丁寧に解説されてますのでおすすめです