AlexaからLINE Botに通知してみる(ASK+Messaging API+LINEログイン+Social API)

# はじめに

Clovaのいいところとして、LINE Botと(Messaging API)の連携があります。
ただ、開発者的にもユーザー的にも一つ手間がかかりますがAlexa、GoogleAssistantでもLINE Botに通知を送ることはできます。
今回はAlexaを使って、その実装方法をみていきます。

この記事では、Alexaのスキル開発方法を一からは書いていません。
簡単なAlexaスキルを開発したことがある方を対象としています。

# 仕組み

以下のサービスを使います

* ASK(Alexaスキル)
* LINEログイン（Alexaのアカウントリンクに使用）
* MessagingAPI（LINE Bot)

Alexaの[アカウントリンク](https://developer.amazon.com/ja/docs/custom-skills/link-an-alexa-user-with-a-user-in-your-system.html)の機能とLINEログインを使用します。
これにより、ユーザーはスキルを有効にするときにLINEアカウントのログインを求められます。
そうすることでスキル側でMessagingAPIのuserIdを取得することができます。

# Messaging API

## Messaging APIとは

LINE Botのアカウントを作成します。
ユーザーのメッセージに応答したり、プッシュ通知を送ることができます。
今回はAlexaからのメッセージなのでプッシュ通知を使います。
[こちら](https://developers.line.me/ja/services/messaging-api/)を参考にしてください。

## MessagingAPI新規チャンネル作成

以下のリンクからLINE Developlers コンソールへログインし適当なプロバイダーを選択するか作成するかしてください。

https://developers.line.me/console/

次に新規チャンネル作成から「Messaging API」を選択してください。

![LINE_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/195882/696a4414-b73a-6707-0754-4e946b5ac541.png)

新規チャネル作成画面が表示されるので以下を入力します。

* アプリ名: サンプルBot（まあ、適当に）
* アプリ説明: AlexaからBotに通知してみるよ！
* プラン: Developer Trial ***(ここは間違ってはいけない)***
* 大業種: ご自身に合わせてお選びください
* 小業種: ご自身に合わせてお選びください
* メールアドレス: ご自身に合わせてお選びください


入力したら「入力内容を確認」→「同意する」→「作成する」を押します。

すると、一度プロバイダートップ画面に移動するのでもう一度、今作成したチャネルを開きます。
「Webhook送信」の欄を利用するに変更して、更新します。

![LINE_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/195882/1f42fae1-9a23-3f64-77e8-3ee579b090c5.png)

その上の、アクセストークンの欄でトークンを再発行し、発行されたトークンをメモります。
このアクセストークンはのちにLambdaの環境変数で使用します。

![LINE_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/195882/76c968a6-8ca1-82a1-88d6-5839fad9207b.png)

さらに、画面下のQRからLINEアプリで検索し、友達追加しておきます。
さらにさらに、そのほかのYour User IDもメモします。

![LINE_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/195882/65f3596b-6460-454c-f884-361e363c4a5f.png)

## curlでテストしてみる

先ほどメモったトークンとuseridを変更して以下のcurlで試してみてください。。

```
curl -v -X POST https://api.line.me/v2/bot/message/push \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {メモしたアクセストークン}' \
-d '{
    "to": "メモしたユーザーID",
    "messages":[
        {
            "type":"text",
            "text":"Hello, world1"
        },
        {
            "type":"text",
            "text":"Hello, world2"
        }
    ]
}'
```

すると、先ほど登録したBotにメッセージがあなた宛に届くと思います。

# LINEログイン

## LINEログインとは

公式ドキュメントより

> LINEログインを使用すると、アプリやウェブサイトのアカウントをユーザーのLINEアカウントで簡単に作成することができます。LINEログインは、iOS、Android、またはウェブアプリに組み込むことができます。

LINE以外のサービスでもユーザー名やプロフィール画像、UserIDなどを取得することができるようにするAPIです。
今回はこちらを用いてMessagingAPIに使用するUserIDを取得します。

## LINEログインの新規チェンネル作成

Alexaのアカウントリンクに使用します。
いわゆるMessagingAPIとAlexaスキルのつなぎ目的な感じだと思います。
まず、新規チャンネル作成から「LINEログイン」を選択してください。

<img width="819" alt="LINE_Developers.png" src="https://qiita-image-store.s3.amazonaws.com/0/195882/2a0ca04d-519b-ac3c-fa5d-f5e56ccab5a3.png">

LINEログインの情報の入力を求められるので、適当に以下を入力します。

* アプリ名: サンプルLINEログイン
* アプリの説明: Alexaとの連携テストに使用します。
* アプリタイプ: WEB
* メールアドレス: ご自身のメールアドレスをご使用ください。

するとチャネルが作成され、Channel IDやChannel Secretが取得できるのでメモしておきます。

<img width="1189" alt="LINE_Developers.png" src="https://qiita-image-store.s3.amazonaws.com/0/195882/cfcf36e6-b732-c9c5-d973-1335ed3d85df.png">

# Alexaスキルの作成

次にAlexaスキルを作成していこうと思います。
といっても、スキル作成の一からの手順は書きません。
呼び出し名を設定して適当なインテントを作成してビルドまで終わってる前提で話します。
***コードとかは後でいいので必ずエンドポイントは設定して置いてください。でないとうまくリンクできません。***

画面左下の「アカウントリンク」ボタンからアカウントリンクの設定画面を開きます。

![Alexa_Skills_Kit_Developer_Console.png](https://qiita-image-store.s3.amazonaws.com/0/195882/5870cde7-a142-374e-61ed-5342ff80dc64.png)

そして以下の項目を埋めていきます。

|タイトル|項目|
|-----|----|
|認証画面のUR|https://access.line.me/oauth2/v2.1/authorize|
|アクセストークンのURI|https://api.line.me/oauth2/v2.1/token|
|クライアント ID|LINEログインでメモしたChannelID|
|クライアントシークレット|LINEログインでメモしたChannel Secret|
|クライアントの認可方法|HTTP Basic認証|
|スコープ|profile|
|ドメインリスト|空白でOK|
|デフォルトのアクセストークンの有効期限|空白でOK|

次に画面１番下にある`リダイレクト先のURL`の項目の3つのURLをメモします。

![Alexa_Skills_Kit_Developer_Console.png](https://qiita-image-store.s3.amazonaws.com/0/195882/5e760583-22a4-9e64-2aff-224ea19f0229.png)

今度はLINEログイン画面に戻り、画面上の「アプリ設定」をクリックし「Callback URL」に今メモしたURLを入力します。

![LINE_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/195882/8fead01c-badb-2c0b-61ea-5d5f2744512f.png)

# スキルからLINEログインを試してみる

それでは実際にスキルの設定画面から、LINEログインがうまくいくかを試してみましょう。
コードはその後です。
今作成したスキルを有効にしてみます。
画面には「アカウントのリンクが必要です」とあるはずです。

![Amazon_Alexa.png](https://qiita-image-store.s3.amazonaws.com/0/195882/70f5c3df-4ae8-4e4e-8964-cc26ad0bd87a.png)

するとLINEのログイン画面が出てくるのでログインしてみましょう。

![LINE.png](https://qiita-image-store.s3.amazonaws.com/0/195882/55316dff-7993-8de6-8971-cbd59f386174.png)

うまくいくと以下のうような画面になると思います。

![ボイスシンガー_アカウントのリンクAccount_Linking.png](https://qiita-image-store.s3.amazonaws.com/0/195882/dfe813af-a04f-c6fa-8b27-88d003a7fd89.png)

これでスキル（Lambdaに送られてくるJSON）でアクセストークンを取得することができます。
アクセストークンを用いてuserIdを取得しようと思います。

# コードの実装

Lambdaを使っていきます。
何はともあれモジュールをインストールします。
「@line/bot-sdk」はLINE公式が出しているMessagingAPIのSDKです。

```
$ npm init
$ npm install --save ask-sdk-core
$ npm install --save ask-sdk-model
$ npm install --save request-promise request
$ npm install --save @line/bot-sdk
```

とりあえず、スキル起動時に（LaunchRequest）Botに「スキルが起動されました」とでも通知しておきましょうか。
いかがそのコードです。

```js
'use strict';

const Alexa = require('ask-sdk-core');
const rp = require('request-promise');
const line = require('@line/bot-sdk');

const client = new line.Client({
  // Lambdaの環境変数よりMessagingAPIのチャネルアクセストークンを取得
  channelAccessToken:  process.env["channelAccessToken"]
});

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  async handle(handlerInput) {
    // Userごとのアクセストークン
    const accessToken = handlerInput.requestEnvelope.session.user.accessToken;
    console.log(accessToken);

    var options = {
      method: 'GET',
      uri: 'https://api.line.me/v2/profile',
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    };
    // アクセストークンより、LINEのUser情報を取得
    var lineData = JSON.parse(await rp(options));

    const message = {
      type: 'text',
      text: 'スキルが起動されました。'
    };

    const userId = lineData.userId;

    // botに通知を送信
    await client.pushMessage(userId, message)

    var msg = 'Botにメッセージが送信されました';

    return handlerInput.responseBuilder
      .speak(msg)
      .reprompt(msg) 
      .getResponse();
  }
};

exports.handler = Alexa.SkillBuilders.custom()
  .addRequestHandlers(
    LaunchRequestHandler)
  .lambda();
```

次にLambdaの環境変数にMessagingAPIのアクセストークンを入力します。
変数名は`channelAccessToken`です。

![LINE_Developers.png](https://qiita-image-store.s3.amazonaws.com/0/195882/b71c0d0c-c93b-66b4-84e4-076efc06d4fe.png)

![Lambda_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/195882/cf27d75b-158d-a834-43aa-18f65b350103.png)

これで完成です？一応動きます。
スキルを起動してみてください。Botに以下のようなメッセージが送られると思います。

<img width="354" alt="ボイスシンガー.png" src="https://qiita-image-store.s3.amazonaws.com/0/195882/4bac7af1-865f-9699-18ba-cf8fd89f6ee0.png">

# 終わりに

かなりめんどくさい、、、
Clovaだったらもっと楽に連携させられるからBot使いたいスキルはやっぱりClovaですね！