{"id":39951936,"url":"https://github.com/koizuka/narou-watcher","last_synced_at":"2026-01-18T20:31:41.380Z","repository":{"id":36985623,"uuid":"347382371","full_name":"koizuka/narou-watcher","owner":"koizuka","description":"「小説家になろう」の新着小説をチェックする","archived":false,"fork":false,"pushed_at":"2026-01-12T03:47:25.000Z","size":36320,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-12T10:36:51.934Z","etag":null,"topics":["golang","narou","scraping"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/koizuka.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2021-03-13T13:46:40.000Z","updated_at":"2026-01-12T03:46:36.000Z","dependencies_parsed_at":"2023-09-30T03:13:19.489Z","dependency_job_id":"1d214688-e4a3-473a-8be7-44e7571715bf","html_url":"https://github.com/koizuka/narou-watcher","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/koizuka/narou-watcher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koizuka%2Fnarou-watcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koizuka%2Fnarou-watcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koizuka%2Fnarou-watcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koizuka%2Fnarou-watcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/koizuka","download_url":"https://codeload.github.com/koizuka/narou-watcher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/koizuka%2Fnarou-watcher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28549813,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T19:56:05.265Z","status":"ssl_error","status_checked_at":"2026-01-18T19:55:54.685Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","narou","scraping"],"created_at":"2026-01-18T20:31:41.302Z","updated_at":"2026-01-18T20:31:41.368Z","avatar_url":"https://github.com/koizuka.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# narou-watcher\n\n小説家になろうの新着小説をチェックしたい\n\n## 構成\n\n### サーバー (narou-watcher)\n\n場所: `./`\n\n「小説家になろう」の新着チェック中小説ページ(isnoticelist)をパースしてJSONにして返すAPIおよび、login/logout、ログインセッションクッキーを中継する仕組みを提供します。\nデフォルトで port 7676 を listen します。\n\n実行中に SIGINT (キーであれば CTRL+C ) を送ると正常にシャットダウンします。\n\n#### コマンドライン引数\n\n|option|default|説明|\n|---|---|---|\n|-port 数値|7676|HTTPリッスンポート|\n|-reverse-proxy 文字列|\u003chttps://koizuka.github.io/narou-watcher/\u003e|フロントエンドを読み込むアドレス|\n|-log-dir 文字列|githubの作業ディレクトリのトップ/log/narou|開発ログの保存先|\n|-public-url 文字列|\"\"|公開サーバーからreverse proxyするときの外に見えるアドレス(httpsにするときは必須)。パスは `/` より下も可能。|\n|-open|bool|サーバーが起動したら公開アドレスをブラウザで開く(ローカル起動用)|\n|-debug|bool|-log-dir のディレクトリに通信ログを記録する(ローカル起動用)|\n|-testdata|bool|テストデータモードで起動（なろうにアクセスせず、テストデータを返す）|\n\n##### テストデータモード\n\n`-testdata` フラグを指定すると、実際の「小説家になろう」サイトにアクセスせずに、事前定義されたテストデータを返すモードで起動します。\n\n```bash\n./narou-watcher -testdata\n./narou-watcher -testdata -port 8080  # 別のポートで起動\n```\n\n**特徴:**\n\n- 起動時刻を基準にした「更新したばかりの作品」が毎回表示される\n- 時間経過のシミュレーション（特定の作品は起動1分後にアクセス可能になる）\n- ログイン不要で動作確認が可能\n- フロントエンド開発時のバックエンドとして利用可能\n\n**テストデータの内容:**\n\n- 更新通知一覧: 10作品（起動時刻、1時間前、1日前、1週間前など様々な更新時刻）\n- ブックマーク: 4カテゴリ、各カテゴリに複数作品\n- 作品詳細: 10エピソード（一部の作品は起動1分後に11話が追加される）\n\nこのモードは開発・テスト目的で使用してください。\n\n#### API\n\n- `POST /login`\n  - form post形式で、 `id` にIDまたはメールアドレス、`password` にパスワードを入れて POSTすると、「小説家になろう」にログインを試みます。\n    - 成功したら HTTP status=200, レスポンスボディは true を返すとともに、セッションキーをクッキーで返します(後述)。このため、ログイン情報はサーバーに保持せず、ユーザーのブラウザに覚えさせます。\n    - 失敗したら HTTP status=401 を返します。\n- `GET /logout`\n  - 「小説家になろう」からログアウトし、こちらのセッションクッキーも削除します。\n- `GET /narou/isnoticelist` `GET /r18/isnoticelist`\n  - ログイン状態でなければ HTTP status=401 を返します。\n  - ログイン状態で、新着更新チェック中小説一覧の1ページ目を取得して以下のオブジェクトを配列にしてJSONにして返します。\n  - クエリパラメータ `max_page` は指定分、次ページを合成する。1(初期値)なら指定ページのみ。\n\n|key|type|説明|\n|---|---|---|\n|base_url|string|小説自体のURL|\n|update_time|ISO8601形式の日時|更新時刻(分解能は分まで)|\n|bookmark|uint|しおりの部分番号|\n|latest|uint|最終更新の部分番号|\n|title|string|小説のタイトル|\n|author_name|string|著者の名前|\n\n- `GET /narou/bookmarks` `GET /r18/bookmarks`\n  - ブックマーク名一覧。以下のオブジェクトが登録分並ぶ。\n\n|key|type|説明|\n|---|---|---|\n|no|number|1〜10|\n|name|string|ブックマーク名|\n|num_items|number|登録アイテム数|\n\n- `GET /narou/bookmarks/:no` `GET /r18/bookmarks/:no`\n  - ブックマークの内容の1ページ\n  - `:no` は1〜10\n  - クエリパラメータ `page` をつけるとページング。1が先頭\n  - クエリパラメータ `order` はソートオーダー。そのまま中継される。\n    - `updated_at` がブックマーク更新順\n    - `new` はブックマーク追加順\n  - クエリパラメータ `max_page` は指定分、次ページを合成する。1(初期値)なら指定ページのみ。\n\n| key         | type         | 説明               |\n|-------------|--------------|------------------|\n| base_url    | string       | 小説自体のURL         |\n| update_time | ISO8601形式の日時 | 更新時刻(分解能は分まで)    |\n| bookmark    | uint         | しおりの部分番号(短篇なら0)  |\n| latest      | uint         | 最終更新の部分番号(短篇なら0) |\n| title       | string       | 小説のタイトル          |\n| author_name | string       | 著者の名前            |\n| is_notice   | boolean      | 更新チェック中ならtrue    |\n| completed   | boolean      | 完結ならtrue         |\n| memo        | string       | メモ(存在する場合のみ)     |\n\n- `GET /narou/novels/:ncode` `GET /r18/novels/:ncode`\n  - 小説のncodeから概要ページの内容の抜粋を得る\n\n|key|type| 説明                               |\n|---|---|----------------------------------|\n|base_url|string| 小説のURL                           |\n|title|string| 小説のタイトル                          |\n|abstract|string| 小説の概要(HTML)                      |\n|author_name|string| 著者の名前                            |\n|author_url|string| 著者ページのURL                        |\n|keywords|[]string| キーワード                            |\n|bookmark_url|string| ブックマークカテゴリURL(登録されていなければフィールドなし) |\n|bookmark_no|uint| ブックマークのカテゴリ番号(登録されていなければフィールドなし) |\n|bookmark_episode|uint| しおり部分(登録されていなければフィールドなし)         |\n|contents|[]chapter| 章一覧                              |\n\n- chapter\n\n| key      | type      | 説明                             |\n|----------|-----------|--------------------------------|\n| chapter  | string    | 章のタイトル。章設定をしていない作品にはこのキーは付かない。 |\n| episodes | []episode | エピソード一覧                        |\n\n- episode\n\n| key      | type    | 説明                  |\n|----------|---------|---------------------|\n| subtitle | string  | サブタイトル              |\n| no       | uint    | エピソード番号(1〜)         |\n| date     | ISO8601 | 投稿日時                |\n| update   | ISO8601 | 改稿日時(改稿されていない場合は省略) |\n\n- `GET /narou/fav-user-updates`\n  - お気に入りユーザーの更新情報\n\n| key              | type   | 説明           |\n|------------------|--------|--------------|\n| r18passive_count | int    | 不明           |\n| blog_list_html   | string | WIP(現在はHTML) |\n| novel_list_html  | string | WIP(現在はHTML) |\n| passive_count    | int    | 不明           |\n\n- `GET /narou/check-novel-access/:ncode/:episode` `GET /r18/check-novel-access/:ncode/:episode`\n  - 指定した小説の特定エピソードにアクセス可能かどうかを確認する（ログイン不要）\n  - `:ncode` は小説コード（例：n1234ab）\n  - `:episode` はエピソード番号（例：1、2、3...）\n  - 公開直後の小説が実際にアクセス可能かを判定するために使用\n\n| key        | type    | 説明                                      |\n|------------|---------|-------------------------------------------|\n| accessible | boolean | 小説にアクセス可能な場合true                      |\n| statusCode | int     | なろうサーバーからのHTTPステータスコード（200: 成功、404: 存在しない等） |\n\n#### ログインセッションクッキー\n\n小説家になろうのサイトが Set-Cookieしてきたものの名前の前に `narou-` をつけてこちらのクッキーとして Set-Cookie にして返し、ブラウザに覚えさせます。\n\nブラウザからのリクエストについているクッキーに `narou-` で始まるものがあれば、この後の名前にして「小説家になろう」に送信します。\n\n### フロントエンド (narou-react)\n\n場所: `./narou-react/`\n\n開くとまずサーバーのアドレスを以下のルールで決定します。\n\n1. クエリパラメータに `server` があれば、その値をサーバーURLとする\n2. 自分のURLをみて、URLスキームが `http:` であれば、 `localhost:7676` をサーバーURLとする\n3. ドメインをみて、 `github.io` でなければ、自分のアドレスをサーバーURLとする\n4. 上記に該当しなければエラー\n\nログイン状態で無ければ、ログイン画面が開きます。\n![image](https://user-images.githubusercontent.com/864587/116656634-f7729600-a9c7-11eb-852d-71baa8ce3f91.png)\n\n無事ログインすると、新着更新チェック中一覧の新しい順の数十件が出ます。タブをアクティブにするたびに更新します。また、5分ごとにも更新します。\n未読数はページタイトルに設定されます。\n\n![image](https://user-images.githubusercontent.com/864587/121801775-05c4fa80-cc74-11eb-8d9b-0feaf4cd333c.png)\n\n未読があるとバッジにそれぞれの未読数がでて、そのうち一番更新が古い作品の色が変わっていてこの状態で Enter キーを押すとそれが新しいタブで開きます。\n開いた作品を読んでしおりを更新してタブを閉じると、再びこのページに戻ってくると即座に更新され、次の未読が選択されます。\n\nログアウトは、一番下にボタンがあります。\n\n## 開発\n\n### サーバーの開発\n\nGo言語がビルドできる環境で\n`go build`\n\nで `./narou-watcher` のバイナリができます。\n\n`./narou-watcher` を実行すると localhost:7676 をlisten して起動します。\n\n`./narou-watcher -open` で起動すると、上記に加えてブラウザで `localhost:7676` を開きますが、フロントエンドは `https://koizuka.github.io/narou-watcher/` にデプロイされているものを reverse-proxyして読み込みます。\n\n### フロントエンドの開発\n\n`./narou-react` ディレクトリで、 node + npm を入れた状態で\n\n```bash\nnpm install # (初回)\nnpm run start\n```\n\nでViteによるビルドしたフロントエンドを読み込む localhost:3000 が開き、localhost:7676 のサーバーに接続する動作をします。\n\n#### モバイルデバイス(iPhone/Android)からのアクセス\n\n開発サーバーはネットワーク経由でアクセス可能に設定されています。\n\n1. PCでバックエンドとフロントエンドを起動:\n\n   ```bash\n   ./narou-watcher        # バックエンド (ポート7676)\n   cd narou-react\n   npm start              # フロントエンド (ポート3000)\n   ```\n\n2. PCのローカルIPアドレスを確認:\n\n   ```bash\n   ifconfig | grep \"inet \" | grep -v 127.0.0.1\n   # 例: inet 192.168.0.60\n   ```\n\n3. モバイルデバイスのブラウザから `http://\u003cPCのIPアドレス\u003e:3000` にアクセス\n   - 例: `http://192.168.0.60:3000`\n   - Viteのプロキシ機能により、APIリクエストは自動的にバックエンドに転送されます\n\n#### 技術スタック\n\n- React 19.2.0\n- TypeScript 5.9.3\n- Vite 7.1.11 (ビルドツール)\n- Material-UI 7.1.0\n- Vitest 4.0.3 (テスト)\n- SWR 2.3.6 (データフェッチ)\n- date-fns 4.1.0 (日時処理)\n\n#### その他のコマンド\n\n```bash\nnpm run build   # プロダクション用ビルド\nnpm run test    # テスト実行\n```\n\n### サーバーの公開\n\nサーバー上でGitHubから git clone, go buildした `narou-watcher` に `-public-url` を設定して起動し、 nginxなどで `localhost:7676` (デフォルト) にリバースプロキシすることでhttpsな自分のサーバーで公開することができます。フロントエンドのコードも自作にする場合は `-reverse-proxy` 引数に置き場所のURLを与えます。\n\n## メモ\n\n\u003chttps://github.com/koizuka/scraper\u003e を使ってます。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoizuka%2Fnarou-watcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkoizuka%2Fnarou-watcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkoizuka%2Fnarou-watcher/lists"}