JavaScript
lambda
APIGateway
LINEmessagingAPI

LineのMessaging APIとAWS(API GatewayとLambda)を使っておうむ返しbotを作って見た

初めてのQiita投稿

LineのMessaging APIを使ってやりたいことがあるから
その検証用で作って見た。

使ったもの

  • Messaging API
  • AWS Lambda
  • API Gateway

Messaging APIの使い方とかは色々と情報ある
Messaging APIでできることのまとめ - おーがの日記

あとは公式にもしっかりと書いてある
Messaging APIを利用するには
のでここら辺を参考に

そんなこんなでざっくりやりたいこと

  1. Lineで某友達に文字列を投稿する
  2. その文字列をAPI GateWayで受け取る
  3. 文字列をLambda(文字列受け取り)で受け取る
  4. 別のlambda(他のシステムへ橋渡し)をlambda(文字列受け取り)から起動する
  5. lambda(文字列受け取り)は他のシステムと連携して処理をする
  6. lambda(文字列受け取り)はlineに応答する(今回はおうむ返し)

blog.Linebot.png

今回、lambdaを二つに分けたのは機能別でlambdaを分けたかったから
lambdaの連携はStep FunctionやAPI GateWayをさらに噛ませる方法もあるが
今回は簡易的に実装するためにinvokeで連携した。

そんなこんなで以下実現したコード

bot.js
// load modules
var http = require("http");
var aws = require('aws-sdk');

exports.handler = (event, context, callback) => {
    console.log(event.body);
    var data = JSON.parse(event.body);
    var replyToken = data.events[0].replyToken;
    var text = data.events[0].message.text;
    var opts = {};


//linebot返却オプション
    var data = JSON.stringify({
       replyToken: replyToken,
       messages: [{type: "text", text: text}]
    });
    opts = {
        hostname: 'api.line.me',
        path: '/v2/bot/message/reply',
        method: 'POST',
        headers: {
            "Content-type": "application/json; charset=UTF-8",
            'Content-Length': Buffer.byteLength(data),
            "Authorization": "Bearer {Channel Access Token}" // LINE Developersの「Channel Access Token」を使用
        },
        json: data,
    };


//Linebotに返却
    var req = https.request(opts, function(res) {
        res.on('data', function(res) {
            console.log('SUCESS'+res.toString());
        }).on('error', function(e) {
            console.log('ERROR: ' + e.stack);
        });
    });
    req.write(data);
    req.end();

//外部呼び出し
    var lambda = new aws.Lambda({apiVersion: '2014-11-11'});
    var params = {
        FunctionName: "lamda name",
        InvokeArgs: JSON.stringify({
            "messages": [
                {
                "type": "text",
                "text": text
                }
            ]
        }
            , null, ' ')
        };

    lambda.invokeAsync(params, function(err, data){
        if(err) context.done(err, err.stack);
        else context.done(null, '');
    })
}

Lineのwebhook先にAPI Gatewayのendpointを設定したがこれはよくて
Lineはちゃんとしたサーバ証明書によるSSLでしか受け付けない
さらにちゃんと200 OKも返さないといけない(当然だが)
ただ遊ぶだけにサーバ証明書取るのはなんだかなぁ・・・
レスポンスもめんどくさいなぁ・・・というものぐさなわさしは
API GateWayのまともなSSLをしてレスポンスもよきに返してくれるので非常に楽だった。

ということで備忘録てきな初投稿