はじめに
オプチャグラフは、LINE OpenChatの統計情報を収集・分析・可視化するWebサービスです。
前回までの記事:
- ①データパイプライン - 25万件/毎時のクロール〜静的ファイル生成
- ②差分検出 - 25万件の更新を99%削減する仕組み
- ③バッチ設計 - 冪等性・再開可能性・障害耐性
本記事では、2024年末〜2025年の技術的チャレンジを振り返ります。
2025年の開発規模
- コミット数:902件
- 主要開発期間:2025年1月(356件)、7-8月(368件)
1. 多言語対応の実装(2024年末〜2025年1月)
背景
LINE OpenChatは日本だけでなく台湾・タイでも展開されています。これらの国向けにサービスを拡張しました。
対応した項目
- UI翻訳:日本語/繁体字中国語/タイ語の3言語
-
URL設計:
/tw/oc/*(台湾),/th/oc/*(タイ) - データベース分離:言語別にSQLiteファイルを分離
- タイムゾーン:各国のUTCオフセットに対応
苦労した点
- 動的設定の複雑化:言語ごとの設定を動的に切り替える仕組みが肥大化し、後にリファクタリングが必要に
- 機能の部分無効化:マイリスト・コメント機能は日本以外で無効化(データ量・運用コストの問題)
- タイムゾーン対応:グラフ表示やランキング更新時刻の調整が複雑に
関連ソース:
- translation.json - 翻訳定義ファイル
- TagDefinition/ - 言語別タグ定義
- 383473da - 言語による動的設定の初期実装
2. MinimalCMSフレームワークの改修とアプリケーション設定の整理(2024年末〜2025年1月)
背景
多言語対応を実現するため、フレームワーク(MinimalCMS)自体の改修が必要でした。それに伴い、アプリケーション側の設定も整理しました。
フレームワーク側の変更
自作フレームワークMinimalCMSに以下の改修を実施。
-
URLプレフィックス対応:
/tw/や/th/のようなパス接頭辞をフレームワーク全体で扱えるように - DI機能の強化:ConstructorInjectionでUnion型/Nullable型に対応
関連コミット(MinimalCMS):
- f68523f - URLプレフィックス対応
- 7df7a92 - 設定のstatic変数化(38ファイル変更)
- d093204 - ConstructorInjectionのUnion/Nullable対応
関連コミット(Open-Chat-Graph):
- 047723b5 - フレームワーク最新化とConfig整理(131ファイル変更)
3. 説明文のキーワード羅列折りたたみ
課題
オープンチャットの問題点の一つとして、検索ワード羅列のキーワードスパムが蔓延しています。
友達募集 雑談 通話 暇つぶし 話し相手 恋バナ 相談 愚痴 #友達 #雑談 #通話 ...
このような説明文がそのまま表示されるとGoogleのSEOに対し不利に働きます。
解決策
CollapseKeywordEnumerationsクラスを実装し、キーワード羅列を自動検出・折りたたみするようにしました。
処理の流れ:
- ハッシュタグを検出し、本文に含まれないものだけ指定数残す
- 読点・スペース・縦棒で区切られたキーワード羅列を検出
- 「キーワード的」か「文章的」かを判定(ひらがな率、助詞の有無など)
- キーワード羅列と判定された場合、先頭数個を残して「…」で省略
結果:
Before: 友達募集 雑談 通話 暇つぶし 話し相手 恋バナ 相談 愚痴 #友達 #雑談 #通話 #暇つぶし
After: 友達募集…
関連ソース:
- CollapseKeywordEnumerations.php - メイン実装
- CollapseKeywordEnumerationsTest.php - テストケース
関連コミット:
4. 外部API機能の追加
外部連携用にいくつかのAPIを追加しました。
このAPIを使いXの自動ポスト機能を開発しました。
- DatabaseApiController:データベースクエリ・スキーマ取得・最終更新時間取得
- 削除済みオープンチャットリストAPI:削除されたオープンチャットの一覧取得(認証付き)
関連ソース:
- DatabaseApiController.php
- ApiDeletedOpenChatListRepository.php
- 2c78c581 - APIデータベース接続クラス追加
- #69 - 削除済みオープンチャットAPI
5. SQLiteリトライ機能
課題
約1.8億レコードのSQLiteファイルへの並行アクセスでdatabase lockedエラーが発生していました。
解決
database lockedエラー時に一定時間待機してリトライする処理を実装。WALモードを使用していてもCron実行中の競合は完全には防げないため、アプリケーション層でのリトライが必要でした。
関連ソース:
関連コミット:
- 10ab5f5b - SQLiteStatisticsRepositoryでのリトライ処理実装
- b608b634 - リトライ機能追加とエラーハンドリング改善
- 0ef3e030 - SqliteRankingPositionPageRepositoryのリトライロジック
6. その他の改善
-
LINE Notify通知→Discord移行
- de631752 - Discord通知機能追加
-
JumpOpenChat機能:利用規約画面付きの「LINEで開く」リンク
- c1188cfd - JumpOpenChat機能追加
- JumpOpenChatPageController.php
-
Docker/Devcontainer整備:VSCode Remote Containers対応で開発環境を標準化
- 3a114dc5 - Docker設定リファクタリング
- .devcontainer/
- verbose Cron Log:バッチ処理の詳細ログ出力で問題調査を効率化
まとめ
2025年は多言語対応とフレームワークリファクタリングが二大テーマでした。
- 多言語対応により台湾・タイへサービスを拡張
- シンプルな設計の重要性を再認識
- スパム的キーワード羅列対策としてキーワード羅列折りたたみを実装
- SQLiteのロック問題にリトライ処理で対応
月額1,000円のレンタルサーバーで25万件以上のオープンチャットを処理する仕組みは引き続き健在です。