Alexa徹底入門

# はじめに
この記事は社内のLT大会で発表した資料とその発表内容です。
さくっと見たい方は以下の資料を参照ください。

[![introduction_alexa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398666/b538c57e-f3ae-ed70-642f-fbad719c34c1.png)](https://a-terarara.github.io/lightning-talks_alexa/)

# 何故今更Alexa？

[モブプロ勉強会でAlexaをテーマに実施した](https://qiita.com/masao_yamakawa/items/b13a3b4fcf39b7006114) ところ、老若男女問わず好評でした。
にも関わらず特に気になったのは、Alexaのシステム構成が浸透していない部分でした。
AlexaSkill開発は下火になっている印象を持つものの、まだまだその領域に手を出していないエンジニアが多いというのは勿体ない気がしていて、改めてAlexa教に入門していただき、**Alexaの発展に貢献していただこう** というのがきっかけです。
注意) 筆者はAlexaとは全く関係ありません。趣味です。

# Alexaの始め方

1. メールアドレスを用意する
2. [スキル開発 基礎トレーニングシリーズ](https://developer.amazon.com/ja/alexa-skills-kit/training/building-a-skill#%E3%82%B9%E3%82%AD%E3%83%AB%E9%96%8B%E7%99%BA%20%E5%9F%BA%E7%A4%8E%E3%83%88%E3%83%AC%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA) を読む

以上です。
AWSアカウントもAmazonEchoも不要です。
Lets Alexa Life!!

# Alexa Structure

## 全体構成
![alexa_order.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398666/ce08aa00-4e5a-aa65-199a-e4539932cf90.png)


|登場人物|役割(start)|役割(end)|
|:---------|:----------|:----------|
|人間|声を出す|耳で聞く|
|Echo|声からAlexaSkillを切り分けて該当するSkillを呼び出し|人に会話を返す|
|Alexa|声データからIntentを切り分けてBackendを呼び出し|Backendから言われた通りにEchoに返す|
|Backend|Alexaが構造化したデータを基にビジネスロジック|それっぽい会話テキストを返す|

大体Backendがメインです。

## Skill
Alexa Skill１つにつき１つの呼び出し名を持ちます。

- 例１：「<font color="red">Alexa</font>、<font color="blue">天気</font>を教えて」
- 例２：「<font color="red">Alexa</font>、<font color="blue">ピカチュウ</font>を呼んで」

ウェイクワード「<font color="red">Alexa</font>」、呼び出し名「<font color="blue">天気</font>」
呼び出し名によって呼び出すSkillを切り替えています

### Skill内会話
Skill内の会話にはセッションを持ちます

:boy_tone2:「Alexa、コーヒーショップを開いて」
:microphone2: 「何をご注文なさいますか」
:boy_tone2:「アイスコーヒーください」
:microphone2: 「ご注文ありがとうございます」

呼び出し～会話の終わりまでAlexaSkillはあなたを待ち受けています

## Intent
Skillは複数のインテント＝会話パターンを持ちます

- 例１：「アイスコーヒーください」
- 例２：「ストローもつけてください」
- 例３：「３杯お願いします」

あらかじめ会話パターンは定義しておきます
**つまりユーザの会話を予測しておかなければなりません**

### フレーズスロット
インテントにはフレーズスロット＝可変長の引数を定義できます

- 例１：「<font color="red">アイスコーヒー</font>ください」
- 例２：「<font color="red">紅茶</font>ください」

フレーズスロット<font color="red">「アイスコーヒー」、「紅茶」</font>
**ユーザが自由に発話出来る引数を定義** しておき、Backendの処理内容を変えられます

### SearchQuery

フレーズスロットは飲み物の種類等Amazon側で予め用意された単語を拾います
自由な単語を拾うためには SearchQuery を使います

ただし、Alexa側で良い感じな変換処理をかけてくれないので、 **予想したフレーズと実際の発話フレーズが異なることがあります**
例：「コーヒー」⇒「こおひい」

## ここまでの整理
<img src="https://a-terarara.github.io/lightning-talks_alexa/images/intent_sequence.png"/>

## Alexa機能集

### アカウントリンク
認可フローで別のリソースにアクセスする機能です。
イメージ
<img src="https://a-terarara.github.io/lightning-talks_alexa/images/accountlink_sequence.png"/>
\#access tokenってAlexaさんが管理してくれる？ :thinking: 

### ユーザ情報取得API
Amazonアカウント情報にアクセスする機能(OIDC)
イメージ
<img src="https://a-terarara.github.io/lightning-talks_alexa/images/userinfo_sequence.png"/>

### Skill Connections(現在Preview)
別のSkillにデータ連携出来る

例) 
:boy_tone2:「Alexa、Amazonで〇〇を購入して」
:boy_tone2:「注文書をプリンタで印刷して」
　　　⇒（別のSkillに情報連携して印刷予約）

### 声帯変更
Backendのreturn時にSSML（音声合成マークアップ言語）を定義することで声帯を変更する
エフェクトの変更やmp3を読み上げさせるオプションもある
\# あなた好みの声に変更できるチャンス :thinking: 

## Backend
### サーバ選定
BackendはAWS Lambdaのイメージが強いですが、下記の要件を満たせればなんでも良いです。

 - Rest API
 - I/FはJSON
 - エンドポイントは１つ
 - SSL通信

**つまり言語もサーバも自由に選べます**
\# なんだったらFaaSのColdStart問題とAlexaの8秒制約あるので自前サーバの方が都合良いやも

### I/F
I/Fはapplication/jsonです

sample(Request)

```json
{
  "request": {
    "type": "IntentRequest",
    "intent": {
      "name": "HelloWorldWithNameIntent",
      "slots": {
        "firstName": {
          "name": "firstName",
          "value": "terarara",
          "confirmationStatus": "NONE"
        },
      ・・・
```
\# HelloWorldWithNameIntentにfirstNameを渡しています

### Unit Testing
I/F情報を保持しておけば単体テストコードも書けます

```js
const request = {
   //JSONをコピペ
  ・・・
}
describe("お試し", () => {
  it("requestを処理すると注文を受け付ける", () => {
    target(request, res);

    assert.deepEqual(
      res.body.response.outputSpeech.ssml,
      "<speak>ご注文ありがとうございます</speak>"
    );
  });
}
```

### コード管理
AlexaSkillは[JSON Editor機能があります](https://developer.amazon.com/ja/docs/custom-skills/create-the-interaction-model-for-your-skill.html#code-editor) のでJSONを保持しておくことでコード管理が可能です
backendは言わずもがな、管理しておきましょう

# おわりに
一口にAlexaと言っても様々な機能の上に成り立っていることがわかります。
これらの他にも [Alexa echo show](https://www.amazon.co.jp/dp/B07KD87NCM)を使った視覚サポートやIoTデバイスとの連携などまだまだ進化を続けています。
皆さんも是非AlexaSkillを開発してVUI業界を盛り上げていきましょう！
注意) 筆者はAlexaとは全く関係ありません。趣味です。