Automate your multi-platform live streams with intelligent social media announcements
Monitor Twitch, YouTube, and Kick streams • Post to Mastodon, Bluesky, Discord, and Matrix • AI-powered messages with Google Gemini
Features • Quick Start • Documentation • Contributing • Author • Support
Stream Daemon is an enterprise-grade, open-source automation platform for content creators. Monitor your live streams across Twitch, YouTube, and Kick, then automatically announce to Mastodon, Bluesky, Discord, and Matrix when you go live or end your stream.
- 🤖 AI-Powered Messages - Google Gemini generates unique, engaging announcements for every stream
- � Enterprise Security - Doppler, AWS Secrets Manager, HashiCorp Vault integration
- 🌐 7 Platform Support - Streaming: Twitch, YouTube, Kick | Social: Mastodon, Bluesky, Discord, Matrix
- 📊 Discord Rich Embeds - Real-time viewer counts, live thumbnails, in-place updates
- 🎯 Smart Multi-Platform - Stream to multiple platforms? Choose combined, threaded, or separate announcements
- 🐳 Production Ready - Docker, Docker Compose, systemd service support
- ⚡ Lightweight - Runs on anything from Raspberry Pi to AWS Lambda
- Twitch - OAuth 2.0 with async API support, rate limiting, comprehensive error handling
- YouTube Live - Auto-resolves channel from @handle or channel ID, quota-aware with retry logic
- Kick - OAuth 2.0 authentication required, 2FA-enabled developer portal access
- Mastodon - Post to any Mastodon-compatible instance (Mastodon, Hometown, Pleroma, etc.)
- Bluesky - Native AT Protocol support with automatic link cards and metadata
- Discord - Advanced rich embed system:
- Real-time viewer counts and live stream thumbnails
- In-place embed updates (no duplicate posts!)
- Customizable role mentions per platform (@Twitch Viewers, @YouTube Fans, etc.)
- "Stream ended" messages with VOD links and statistics
- Per-platform webhook support
- Matrix - Bot integration with room posting:
- Token or password authentication
- Custom display names and avatars
- Homeserver configuration support
- Message retry with exponential backoff
- Google Gemini LLM Integration - Generate unique announcements for every stream
- Platform-aware character limits (Bluesky: 300, Mastodon: 500, Discord: 2000)
- Automatic hashtag generation from stream titles and game names
- Dynamic, personalized messages that never repeat
- Graceful fallback to static messages if LLM unavailable
- Cost-effective: ~$0.0001 per announcement with Gemini 2.0 Flash Lite
- Configurable temperature and creativity controls
- Doppler - Modern secrets platform with environment-specific tokens (dev/staging/prod)
- AWS Secrets Manager - Secure cloud-based credential storage with IAM integration
- HashiCorp Vault - Self-hosted secrets with dynamic credentials and audit logging
- Priority System - Secrets managers override environment variables for maximum security
- Fallback Chain - Doppler → AWS → Vault → Environment variables
- Platform-Specific Messages - Different announcements for each platform (Twitch, YouTube, Kick)
- Template Variables - Dynamic content:
{url},{title},{game},{viewers},{platform} - INI-Style Configuration - Simple
[DEFAULT],[TWITCH],[YOUTUBE],[KICK]sections - Live & End Messages - Separate templates for "going live" and "stream ended" announcements
- Toggle Control - Use platform-specific messages or unified DEFAULT messages
When streaming to multiple platforms simultaneously (e.g., Twitch + YouTube + Kick):
Live Announcements:
- Separate - Individual posts per platform ("Live on Twitch!" "Live on YouTube!")
- Thread - Reply chain of announcements ("Live on Twitch!" → "Also on YouTube!")
- Combined - Single post for all platforms ("Live on Twitch, YouTube, and Kick!")
Stream Ended Announcements:
- Disabled - No end messages
- Separate - Individual end posts per platform
- Thread - Reply to each platform's live announcement with end message
- Combined - Single end message per platform
- Single When All End - Wait until ALL platforms offline (perfect for handling crashes gracefully!)
- Docker - Production-ready containerized deployment
- Docker Compose - Multi-container orchestration with health checks
- Systemd - Native Linux service integration
- Bare Metal - Direct Python execution
- Cloud Platforms - AWS Lambda, Google Cloud Run, Azure Functions ready
- Kubernetes - ConfigMap and Secrets support
- Python 3.10+ (3.11+ recommended)
- API credentials for at least one streaming platform (Twitch, YouTube, or Kick)
- Credentials for at least one social platform (Mastodon, Bluesky, Discord, or Matrix)
- (Optional) Doppler account for enterprise secrets management
- (Optional) Google AI Studio API key for AI-generated messages
-
Clone and install
git clone https://github.com/ChiefGyk3D/Stream-Daemon.git cd Stream-Daemon pip install -r requirements.txt -
Configure secrets ⭐ NEW!
# Interactive wizard for setting up credentials ./scripts/create-secrets.shChoose your secrets platform:
- Doppler (recommended) - Modern cloud secrets with environment support
- AWS Secrets Manager - Secure cloud storage with IAM integration
- HashiCorp Vault - Self-hosted enterprise secrets
- .env file - Quick local development
The wizard will guide you through configuring all platforms interactively.
-
Run!
python3 stream-daemon.py # Or with Doppler doppler run -- python3 stream-daemon.py
That's it! Stream Daemon will now monitor your streams and post announcements automatically.
📖 Secrets Wizard Documentation - Full guide to the interactive setup tool
Option 1: Use Pre-Built Image from GitHub Container Registry (Recommended)
# Pull the latest image
docker pull ghcr.io/chiefgyk3d/stream-daemon:latest
# Run with environment file
docker run -d \
--name stream-daemon \
--restart unless-stopped \
--env-file .env \
-v $(pwd)/messages.txt:/app/messages.txt \
-v $(pwd)/end_messages.txt:/app/end_messages.txt \
ghcr.io/chiefgyk3d/stream-daemon:latest
# View logs
docker logs -f stream-daemonOption 2: Use Docker Hub
docker pull chiefgyk3dx/stream-daemon:latest
docker run -d \
--name stream-daemon \
--restart unless-stopped \
--env-file .env \
chiefgyk3dx/stream-daemon:latestOption 3: Build from Source
# Clone the repository
git clone https://github.com/ChiefGyk3D/Stream-Daemon.git
cd Stream-Daemon
# Build the Docker image
docker build -f Docker/Dockerfile -t stream-daemon:local .
# Run with environment file
docker run -d \
--name stream-daemon \
--restart unless-stopped \
--env-file .env \
-v $(pwd)/messages.txt:/app/messages.txt \
-v $(pwd)/end_messages.txt:/app/end_messages.txt \
stream-daemon:local
# View logs
docker logs -f stream-daemonOption 4: Docker Compose (Build or Pull)
cd Docker
# Copy the example configuration
cp docker-compose.example.yml docker-compose.yml
# Edit docker-compose.yml with your credentials
# Use 'image: ghcr.io/chiefgyk3d/stream-daemon:latest' to pull pre-built
# Or use 'build: context: .. dockerfile: Docker/Dockerfile' to build from source
nano docker-compose.yml
# Start the container
docker-compose up -d
# View logs
docker-compose logs -f stream-daemonRun Stream Daemon as a system service with automatic startup and logging:
# One-command installation
sudo ./scripts/install-systemd.sh
# Service management
sudo systemctl start stream-daemon # Start
sudo systemctl stop stream-daemon # Stop
sudo systemctl status stream-daemon # Check status
sudo journalctl -u stream-daemon -f # View logsSee systemd Service Guide for full details.
For production deployments, comprehensive guides, and advanced features:
- Getting Started Guide - Detailed first-time setup
- Installation Guide - All deployment methods
- Secrets Wizard 🪄 - Interactive setup tool for all platforms
- Secrets Management - Doppler, AWS, Vault setup
Stream Daemon uses pure environment variables - perfect for Docker, Kubernetes, and cloud deployments. No config files to manage!
Streaming Platforms
# Twitch
TWITCH_ENABLE=True
TWITCH_USERNAME=your_username
TWITCH_CLIENT_ID=your_client_id
TWITCH_CLIENT_SECRET=your_client_secret
# YouTube
YOUTUBE_ENABLE=True
YOUTUBE_USERNAME=@YourHandle # Auto-resolves to channel ID!
YOUTUBE_API_KEY=your_api_key
# Kick
KICK_ENABLE=True
KICK_USERNAME=your_username
KICK_CLIENT_ID=your_client_id # Optional: better rate limits
KICK_CLIENT_SECRET=your_secretSocial Media Platforms
# Mastodon
MASTODON_ENABLE=True
MASTODON_INSTANCE_URL=https://mastodon.social
MASTODON_ACCESS_TOKEN=your_access_token
# Bluesky
BLUESKY_ENABLE=True
BLUESKY_HANDLE=yourhandle.bsky.social
BLUESKY_APP_PASSWORD=your_app_password
# Discord
DISCORD_ENABLE=True
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
DISCORD_ROLE_TWITCH=@Twitch Viewers # Mention roles
DISCORD_ROLE_YOUTUBE=@YouTube Fans
DISCORD_UPDATE_LIVE_MESSAGE=True # Live embed updates!
# Matrix
MATRIX_ENABLE=True
MATRIX_HOMESERVER=https://matrix.org
MATRIX_ACCESS_TOKEN=your_token # OR use password auth
MATRIX_ROOM_ID=!roomid:matrix.orgSecrets Management (Recommended for Production)
# Doppler (Recommended)
SECRETS_MANAGER=doppler
DOPPLER_TOKEN=dp.st.dev.xxxx # Environment-specific token
DOPPLER_CONFIG=dev # dev, stg, or prd
SECRETS_DOPPLER_TWITCH_SECRET_NAME=twitch
SECRETS_DOPPLER_YOUTUBE_SECRET_NAME=youtube
# AWS Secrets Manager
SECRETS_MANAGER=aws
AWS_REGION=us-east-1
SECRETS_AWS_TWITCH_SECRET_NAME=prod/stream-daemon/twitch
# HashiCorp Vault
SECRETS_MANAGER=vault
SECRETS_VAULT_URL=https://vault.example.com
SECRETS_VAULT_TOKEN=your_vault_token
SECRETS_VAULT_TWITCH_SECRET_PATH=secret/data/stream-daemon/twitchPriority Chain: Doppler → AWS → Vault → Environment variables
Secrets managers always override environment variables for maximum security.
📖 Secrets Wizard - Interactive setup tool (recommended)
📖 Complete Secrets Guide - Manual configuration
AI-Powered Messages
# Google Gemini LLM
LLM_PROVIDER=gemini
GEMINI_API_KEY=your_api_key # From https://aistudio.google.com
# Platform-specific character limits
LLM_MAX_LENGTH_BLUESKY=300
LLM_MAX_LENGTH_MASTODON=500
LLM_MAX_LENGTH_DISCORD=2000
LLM_MAX_LENGTH_MATRIX=500
# Creativity controls
LLM_TEMPERATURE=0.9 # 0.0-2.0, higher = more creative
LLM_TOP_P=0.95 # Nucleus samplingCost: ~$0.0001 per message with Gemini 2.0 Flash Lite!
📖 AI Messages Guide
Custom Messages
Edit messages.txt:
[DEFAULT]
🔴 I'm live! Come watch: {url}
[TWITCH]
🎮 Live on Twitch! Playing {title}
👉 {url}
[YOUTUBE]
📺 Streaming now on YouTube!
{url}
[KICK]
⚡ Live on Kick! {url}Configuration:
MESSAGES_MESSAGES_FILE=messages.txt
MESSAGES_END_MESSAGES_FILE=end_messages.txt
MESSAGES_USE_PLATFORM_SPECIFIC_MESSAGES=True # Use [TWITCH] vs [DEFAULT]Multi-Platform Streaming
# Live announcements when streaming to multiple platforms
MESSAGES_LIVE_THREADING_MODE=combined
# Options: separate | thread | combined
# Stream ended announcements
MESSAGES_END_THREADING_MODE=thread
# Options: disabled | separate | thread | combined | single_when_all_endExample: Streaming to Twitch + YouTube + Kick with combined:
- Posts: "🔴 Live on Twitch, YouTube, and Kick!"
- Instead of 3 separate posts
Pro Tip: Use single_when_all_end to handle platform crashes gracefully!
Timing & Intervals
# How often to check when OFFLINE (minutes)
SETTINGS_CHECK_INTERVAL=5
# How often to check when LIVE (minutes)
SETTINGS_POST_INTERVAL=5
# Discord live embed update frequency (seconds)
DISCORD_UPDATE_INTERVAL=60For platform-specific setup guides, advanced features, and troubleshooting:
View Full Documentation
- Quickstart Guide - Get up and running in 10 minutes
- Installation Guide - All deployment methods (Docker, systemd, bare metal)
- Twitch Setup - OAuth 2.0, client ID/secret, rate limits, troubleshooting
- YouTube Live Setup - API key, channel ID resolution, quota management
- Kick Setup - OAuth flow, 2FA requirements, public API fallback
- Mastodon Setup - Instance URL, access tokens, custom instances
- Bluesky Setup - App passwords, handle configuration, AT Protocol
- Discord Setup - Webhooks, rich embeds, role mentions, live updates
- Matrix Setup - Bot creation, room IDs, authentication methods
- Secrets Wizard 🪄 - Interactive setup tool for all platforms (recommended)
- Automated Doppler, AWS, Vault, or .env configuration
- Step-by-step credential collection
- Supports updating existing configurations
- Secrets Management - Manual setup: Doppler, AWS Secrets Manager, HashiCorp Vault
- Environment-specific Doppler tokens (dev/staging/prod)
- Priority chain and security best practices
- Docker integration and testing guides
- AI-Powered Messages - Google Gemini LLM integration for dynamic announcements
- Custom Messages - Platform-specific templates, variables, INI format
- Multi-Platform Streaming - Threading modes, combined posts, strategies
- v1 to v2 Migration - Upgrading from twitch-and-toot v1.x
- Documentation Index - Browse all guides and references
Stream Daemon includes a comprehensive test suite using pytest to validate your configuration before going into production.
# Test all platforms with current configuration
python3 stream-daemon.py --test
# Test specific platform
python3 stream-daemon.py --test --platform twitchThe modern test suite uses pytest for better organization and coverage. See tests/README.md for complete documentation.
# Install pytest
pip install pytest pytest-asyncio pytest-cov
# Run all tests
pytest tests/ -v
# Run tests by category
pytest tests/ -m streaming # Twitch, YouTube, Kick
pytest tests/ -m social # Mastodon, Bluesky, Discord, Matrix
pytest tests/ -m integration # End-to-end workflows
# Run specific test file
pytest tests/test_config.py -v
pytest tests/test_streaming_platforms.py -v
pytest tests/test_social_platforms.py -v
pytest tests/test_integration.py -v
# Run with coverage
pytest tests/ --cov=stream_daemon --cov-report=html
# Run platform validation tests
pytest tests/test_platform_validation.py -vComprehensive validation tests for all platforms (replaces legacy test_doppler_*.py files):
# Test all platforms
pytest tests/test_platform_validation.py -v
# Test specific platform
pytest tests/test_platform_validation.py::TestTwitchValidation -v
pytest tests/test_platform_validation.py::TestMastodonValidation -v
# Test by category
pytest tests/test_platform_validation.py -m streaming -v # All streaming
pytest tests/test_platform_validation.py -m social -v # All social
# Quick configuration check
pytest tests/test_platform_validation.py::TestAllPlatformsValidation::test_configuration_summary -v -s✅ Configuration Loading - Environment variables and .env files
✅ Secrets Management - Doppler/AWS/Vault integration
✅ API Authentication - Valid credentials for each platform
✅ Stream Detection - Live status checking and data retrieval
✅ Social Posting - Message formatting and platform-specific features
✅ Security - Secret masking and safe logging
✅ Error Handling - Graceful degradation on failures
✅ Integration - Complete stream lifecycle workflows
🔐 Testing Twitch Integration...
✓ Doppler: Successfully fetched secrets
✓ Authentication: Valid OAuth token
✓ API: Successfully retrieved user data
✓ Stream Status: Currently offline
✓ Security: No secrets leaked in logs
🎉 All tests passed!
Note: Tests use real API calls but don't post announcements. Safe to run anytime!
Stream Daemon is built with a modular, extensible architecture:
stream-daemon.py # Main daemon application
├── stream_daemon/ # Core application package
│ ├── platforms/
│ │ ├── streaming/ # Streaming platform monitors
│ │ │ ├── TwitchPlatform # Twitch API (async, OAuth 2.0)
│ │ │ ├── YouTubePlatform # YouTube Data API v3
│ │ │ └── KickPlatform # Kick OAuth + public API fallback
│ │ └── social/ # Social media publishers
│ │ ├── MastodonPlatform # Mastodon API
│ │ ├── BlueskyPlatform # AT Protocol (Bluesky)
│ │ ├── DiscordPlatform # Discord webhooks + rich embeds
│ │ └── MatrixPlatform # Matrix bot API
│ ├── secrets/ # Secrets management
│ │ ├── DopplerClient # Doppler SDK integration
│ │ ├── AWSSecretsClient # AWS Secrets Manager
│ │ └── VaultClient # HashiCorp Vault
│ └── utils/
│ ├── AIMessageGenerator # Google Gemini LLM integration
│ └── MessageParser # Template variable substitution
├── messages.txt # Live stream message templates
├── end_messages.txt # Stream ended message templates
└── Docker/ # Container deployment files
├── Dockerfile
└── docker-compose.yml
graph LR
A[Stream Daemon] --> B{Check Interval}
B --> C[Twitch API]
B --> D[YouTube API]
B --> E[Kick API]
C --> F{Stream Live?}
D --> F
E --> F
F -->|Yes| G[Generate Message]
F -->|No| B
G --> H{AI Enabled?}
H -->|Yes| I[Gemini LLM]
H -->|No| J[Template Parser]
I --> K[Post to Social]
J --> K
K --> L[Mastodon]
K --> M[Bluesky]
K --> N[Discord]
K --> O[Matrix]
Flow:
- Monitor - Daemon checks configured streaming platforms every
CHECK_INTERVAL(default: 5 min) - Detect - Identifies state changes: offline→live or live→offline
- Generate - Creates announcement using AI (Gemini) or templates
- Publish - Posts to all enabled social platforms once per state change
- Update - While live: Discord embeds update with viewer counts, continues checking for stream end
- Repeat - Returns to monitoring when offline
Smart Posting: Stream Daemon only posts when stream state changes, never spamming followers with duplicate announcements every check cycle.
Stream Daemon not detecting when I go live
-
Verify platform is enabled:
# Check environment variables echo $TWITCH_ENABLE # Should be True echo $TWITCH_USERNAME
-
Test API authentication:
python3 stream-daemon.py --test --platform twitch
-
Check intervals:
# Lower CHECK_INTERVAL for faster detection export SETTINGS_CHECK_INTERVAL=1 # Check every 1 minute
-
Review logs for errors:
# Look for authentication or API errors tail -f stream-daemon.log
Announcements not posting to social media
-
Test social platform authentication:
python3 tests/test_mastodon.py python3 tests/test_discord.py
-
Check platform is enabled:
echo $MASTODON_ENABLE # Should be True echo $MASTODON_INSTANCE_URL echo $MASTODON_ACCESS_TOKEN # Should be set
-
Verify Discord webhook:
# Test webhook URL manually curl -X POST -H "Content-Type: application/json" \ -d '{"content": "Test message"}' \ "$DISCORD_WEBHOOK_URL"
-
Check message template files:
# Ensure files exist and are readable cat messages.txt cat end_messages.txt
Secrets not loading from Doppler/AWS/Vault
-
Verify secrets manager configuration:
echo $SECRETS_MANAGER # Should be: doppler, aws, or vault echo $DOPPLER_TOKEN # If using Doppler echo $DOPPLER_CONFIG # Should match environment: dev, stg, prd
-
Test secret fetching:
python3 -c "from doppler_sdk import DopplerSDK; \ sdk = DopplerSDK(); sdk.set_access_token('$DOPPLER_TOKEN'); \ print(sdk.secrets.get('twitch'))"
-
Check priority chain:
- Secrets managers override environment variables
- If both are set, secrets manager wins
- See Secrets Priority Guide
-
Verify Doppler token environment:
devtokens only accessdevsecrets- Use
prdtoken for production deployments - See Doppler Guide
Discord embeds not updating
-
Enable live updates:
export DISCORD_UPDATE_LIVE_MESSAGE=True -
Check update interval:
export DISCORD_UPDATE_INTERVAL=60 # Update every 60 seconds
-
Verify webhook permissions:
- Webhook must have permission to edit messages
- Check Discord server settings
-
Check for rate limiting:
- Discord limits: 30 requests/minute per webhook
- Lower update interval if hitting limits
AI messages not working
-
Verify Gemini API key:
echo $LLM_PROVIDER # Should be: gemini echo $GEMINI_API_KEY # Should be set
-
Test Gemini API:
python3 -c "import google.genai; \ client = google.genai.Client(api_key='$GEMINI_API_KEY'); \ response = client.models.generate_content(model='gemini-2.0-flash-lite', contents='Say hello'); \ print(response.text)"
-
Check fallback behavior:
- If LLM fails, Stream Daemon falls back to static messages
- Check logs for LLM errors
- Verify
messages.txthas valid templates
-
Verify character limits:
export LLM_MAX_LENGTH_BLUESKY=300 export LLM_MAX_LENGTH_MASTODON=500
- 📖 Documentation - Complete guide index
- 🐛 Bug Reports - GitHub Issues
- 💬 Questions - GitHub Discussions
- 🔍 Search Issues - Someone may have solved your problem!
When opening an issue, please include:
- Stream Daemon version - Check
stream-daemon.pyversion - Python version -
python3 --version - Platform details - OS, Docker version (if applicable)
- Configuration - Enabled platforms, secrets manager (no actual secrets!)
- Error logs - Relevant error messages (secrets are auto-masked)
- Steps to reproduce - How to trigger the issue
Example:
**Version:** Stream Daemon v2.0.0
**Python:** 3.11.4
**OS:** Ubuntu 22.04 LTS
**Docker:** 24.0.5
**Configuration:**
- Streaming: Twitch + YouTube
- Social: Mastodon + Discord
- Secrets: Doppler (prd environment)
- AI: Gemini enabled
**Error:**
ERROR: Failed to post to Mastodon: 401 Unauthorized
**Steps:**
1. Enable Mastodon with invalid token
2. Go live on Twitch
3. Daemon attempts to post, fails with 401
If Stream Daemon is using too many resources:
-
Increase check intervals:
export SETTINGS_CHECK_INTERVAL=10 # Check every 10 minutes instead of 5
-
Disable unused platforms:
export KICK_ENABLE=False # Disable platforms you don't use
-
Disable Discord live updates:
export DISCORD_UPDATE_LIVE_MESSAGE=False # Reduce API calls
-
Monitor resource usage:
# Docker docker stats stream-daemon # Bare metal htop # Filter by 'stream-daemon'
Option 1: Use Pre-Built Image (Recommended)
version: '3.8'
services:
stream-daemon:
image: ghcr.io/chiefgyk3d/stream-daemon:latest # or chiefgyk3dx/stream-daemon:latest
container_name: stream-daemon
restart: unless-stopped
environment:
# Secrets Management
- SECRETS_MANAGER=doppler
- DOPPLER_TOKEN=${DOPPLER_TOKEN}
- DOPPLER_CONFIG=prd
# Streaming Platforms
- TWITCH_ENABLE=True
- TWITCH_USERNAME=your_username
- YOUTUBE_ENABLE=True
- YOUTUBE_USERNAME=@YourHandle
- KICK_ENABLE=True
- KICK_USERNAME=your_username
# Social Platforms
- MASTODON_ENABLE=True
- BLUESKY_ENABLE=True
- DISCORD_ENABLE=True
- MATRIX_ENABLE=True
# AI Messages (optional)
- LLM_PROVIDER=gemini
volumes:
- ./messages.txt:/app/messages.txt
- ./end_messages.txt:/app/end_messages.txt
healthcheck:
test: ["CMD", "python", "-c", "import sys; sys.exit(0)"]
interval: 30s
timeout: 10s
retries: 3Option 2: Build from Source
version: '3.8'
services:
stream-daemon:
build:
context: .
dockerfile: Docker/Dockerfile
container_name: stream-daemon
restart: unless-stopped
environment:
# ... same environment variables as aboveDeploy:
cd Docker
# Copy example configuration
cp docker-compose.example.yml docker-compose.yml
# Edit with your credentials
nano docker-compose.yml
# Start container
docker-compose up -d
# View logs
docker-compose logs -f stream-daemon
# Restart
docker-compose restart
# Stop
docker-compose downContainer Name: The container will be named stream-daemon for easy reference in all Docker commands.
Stream Daemon is published to two container registries:
- GitHub Container Registry:
ghcr.io/chiefgyk3d/stream-daemon:latest(Recommended) - Docker Hub:
chiefgyk3dx/stream-daemon:latest(Alternative)
Both images are automatically built and published on every release with support for linux/amd64 and linux/arm64 platforms.
# Clone the repository (if not already cloned)
git clone https://github.com/ChiefGyk3D/Stream-Daemon.git
cd Stream-Daemon
# Build image from source
docker build -f Docker/Dockerfile -t stream-daemon:local .
# Run with environment file
docker run -d \
--name stream-daemon \
--restart unless-stopped \
--env-file .env \
-v $(pwd)/messages.txt:/app/messages.txt \
-v $(pwd)/end_messages.txt:/app/end_messages.txt \
stream-daemon:local
# View logs
docker logs -f stream-daemon
# Enter container for debugging
docker exec -it stream-daemon /bin/bashWhy build from source?
- Testing local changes before submitting a PR
- Custom modifications for your environment
- Running unreleased features from development branches
- Air-gapped or restricted network environments
Doppler Integration
# Pass Doppler token only, fetch all other secrets from Doppler
docker run -d \
--name stream-daemon \
-e SECRETS_MANAGER=doppler \
-e DOPPLER_TOKEN=dp.st.prd.xxxx \
-e DOPPLER_CONFIG=prd \
-e TWITCH_ENABLE=True \
-e TWITCH_USERNAME=your_username \
ghcr.io/chiefgyk3d/stream-daemon:latestAll credentials (client IDs, secrets, tokens) are fetched securely from Doppler!
AWS Secrets Manager Integration
docker run -d \
--name stream-daemon \
-e SECRETS_MANAGER=aws \
-e AWS_REGION=us-east-1 \
-e AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \
-e AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
-e SECRETS_AWS_TWITCH_SECRET_NAME=prod/stream-daemon/twitch \
ghcr.io/chiefgyk3d/stream-daemon:latestOr use IAM roles with ECS/EKS for credential-free authentication!
- Use
prdDoppler environment or production AWS/Vault secrets - Set
restart: unless-stoppedin docker-compose.yml - Mount message template files as volumes
- Configure health checks
- Set up log aggregation (Docker logs → CloudWatch/Datadog)
- Monitor resource usage (CPU/memory limits)
- Enable auto-updates (Watchtower or manual rebuild schedule)
- Test secrets rotation procedures
Contributions make Stream Daemon better! We welcome:
- 🐛 Bug Reports - Found an issue? Open an issue
- 💡 Feature Requests - Have an idea? Start a discussion
- 🔧 Pull Requests - Want to contribute code? PRs are welcome!
- 📖 Documentation - Help improve guides and examples
- 🧪 Testing - Try Stream Daemon on different platforms and report findings
# Clone repository
git clone https://github.com/ChiefGyk3D/Stream-Daemon.git
cd Stream-Daemon
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Configure test environment
cp .env.example .env
# Add your test credentials
# Run tests
python3 tests/test_doppler_all.py
# Code formatting (we use Black)
pip install black
black stream-daemon.py stream_daemon/- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Test your changes thoroughly
- Follow Black code formatting
- Update documentation if needed
- Commit with clear messages (
git commit -m 'Add amazing feature') - Push to your fork (
git push origin feature/amazing-feature) - Open a Pull Request with description of changes
- Follow PEP 8 guidelines
- Use Black for code formatting
- Add type hints where applicable
- Include docstrings for functions and classes
- Write descriptive commit messages
- 📖 Read the Documentation
- 💬 Join GitHub Discussions
- 🐛 Search existing Issues
- Matrix Support - Post to Matrix rooms with bot integration
- Discord Rich Embeds - Live updating embeds with viewer counts and thumbnails
- AI Message Generation - Google Gemini LLM integration for dynamic announcements
- Modular Architecture - Platform classes extracted to
stream_daemon/platforms/ - Multi-Platform Strategies - Combined, threaded, and separate posting modes
- Comprehensive Documentation - Platform guides, feature docs, migration guides
- Systemd Service Templates - Easy Linux service installation
- Web Dashboard - Monitor streams and configure settings via web UI
- Prometheus Metrics - Export metrics for monitoring and alerting
- Advanced Scheduling - Custom intervals per platform, quiet hours
- Additional Social Platforms
- Threads (Meta)
- X/Twitter (API permitting)
- Telegram channels
- Streaming Platform Expansion
- Facebook Gaming
- Trovo
- DLive
- Advanced Features
- Webhooks for stream events
- Stream analytics and reporting
- Multi-language message templates
- Clip sharing to social media
- VOD announcements
- Schedule-aware posting (don't announce late-night streams)
- Enterprise Features
- Multi-tenant support (manage multiple streamers)
- RBAC (role-based access control)
- Audit logging
- SSO integration
Have a feature idea? Open a discussion or vote on existing proposals!
Kick.com Link Previews
- CloudFlare security blocks metadata scraping for link preview cards
- Kick URLs remain fully clickable in all posts
- Rich preview cards (thumbnails, titles) not available for Kick on Bluesky
- Mastodon preview support varies (depends on whether Kick blocks Mastodon's servers)
- ✅ Twitch and YouTube work perfectly with full preview cards
YouTube API Quotas
- YouTube Data API has daily quota limits (10,000 units/day by default)
- Each channel lookup: ~3 units, stream check: ~1 unit
- Default 5-minute intervals: ~288 checks/day (~288 units)
- Stream Daemon is quota-efficient but be aware if running multiple instances
- 📖 See YouTube Setup Guide
Kick OAuth Requirements
- Kick OAuth requires 2FA enabled on your account
- Initial authentication must be done interactively (can't be fully automated)
- Public API fallback available without OAuth (higher rate limits with auth)
- 📖 See Kick Setup Guide
Webhook Permissions
- Cannot edit or delete messages sent by other bots/users
- Rate limited to 30 requests per minute per webhook
- Embeds have size limits (6000 characters total)
- Cannot pin messages or manage reactions via webhooks
Live Embed Updates
- Updates happen via message edit (requires storing message ID)
- If daemon restarts while stream is live, tracking is lost
- Recommendation: Use persistent storage for message IDs (planned feature)
Message Size
- Some Matrix servers impose message size limits (typically 64KB)
- Long messages may be truncated or rejected
- Use
LLM_MAX_LENGTH_MATRIXto control AI-generated message length
Authentication
- Access tokens don't expire but can be revoked
- Password authentication creates new session each restart
- Recommendation: Use access tokens for production deployments
State Persistence
- Daemon tracks stream state in memory only
- Restart during live stream will re-post "going live" announcement
- Planned: Redis/SQLite state persistence
Network Reliability
- Temporary API outages may cause missed stream state changes
- No automatic retry for failed posts (logged as errors)
- Recommendation: Monitor logs and set up alerting
Time Zones
- All times logged in UTC by default
- Discord timestamps auto-convert to user's local time
- Other platforms show times as posted
Credentials Storage
- Environment variables visible to all processes with same user
- Strongly recommend using Doppler/AWS/Vault for production
- Docker containers should use secrets management, not .env files
API Keys in Logs
- All secrets are automatically masked in logs
- Test outputs show
***MASKED***instead of actual credentials - Always review logs before sharing publicly
Resource Usage
- Minimal CPU usage (< 1% idle, ~5% during checks)
- Memory footprint: ~50-100MB depending on enabled platforms
- Network: ~1-5KB per check cycle
- Safe for Raspberry Pi, VPS, or cloud deployments
Check Intervals
- Default 5-minute intervals balance responsiveness vs API usage
- Lower intervals = faster detection but higher API usage
- Recommendation: 5 minutes for most users, 1-2 minutes for time-sensitive needs
Stream Daemon is licensed under the Mozilla Public License 2.0 (MPL 2.0).
✅ You CAN:
- Use Stream Daemon commercially
- Modify the source code
- Distribute your modifications
- Use it privately
- Use it for patent grants
- Disclose source of MPL-licensed files
- Include the original license and copyright
- State significant changes made to the code
- Release modifications under MPL 2.0 (file-level copyleft)
❌ You CANNOT:
- Hold the authors liable
- Use contributors' names for endorsement
The Mozilla Public License 2.0 is a middle ground between permissive licenses (like MIT) and strong copyleft licenses (like GPL):
- File-level copyleft - Only modified MPL files must stay open source
- Commercial friendly - Can combine with proprietary code
- Patent protection - Grants patent license from contributors
- Simple compliance - Just keep MPL files open and attributed
For organizations that cannot comply with MPL 2.0 terms, commercial licensing is available. Contact ChiefGyk3D for inquiries.
Stream Daemon is built on the shoulders of giants:
- TwitchAPI - Excellent Python Twitch API wrapper
- Google Generative AI - Gemini LLM for AI-powered messages
- Doppler Python SDK - Enterprise secrets management
- Boto3 - AWS SDK for Secrets Manager
- HVAC - HashiCorp Vault client
- Mastodon.py - Mastodon API client
- atproto - Bluesky AT Protocol SDK
- matrix-nio - Matrix client library
- Open-source streaming community - For driving innovation in content creation tools
- All contributors - Every PR, issue, and discussion makes Stream Daemon better
- Early adopters - For testing, feedback, and feature requests
- Doppler - For providing excellent secrets management platform and documentation
- GitHub Copilot - For assistance with code generation and documentation
- Python community - For creating an amazing ecosystem
- ⭐ Star the repo - Show your support!
- 📢 Share - Tell other streamers about Stream Daemon
- 🐛 Report bugs - Help us improve quality
- 💡 Request features - Share your ideas
- 🔧 Contribute - Submit pull requests
- 📖 Improve docs - Help others get started
- GitHub Discussions - Ask questions, share setups
- GitHub Issues - Bug reports and feature requests
- Pull Requests - Contribute code and improvements
- Watch releases - Get notified of new versions
- Follow development - Track progress on roadmap items
- Join discussions - Participate in feature planning
If you find Stream Daemon useful, consider supporting development:
Donate:
Made with ❤️ by ChiefGyk3D
| Mastodon | Bluesky | Twitch | YouTube | Kick | TikTok | Discord | Matrix |
ChiefGyk3D is the author of Stream Daemon (formerly Twitch and Toot)
If Stream Daemon helps you, consider ⭐ starring the repo!
Using Stream Daemon for your streams? Share your story and get featured here!
Stream Daemon - Automate your multi-platform streaming presence
