【ハンズオン】LINE Bot「ナグサメくん」のつくりかた（Microsoft Flow＋COTOHA API＋A3RT Talk API）

※2019/3/23追記
Microsoft FlowのHTTP関係のコネクターが無料プランでは使えなくなってしまいました。
Microsoft FlowのPremiumアカウントかAzure Logic Appsを使えば作れますが、当初のように「無料」ではできなくなってしまっています。
（現状、以下の記事は元のままになっています）


## はじめに
無料で使えるAI系のAPIを組み合わせてLINE Botを作ってみました。
LINE Messaging APIとの接続役は「Microsoft Flow」に行わせているので、ノンコーディングでできました。
※実装サンプルとして作っただけなので大した機能はもちません

以下、仕様・使った技術・つくりかたです。

## 仕様
送ったメッセージに対してAIが返答をしてくれる（マルチターンの会話はなし）。
ネガティブなメッセージを送るとなぐさめてくれる（定型）。

※今回作ったサンプルBotはここからお試しいただけます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/66a1f605-3534-f631-9dc0-eef1a5f685e0.png)

## 使った技術
* [LINE Messaging API](https://developers.line.biz/ja/services/messaging-api/) - LINE Bot開発に必須
* [Microsoft Flow](https://japan.flow.microsoft.com/ja-jp/) - Messaging APIのバックエンド全般を担当、各APIの仲介
* [COTOHA API](https://api.ce-cotoha.com/contents/) - 感情分析のAPIをなぐさめるべきかの判定に使用 ※開発者アカウントを使用
* [A3RT Talk API](https://a3rt.recruit-tech.co.jp/product/talkAPI/) - 日常会話応答機能を提供してくれる

## つくりかた
※注意※
以前書いた記事、[賢いLINE Botを完全無料＆ノンコーディングで開発する（Dialogflow＋Microsoft Flow）](https://qiita.com/himarin269/items/5c0190a13f95b5538546)では各手順をかなり細かく書きました。
本記事では要点のみ記載しており、上記と共通する部分は特に端折っています。必要に応じて上記記事や他の情報もご参照ください。

### 1. Messaging APIでのチャネル作成
Messaging APIでLINE Botのチャネルを作成し、必要な設定を済ませておきます（省略）。
ReplyのAPIしか使わないので、フリープランです。
アイコンは、「ナグサメくん」なのでサメの絵にしました。
https://www.irasutoya.com/2013/01/blog-post_29.html

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/48734f13-dfbb-b5c0-01da-9e8f43e3e6f8.png)

絶対にやる必要があること：

* アクセストークン再発行（0で無期限）
* 自動応答メッセージを「利用しない」に


### 2. Microsoft Flowでのバックエンド作成
Messaging APIのWebhook先としてMicrosoft FlowのHTTPトリガーフローを使います。
Microsoft Flowにサインインし、新規フローを作成します。トリガーは「HTTP要求の受信時」です。

[Messaging APIの公式ドキュメント](https://developers.line.biz/ja/reference/messaging-api/#webhook-event-objects)のイベントメッセージの例に記載されているJSONを使い、スキーマ登録します。

```json
{
  "destination": "xxxxxxxxxx", 
  "events": [
    {
      "replyToken": "0f3779fba3b349968c5d07db31eab56f",
      "type": "message",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      },
      "message": {
        "id": "325708",
        "type": "text",
        "text": "Hello, world"
      }
    },
    {
      "replyToken": "8cf9239d56244f4197887e939187e19e",
      "type": "follow",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      }
    }
  ]
}
```
「サンプルのペイロードを使用してスキーマを生成する」から上記JSONを貼り付ければOKです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/356e7df4-9847-7979-2134-8a247d0270e9.png)

次に「新しいステップ」で組み込み→HTTPのアクションを追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/00713a2c-478b-9ecc-62d1-b7a340fee46e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/5dfbd56c-d68f-bcc0-7139-03c87e23d225.png)

* 方法に `POST`
* URIに `https://api.line.me/v2/bot/message/reply`
* ヘッダーに `Content-Type` : `application/json`
* ヘッダーに `Authorization` : `Bearer { アクセストークン }`

を設定し、先ほどと同じく[公式ドキュメント](https://developers.line.biz/ja/reference/messaging-api/#send-reply-message)を参考に以下のJSONを返答の本文に貼り付けます。

```json
{
    "replyToken":"nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
    "messages":[
        {
            "type":"text",
            "text":"Hello, user"
        }
    ]
}
```
そして、replyTokenとtextの内容を「動的なコンテンツ」からそれぞれ「replyToken」「text」に変更します。 

「Apply to each」が自動で追加され、フローが完成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/a908b5b4-60b2-2baf-d946-7cf623183480.png)

これで、ユーザーからの入力内容をそのまま返すオウム返しBotになります。

いったんフローを保存し、URLを生成・コピーし、Messaging APIのチャネル側に設定し、Webhook送信を「利用する」に変更します。
※追記：Webhook URLを設定する前に変更しようとしても「利用しない」に戻ってしまうので、必ずWebhook URLを設定してから変更してください


このタイミングで、LINEで動作確認をするとこうなります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/194664/eec401b7-ef3f-426e-d0a6-634e289b746d.png" width="350px">


※任意ですが、一番最後に「応答」のブロックを付けておくとLINE Developersから接続確認した際にエラーが出なくなります

### 3. A3RT Talk APIによる日常会話対応
A3RTの[Talk APIのページ](https://a3rt.recruit-tech.co.jp/product/talkAPI/)より、API KEYの発行を行います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/6fae58e6-5bfb-413c-5b7d-8e91c2999ac8.png)

利用規約を読んで（すべてスクロールしないと先に進めない）メールアドレスを登録し、そのメールに届いた確認URLにアクセスするとAPI KEYがメールで送られてきます。

Microsoft Flowで「Apple to each」内の「HTTP」の前の＋をクリックして新たにHTTPのアクションを追加します。
追加された「HTTP 2」には、

* 方法に `POST`
* URIに `https://api.a3rt.recruit-tech.co.jp/talk/v1/smalltalk`
* ヘッダーに `Content-Type` : `application/x-www-form-urlencoded` **※重要！**
* 本文に `apikey=（送られてきたAPI KEY）&query=（動的コンテンツの「text」）`

を入れます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/764e6951-47ba-8a31-9567-a7509a073556.png)


続いて「HTTP 2」と「HTTP」の間に「組み込み」→「データ操作」→「JSONの解析」のアクションを追加します。

コンテンツには動的なコンテンツのなかから「HTTP 2」の「本文」（APIからのレスポンスです）を設定し、解析のためのJSONスキーマ情報はサンプルのペイロードに以下のJSONを使用し、生成します。

```json
{
	"status": 0,
	"message": "ok",
	"results": [{
		"perplexity": 2.3688167429546714,
		"reply": "おはようございます"
	}]
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/91c97465-2306-06a5-d08a-9a03f6902d80.png)

そのあとに続く最後の「HTTP」のブロックの、本文で使っていた「text」を、JSONの解析結果の「reply」に変更します。
すると、自動で「Apply to each 2」が追加され以下のようになると思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/c0b46d8d-ecd8-d382-82b5-1c8c61807762.png)

この状態で、Botが雑談に対応します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/194664/8d22d356-4720-c56f-c9ac-852edaa11f82.png" width="350px">


### 4. COTOHA APIによる感情分析対応（ネガポジ）
[COTOHA API Portal](https://api.ce-cotoha.com/contents/index.html)から無料で試せる開発者用アカウント（for Developersアカウント）を発行します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/b454dc04-70d4-7946-a15d-a0831a808808.png)

画面の指示に従い登録ができたら、登録情報を確認します。

Microsoft Flowで最初の「HTTP要求の受信時」ブロックの次にHTTPアクションを追加し

* 方法に `POST`
* URIに `https://api.ce-cotoha.com/v1/oauth/accesstokens`
* ヘッダーに `Content-Type` : `application/json`
* ヘッダーに `charset` : `UTF-8`
* 本文に自身の登録情報で以下

```json
{
  "grantType":"client_credentials",
  "clientId":"[client id]",
  "clientSecret":"[client secret]"
}
```

を設定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/3f8fd17c-64d7-5d0a-b403-3cdc484d93be.png)

そしてその下に組み込み→データ操作→JSONの解析を追加し、コンテンツに「HTTP 3」の「本文」を設定し、以下のJSONをもとにスキーマ生成します。

```json
{
            "access_token": "[access_token]",
            "token_type": "bearer",
            "expires_in": "86399" ,
            "scope": "" ,
            "issued_at": "1545040132138"
}
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/977cb605-effe-75a0-1649-f74196b04b4d.png)


さらに「HTTP 2」（A3RT Talk APIにアクセスしているブロック）の手前にさらにHTTPのアクションを追加します。
以下登録例です（COTOHA APIの登録情報をもとに設定してください）。

* 方法に `POST`
* URIに `https://api.ce-cotoha.com/api/dev/nlp/v1/sentiment`
* ヘッダーに `Content-Type` : `application/json`
* ヘッダーに `charset` : `UTF-8`
* ヘッダーに `Authorization` : `Bearer ` + 「JSONの解析 2」の「access_token」
* 本文に `{ "sentence": "（text）" }`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/a2f1ab0d-7cee-8763-42a7-20ae88dd1367.png)

これでユーザーの入力文字列をCOTOHA APIの感情分析APIにかけた結果が取得できるので、JSONで解析します。
レスポンスサンプルの以下を使用します。

```json
{
  "result":
    {
    "sentiment":"Positive",
    "score":0.20766788536018937,
    "emotional_phrase":[
      {
        "form":"謳歌",
        "emotion":"喜ぶ,安心"
      }
    ]
  },
  "status":0,
  "message":"OK"
}
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/13b39016-9579-05e3-0ab9-d76371b0eeea.png)

そしてその結果による分岐を追加します。
「制御」の「条件」を追加し、
さきほどの解析結果の「sentiment」が「Negative」だったら、という条件にします。
「いいえ」側に後続の「HTTP 2」「JSONの解析」「Apply to each 2」をD&Dで移動させます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/3d5b4f2f-2aaa-ab6d-2587-63d906797883.png)


「はい」側には固定のなぐさめメッセージとして以下のようにHTTPアクションを追加します。
各情報は最初の「HTTP」アクションと同じなので、そちらと同様に値を入れてください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/194664/abe80321-d2cb-a189-c969-d309e4dc5b78.png)

### 5. 動作確認
こんなかんじです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/194664/03302d5f-98ad-e585-0cde-92efe1d6ca70.png" width="350px">

発展例としては、なぐさめメッセージをランダムで数通りから選ばれるようにしたり（Microsoft Flowでrand関数を使えば乱数生成できるのでそれに基づく分岐を作る）、A3RT Talk API単体でも励ましのメッセージをくれることも多いためA3RT Talk APIのレスポンスは活かしつつスタンプを付与したりする（分岐の位置を変える）、なども考えられます。

## おわりに
まったく難しいことをせずに、AIの恩恵を受けることができました。
最近は無料や低価格なAI系サービス／APIが増えてきました。そしてそれらをつなげ、ユーザーに価値として届ける手段も増えています。
さまざまなAPIをつなげることで新しい価値がたくさん生み出される世の中になりつつあると思うと、とてもわくわくしますね。

以上です。