見出し画像

【自動化第4弾】note.comでいいね&コメントを自動化——非公式APIを掘り当てるまでの全記録

前回(第3弾)では、公式APIが突然死んだことをきっかけに、HTMLスクレイピングへ転換した話を書いた。投稿の自動化は完成した。だが、記事を書いて投稿するだけでは片手落ちだと気づいた。

発信だけして、他者の記事を読まないのはマナー違反だ。

note.comはSNSだ。フィードに流れてくる他のクリエイターの記事を読み、いいねを送り、コメントで感想を伝える。それが循環を生む。しかし手作業でこれをやると時間がかかる。ならば自動化するしかない。


1. 作るもの:engageコマンド

設計はシンプルだ。


フェーズ1(fetch):
新着記事を取得 → AIがコメント草案を生成 → YAMLキューに保存

フェーズ2(post):
ユーザーがYAMLを確認・編集 → いいね+コメントを実行

人間が草案をチェックする工程を必ず挟む。AIが勝手にコメントを垂れ流す設計にはしない。 これは信条だ。


2. 新着記事フィードの発見

最初の課題は「どの記事にいいねするか」だ。フォローしているクリエイターに限定する案もあったが、それでは出会いがない。note.com全体の新着を取りたい。

FirefoxのDevToolsを開き、note.comのトップページを眺める。ネットワークタブに流れるリクエストの中に、見覚えのないエンドポイントがあった。


GET /api/v3/notes?page=1&per=20

叩いてみると、全クリエイターの新着記事が返ってくる。しかもbodyフィールドにプレーンテキストの本文まで含まれている。スクレイピング不要だ。


{
"data": [
{
"type": "TextNote",
"key": "n8699e4e63db3",
"name": "記事タイトル",
"body": "本文テキスト...",
"user": { "urlname": "someuser", "nickname": "クリエイター名" }
}
],
"next_page": 2
}

--page Nフラグでページを指定すれば、毎回違う記事が取れる。10件ずつ処理するのが今のやり方だ。


3. いいねAPIの発見——v3、しかもIDではなくkeyで叩く

いいねのAPIは一筋縄ではいかなかった。最初に試したのはこれだ。


POST /api/v1/notes/{数値ID}/likes → 403 Forbidden

403。自分の記事への自己いいねが禁止されているのかと思った。違った。エンドポイント自体が間違っていた。

正しいエンドポイントはPythonのPlaywrightでブラウザの実際の通信を記録して発見した。


POST /api/v3/notes/{key}/likes

v3で、数値IDではなく英数字のkey(n58da77ec9658のような文字列)を使う。レスポンスはHTTP 201。これで動いた。


4. コメントAPIの発見——構造体JSONが必要だった

コメントも同じく罠があった。当初の実装はこうだ。


payload := map[string]string{"comment": "コメント本文"}
POST /api/v1/notes/{数値ID}/comments

実行すると全記事で「この記事はコメント機能が無効になっています」という403が返ってくる。10件全部。

嘘だ、と思った。実際にnote.comでコメント欄を開いて投稿ボタンを押し、DevToolsでリクエストをキャプチャした。


POST /api/v3/notes/{key}/note_comments

{
"comment": {
"type": "root",
"children": [{
"type": "element",
"tag_name": "p",
"children": [{"type": "text", "value": "コメント本文"}]
}]
},
"acknowledgement": false
}

エンドポイントもペイロードも全然違った。

  • v1ではなくv3

  • 数値IDではなくkey

  • プレーンな文字列ではなくAST(抽象構文木)形式のJSON

note.comはリッチテキストエディタのデータ構造をそのままAPIに渡す設計になっている。テキストノードを段落要素でラップし、それをrootで包む。


5. レート制限の壁

コメントAPIが動き始めると、すぐに次の壁にぶつかった。


HTTP 429
{"error": {"message": "上限に達したためご利用できません。しばらくお待ちいただいた後、再度お試しください。", "type": "too_many_requests"}}

1セッションで約9件コメントした直後に、次のバッチで全件429になった。コメントにはレート制限がある。いいねには今のところ制限は見当たらない。

対策は2つ。

コメント間に3秒のsleepを入れるバッチ間は5分以上空ける


6. キューファイルの設計

フェーズ1で生成されるYAMLはこういう構造だ。


creator: random
fetched_at: "2026-07-12T19:34:29+09:00"
articles:
- key: n8699e4e63db3
title: "記事タイトル"
url: "https://note.com/someuser/n/n8699e4e63db3"
summary: "本文の先頭200文字..."
comment_draft: "AIが生成したコメント草案(100字以内)"
action: like # like | comment | skip
liked: false
comment_id: 0

actionフィールドを人間が編集してから--postを実行する。commentにした記事だけコメントが投稿される。草案が気に入らなければ書き直す。Nullと書けばいいねのみ。

コメント草案の生成にはOpenAI gpt-4o-miniを使っている。プロンプトは「記事タイトルと本文200文字から、日本語で100字以内のコメントを生成せよ」というだけだ。


7. 実際に動かしてみて


# 新着10件を取得(page=2から)
go run ./src/ engage --limit 10 --page 2

# キューを確認・編集してから投稿
go run ./src/ engage --post engage/queue-20260712-193449.yaml

いいね10件は一瞬で完了する。コメントは草案確認があるぶん、投稿まで少し手がかかるが、それでいい。完全無人化より、人間が一度読む設計のほうが誠実だ。


振り返り

今回の教訓:

  • DevToolsは最強の仕様書 — v1とv3、IDとkey、単純文字列とAST、全部DevToolsが教えてくれた
  • 「403=禁止」と思うな — エンドポイントが間違っているときも403が返る
  • レート制限は実験して初めてわかる — ドキュメントには書いていない

次は、フォロー中クリエイターの新着を優先取得する機能と、コメント済み記事の重複スキップを実装したい。


コメントや知見の共有はコメント欄へどうぞ。

いいなと思ったら応援しよう!