LoginSignup
94
84

More than 5 years have passed since last update.

LINE Messaging API を使用して、会話の「くっころ」という言葉に反応して「くっころ」してしまうBOTを作成する方法

Posted at

始めに

Node.js の勉強のために、LINE Messaging API を使用したBOTを作成しました。
Qiitaには LINE BOT API についての記事は多かったのですが、LINE Messaging API についての記事は少なかったため、共有します。

作ったもの

LINEの会話の「くっころ」という言葉に反応して、「くっころ」してしまうBOTです。
1対1の会話と、トークルームでの会話に対応しています。
ソースは以下で公開しています。
https://github.com/k-nakayama-pg/kukkoro-bot

キャプチャ.PNG

作成方法

1.LINE Messaging API の登録

Messaging APIのご紹介 | LINE Business Center から登録できるので、必要な情報を入力して登録してください。

2.LINE@ MANAGER でWebhook送信を利用するに設定

登録が終わるとLINE@ MANAGER という画面に移ると思います。
ここで [アカウント設定]>[BOT設定]>[リクエスト設定]のWebhook送信を「利用する」にチェックを入れてください。
これを忘れると、後で設定するWebhook URLを設定してもリクエストがBOTに送信されません(実体験)

キャプチャ2.PNG

3.LINE Developers でChannel SecretとChannel Access Tokenを確認

LINE@ MANAGERの[アカウント設定]>[BOT設定]>[ステータス]の「LINE Developersで設定する」というリンクからLINE Developersの画面に行きます。そこで、Messaging APIに必要な以下の2つの値を確認してください。
 - Channel Secret : リクエストがLINE Platformから送られてきたか署名検証する際に必要になります
 - Channel Access Token : Messaging APIの認証に必要になります

キャプチャ3.PNG

キャプチャ4.PNG

4.LINE Platformからリクエストを受け取って、Messaging APIに返事のテキストを送信するBOTの作成

以下がソースです。
Nodejs+LINE BOTでレストラン検索 - Qiita を参考にして作成しました。
Messaging APIから受け取るレスポンスやリクエストの方法は、LINE Developers API Document に詳しく説明されていたため、それを参考にしました。

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var request = require('request');
var crypto = require("crypto");
var async = require('async');

app.set('port', (process.env.PORT || 8000));
// JSONの送信を許可
app.use(bodyParser.urlencoded({
    extended: true
}));
// JSONのパースを楽に(受信時)
app.use(bodyParser.json());

app.post('/callback', function(req, res) {
    async.waterfall([
            function(callback) {
                // リクエストがLINE Platformから送られてきたか確認する
                if (!validate_signature(req.headers['x-line-signature'], req.body)) {
                    return;
                }
                // テキストが送られてきた場合のみ返事をする
                if ((req.body['events'][0]['type'] != 'message') || (req.body['events'][0]['message']['type'] != 'text')) {
                    return;
                }
                // 「くっころ」という単語がテキストに含まれている場合のみ返事をする
                if (req.body['events'][0]['message']['text'].indexOf('くっころ') == -1) {
                    return;
                }

                // 1対1のチャットの場合は相手のユーザ名で返事をする
                // グループチャットの場合はユーザ名が分からないので、「貴様ら」で返事をする
                if (req.body['events'][0]['source']['type'] == 'user') {
                    // ユーザIDでLINEのプロファイルを検索して、ユーザ名を取得する
                    var user_id = req.body['events'][0]['source']['userId'];
                    var get_profile_options = {
                        url: 'https://api.line.me/v2/bot/profile/' + user_id,
                        proxy: process.env.FIXIE_URL,
                        json: true,
                        headers: {
                            'Authorization': 'Bearer {' + process.env.LINE_CHANNEL_ACCESS_TOKEN + '}'
                        }
                    };
                    request.get(get_profile_options, function(error, response, body) {
                        if (!error && response.statusCode == 200) {
                            callback(body['displayName']);
                        }
                    });
                } else if ('room' == req.body['events'][0]['source']['type']) {
                    callback('貴様ら');
                }
            },
        ],
        function(displayName) {
            //ヘッダーを定義
            var headers = {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer {' + process.env.LINE_CHANNEL_ACCESS_TOKEN + '}',
            };

            // 送信データ作成
            var data = {
                'replyToken': req.body['events'][0]['replyToken'],
                "messages": [{
                    "type": "text",
                    "text": displayName + 'にこんな辱めを受けるとは...!\nくっ...殺せ!'
                }]
            };

            //オプションを定義
            var options = {
                url: 'https://api.line.me/v2/bot/message/reply',
                proxy: process.env.FIXIE_URL,
                headers: headers,
                json: true,
                body: data
            };

            request.post(options, function(error, response, body) {
                if (!error && response.statusCode == 200) {
                    console.log(body);
                } else {
                    console.log('error: ' + JSON.stringify(response));
                }
            });
        }
    );
});

app.listen(app.get('port'), function() {
    console.log('Node app is running');
});

// 署名検証
function validate_signature(signature, body) {
    return signature == crypto.createHmac('sha256', process.env.LINE_CHANNEL_SECRET).update(new Buffer(JSON.stringify(body), 'utf8')).digest('base64');
}

気をつけたところ

1.リクエストがLINE Platformから送られてきたか確認

 
LINE Developers API Document で以下のような記述がありました。

X-Line-Signature Request Headerに入っているSignatureを検証することによって、
リクエストがLINE Platformから送信されたものであることを確認する必要があります。

検証は以下の手順で行います。

  1. Channel Secretを秘密鍵として、HMAC-SHA256アルゴリズムによりRequest Bodyのダイジェスト値を得る。
  2. ダイジェスト値をBASE64エンコードした文字列が、Request Headerに付与されたSignatureと一致することを確認する。

検証には3.で確認したChannel Secretが必要になります。
ソース内の validate_signature(signature, body) メソッドが検証をしているメソッドになります。
LINE Messaging APIでX-Line-Signatureの署名検証を行う - Qiita を参考にしました。

2.Messaging API にリクエストする時のパラメータ

Messaging APIは、それまでのBOT APIと違って、リクエスト時に必要なパラメータが違いました。
BOT APIの時に必要だったMIDはなくなりました。
Messaging APIには以下のパラメータが必要です。

  • Request Headers
    • Authorization : Bearer {Channel Access Token}(3.で確認したChannel Access Token)
  • Request Body
    • replyToken : Webhookで受信したreplyToken(webhookからのリクエストのbody内に入っています)

詳しくはLINE Developers API Documentを参考にしてください。

5.herokuにソースをデプロイ

herokuへのデプロイはたくさん記事があるのでここでは書きません。
Channel SecretとChannel Access Tokenを忘れずに環境変数に追加してください。

6.Webhook URLの設定

最後の設定です。デプロイしたソースのアクセスURLをWebhook URLに設定します。
LINE BOT の参加しているトークルームや友達から会話があると、ここに設定したURLにリクエストが送られるようになります。
LINE Developersから設定できます。

キャプチャ5.PNG

7.動作確認

作成したLINE BOT を友達に追加して、話しかけることで確認できます。

キャプチャ6.PNG

まとめ

LINE Messaging APIはドキュメントが丁寧に書かれていたため、特につまづくことなく作成することができました。
特にLINE Developers API Documentには、APIの説明だけでなく、各言語別の実装サンプルコードまで書いてあったため、すごく助かりました。
皆さんも、LINE Messaging APIを使ってLINE BOTを作ってみてください。

94
84
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
94
84