Node.jsでオウム返しLINE BOT （axios利用) #botawards


以前書いた[LINE BOTをNode.jsで外部依存モジュールを使用せずに作る](http://qiita.com/n0bisuke/items/56d7ace2193fbc106639)のコードをもとに先日[SuperAgent利用版](http://qiita.com/n0bisuke/items/52a0512782446fd52c2b)を書きました。今回はaxiosを利用してみます。

[LINE BOTのもくもく会](https://linedev.connpass.com/event/49885/)中に書いてます。

<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-version="7" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:37.5% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://www.instagram.com/p/BQP1X7mDmpK/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;" target="_blank">もくもく　#BotAwards</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">n0bisukeさん(@n0bisuke)が投稿した写真 - <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2017-02-08T10:33:33+00:00">2017  2月 8 2:33午前 PST</time></p></div></blockquote>
<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>

## axios

https://www.npmjs.com/package/axios

HTTPクライアントライブラリです。

[先日の#nodeschool_tokyo](https://nodejs.connpass.com/event/45720/)で会長がライブコーディングで使っていました。

SuperAgentのメソッドチェーン利用がしっくりこない人はaxiosを使う場合が多いようです。

基本の使い方は以下のような感じでPromiseな書き方で使えます。

```app.js
var axios = require('axios');

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
```

## LINE Botを作る

`Node.js v7.4.0`で試しています。

* 準備

```bash
$ mkdir mylinebot && cd mylinebot
$ npm init --yes
$ npm i --save axios
```

* app.jsを作る

「[LINE BOTをNode.jsで外部依存モジュールを使用せずに作る](http://qiita.com/n0bisuke/items/56d7ace2193fbc106639)」で利用してるコードからHTTPクライアントの部分を主に差し替えてます。

```app.js
'use strict';

const http = require('http');
const crypto = require('crypto');
const axios = require('axios');
const BASE_URL = 'https://api.line.me';
const REPLY_PATH = '/v2/bot/message/reply';//リプライ用
const CH_SECRET = process.env.SECRET || ''; //Channel Secretを指定
const CH_ACCESS_TOKEN = process.env.TOKEN || ''; //Channel Access Tokenを指定
const SIGNATURE = crypto.createHmac('sha256', CH_SECRET);
const PORT = process.env.PORT || 3000;

http.createServer((req, res) => {    
    if(req.url !== '/' || req.method !== 'POST'){
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('hello');
    }

    let body = '';
    req.on('data', (chunk) => {
        body += chunk;
    });        
    req.on('end', () => {
        if(body === ''){
          console.log('bodyが空です。');
          return;
        }

        let WebhookEventObject = JSON.parse(body).events[0];
        
        //メッセージが送られて来た場合
        if(WebhookEventObject.type === 'message'){
            let SendMessageObject;
            if(WebhookEventObject.message.type === 'text'){
                SendMessageObject = [{
                    type: 'text',
                    text: WebhookEventObject.message.text
                }];
            }

            axios.request({
                method: 'post',
                baseURL: BASE_URL,
                headers: {
                    'Content-Type': 'application/json; charset=UTF-8',
                    'X-Line-Signature': SIGNATURE,
                    'Authorization': `Bearer ${CH_ACCESS_TOKEN}`
                },
                url: REPLY_PATH,
                data: {replyToken: WebhookEventObject.replyToken, messages: SendMessageObject},
            }).then((res) => {
                console.log(res.status);
            })
            .catch((error) => {
                console.log(error);
            });
        }

        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('success');
    });
}).listen(PORT);

console.log(`Server running at ${PORT}`);
```

* 実行

(※)今回は`process.env.SECRET`と`process.env.TOKEN`からLINE BOTの`channel secret`と`channel access token`を受け取るようにしています。

```bash
$ SECRET=xxxx TOKEN=xxxxxxxx node app.js
```

これで実行するとおうむ返ししてくれるようになります。

##おわりに

axiosを使ってLINE BOT開発をしたい方の参考になれば幸いです。

まだもくもく会やるのできてくださいね〜

* 2/9 at LINE本社 https://linedev.connpass.com/event/49982/