はじめに
この記事は②です。
①.https://qiita.com/minatopi/items/0230de1d4f888943bfff
API作ったけど使いにくーい(あらすじ)
①の記事でAPIを作ったんだけど、感想で述べた通りに、pico w使って液晶に表示させてみたんだけど、記事数が多くて読み込むの重いし、限定的に表示するようにしました。
目標
LNE、pico wの液晶で、閲覧数、ハート数の変化を検知できるようにする。
LINEで検知
https://qiita.com/tomorrow56/items/3fe31d709fcc0ba1c806
上の記事を参考にしました。

と、

を入手して、これをgithabを使って自分のアカウントに送ります。
作りたいもの
- JSON取得
- 前回データとの差分比較
- 変化があればLINE通知
- 最新状態を保存
全体の流れ
JSON取得
│
▼
前回のデータ(cache.json)を読む
│
▼
差分を比較
│
└─2人以上に閲覧されている。イイネが押されている。
│
├─LINE通知
├─履歴(output.json)へ保存
│
┌────┘
│
├─それ以外
│
30日たっているなら、そのデータは削除
│
▼
最新データをcache.jsonへ保存
│
▼
heartbeat.txt更新
https://qiita.com/kouz496/items/338cdf601bc3f291480c
│┤├┌└などの書き方。
コード説明
1. 定数の定義
URL = "https://minatopi.github.io/chanpro-api/data.json"
ACCESS_TOKEN = os.environ.get("LINE_TOKEN")
USER_ID = os.environ.get("LINE_USER_ID")
ここでは
- 監視対象のJSON
- LINE Messaging APIのアクセストークン
- 通知先ユーザーID
を設定しています。
アクセストークンは環境変数から取得しているため、ソースコードへ秘密情報を書かずに済みます。
2. LINE通知
def send_line(msg):
この関数はLINE Messaging APIを利用してPush通知を送ります。
送信するJSONは
{
"to": "ユーザーID",
"messages": [
{
"type": "text",
"text": "通知内容"
}
]
}
というシンプルな構造です。
エラーが発生してもプログラム全体は停止せず、
try:
...
except Exception:
で安全に処理しています。
3. JSONの読み込み・保存
load_json()
load_json(path, default)
ファイルが存在すれば読み込み、
存在しない・壊れている場合は
default
を返します。
これにより初回実行でもエラーになりません。
save_json()
tmp = path + ".tmp"
一旦
cache.json.tmp
へ保存してから
os.replace()
で置き換えています。
これはアトミック書き込みと呼ばれる方法で、
途中で停止してもJSONファイルが壊れにくくなります。
4. Heartbeat
write_heartbeat()
現在時刻を
heartbeat.txt
へ保存しています。
2025-06-28T10:15:21+00:00
のようなISO8601形式になります。
これによって
- BOTが動いているか
- GitHub Actionsが正常終了したか
を確認できます。
5. JSON取得
def fetch():
ここでは
requests.get(URL)
でJSONを取得しています。
取得後
return r.json()
によってPythonの辞書へ変換します。
6. 履歴の整理
cleanup_history()
履歴は増え続けるため、
30日前
より古いデータを削除しています。
cutoff = now - timedelta(days=30)
として比較しています。
7. メイン処理
main()
ここがプログラム全体の中心になります。
最初に
cache.json
と
output.json
を読み込みます。
続いて最新JSONを取得します。
8. 初回実行
初回は比較対象がありません。
そのため
if not cache:
で判定しています。
初回は
記事タイトル
いいね数
閲覧数
だけ保存して終了します。
通知は送りません。
9. 差分比較
各記事について
title
をキーとして比較します。
prev = cache.get(title)
で前回データを取得します。
変化条件は
likeが変わった
または
閲覧数が2以上増えた
です。
if (
prev.get("like") != like
or (
views - prev.get("views") >= 2
)
):
という条件になっています。
10. LINE通知
変化があれば
📌 更新検知
記事タイトル
👍 10 → 12
👀 150 → 168
のようなメッセージを生成します。
send_line(msg)
を呼ぶだけで通知できます。
11. 履歴保存
通知した内容は
history.append()
で保存します。
保存されるデータは
{
"title": "...",
"like_before": 10,
"like_after": 12,
"views_before": 100,
"views_after": 108,
"updated_at": "2025-06-28T..."
}
となります。
これにより後から変化履歴を確認できます。
12. 最後に保存
最後に
save_json(CACHE_FILE, new_cache)
で今回取得したデータを保存します。
次回実行時はこれが比較対象になります。
今回のソースコード
今回のソースコード↓
https://github.com/minatopi/LINE-chanpro-Surveillance
動いているはずのAPI的な奴↓
https://minatopi.github.io/LINE-chanpro-Surveillance/output.json
感想
- LINEから、どれくらい見られているかわかりやすくなった。
- pico wの液晶ディスプレイからも見れるようになった。
- 30日後にはデータ消えるから、重くならない。