AWSLambdaを使用してLINE天気Botを作ってみた

執筆日: 2021-10-23

概要

私は傘をよく忘れます。
理由は簡単で、その日の天気予報を見ずして出発してしまうからです。
どうしたら忘れないのか、簡単に天気を確認できる方法はないだろうか、と考えていました。

そこでLINEで朝に定期通知で天気を送ったら見過ごすことはないのではないかと考えました。
それから生まれたのが「答えてみせるよ岩田くんBot」です。

今回はその過程と注意点など、共有していきたいと思います。

前提

以下を実施済みの前提で進めていきます。

  • LINE Developerの登録
  • AWS アカウントの登録

LINE Developerは以下のリンクから。
https://developers.line.biz/ja/

LINE Developer

LINE Developerにて設定・確認する事項がいくらかあります。

トークン確認

lambda関数とLINEで通信する際に必要なトークンなどを確認します。

Messageing API設定タブから、下方にあるチャネルアクセストークンを発行し、控えてください。

ld token

あとはユーザーIDを確認します。チャネル基本設定から確認できます。

ld userid

これらはlambda関数の環境変数で設定します。

Lambda関数作成

AWS Lambdaを選択し、「関数」タブから新たに関数を作成します。
名前はなんでも構いません。ここではcronLineWeatherReporter関数とします。

細かいコードの説明は省略させていただきます。

index.js
"use strict";
const { format } = require('date-fns');
const ja = require('date-fns/locale/ja');
const axios = require("axios");
const line = require("@line/bot-sdk");
const client = new line.Client({ channelAccessToken: process.env.ACCESSTOKEN });

exports.handler = async (event, context) => {
  const api = 'https://www.jma.go.jp/bosai/forecast/data/overview_forecast/340000.json'
  const { data } = await axios.get(api)
  const time = format(new Date(data.reportDatetime), 'yyyy/MM/dd EEEE HH:mm', {
    locale: ja
  })
  const area = data.targetArea
  const headlineText = data.headlineText
  const bodyText = data.text
  const resultText = `${area}\n${time}\n\n${headlineText}\n${bodyText}`
  const message = {
    type: "text",
    text: resultText,
  };
  // プッシュメッセージを送る
  try {
    await client.pushMessage(process.env.USERID, message)
    console.log('successed push message.')
  } catch (e) {
    console.log(e.message)
  }
};

先程、確認したトークンなどを環境変数に設定します。

setting env

パッケージ容量の肥大化問題

node_modulesと一緒にアップロードすると、パッケージ容量が大きすぎますと警告が出てしまいます。この状態だとインライン編集ができなくなります(関数は問題なく実行できます)。
インライン編集は結構便利なので、どうにかして問題を解決したいです。

解決:レイヤーの使用

そこでレイヤーを使用します。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html

左のタブからレイヤーを選択し、新たにレイヤー作成します。
名前は自分の決めた名前を指定します。ここでは「replyLineLayer」とします。

layer

ここで注意すべきことは、レイヤーはサポートするパスがあらかじめ決まっていることです。
いくらかありますが、Node.jsではnodejs/node_modulesになりますので、アップロードする際はnodejsディレクトリの中にnode_modulesを移動させて、圧縮する必要があります。

作成後は、再び関数を選択し、下にあるレイヤーの追加をします。

add layer

CoundWatch

定期実施設定のために、CloudWatchサービスを利用します。
AWSの検索からCloudWatchを選択し、ルールタブを開きます。

下記のような設定になります。

cloudwatch

cron式での注意点

今回は午前6時にlambda関数を実行したいです。
ここで重要なことは、UTC基準なので、JSTに変換して設定するということです。

日本時間に変換するには時差9時間ありますので、設定したい時間から9時間を引けば問題ありません。
0 21 * * ? *となります。

CloudWatchでは、独特のcron式があります。注意して設定します。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html

テスト実施

一通り実装できましたが、テストして実際に通知がくるか確認してみましょう。

lambdaから関数を選択し、テストタブを開きます。
新たにテストを作成します。

test lambda

テストを押下し、エラーなく実施できたことを確認します。

LINEにて通知確認

実際に通知がきているかを確認します。

LINE DeveloperのMessaging API設定にQRコードがありますので読み取ってください。
通知がきていれば成功です。

line reply

先程設定したCloudWatchでも一旦1分ごとに設定し、定刻に通知がなされるか確認した方がいいかもしれません。

感想

一つのLINE Botを作成するのに多くの設定や技術が使用されていたため、勉強になりました。

これで傘を忘れずに外出できればいいですね。私。

運営について

Natural Tearoomはシステム開発会社フロントエンドエンジニアがんちゃんが運営するメディアです。
フロントエンド技術を中心に発信しています。

SNS

SNSも積極的に配信しています。
よければフォローお願いします!

© 2021 天然珈琲店