LINEのボイスメッセージを文字起こしするBotの開発①

## 背景
LINEのボイスメッセージ機能は送る側としてはかなり便利だと思うのですが、受信した側は音声を再生する必要があってイヤホンをつけていたり、スピーカーを使っても大丈夫な場所だったり、再生できる環境は限られていると思います。
そこでLINEのボイスメッセージをBOTに送ったとき、自動で文字起こしをしてくれたら、受け取る側として便利だろうなと思って開発しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56557/12bfff13-8683-ba6f-4228-8d217f40a8c8.gif" width="320px">


## 概要
基本的には、次の図のような構成になります。LINE Botを扱うAPIのことをLINE Messeging APIといい、サーバ上から呼び出します。サーバはnodejsで実装し、文字起こしには Google Cloud Speech APIを使用しました。しかし、Messeging APIから得られるのは、m4a形式のbufferで、Google Cloud Speech APIはm4a形式に対応していなかったので、サーバ上で変換を行ってから、APIに音声を投げています。
![LineBotImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56557/703bba97-22bd-36d4-2a87-e90ff64b03e5.png)

本投稿では、LINE Messeging API、サーバの実装、Google Cloud Speech APIの順番で執筆します。
本投稿で使用しているコードの全部の内容は次のgithubレポジトリに上がっています。
https://github.com/tommy19970714/Voice2TextBot

## LINE Messeging API
まず以下を参考に、developerアカウントを作成し、BOTを作成してください。以下のURLは、LINE developerのgetting startedのページです。
https://developers.line.biz/ja/docs/messaging-api/getting-started/

次のページまで辿り着いたら、「チャンネル基本設定」の項目から次を行ってください。

- Channel Secretをメモしてください。
- アクセストークン（ロングターム）を発行
- Webhook送信を「利用しない」から「利用する」に変更

<img width="885" alt="スクリーンショット 2019-06-01 1.09.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56557/dd8e2d52-4e5c-1baa-c21c-8785aa1548fb.png">

## webhook
LINE Botを動かすには、先程のチャンネル基本設定ページのWebhookURLを登録する必要があります。
SSLが必要なのですが、証明書の取得など手間がかかるので、今回は簡単に行うことができるように、手元のPCのlocalhostにグローバルからアクセスできるようにするトンネリングツールを利用します。
ngrokというツールをnpm経由でインストールします。

```
$ npm i -g ngrok
```

基本的に`ngrok http ポート名`と指定します。今回、expressを3000番ポートで開いているので、3000と指定します。

```
$ ngrok http 3000
```

立ち上がったら、httpsのurlに/webhookのエンドポイントを加えて、LINE developerページの「チャンネル基本設定」のWebhookURLを登録します。
`https://7535dgr6.ngrok.io/webhook`のように書きます。

ngrokの導入の仕方は、次のページで分かりやすく解説しています。因みにngrokにログインすると制限時間がなくなります。
https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d#3-ngrok%E3%81%A7%E3%83%88%E3%83%B3%E3%83%8D%E3%83%AA%E3%83%B3%E3%82%B0


## サーバ
基本的にnodejsで実装していきます。まずはlinebotとexpressのパッケージをインストールします。

```
$ npm i --save @line/bot-sdk express
```

以下はexpressでサーバを立ち上げ、'/webhook'のエンドポイントを作成しています。

```javascript:server.js
const express = require('express');
const line = require('@line/bot-sdk');

const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: 'xxxxxxxxxxxxxxxxxx',
    channelAccessToken: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
};

const lineClient = new line.Client(config);

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result))
      .catch((error) => {
        if(error.response) {
          console.log(error.response);
        }
        console.log("Problem submitting New Post: ", error);
      });
});

function handleEvent(event) {

    // for Connection check on developr console
    const replyToken = event.replyToken;
    if (replyToken === '00000000000000000000000000000000') {
        console.log('this request is connection check.');
        return {
            statusCode: 200,
        };
    }
    
    // if message is audio type
    if (event.message.type === 'audio') {
        console.log("this is voice messege"); 
    } else {
        console.log("this is not voice messege");
    } 
}
```

上記のコードを記入したら、以下のように3000番ポートでサーバを立ち上げましょう。これでLINE Botにメッセージを送るとボイスメッセージかどうかで異なった返答が返ってくると思います。

```
$ node server.js
```

## 次回

次回はサーバ上での音声バッファの変換の実装、Google Cloud Speech APIの設定の仕方について、書きます。
github上でも公開されているので参考にしてください。
https://github.com/tommy19970714/Voice2TextBot

次の記事になります。
https://qiita.com/tommy19970714/items/a09998312e44c6789f55