GitHub - ronaldlangeveld/telefizz: A production-ready webhook relay that transforms Fizzy notifications into Telegram messages using Clean Architecture principles. No need for Zapier.

5 min read Original article β†—

Telefizz πŸ€–

A production-ready webhook relay that transforms Fizzy notifications into Telegram messages using Clean Architecture principles.

License: MIT Ruby: 3.3+ Deployed with Kamal

Overview

Telefizz listens for webhook events from Fizzy and instantly relays them to Telegram. Built with Clean Architecture for maintainability, it's designed to be self-hosted, scalable, and easy to understand.

Perfect for teams that want real-time Fizzy notifications without context-switching.

Features

✨ Real-time Notifications - Instant Telegram alerts for Fizzy events
πŸ”’ Secure - HMAC-SHA256 signature verification for webhook authenticity
πŸ—οΈ Clean Architecture - Well-organized, testable, and maintainable codebase
🐳 Containerized - Production-ready Docker setup with Kamal deployment
πŸš€ Zero-Downtime Deploys - Automatic rolling updates via Kamal
βœ… Health Checks - Built-in /up endpoint for monitoring

Supported Events

  • πŸ“Œ Card Published
  • πŸ“‹ Card Board Changed
  • πŸ’¬ Comment Created
  • πŸ‘€ Card Assigned / Unassigned
  • 🏷️ Card Triaged
  • βœ… Card Closed / Reopened
  • ⏸️ Card Postponed
  • πŸ”„ Card Sent Back to Triage

Quick Start

Local Development

  1. Clone and install dependencies:

    git clone <repository>
    cd telefizz
    bundle install
  2. Configure environment variables:

    Edit .env with your credentials:

    TELEGRAM_BOT_TOKEN=your_bot_token_here
    TELEGRAM_CHAT_ID=your_chat_id_here
    FIZZY_WEBHOOK_SECRET=your_webhook_secret_here
  3. Run the application:

    The app will be available at http://localhost:9292

  4. Run tests:

API Endpoints

Method Endpoint Purpose
GET /up Health check (returns 200 OK)
POST /webhook Fizzy webhook receiver

Deployment with Kamal

Telefizz is production-ready with Kamal, a zero-downtime deployment tool for containerized applications.

Prerequisites

  • Docker installed on your deployment server
  • SSH access to your server
  • A domain name with DNS pointing to your server

Setup

  1. Install Kamal:

  2. Configure deployment:

    Edit config/deploy.yml:

    • Update servers.web with your server IP (or set SERVER_IP in .env)
    • Update proxy.host with your domain (or set APP_HOST in .env)
    • Configure registry credentials if using a private registry
  3. Create .env file with your secrets:

    cp .env.example .env
    # Edit .env with actual values

    πŸ’‘ Tip: We recommend using the dotenv gem for to easily handle your credentials. Install it globally and use dotenv kamal setup instead of kamal setup to automatically load your .env file. Of course, you can also use a Password Manager as per Kamals Documentation.

  4. Deploy:

    # With dotenv
    dotenv kamal setup     # First-time setup
    dotenv kamal deploy    # Deploy your app
    
    # Or without dotenv
    kamal setup
    kamal deploy

Kamal Commands

# View deployment status
kamal status

# View container logs
kamal logs

# Execute a command in the container
kamal app exec "command"

# Rollback to previous version
kamal rollback

# Stop the application
kamal stop

# Start the application
kamal start

# Redeploy current version
kamal redeploy

SSL/TLS

Kamal automatically provisions free SSL certificates via Let's Encrypt. Update config/deploy.yml:

proxy:
  ssl: true
  host: your-domain.com

Architecture

Telefizz follows Clean Architecture principles for maximum maintainability:

lib/
β”œβ”€β”€ entities/              # Domain objects
β”‚   β”œβ”€β”€ event.rb          # Webhook event representation
β”‚   └── message.rb        # Telegram message representation
β”œβ”€β”€ use_cases/            # Business logic
β”‚   └── process_webhook_event.rb
β”œβ”€β”€ interfaces/           # Controllers and gateways
β”‚   β”œβ”€β”€ webhook_controller.rb
β”‚   └── gateways/
β”‚       └── message_gateway.rb
└── infrastructure/       # External services
    └── telegram_message_gateway.rb

Key Concepts

  • Entities: Pure domain objects with no external dependencies
  • Use Cases: Application business logic, independent of delivery mechanism
  • Interfaces: Controllers (HTTP handlers) and gateway interfaces
  • Infrastructure: Concrete implementations of external integrations (Telegram API)

This structure allows you to:

  • Test business logic without HTTP or external service mocking
  • Easily swap implementations (e.g., different notification services)
  • Understand the codebase at a glance

Development

Running Tests

Project Structure

telefizz/
β”œβ”€β”€ app.rb                 # Sinatra application entry point
β”œβ”€β”€ config.ru              # Rack configuration
β”œβ”€β”€ Gemfile               # Ruby dependencies
β”œβ”€β”€ Gemfile.lock          # Locked dependency versions
β”œβ”€β”€ Dockerfile            # Production container definition
β”œβ”€β”€ config/
β”‚   └── deploy.yml        # Kamal deployment configuration
β”œβ”€β”€ lib/                  # Application code
└── test/                 # Test files

Configuration Reference

Environment Variables

Variable Required Description
TELEGRAM_BOT_TOKEN βœ… Your Telegram bot token from @BotFather
TELEGRAM_CHAT_ID βœ… Chat ID where messages will be sent
FIZZY_WEBHOOK_SECRET βœ… Secret key for webhook signature verification
SERVER_IP (Kamal) IP address of your deployment server
APP_HOST (Kamal) Domain name for your app

Kamal Configuration

See config/deploy.yml for all available options. Key settings:

  • servers.web: Your deployment server(s)
  • proxy.host: Your domain name
  • proxy.ssl: Enable HTTPS (default: true)
  • env.secret: Environment variables to inject into containers

Monitoring

The /up endpoint provides a health check for monitoring solutions:

curl https://your-domain.com/up
# Returns: 200 OK

Use this with Kamal's health checks, monitoring services, or load balancers to ensure your app stays running.

Security

  • βœ… Webhook signatures verified via HMAC-SHA256
  • βœ… Runs as non-root user in container
  • βœ… Environment secrets never committed to git
  • βœ… SSL/TLS encryption enabled by default

Troubleshooting

Webhook not receiving events

  1. Verify FIZZY_WEBHOOK_SECRET matches your Fizzy webhook configuration
  2. Check logs: kamal logs
  3. Test webhook manually with cURL

SSL Certificate issues

Kamal automatically handles Let's Encrypt certificates. If issues persist:

kamal redeploy  # Restart to refresh certificates

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For issues, questions, or suggestions, please open an issue on GitHub.


Made with ❀️ for real-time notifications