Skip to content

Latest commit

 

History

387 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🐱 ReLINE - 猫メッセンジャーBot

Ruby Rails LINE

かわいい猫の仲間と一緒に、LINEグループを活性化しましょう!

🚀 はじめに

猫マスコット


📖 概要

ReLINEは、休眠状態のグループチャットを活性化するインテリジェントなLINE Botサービスです。かわいい猫のマスコットが魅力的なメッセージを送信します。LINEグループが一定期間非アクティブになると、Botが自動的に会話のきっかけとなるメッセージを送信し、メンバーの再参加とコミュニティの交流を促進します。

🗺 全体像

ReLINEの全体像。休眠検知 → きっかけ配信 → 会話再開 → 効果の可視化という利用フローと、主な機能、システムアーキテクチャ(LINEプラットフォーム → CatLineBot → 各種イベントハンドラ → ActiveJob → LineMessaging)、データと状態管理(MySQL 8.0の7テーブル)、技術スタック、テスト、セキュリティ、運用・可観測性をまとめた図

④の管理ダッシュボードに表示している数値・グループ名は画面イメージ用のサンプルです。

各項目の詳細は以下のセクションで説明します。

🎯 主な機能

  • 🤖 自動グループ監視 - グループの活動を追跡し、休眠状態を検出
  • 💬 スマートメッセージ配信 - 最適なタイミングで文脈に応じた会話のきっかけを送信
  • 📊 管理ダッシュボード - グループの管理とエンゲージメント指標の監視
  • 🔐 セキュアな認証 - ロールベースの権限による保護された管理者アクセス
  • 📱 PWA対応 - インストール可能・オフライン対応のWebフロントエンド
  • 📈 可観測性 - ヘルスチェック / Prometheusメトリクス / 構造化ログ

🎬 使い方

使用例

ユーザーインターフェースギャラリー

Webランディングページ QRコード画面 LINEアプリ連携
Webトップページ QRコード LINEページ
マスコットと「友だち追加」ボタンのあるメインランディングページ PC用QRコード表示 モバイルアプリ連携画面

🛠 技術スタック

バックエンド

技術 バージョン 用途
Ruby 4.0.5 コア言語
Rails 8.1.3 Webフレームワーク
MySQL 8.0+ データベース(全環境)
LINE 2.x メッセージング連携

コアGems

  • 認証 - Rails 8 has_secure_password - bcryptによるセキュアな管理者ログイン
  • 認可 - pundit - ポリシーベースのアクセス制御
  • レート制限 - rack-attack - ブルートフォース攻撃対策とリクエストスロットリング
  • メッセージング - line-bot-api - LINE Messaging API連携
  • 監視 - prometheus-client - メトリクス収集と監視
  • ログ - lograge - リクエストIDつき構造化ログ

開発・テスト

  • テストフレームワーク - rspec-rails - 包括的なテストスイート
  • ブラウザ自動化 - selenium-webdriver - ヘッドレスChromeによるシステムテスト
  • コード品質 - rubocop(Rails、Performance、RSpec拡張付き)
  • テストデータ - factory_bot_railsfaker - ファクトリとフィクスチャ生成
  • セキュリティ - brakemanbundler-audit - セキュリティ脆弱性スキャン
  • カバレッジ - simplecov - COVERAGE=trueまたはCI=trueでの実行時に計測し、行・ブランチともに100%を必須とする

フロントエンド

技術 用途
Bootstrap レスポンシブUIフレームワーク
JavaScript クライアントサイドインタラクティビティ
Stimulus JavaScriptフレームワーク
Turbo SPA風ナビゲーション
Jest Service Workerモジュールのユニットテスト

アセットパイプライン

  • JSバンドル - jsbundling-rails(esbuild使用)
  • CSSバンドル - cssbundling-rails(Bootstrap使用)
  • アセット配信 - propshaft - モダンなアセットパイプライン

📐 アーキテクチャ

データベーススキーマ

ER図

インフラストラクチャ

インフラ構成図

イベント処理アーキテクチャ

LINE Botリアクションフロー

単一のエンドポイントで複数のLINE Messaging APIイベントを処理します。 LINE SDK(line-bot-api v2)に触れる箇所はLineMessagingへ寄せ、コントローラーは受け口に徹しています。

クラス / モジュール 責務
CatLineBot Webhookイベントの振り分け
LineMessaging LINE Messaging APIとのやり取り(送信・退出・人数取得)
MessageEvent メッセージイベントの処理(合言葉への応答・1対1トーク)
LineGroup グループの記録と、次に働きかける日の管理
Scheduler 定期的な働きかけの組み立て
LineReminderJob / LineWelcomeMessageJob LINEへの送信(通信エラー時は指数バックオフで再試行)
ErrorSanitizer ログ・通知からの資格情報の除去

Webhookの署名検証とイベントのパースは、SDKのLine::Bot::V2::WebhookParserがまとめて担当します。 グループのメンバー数はRails.cacheに短時間だけ保持し、イベントごとの問い合わせを抑えています。

認証アーキテクチャ

Sorceryからの移行後、認証はRails 8標準のhas_secure_passwordで構成されています。

  • Authentication - ログイン・ログアウトとログイン状態の保持(コントローラーconcern)
  • BruteForceProtection - 失敗回数によるアカウントロック(モデルconcern)
  • Operator - normalizesによるメールアドレスの正規化と、パスワードの複雑性検証

PWA

Webフロントエンドはインストール可能なPWAとして動作します。

  • Service Worker - app/javascript/serviceworker.js(esbuildでpublic/serviceworker.jsへバンドル)
  • キャッシュ戦略 - cache-first / network-first / network-onlyStrategyRouterが振り分け
  • 設定の外部化 - config/pwa_config.ymlで環境ごとのキャッシュ戦略・マニフェストを定義し、GET /api/pwa/configで配信
  • マニフェスト - GET /manifest.jsonをI18n対応で動的生成
  • オフライン表示 - public/offline.html
  • クライアント計測 - POST /api/client_logsPOST /api/metricsでブラウザ側のログ/メトリクスを収集

監視エンドポイント

エンドポイント 用途
GET /health Liveness用の軽量チェック
GET /health/deep DB接続とディスク空き容量を含む詳細チェック
GET /health/ready Readiness用のDB接続チェック
GET /metrics Prometheusテキスト形式のメトリクス(本番はBasic認証)

📊 テスト

  • RSpec - モデル / コントローラー / ジョブ / リクエスト / システムスペックを網羅
  • SimpleCov - COVERAGE=trueまたはCI=trueでの実行時のみ計測され、行・ブランチともに100%を下回るとテストが失敗(通常のbundle exec rspecでは計測されません)
  • Selenium - ヘッドレスChromeによるシステムテスト
  • Jest - Service Workerモジュール(app/javascript/pwa/**)のユニットテスト

テストコマンドやカバレッジ設定の詳細はTESTING.mdを参照してください。


🚀 はじめに

前提条件

🐳 Dockerセットアップ

  1. リポジトリをクローン
git clone https://github.com/Tsuchiya2/ReLINE.git
cd ReLINE
  1. 環境変数と資格情報を設定

.env.exampleをコピーして.envを作成します。

cp .env.example .env

LINEのチャネル情報やWebhookのコールバックパスはRailsの暗号化credentialsで管理します。 config/routes.rbcredentials.callback_routeを参照するため、アプリケーションを起動する前に設定してください。

まだコンテナを起動していないため、execではなくrun --rmでワンショット実行します。

docker compose run --rm -e EDITOR=vi web bin/rails credentials:edit

すでにdocker compose upでコンテナが起動している場合は docker compose exec -e EDITOR=vi web bin/rails credentials:edit でも編集できます。

必要なキーは以下のとおりです。

# LINE Messaging API
channel_secret: YOUR_CHANNEL_SECRET  # Webhookの署名検証に使用
channel_token: YOUR_CHANNEL_TOKEN    # チャネルアクセストークン
callback_route: your_webhook_path    # POST /operator/<callback_route> になります

# db:seed で使用する初期データ
guest:
  email: guest@example.com
  password: your_guest_password
operator:
  email: operator@example.com
  password: your_operator_password
content:
  movie: https://example.com/movie
alarmcontent:
  url: https://example.com/alarm

# 本番のメール送信(config/environments/production.rb)
gmail:
  user_name: your_email@gmail.com
  password: your_app_password
  1. アプリケーションを起動
docker compose up

これにより:

  • MySQL 8.0データベースコンテナが起動
  • Railsアプリケーションがビルドされ起動
  • http://localhost:3000でアプリが実行
  1. データベースを準備
docker compose exec web bin/rails db:create db:schema:load
docker compose exec web bin/rails db:seed

便利なDockerコマンド:

# バックグラウンドで起動
docker compose up -d

# ログを表示
docker compose logs -f web

# Railsコンソールを実行
docker compose exec web bin/rails console

# コンテナを停止
docker compose down

# Gemfile/package.json変更後に再ビルド
docker compose build

# テストを実行
docker compose exec web bundle exec rspec

# カバレッジ付きでテストを実行
docker compose exec web bash -c "COVERAGE=true bundle exec rspec"

# システムテストのみを実行
docker compose exec web bundle exec rspec spec/system

# JavaScript(Service Worker)のテストを実行
docker compose exec web npm test

# コード品質チェック
docker compose exec web bundle exec rubocop

# セキュリティ監査
docker compose exec web bundle exec brakeman
docker compose exec web bundle exec bundler-audit

# ルートを表示
docker compose exec web bin/rails routes

詳細なテストコマンドとオプションはTESTING.mdを参照してください。

⏰ 定期実行タスク

グループへの働きかけはRakeタスクとして提供されています。cronなどのスケジューラから実行してください。

# 短いスパンでの働きかけ(Scheduler.call_notice)
docker compose exec web bin/rails call_notice:call_reminds

# 不定期な働きかけ(Scheduler.wait_notice)
docker compose exec web bin/rails wait_notice:wait_reminds

🎓 技術的ハイライト

課題:単一エンドポイントで多様なイベントを捌く

LINE Messaging APIのWebhookは、メッセージ・参加・退出・フォローなど複数の種類のイベントを単一のエンドポイントへ送ります。それぞれ処理が異なるうえ、LINEへの応答は速やかに返す必要があります。

解決策:

  • 振り分けと送信の分離 - CatLineBotがイベントの種類を判定し、LINEへの送信はLineReminderJob / LineWelcomeMessageJobへ委譲。Webhookの応答が外部APIの応答時間に引きずられないようにしています
  • SDKに触れる箇所の集約 - Line::Bot::V2::*を直接扱うのはLineMessagingだけに限定し、SDKの変更の影響範囲を閉じ込めています
  • 失敗への備え - 通信エラーはActiveJobのretry_onで指数バックオフ再送。処理できなかったイベントは、資格情報を伏せたうえで運用者へメール通知します
  • Railsの語彙で表現する - モデル・concern・ジョブといったRails標準の置き場に収め、独自のレイヤーを増やさない構成にしています

このアーキテクチャは以下を通じて形になりました:

  • 経験豊富なエンジニアからのフィードバック
  • 「パーフェクトRuby on Rails」のベストプラクティスの学習
  • Fat ControllerとFat Modelの両方を避けるための反復的なリファクタリング
  • 厳格なRubocop準拠と、行・ブランチともに100%のテストカバレッジ

📚 リソース

プロジェクトドキュメント

外部ドキュメント


🤝 コントリビューション

コントリビューションを歓迎します!お気軽にプルリクエストを送信してください。

  1. リポジトリをフォーク
  2. フィーチャーブランチを作成(git checkout -b feature/amazing-feature
  3. 変更をコミット(git commit -m 'Add some amazing feature'
  4. ブランチにプッシュ(git push origin feature/amazing-feature
  5. プルリクエストを開く

👤 作者

Tsuchiya Yuji

About

🐱 会話が止まったLINEグループを、かわいい猫のメッセージで自然に再開させるLINE Botサービス。休眠検知・自動メッセージ配信・管理ダッシュボードを備え、Ruby on Rails 8 と LINE Messaging API で構築。

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages