Edited at

ゴミ出し日の前日にLINEで通知してくれるアプリを作る(Node.js / AWS Lambda)


ゴミ出し日の前日にLINEで通知してくれるアプリを作る


なぜ作るのか

1ヶ月半前でしょうか、新しく引っ越したマンションのゴミの分別が厳しい。

覚えるのもめんどくさいし、怒られるのも嫌なので、前日に通知してくれるやつ作ってしまおう。

というのがきっかけ。

レポジトリ


事前準備


LINE Developers (Messaging API)

image.png

LINE DevelopersでLINEアカウントでログインします。

[新規プロバイダー作成] - [新規チャネル作成] - [MessagingAPI]順で進み、

アプリの情報を書いていきましょう。

メッセージ送受信設定のところにあるアクセストークンと、

その他にあるYour user IDをメモしておきましょう。


Amazon Web Service (AWS Lambda, Amazon CloudWatch)

AWSにログインし、

Lambda関数の作成を行います。

image.png

これで事前準備は完了です。


ローカルでの環境

Lambdaのコンソールで作成しても良いのですが、便宜上ローカルで開発を行います。


npm

npm i @line/bot-sdk moment-timezone


ゴミ出し日ロジックの実装

まず、曜日を扱うので、moment-timezoneを使ってロジックを実装しました。


utils/date.js

const moment = require('moment-timezone');

moment.tz('Asia/Tokyo').locale('ja');

const Monday = 1;
const Tuesday = 2;
const Wednesday = 3;
const Thursday = 4;
const Friday = 5;
const Saturday = 6;
const Sunday = 7;

// 今日
function getMoment(date = new Date()) {
return moment(date)
.tz('Asia/Tokyo')
.locale('ja');
}

// 何番目の週か
function getWeekOfMonth(date) {
return Math.ceil(date.date() / 7);
}

module.exports = {
Monday: Monday,
Tuesday: Tuesday,
Wednesday: Wednesday,
Thursday: Thursday,
Friday: Friday,
Saturday: Saturday,
Sunday: Sunday,
getMoment: getMoment,
getWeekOfMonth: getWeekOfMonth,
};


私の住んでるところのゴミ出し日の情報を書いていきます。

可燃ゴミは水・土、不燃ゴミは2週・4週目の火曜日、資源ゴミは月曜日だったので、

以下のように書きました。


index.js

const {

getMoment,
getWeekOfMonth,
Monday,
Tuesday,
Wednesday,
Saturday,
} = require('./utils/date');

const info = {
burnable: {
message: '明日は燃やすゴミの日です',
days: [Wednesday, Saturday],
weeks: [],
},
unburnable: {
message: '明日は燃やさないゴミの日です',
days: [Tuesday],
weeks: [2, 4],
},
recyclable: {
message: '明日は資源ゴミの日です',
days: [Monday],
weeks: [],
},
};
...


そして、今日がゴミ出しの日かどうかを判断する関数を書けばOKです。


index.js

...

// 曜日が合ってるか
const isDateDay = (date, days = []) => {
return days.includes(date.day());
};

// 週が合ってるか
const isWeekDay = (date, weeks = []) => {
const weekOfMonth = getWeekOfMonth(date);
return weeks.length > 0 ? weeks.includes(weekOfMonth) : true;
};

// ゴミ出しの日か
const isTrashDay = (date, obj) => {
return isDateDay(date, obj.days) && isWeekDay(date, obj.weeks);
};

// ゴミ出しの日だったら、メッセージを返す
const getMessage = date => {
let message = undefined;
Object.keys(info).forEach(key => {
const obj = info[key];
if (isTrashDay(date, obj)) message = obj.message;
});
return message;
};
...



LINE Messaging APIの実装

@line/bot-sdkからlineをインポート、

一番最初にメモしておいたアクセストークンを使います。

ですが、そのまま書くのではなく、Lambdaでもenv設定ができるので、

process.env.ACCESS_TOKENを渡しましょう。


index.js

const line = require('@line/bot-sdk');

...

const client = new line.Client({
channelAccessToken: process.env.ACCESS_TOKEN
});


最後にメイン処理のhandlerを実装します。

requestが来たら、Lambdaがhandlerが実行されます。

もし、ゴミ出し日でなかったらメッセージは送られないように作っていきます。


index.js

exports.handler = async event => {

//明日がゴミ出し日かどうか
const tomorrow = getMoment().add(1, 'days');
const message = getMessage(tomorrow);

if (message) {
const postMessage = {
type:'text',
text: message,
}
try {
await client.pushMessage(process.env.USER_ID, postMessage);
} catch (error) {
console.log(error)
}

return {
statusCode: 200,
body: JSON.stringify(postMessage)
};
}

return {
statusCode: 200
}
};


client.pushMessageメソッドにUSER_IDと、postMessageを渡してあげることで完成です。


Lambdaの設定

今までローカルで作業してたフォルダーを圧縮し、.zipファイルにします。

image.png

書いたコードをアップロードできます。

そして、環境変数にACCESS_TOKENUSER_IDを設定しましょう。

image.png


CloudWatchで毎晩10時にeventを実行する

トリガーを追加CloudWatch Eventsを選び、

新しいルールを追加します。

image.png

私はスケジュール式でcron式を書きました。(時間はUTCで、日本の時間と違うので注意)

cron(0 13 * * ? *)

夜10:00に通知を送ってくれるようになりました。


最後に

image.png


いや、分別めんどくさいわ!