YouTube配信の開始を自動検知してDiscordに通知するPythonアプリケーションです。 YouTube API使用量を98%削減した超低コスト設計で、1分間隔の高頻度チェックが可能。 クリーンアーキテクチャに準拠した保守性の高い設計で、VTuberや配信者のファンコミュニティに最適です。
- ✅ 複数チャンネル同時監視: 複数のYouTubeチャンネルを同時に監視可能
- ✅ リッチな通知: Discord Webhookで埋め込み(Embed)形式の美しい通知を送信
- ✅ 重複通知防止: 配信状態を永続化し、同じ配信の重複通知を防止
- ✅ クリーンアーキテクチャ: 保守性・拡張性・テスタビリティを重視した設計
- ✅ 詳細なログ: ファイル&コンソールに詳細なログを出力
- ✅ カスタマイズ可能: チェック間隔、メンション、通知色などを柔軟に設定
- ✅ テストコード完備: ユニットテスト + 統合テストで品質を保証
- 🚀 超低コストAPI設計: わずか2 units/回のクォータ消費(一般的な方式の1/50)
- 🚀 高頻度チェック対応: 1分間隔の監視でも1日2,880 units(無料枠10,000の30%未満)
- 🚀 事前作成配信枠対応: 週初めに複数配信枠を作成するケースにも対応
- 🚀 自動リトライ機能: 一時的なネットワークエラーに自動対応(指数バックオフ)
$ python main.py
2026-01-21 20:00:00 - root - INFO - ロギング設定完了
2026-01-21 20:00:00 - __main__ - INFO - YouTube配信監視システムを起動します
2026-01-21 20:00:00 - __main__ - INFO - ============================================================
2026-01-21 20:00:00 - __main__ - INFO - YouTube配信監視システム起動
2026-01-21 20:00:00 - __main__ - INFO - 監視チャンネル数: 2
2026-01-21 20:00:00 - __main__ - INFO - チェック間隔: 60秒
2026-01-21 20:00:00 - __main__ - INFO - ============================================================
2026-01-21 20:00:00 - __main__ - INFO - - 配信者A (UCxxxxxxxxxxxxxxxxxxxxxx)
2026-01-21 20:00:00 - __main__ - INFO - - 配信者B (UCyyyyyyyyyyyyyyyyyyyyyy)
2026-01-21 20:00:00 - __main__ - INFO - ============================================================
2026-01-21 20:00:00 - __main__ - INFO - 監視開始(Ctrl+Cで終了)最速で動かすための3ステップ:
# 1. 依存関係をインストール
pip install -r requirements.txt
# 2. 環境変数を設定(.envファイル作成)
cp config/.env.example config/.env
# config/.env を編集してYouTube API KeyとDiscord Webhook URLを設定
# 3. 監視対象チャンネルを設定
# config/config.json を編集してチャンネルIDを追加
# 4. 起動
python main.py詳細はインストールセクションを参照してください。
- Python 3.10以上
- YouTube Data API v3のAPIキー
- Discord Webhook URL
git clone https://github.com/YOUR_USERNAME/live-stream-discord-bot.git
cd live-stream-discord-botpip install -r requirements.txt必要なパッケージ:
requests- Discord Webhook通信用google-api-python-client- YouTube Data API v3クライアントpython-dotenv- 環境変数管理
- Google Cloud Console にアクセス
- 新しいプロジェクトを作成
- APIとサービス → ライブラリ から YouTube Data API v3 を検索して有効化
- 認証情報 → 認証情報を作成 → APIキー を選択
- 作成されたAPIキーをコピー
重要: APIキーは第三者に公開しないでください。
- Discordサーバーの設定を開く
- 連携サービス → ウェブフック → 新しいウェブフック
- ウェブフック名を設定(例:
YouTube配信通知) - 通知を送信したいチャンネルを選択
- ウェブフックURLをコピー をクリック
cp config/.env.example config/.envconfig/.env を編集:
YOUTUBE_API_KEY=あなたのYouTube API Key
DISCORD_WEBHOOK_URL=あなたのDiscord Webhook URLconfig/config.json を編集:
{
"check_interval": 60,
"channels": [
{
"id": "UCxxxxxxxxxxxxxxxxxxxxxx",
"name": "配信者A",
"mention": "@everyone"
}
],
"notification": {
"show_thumbnail": true,
"color": 16711680,
"include_end_notification": false
},
"log_level": "INFO"
}方法1: チャンネルURLから取得
https://www.youtube.com/channel/UCxxxxxxxxxxxxxxxxxxxxxx
↑ この部分がチャンネルID
方法2: @ハンドルから取得
https://www.youtube.com/@channelnameにアクセス- ページのソースを表示(Ctrl+U)
"channelId"で検索"channelId":"UCxxxxxxxxxxxxxxxxxxxxxx"を見つける
注意: チャンネルIDは必ず UC で始まる24文字 です。?si= などのパラメータは不要です。
| 項目 | 型 | 説明 | デフォルト |
|---|---|---|---|
check_interval |
number | チェック間隔(秒) | 60 |
channels[].id |
string | YouTubeチャンネルID(UC始まり24文字) | - |
channels[].name |
string | 表示名(任意) | - |
channels[].mention |
string | Discordメンション(@everyone, @here, <@&ロールID>) |
@everyone |
notification.color |
number | 埋め込みの色(10進数) | 16711680(赤) |
notification.show_thumbnail |
boolean | サムネイル表示 | true |
log_level |
string | ログレベル(DEBUG/INFO/WARNING/ERROR) | INFO |
- 全員にメンション:
@everyone - オンラインユーザーにメンション:
@here - 特定ロールにメンション:
<@&ロールID>- ロールIDの取得方法:
- Discord開発者モードを有効化
- ロールを右クリック → IDをコピー
<@&コピーしたID>の形式で設定
- ロールIDの取得方法:
埋め込みの色は10進数で指定します:
| 色 | 10進数 |
|---|---|
| 赤 | 16711680 |
| 青 | 255 |
| 緑 | 65280 |
| 黄 | 16776960 |
| 紫 | 10181046 |
カラーコード変換: RGB to Decimal Converter
v1.2.0から、より便利なWebhook中心設定形式をサポートしました。従来の形式も引き続き使用可能です。
1つのWebhookで複数チャンネルを監視する場合に便利です。
旧形式(v1.1.0以前):
{
"channels": [
{"id": "UCxxx111...", "name": "配信者A", "webhooks": [{"url": "https://...", "mention": "@everyone"}]},
{"id": "UCxxx222...", "name": "配信者B", "webhooks": [{"url": "https://...", "mention": "@everyone"}]},
{"id": "UCxxx333...", "name": "配信者C", "webhooks": [{"url": "https://...", "mention": "@everyone"}]}
]
}新形式(v1.2.0以降):
{
"webhooks": [
{
"name": "メインサーバー",
"url": "https://...",
"mention": "@everyone",
"channels": ["UCxxx111...", "UCxxx222...", "UCxxx333..."]
}
],
"channels": [
{"id": "UCxxx111...", "name": "配信者A"},
{"id": "UCxxx222...", "name": "配信者B"},
{"id": "UCxxx333...", "name": "配信者C"}
]
}{
"webhooks": [
{
"name": "メインサーバー",
"url": "https://discord.com/api/webhooks/111/aaa",
"mention": "@everyone",
"channels": ["UCxxx111...", "UCxxx222..."]
},
{
"name": "サブサーバー",
"url": "https://discord.com/api/webhooks/222/bbb",
"mention": "<@&1234567890>",
"channels": ["UCxxx333...", "UCxxx444..."]
}
],
"channels": [
{"id": "UCxxx111...", "name": "配信者A"},
{"id": "UCxxx222...", "name": "配信者B"},
{"id": "UCxxx333...", "name": "配信者C"},
{"id": "UCxxx444...", "name": "配信者D"}
]
}{
"webhooks": [
{
"name": "メインサーバー",
"url": "https://discord.com/api/webhooks/111/aaa",
"channels": ["UCxxx111...", "UCxxx222..."]
},
{
"name": "サブサーバー",
"url": "https://discord.com/api/webhooks/222/bbb",
"channels": ["UCxxx222..."] // UCxxx222を重複監視
}
],
"channels": [
{"id": "UCxxx111...", "name": "配信者A"},
{"id": "UCxxx222...", "name": "配信者B"} // 2つのWebhookで通知される
]
}{
"webhooks": [
{
"name": "メインサーバー",
"url": "https://discord.com/api/webhooks/111/aaa",
"channels": ["UCxxx111...", "UCxxx222..."]
}
],
"channels": [
{"id": "UCxxx111...", "name": "配信者A"},
{
"id": "UCxxx222...",
"name": "配信者B",
"webhooks": [
{"url": "https://discord.com/api/webhooks/333/ccc", "mention": "<@&456>"}
]
}
]
}→ UCxxx111は「メインサーバー」Webhookで監視 → UCxxx222は「メインサーバー」+「個別Webhook」の両方で監視(重複監視)
- 後方互換性: 旧形式の設定ファイルも引き続き動作します
- マイグレーション不要: すぐに移行する必要はありません
- 混在可能: 新形式と旧形式を同時に使用できます
python main.pyCtrl+C で安全に停止できます。
- コンソール: INFO レベル以上のログを表示
- ファイル:
logs/monitor.logに DEBUG レベル以上のログを記録
ログファイルは10MBごとにローテーションされ、最大5世代まで保存されます。
- タスクスケジューラを起動
- 基本タスクの作成
- トリガー: システム起動時
- 操作:
python C:\path\to\live-stream-discord-bot\main.py
/etc/systemd/system/youtube-monitor.service を作成:
[Unit]
Description=YouTube Live Stream Monitor
After=network.target
[Service]
Type=simple
User=your_user
WorkingDirectory=/path/to/live-stream-discord-bot
ExecStart=/usr/bin/python3 main.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetサービスの有効化と起動:
sudo systemctl enable youtube-monitor
sudo systemctl start youtube-monitor
sudo systemctl status youtube-monitor本アプリケーションはYouTube Data API v3を効率的に使用する独自実装を採用しています。
search.list(eventType='live')
→ 1回のチェックで100 units消費
→ 1分間隔 × 24時間 = 144,000 units/日(無料枠10,000を大幅超過)
1. playlistItems.list(アップロード済み動画の最新20件取得)→ 1 unit
2. videos.list(一括取得してlive判定)→ 1 unit
→ 1回のチェックで2 units消費
→ 1分間隔 × 24時間 = 2,880 units/日(無料枠の30%未満)
比較: 一般的な実装と比べて 1/50のコスト(98%の効率化)
- ✅ 1分間隔でも余裕: 無料枠内で高頻度チェック可能
- ✅ 複数チャンネル対応: 3チャンネルまで1分間隔で監視可能
- ✅ 事前配信枠に対応: 週初めに7個の配信枠を作成しても検知可能
- ✅ より正確な開始時刻: liveStreamingDetails.actualStartTimeを使用
- ✅ リトライ機能: ネットワークエラー時の自動再試行(指数バックオフ)
詳細は公式ドキュメント「クォータの節約」を参照。
このプロジェクトはクリーンアーキテクチャに準拠して設計されています。
┌─────────────────────────────────────────────┐
│ Presentation Layer (CLI) │ ← ユーザーインターフェース
├─────────────────────────────────────────────┤
│ Application Layer (Use Cases) │ ← ビジネスロジック
├─────────────────────────────────────────────┤
│ Domain Layer (Entities, Interfaces) │ ← ドメインモデル(最内層)
├─────────────────────────────────────────────┤
│ Infrastructure Layer (Impl) │ ← 外部システム実装
└─────────────────────────────────────────────┘
依存の方向: Presentation → Application → Domain ← Infrastructure
live-stream-discord-bot/
├── domain/ # ドメイン層(エンティティ、インターフェース)
│ ├── entities/ # ビジネスオブジェクト
│ ├── value_objects/ # 値オブジェクト
│ └── repositories/ # リポジトリインターフェース(抽象)
├── application/ # アプリケーション層(ユースケース)
│ ├── use_cases/ # ビジネスロジック
│ ├── services/ # アプリケーションサービス
│ └── dto/ # データ転送オブジェクト
├── infrastructure/ # インフラ層(外部システム実装)
│ ├── youtube/ # YouTube API実装
│ ├── discord/ # Discord Webhook実装
│ ├── persistence/ # 状態管理実装
│ └── logging/ # ロギング設定
├── presentation/ # プレゼンテーション層(UI)
│ └── cli/ # CLIコントローラー
├── config/ # 設定ファイル
├── data/ # 状態保存
├── logs/ # ログファイル
├── tests/ # テストコード
└── main.py # エントリーポイント
- 依存性逆転の原則: 内側のレイヤーは外側を知らない
- 単一責任の原則: 各クラスは1つの責務のみを持つ
- インターフェース分離: 抽象に依存し、具象実装は注入
- テスタビリティ: モックやスタブでテスト可能
詳細は アーキテクチャドキュメント を参照してください。
原因: config/.env にAPIキーが設定されていない
解決策:
config/.envファイルが存在するか確認YOUTUBE_API_KEY=your_api_key_hereの形式で設定されているか確認- APIキーの前後に余分なスペースがないか確認
原因: チャンネルIDの形式が正しくない
解決策:
- チャンネルIDは UC で始まる24文字 である必要があります
?si=などのパラメータが含まれていないか確認- 例:
UCxxxxxxxxxxxxxxxxxxxxxx(正しい) - 例:
UCxxxxxxxxxxxxxxxxxxxxxx?si=xxxxx(誤り)
原因: YouTube Data API v3の無料枠を超過
詳細:
- 無料枠: 1日10,000クォータ
- 本アプリは1回のチェックで2クォータのみ消費(最適化済み)
- 1分間隔で24時間監視: 1,440回 × 2 = 2,880クォータ(無料枠の30%未満)
- デフォルト設定(1分間隔)なら余裕で運用可能
解決策(万が一超過した場合):
- 監視チャンネル数を確認(3チャンネル以下を推奨)
- Google Cloud Consoleでクォータ使用状況を確認
- 他のアプリケーションと同じAPIキーを共有していないか確認
原因1: Webhook URLが間違っている
config/.envのURLを再確認
原因2: Webhookが削除された
- Discordサーバー設定でWebhookが存在するか確認
原因3: ネットワークエラー
- ログファイル
logs/monitor.logでエラー詳細を確認
考えられる原因:
- すでに通知済み: 同じ配信の重複通知は防止されます
- チェック間隔: 次のチェックまで待つ必要があります
- APIエラー: ログでエラーを確認
確認方法:
# ログレベルをDEBUGに変更
# config/config.json の log_level を "DEBUG" に変更
# 再起動してログを確認現在はYouTube専用ですが、クリーンアーキテクチャ設計により拡張は容易です。
infrastructure/ 配下に新しいリポジトリ実装を追加することで対応可能です。
いいえ、このアプリケーションはWebhookを使用するため、Discordボットトークンは不要です。 サーバーに常駐させる形式で動作します。
config/config.json の各チャンネル設定で異なるWebhook URLを指定することで可能です。
(現在の実装では全チャンネル共通のWebhook URLですが、拡張可能です)
現在の実装では配信開始通知のみですが、StreamChangeDetector の is_stream_ended メソッドを活用することで実装可能です。
はい、ほぼ気にせず使えます。 本アプリは超低コスト設計で、1分間隔でも1日2,880クォータ(無料枠10,000の30%未満)です。 3チャンネルまでなら余裕で24時間監視可能です。
はい、Python 3.10以上がインストールされていれば動作します。
可能です。Dockerfileは現在含まれていませんが、追加は簡単です。 コントリビューションをお待ちしています。
# 開発用依存関係をインストール
pip install -r requirements-dev.txt# ユニットテストを実行
pytest tests/unit/ -v
# 統合テスト(実際のYouTube APIを使用)
# 事前に .env に TEST_CHANNEL_ID を設定してください
pytest tests/integration/ -v -m integration
# カバレッジ付き
pytest tests/unit/ --cov=. --cov-report=html
# 特定のテストのみ
pytest tests/unit/test_entities.py統合テストの実行には環境変数が必要です:
# config/.env に追加
TEST_CHANNEL_ID=UCxxxxxxxxxxxxxxxxxxxxxx
TEST_CHANNEL_NAME=Test Channel Name# Black でフォーマット
black .
# Flake8 でリント
flake8 .
# mypy で型チェック
mypy .# プロジェクト構造を確認(tree コマンド)
tree -I "__pycache__|*.pyc|venv|env"コントリビューションを歓迎します。
プルリクエストを送る前に、以下を確認してください:
- テストが全て通ること(
pytest) - コードフォーマットが適用されていること(
black .) - 型チェックが通ること(
mypy .)
詳細は CONTRIBUTING.md を参照してください。
- このリポジトリをフォーク
- フィーチャーブランチを作成 (
git checkout -b feature/amazing-feature) - 変更をコミット (
git commit -m 'Add some amazing feature') - ブランチにプッシュ (
git push origin feature/amazing-feature) - プルリクエストを作成
このプロジェクトはMITライセンスの下で公開されています。 詳細は LICENSE ファイルを参照してください。
- Clean Architecture by Robert C. Martin
- YouTube Data API v3
- Discord Webhooks
問題が発生した場合は、Issue を作成してください。
Made with QUA for VTuber fans and stream communities
