{"id":50566561,"url":"https://github.com/nlink-jp/mail-triage","last_synced_at":"2026-06-04T15:02:03.446Z","repository":{"id":350034037,"uuid":"1205023999","full_name":"nlink-jp/mail-triage","owner":"nlink-jp","description":"GCS-based email triage with Gemini LLM classification and Slack notification for Cloud Run Jobs","archived":false,"fork":false,"pushed_at":"2026-04-08T16:48:07.000Z","size":128,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-08T17:15:51.954Z","etag":null,"topics":["cloud-run","email","email-analysis","gcp","gemini","llm","security","slack","triage","vertex-ai"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nlink-jp.png","metadata":{"files":{"readme":"README.ja.md","changelog":"CHANGELOG.md","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":"2026-04-08T15:01:56.000Z","updated_at":"2026-04-08T15:57:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nlink-jp/mail-triage","commit_stats":null,"previous_names":["nlink-jp/mail-triage"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/nlink-jp/mail-triage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fmail-triage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fmail-triage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fmail-triage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fmail-triage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nlink-jp","download_url":"https://codeload.github.com/nlink-jp/mail-triage/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nlink-jp%2Fmail-triage/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33910137,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["cloud-run","email","email-analysis","gcp","gemini","llm","security","slack","triage","vertex-ai"],"created_at":"2026-06-04T15:02:03.337Z","updated_at":"2026-06-04T15:02:03.438Z","avatar_url":"https://github.com/nlink-jp.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mail-triage\n\nGCS上のメールファイルをGemini LLMで分類・分析し、結果をSlackに通知するツール。\nGoogle Cloud Run Jobとして動作し、EventarcトリガーおよびCloud Schedulerによる定期実行に対応。\n\n## 機能\n\n- `.eml`（RFC 2822）および `.msg`（OLE2/MAPI）形式のメールをGCSから解析\n- Gemini LLMによるメール分析（カテゴリ・優先度・要約・タグ・言語検出）\n- Slack Block Kit形式の通知投稿\n- 2つの実行モード:\n  - **単一ファイル** (`--file`): EventarcによるGCSオブジェクト作成トリガー\n  - **スイープ** (デフォルト): 未処理ファイルの一括処理、Cloud Schedulerトリガー\n- サマリ内のURL/ドメインを自動デファング（誤クリック防止）\n- ノンスタグXMLラッピングによるプロンプトインジェクション防御\n- LLM一時エラーに対する指数バックオフリトライ\n\n## インストール\n\n```bash\n# クローン\ngit clone https://github.com/nlink-jp/mail-triage.git\ncd mail-triage\n\n# 依存関係のインストール\nuv sync\n```\n\n## 設定\n\nすべての設定は `MAIL_TRIAGE_` プレフィックス付きの環境変数、またはCLIフラグで指定。\n\n| 環境変数 | フラグ | デフォルト | 説明 |\n|----------|--------|-----------|------|\n| `MAIL_TRIAGE_BUCKET` | `--bucket` | (必須) | GCSバケット名 |\n| `MAIL_TRIAGE_PREFIX` | `--prefix` | `inbox/` | 入力プレフィックス |\n| `MAIL_TRIAGE_DONE_PREFIX` | `--done-prefix` | `processed/` | 処理済みプレフィックス |\n| `MAIL_TRIAGE_PROJECT` | `--project` | (必須) | GCPプロジェクトID |\n| `MAIL_TRIAGE_LOCATION` | `--location` | `us-central1` | Vertex AIリージョン |\n| `MAIL_TRIAGE_MODEL` | `--model` | `gemini-2.5-flash` | Geminiモデル名 |\n| `SUMMARY_LANG` | `--summary-lang` | (自動検出) | サマリ言語の強制指定 |\n| `SLACK_BOT_TOKEN` | `--slack-token` | | Slackボットトークン |\n| `SLACK_CHANNEL` | `--slack-channel` | | 投稿先Slackチャンネル |\n\n## 使い方\n\n### ローカル実行\n\n```bash\n# 認証設定\ngcloud auth application-default login\n\n# スイープモード（未処理ファイルを一括処理）\nuv run mail-triage --bucket my-bucket --project my-project --slack-channel '#mail-digest'\n\n# 単一ファイルモード\nuv run mail-triage --bucket my-bucket --project my-project --file inbox/alert.eml\n\n# ドライラン（投稿・移動なしで解析のみ）\nuv run mail-triage --bucket my-bucket --project my-project --dry-run\n```\n\n### Cloud Run Jobデプロイ\n\n`deploy.sh` によるワンライナーデプロイ:\n\n```bash\n# 1. 設定ファイルをコピー・編集\ncp deploy/deploy.env.template deploy/deploy.env\n# deploy/deploy.env を編集\n\n# 2. デプロイ実行\n./deploy/deploy.sh deploy/deploy.env\n\n# 3. SlackボットトークンをSecret Managerに登録\necho -n 'YOUR_SLACK_BOT_TOKEN' | gcloud secrets versions add mail-triage-slack-bot-token \\\n  --data-file=- --project=PROJECT_ID\n```\n\n`deploy.sh` が構築するリソース:\n- GCSバケット\n- Artifact Registryリポジトリ\n- 必要なIAMロールを持つサービスアカウント\n- 環境変数とシークレットを設定したCloud Run Job\n- Eventarcトリガー（GCSオブジェクト作成 → ジョブ実行）\n- Cloud Scheduler（定期スイープ）\n\n### アーキテクチャ\n\n```\n┌──────────────┐  object.finalize  ┌──────────────────┐\n│ GCS          │──── Eventarc ────▶│ Cloud Run Job     │ ← 単一ファイルモード\n│ (inbox/)     │                   │ (mail-triage)   │\n└──────────────┘                   └──────┬───────────┘\n                                          │\n┌──────────────┐  cron (フォールバック)     │\n│ Cloud        │──── trigger ────▶ 同一ジョブ（スイープモード）\n│ Scheduler    │                          │\n└──────────────┘                   ┌──────┼──────┐\n                                   ▼      ▼      ▼\n                                  GCS  Gemini  Slack\n```\n\n## メール分析\n\nメールは以下のカテゴリに分類:\n\n| カテゴリ | 絵文字 |\n|---------|--------|\n| security-alert | :rotating_light: |\n| incident | :fire: |\n| vulnerability | :warning: |\n| compliance | :shield: |\n| threat-intel | :mag: |\n| newsletter | :newspaper: |\n| announcement | :loudspeaker: |\n| discussion | :speech_balloon: |\n| other | :email: |\n\n優先度: **high** (:red_circle:)、**medium** (:large_orange_circle:)、**low** (:white_circle:)\n\n## ビルド\n\n```bash\nmake test    # テスト実行\nmake lint    # リントチェック\nmake build   # dist/ にホイールをビルド\n```\n\n## 必要なAPI権限\n\n| サービス | 権限 |\n|---------|------|\n| GCS | `storage.objects.list`, `get`, `create`, `delete` |\n| Vertex AI | `aiplatform.endpoints.predict` |\n| Slack | Botスコープ: `chat:write`, `files:write` |\n| Secret Manager | `secretmanager.versions.access` |\n\n## ドキュメント\n\n- [README.md](README.md)（English）\n- [README.ja.md](README.ja.md)（日本語）\n- [Architecture](docs/architecture.md)（設計判断と内部構造）\n- [How to Setup](docs/setup.md)（GCP / Slack prerequisites）\n- [How to Setup (ja)](docs/setup.ja.md)（GCP / Slack 事前準備）\n- [CHANGELOG.md](CHANGELOG.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnlink-jp%2Fmail-triage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnlink-jp%2Fmail-triage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnlink-jp%2Fmail-triage/lists"}