LoginSignup
10
11

More than 5 years have passed since last update.

ゼロから始めるLINEBot(AWS×node.js) ①とりあえず動かす

Last updated at Posted at 2017-10-29

この記事で分かること

  • 決まった時間に決まった文章を喋るとこまで
  • 自分がハマったポイント

この記事の対象者

  • いろいろと初心者(自分がそうなので)
  • MessagingAPIのような外部APIを使ったことがない
  • AWSもあんま詳しくない(アカウントは持ってるくらい)

流れ

第1回 とりあえず動かす (この記事)
1.LINE Developersの登録/設定
2.実装(Lambda/node.js)
3.定期実行の設定(CloudWatch)

第2回 オウム返しの実装
4.ドメイン取得,DNS設定,SSL証明書の設定(Route53/ACM/SNS/S3)
5.イベントの受け取り(APIGateWay)
6.ユーザへの返信(Lambda/node.js)

第3回 ユーザ情報、投稿画像の保存 (予定)
7.DBの連携

1. LINE Developersの登録/設定

以下から。
https://developers.line.me/ja/
プロバイダーを作成し、その中にChannelを作成します。
ここまでは公式の説明に沿って行けば大丈夫だと思います。

次に、デフォルトの設定を以下の画像の通りに設定します。
・アクセストークンはこの画面から再発行が可能ですが、最大24時間で切れてしまうので後々自動更新を実装します。 →これは再発行時に、古いトークンが切れる期限であって、ここで設定する長期アクセストークンは有効期限はもっと長かったです。短期アクセストークンでも30日間有効でした。
・WebHook URLは次回の記事で設定します。とりあえず空欄でOK
・その他の設定はキャプチャ通りに設定

スクリーンショット 2017-10-29 02.48.17.png

2. 実装(Lambda/node.js)

AWSにログインして、Lambda→関数の作成→一から作成

  • [名前]...好きな名前
  • [ロール]...[カスタムロールの作成]を選択。

IAM設定画面が開くので、以下のように設定

  • [IAMロール]...[新しいIAMロールの作成]
  • [ロール名]...好きな名前

スクリーンショット 2017-10-29 09.49.23.png

ポリシードキュメント(CloudWatchへの権限だけ付与。デフォルト設定)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    }
  ]
}

[許可]を押してIAMロールを作ったら、そのロールを指定して、Lambda関数を作成。
Lambda関数が作成されたら、関数コードに以下をコピペ。

  • ランタイムはnode.js6.10で動作確認済みです。
  • jsファイル名がindex.jsだと思うので、ハンドラ名はindex.handlerとしてください。
index.js
var https = require('https');
exports.handler = (event, context, callback) => {

    var data = JSON.stringify({
       "to": process.env.USER_ID,//CHANNEL設定画面で確認
       "messages": [
         {
           "type": "text", 
           "text": "そろそろ寝ろ!!"
         }
       ]
    });
    opts = {
        hostname: 'api.line.me',
        path: '/v2/bot/message/push',
        headers: {
            "Content-type": "application/json; charset=UTF-8",
            "Content-Length": Buffer.byteLength(data),
            "Authorization": "Bearer " + process.env.CHANNEL_ACCESS_TOKEN//CHANNEL設定画面で確認
        },
        method: 'POST',
    };

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

LINE側のCHANNEL設定画面から、Your UserIDとアクセストークンを確認して、環境変数に設定します。

  • USER_ID...Your UserID。グループIDや他の人のID取得方法は割愛。
  • CHANNEL_ACCESS_TOKEN...アクセストークン。

スクリーンショット 2017-10-29 10.34.18.png

ここで注意点。

ネットでググると似た記事が複数出てくるのですが、総じて動きませんでした。。
なんの仕様変更なのか、リクエストヘッダーへのContent-Lengthの指定が必須です。

そのため、body(ここではdataという変数)のバイト長を以下のように取得してヘッダーに含めました。
確か2016/10頃にChromeのバージョンアップでも同様のことがあって仕事で対応した気がします。。

プログラムからリクエストを送る場合は必ずContent-Lengthを付けましょう。
"Content-Length": Buffer.byteLength(data),

テスト実行をしてみると、無事LINE上でメッセージが飛んできました!

スクリーンショット 2017-10-29 10.30.03.png

lambda上は正常終了してるのに反応がない場合はcurlで確認すると良いでしょう。

curlコマンドでリクエスト投げるならこう
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer [AccesToken]' -d '{  "to": "[User ID]", "messages":[{"type":"text","text":"curlコマンドから投稿"}]}' https://api.line.me/v2/bot/message/push

3.定期実行の設定(CloudWatch)

さて、僕は夜更かしなので24時なったら寝るように促してくれると嬉しいです。
CloudWatchにcronの設定をします。

※標準時で設定してくださいね。

スクリーンショット 2017-10-29 12.41.49.png

以上です。

上にも書きましたが、AccessTokenが切れると使えなくなってしまいます。
続きの記事で対応しますが、とりあえず動かすことができました。

次回は、ユーザの投稿をHookしてオウム返しする機能をつくります。

所感

  • 1年未満の記事ですら動かないものばかり。コピペプログラマの自分にはしんどい
  • ゼロから記事って、どこまでゼロから書くべきなのか悩む。
10
11
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
10
11