Notionデータベースで設定した日付から任意のタイミングでLINE Notifyに通知できたよ
概要ときっかけ
Notionで防災用の備蓄品リストを作り、賞味期限が1ヶ月前・1週間前・期限切れになった日にLINEで通知してくれる仕組みづくりにトライしました。
Notion内でもリマインド機能はありますが、Notionアプリに通知が届くのでうっかり忘れがち&設定タイミングの最長は1週間前・・消費したいので1か月前が嬉しい・・ということで、もう少し細かい設定ができる方法を探してみました。
📛 今回はピンポイント時刻の設定ではありません。午前9時~10時の間というような時間帯指定です。ピンポイント(例:9時半)にしたい場合はもう少し処理が必要ですが、今回は未対応です。
そもそもNotionって何?
ワークフローやデータを一元管理できるツール「Notion」。本や映画の鑑賞リストや、タスク管理、単語帳など活用方法は様々。PCのブラウザ、PCアプリ、スマホアプリもあり、個人なら無料プランで十分使い倒せる勢いです。
2018年リリース、2022年日本語版対応と新しいサービスですが、世界3,000万人以上のユーザーがおり、日本でも三菱重工やサントリーといった大企業も活用しているとのこと。操作性・拡張性が高く生産効率を高めるツールなんですね~。
ちなみに私の活用方法の一例はブックリスト。(内容はスルー願います🥳)
デモ画面
Notionの備蓄品リスト
以下の画像を見ていただくと、テーブル一行目の「テスト」の「賞味/消費期限」が現時点で1か月を切っています。
※補足:「消費目安」列の中身は関数を入れています。本通知には関係ありませんが一覧表示した際に分かり易くするためのもの。
LINE Notifyに届いた通知内容
私個人に通知されるようにしていますが、設定で対象LINEグループに送ることも可能です。家族間グループとかでもいいかもしれませんね。通知内容も任意で変更可能です。
Notionの備品リスト内のステータス変更
本通知は、毎日1回処理を実行する仕組みとしています。各通知を連日送る必要はありませんので、送るか否かの判断条件として「通知ステータス」という項目(プロパティ)を用意しました。通知後はこのステータスを変更するようになっています。
作り方
できるだけ分かかり易い言葉を使って説明したいと思いますので、厳密にいえば正しい単語ではない場合もあります。ニュアンスでご理解ください。
使うサービス(全部無料)
Notion(自分のワークスペースでデータベースを作る)
Notion API(上記のデータを取得するためのキーを得る)
LINE Notify(対象トークルームへ通知するキーを得る)
Google Apps Script(プログラム処理とトリガーを設定)
🔰 前提:Notionのアカウント登録は済んでいるものとします。
手順① [Notion API] 後続の手順②で作成するNotionテーブルのデータを参照するためのインテグレーションを作成
※インテグレーション:異なるシステムや要素を組み合わせること
以下のリンク先で新しいインテグレーションを作成https://www.notion.so/my-integrations
「内部インテグレーションシークレット」の値を手元のメモ帳などに一旦コピペしておく【コピーA】
手順② [Notion] 自分のワークスペースでテーブル(データベース)を作る&コネクト追加する&データベースIDを得る
新規ページで「テーブル」を作成。必要最低限のプロパティは以下の3つ(左右スクロールできます)
$$
\begin{array}{l:l:l:l}
プロパティ名 & 種類 & オプション & 備考 \\ \hline
名前 & タイトル & - & デフォルトです \\
賞味期限 & 日付 & - & 「日付の形式」は「完全な日付」に \\
通知ステータス & セレクト & 未通知/1か月前/1週間前/期限切れ & 初期値は「未通知」とします \\
\end{array}
$$
作成したテーブル(データベース)に、手順①で作成したインテグレーションをコネクト追加する
ブラウザ版でURLを確認し、以下の`{database_id}`にあたる値を手元のメモ帳などにコピペしておく【コピーB】
手順③ [LINE Notify] 対象トークルームへ通知するキーを得る
以下のリンク先にてLINEアカウントでログインする
マイページからアクセストークンを発行する
通知用のタイトルを入力
通知先のトークルームを選択(個人なら1:1、グループトークも可)
発行されたトークンを手元のメモ帳などにコピペしておく【コピーC】
手順④ [Google Apps Script] プログラム処理とトリガーを設定
以下リンク先のGoogle Apps Script(GAS)で「新しいプロジェクト」を作成
「コード.gs」のファイルに後述のソースコードをコピペ
「実行」でLINE通知&Notionテーブルの通知ステータス更新を確認
実行タイミングを決めるトリガーを設定
毎日1回、設定した時間帯に処理が実行されます
通知の必要が無ければ通知はされません
今回はピンポイント時刻の設定ではありません。午前9時~10時の間というような時間帯指定です。ピンポイント(例:9時半)にしたい場合はもう少し処理が必要ですが、今回は未対応です。
《コード.gsへのコピペソースコード》
const NOTION_API_KEY = 'コピーAの値に置き換えてください'; // 【コピーA】
const DATABASE_ID = 'コピーBの値に置き換えてください'; // 【コピーB】
const LINE_NOTIFY_API_TOKEN = 'コピーCの値に置き換えてください'; // 【コピーC】
/**
* メイン処理
*/
function sendNotification() {
// 通知対象アイテム取得
const itemsToNotify = getItemsToNotify();
itemsToNotify.forEach(item => {
// 日付の整形
const formattedExpiry = formatDate(item.expiry);
// LINE通知
sendLineMessage(item.name, formattedExpiry, item.afterNoticeStatus);
// 通知を送ったらNotionテーブルの通知ステータスを更新
updateNotificationStatus(item.id, item.afterNoticeStatus);
});
}
/**
* 通知対象アイテムをすべて取得
*/
function getItemsToNotify() {
const today = new Date();
const url = `https://api.notion.com/v1/databases/${DATABASE_ID}/query`;
const options = {
method: 'POST',
headers: {
'Authorization': `Bearer ${NOTION_API_KEY}`,
'Content-Type': 'application/json',
"Notion-Version": "2022-06-28",
},
payload: JSON.stringify({
filter: {
property: '賞味期限',
date: {
on_or_after: today, // 実行日(含む)より未来の日付
},
},
}),
};
// 「賞味期限」が期限切れ前(当日含む)をいったんすべて取得
const response = UrlFetchApp.fetch(url, options);
const data = JSON.parse(response.getContentText());
const items = data.results.map(item => {
const expiryDate = new Date(item.properties['賞味期限'].date.start);
// 変更後の通知ステータスを設定
const afterNoticeStatus = setAfterNotificationStatus(expiryDate, today);
return {
id: item.id,
name: item.properties['名前'].title[0].text.content,
expiry: expiryDate.toISOString().split('T')[0],
// 現時点の通知ステータス
currentNoticeStatus: item.properties['通知ステータス'].select.name,
afterNoticeStatus: afterNoticeStatus,
};
});
// 実行日時点で既に該当通知済みのアイテムは除く
return items.filter(item => item.afterNoticeStatus !== item.currentNoticeStatus);
}
/**
* 実行日時点で更新されるべき「通知ステータス」を設定
*/
function setAfterNotificationStatus(expiryDate, today) {
// 期限:1か月前を設定
const oneMonthAgo = new Date(today);
oneMonthAgo.setMonth(oneMonthAgo.getMonth() + 1);
// 期限:1週間前を設定
const oneWeekAgo = new Date(today);
oneWeekAgo.setDate(oneWeekAgo.getDate() + 7);
// アイテムの期限ごとに通知ステータスを判断
if (expiryDate <= today) {
return '期限切れ';
} else if (expiryDate <= oneWeekAgo) {
return '1週間前';
} else if (expiryDate <= oneMonthAgo) {
return '1か月前';
} else {
return '未通知';
}
}
/**
* LINE通知内容に記述する「賞味期限」の日付整形
* 例: "2024/01/22"
*/
function formatDate(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString('ja-JP');
}
/**
* LINE通知
*/
function sendLineMessage(name, expiry, afterStatus) {
// 通知内容の整形
const message = `\n\n【買い替え時:${afterStatus}】\n- アイテム: ${name}\n- 賞味期限: ${expiry}`;
const notifyUrl = 'https://notify-api.line.me/api/notify';
const options = {
method: 'POST',
headers: {
'Authorization': `Bearer ${LINE_NOTIFY_API_TOKEN}`,
'Content-Type': 'application/x-www-form-urlencoded',
},
payload: {
message: message,
},
};
UrlFetchApp.fetch(notifyUrl, options);
}
/**
* Notionデータベースの「通知ステータス」を更新
*/
function updateNotificationStatus(itemId, afterStatus) {
const url = `https://api.notion.com/v1/pages/${itemId}`;
const options = {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${NOTION_API_KEY}`,
'Content-Type': 'application/json',
"Notion-Version": "2022-06-28",
},
payload: JSON.stringify({
properties: {
'通知ステータス': {
select: {
name: afterStatus,
},
},
},
}),
};
UrlFetchApp.fetch(url, options);
}
おわりに
以上です。
杞憂かもしれませんが、備蓄品の賞味期限が切れる前にNotionやLINEやGASの仕様が変わったり、最悪サービス終了にならないかだけ心配ですね🙃
ざーっと作ったのでソースコードに誤りがあればこっそり教えてください。
🙇♀️参考にさせていただいたサイト
この記事が気に入ったらサポートをしてみませんか?