WeChat Local Viewer:ローカルでWeChatチャット履歴を検索・分析

WeChat Local Viewerは、FastAPI、Vue、SQLite FTS5を使用して、ローカル環境でWeChatのチャット履歴を閲覧、検索、エクスポートできるツールです。必要に応じて、OpenAI互換のLLMにも接続できます。

WeChat Local Viewer:ローカルでWeChatチャット履歴を検索・分析

WeChatのチャット履歴が数十万件、あるいは100万件を超えて蓄積されると、システム標準の閲覧方法では検索、アーカイブ、分析のニーズを満たしにくくなります。ops120/wechat-local-viewer は、ローカル優先のソリューションを提供します。ユーザーが自分でチャットデータベースを準備すれば、ブラウザー上で会話を閲覧したり、メッセージを確認したり、全文検索を実行したり、データをエクスポートしたりできます。さらに、必要に応じてLLMを接続し、要約や質問応答を行うことも可能です。

このプロジェクトには重要な制限があります。これは復号ツールではありません。リポジトリには、鍵の抽出、データベースの復号、安全機構の回避に関するコードは含まれていません。チャットデータはユーザー自身で準備し、プロジェクトで定められたディレクトリに配置する必要があります。ビューアーは、すでに読み取り可能なデータを解析・表示する役割のみを担います。

注目すべき理由

このプロジェクトの本質的な価値は、単に「チャット履歴を表示する」ことではありません。ローカルデータ処理の一連の流れを整理している点にあります。

  1. ユーザーが提供したディレクトリから、連絡先、会話、メッセージのデータベースを読み込む。
  2. ETLフローによって、データを中間SQLiteデータベースに整理する。
  3. メッセージに対してFTS5全文インデックスを構築する。
  4. FastAPIを通じて、ページネーション、検索、統計、LLM APIを提供する。
  5. Vueフロントエンドで、会話の閲覧、メッセージのコンテキスト確認、エクスポート操作を行う。

このアーキテクチャにより、フロントエンドが大量の元データベースを直接読み込む必要がなくなり、増分更新、インデックスの再構築、クエリの最適化も容易になります。プロジェクトでは実際に64万件のメッセージをインポートしており、メッセージ閲覧は引き続きスムーズに動作しています。全文検索にはSQLite FTS5を使用し、秒単位、通常は1秒以内の結果返却を目標としています。

主な機能

  • 会話一覧:最終メッセージ時刻の降順で、個人チャット、グループチャット、公式アカウントの会話を表示。
  • メッセージ閲覧:メッセージを時系列順に表示し、ページネーションとメッセージコンテキストに対応。
  • 全文検索:SQLite FTS5でメッセージ本文を検索し、検索候補も提供。
  • 複数形式へのエクスポート:ローカル履歴を保存・後処理しやすい形式でエクスポート。
  • LLMによる要約と質問応答:OpenAI互換プロトコルを通じて、DeepSeek、OpenAI、SiliconFlow、Ollamaなどのサービスに接続。
  • ローカル優先:ユーザーが明示的に設定したLLMサービスを除き、外部HTTPサービスに依存しない。
  • 増分処理:ETLはデータフィンガープリントに基づき、全量処理、増分更新、処理スキップを判断。

動作環境

プロジェクトはWindows 10/11を対象としており、実行環境には以下が含まれます。

  • Python 3.10以降
  • Node.js ^22.19.0 または >=24.0.0
  • Windows 10/11

デフォルトでは、バックエンドが18787番ポート、フロントエンド開発サーバーが15713番ポートで待ち受けます。Windows上で問題が発生しやすい8765番ポートを意図的に避け、競合しやすいViteのデフォルトポート5173も使用しません。

データディレクトリの準備

準備済みのチャットデータをプロジェクトのルートディレクトリに配置します。プロジェクトはdecrypted/または.decrypted/を自動認識するため、どちらか一方を使用できます。

wechat-local-viewer/
├── decrypted/
│   ├── contact/      # 連絡先データ
│   ├── session/      # 会話データ
│   ├── message/      # メッセージデータベース(例:message_*.db)
│   └── hardlink/     # 画像インデックス(任意)
└── start.bat

hardlink/は任意のディレクトリで、通常は画像インデックスに使用します。メディアファイルが完全に揃っていない場合でも、テキストメッセージや復元済みの一部画像は通常どおり閲覧できます。

ワンクリック起動

Windowsでは、プロジェクトのルートディレクトリにあるstart.batをダブルクリックするのが最も簡単です。スクリプトはポートの使用状況を確認し、起動後に次のURLを自動的に開きます。

http://127.0.0.1:18787/

バックエンドはビルド済みのフロントエンド成果物を直接ホストするため、本番利用時にフロントエンド開発サーバーを別途起動する必要はありません。

ポートを変更する場合は、起動前に環境変数を設定します。

set WCVIEWER_PORT=28888
set WCVIEWER_FRONT_PORT=25813
start.bat

ポート検出は実用的な機能です。サービス起動後にバインドエラーが発生するのを待つのではなく、スクリプトが事前に明確な警告を表示できるため、Windows上で複数のローカル開発サービスを同時に実行する場合に特に便利です。

手動起動と開発モード

バックエンドにはFastAPIとUvicornを使用します。

cd backend
pip install -r requirements.txt
python -m uvicorn app.main:app --host 127.0.0.1 --port 18787

フロントエンドにはVueとViteを使用します。

cd frontend
npm install
npm run dev

本番版をビルドするには、次を実行します。

npm run build

ビルド完了後、バックエンドがfrontend/distを自動的にホストします。ネットワークが制限されている場合や、npmインストールの安定性を高めたい場合、プロジェクトのドキュメントではミラーの利用と同時接続数の制限を推奨しています。

npm config set registry https://registry.npmmirror.com
npm config set maxsockets 4
npm config set audit false
npm install

ETLとキャッシュデータベース

プロジェクトでは、ページを開くたびに元のWeChatデータベースを直接スキャンすることはありません。代わりに、backend/app/etl.pyを通じて元データを実行時データベースに変換します。

.cache/app.db
├── sessions
├── contacts
├── messages
└── FTS5インデックス

ETLの処理には、おおむね次のステップが含まれます。

  • parse_sessions:会話を解析し、sessionsテーブルに書き込む。
  • parse_contacts:連絡先を解析し、contactsテーブルに書き込む。
  • parse_messagesmessage_*.dbなどのファイルを読み込み、messagesテーブルに書き込むとともに全文インデックスを構築する。
  • _update_session_stats:会話の統計情報を集計する。

データフィンガープリントを使用して、再処理が必要かどうかを判断します。変更がなければ処理をスキップでき、新規データや変更があれば増分更新を実行します。必要に応じて、管理APIからETLを強制的に実行することもできます。この設計は数十万件のメッセージを扱う場合に特に重要です。アプリケーションを開くたびに完全なインポートを行うと、起動時間が大幅に長くなるためです。

実行時には次のディレクトリも生成されます。これらはソースコードリポジトリには含まれません。

.cache/   # 中間データベース app.db
.export/  # エクスポート成果物
.tmp/     # ログと一時ファイル

これらは.gitignoreによって除外されており、バージョン管理に追加すべきではありません。

API設計

バックエンドは比較的明確なREST APIを提供しており、デバッグや他のクライアントの拡張に利用できます。

エンドポイント メソッド 用途
/api/sessions GET last_timeの降順で会話を取得
/api/sessions/{username} GET 個別の会話詳細を取得
/api/messages?session=X GET メッセージをページ単位で取得
/api/messages/{id} GET 単一のメッセージを取得
/api/messages/{id}/context GET メッセージのコンテキストを取得
/api/search?q=X GET FTS5を使用して全文検索を実行
/api/search/suggest?q=X GET 検索候補を取得
/api/admin/etl POST ETLを実行。{\"force\": true}を渡せる
/api/admin/status GET ETLの状態を確認
/api/admin/logs GET ログ末尾を確認
/api/admin/rebuild-fts POST 全文インデックスを再構築
/api/admin/stats/daily GET 日次統計を取得
/api/llm/config GET / POST LLM設定を読み込みまたは保存
/api/llm/chat POST SSEでストリーミング形式の質問応答結果を返す
/media/... GET 復元済みのメディアファイルを提供

/api/llm/chatはSSEによるストリーミング出力を使用するため、モデルの生成中に内容を段階的に表示でき、完全な応答を待つ必要がありません。

オプションのLLM連携

LLMはビューアーに必須の依存関係ではありません。ページ右上の「設定」で、OpenAI互換サービスを入力できます。

DeepSeek:   https://api.deepseek.com/v1
OpenAI:     https://api.openai.com/v1
Ollama:     http://localhost:11434/v1
SiliconFlow: https://api.siliconflow.cn/v1

モデルの例:

deepseek-chat
gpt-4o-mini
qwen2.5:7b

設定項目にはBase URLAPI KeyModelがあります。APIキーはブラウザーのlocalStorageにのみ保存され、各質問応答リクエストとともにバックエンドへ送信されます。また、環境変数でデフォルト値を設定することもできます。

set LLM_BASE_URL=https://api.deepseek.com/v1
set LLM_API_KEY=your-api-key
set LLM_MODEL=deepseek-chat

LLMを設定していなくても、基本的な会話閲覧、検索、エクスポートは引き続き利用できます。要約機能をクリックした場合、画面には未設定であることが明確に表示され、何も表示されないまま失敗することはありません。

注意すべき点として、「ローカルで実行する」ことは、LLMへのリクエストも完全にローカルで処理されることを意味しません。DeepSeek、OpenAI、その他のリモート互換サービスを使用すると、そのサービスに送信された内容はローカル環境の外部へ送られます。より厳格なデータ境界を維持したい場合は、ローカルで実行するOllamaを使用し、Base URLhttp://localhost:11434/v1に設定できます。

プライバシーとセキュリティの境界

プロジェクトは設計上、ローカル優先を重視しています。

  • ユーザーが設定したLLMのbase_urlを除き、外部HTTPリクエストを実行しない。
  • 静的な/media/ルートでディレクトリ一覧を表示しない。
  • LLMのAPIキーはブラウザーのlocalStorageにのみ保存する。
  • 元データ、キャッシュデータベース、エクスポートファイル、一時ログはすべてローカルに保持する。

ただし、チャット履歴自体には通常、個人の機密情報が含まれます。リモートLLMを使用する場合は、まずサービス提供者のデータ保持方針や学習利用方針を確認し、必要な会話部分だけを送信することを検討してください。機密性の高いデータには、通常、リモートAPIよりローカルモデルのほうが適しています。

パフォーマンスと検証

プロジェクトが示す性能の目安は次のとおりです。

  • 起動から初期画面まで:64万件のメッセージデータベースを基準に数秒程度。ただし、正確な実測時間は文書に記載されていない。
  • 会話を開く:初期画面で30件のメッセージを読み込み、インデックス検索に依存するため良好に動作。
  • 全文検索:FTS5を使用し、秒単位での結果返却を目標とする。
  • LLMストリーミングの最初の文字:主にモデルサービスとネットワーク遅延に依存し、固定の実測値は提供されていない。

デプロイや問題の調査時には、まずフロントエンドのディレクトリ構成を確認できます。

cd <リポジトリのルートディレクトリ>
tree /F frontend

フロントエンドの依存関係がまだインストールされていない場合は、frontendに移動してインストールします。検索結果に異常がある場合は、/api/admin/rebuild-ftsを呼び出してインデックスを再構築できます。ETLの状態が不明な場合は、/api/admin/status/api/admin/logsを確認してください。

適した用途

WeChat Local Viewerは、個人のチャット資料を長期保存、検索、研究したい開発者や上級ユーザーに適しています。たとえば、次のような用途です。

  • 大量の過去メッセージから特定のキーワードや決定事項を探す。
  • 長期プロジェクトの議論を会話単位で閲覧する。
  • チャット履歴を個人アーカイブ用にエクスポートする。
  • ローカルモデルまたはOpenAI互換モデルを使用して長い会話を要約する。
  • データベース全体をアップロードせずに、ローカル検索ツールを構築する。

プロジェクトはMIT Licenseで提供されており、主なコードはPython、Vue、TypeScriptで構成されています。言語比率は、Python 64.8%、Vue 24.2%、TypeScript 7.7%、Batchfile 2.4%、JavaScript 0.5%、HTML/CSSがそれぞれ0.2%程度です。ページに記録された情報によると、リポジトリには143個のstarsと94個のforksがあり、正式なReleaseはまだ公開されていません。

総じて、このプロジェクトは「ローカルのチャットデータベースを読み込む」機能を、拡張可能なローカルアプリケーションへと発展させています。SQLite FTS5が検索の問題を解決し、ETLとキャッシュが規模の問題を解決し、FastAPIとVueが明確なアプリケーション境界を提供します。さらに、オプションのLLM連携によって、要約や質問応答の機能を拡張できます。最も重要なのは、ユーザーがクラウドサービスに依存せず、基本的な閲覧と検索を行えることです。そのうえで、プライバシー要件に応じてモデル機能を有効にするかどうかを選択できます。

Source

ops120/wechat-local-viewer: WeChatローカルチャット履歴ビューアー — 会話閲覧/全文検索/複数形式エクスポート/オプションのLLMによるスマート要約。すべてローカルで実行し、外部依存なし。