Reusable Telegram and Discord ChatOps utilities for Python projects
Project description
chatops-bridge
Reusable Telegram and Discord utilities for Python applications.
This package was extracted from production automation code and generalized for multi-purpose ChatOps use.
Transport-level Telegram/Discord sending is reused from awesome-notify-bridge.
Features
- Telegram send/poll helpers:
- send text and images
- split long text by Telegram limit
- poll updates and extract message text
- robust chat id matching
- Discord webhook sender:
- send message chunks safely
- upload image files
- Discord slash bot:
- register any slash commands dynamically
- optional owner and guild restriction
- Plain text formatter helpers for chat-friendly output
Install
Requires Python 3.9+.
pip install chatops-bridge
For slash-bot support:
pip install "chatops-bridge[discord-bot]"
Install from GitHub:
pip install git+https://github.com/<your-org>/chatops-bridge.git
Quick Start
Telegram
from chatops_bridge.telegram import send_telegram_message
send_telegram_message(
chat_id="123456789",
token="<telegram-bot-token>",
text="Hello from chatops-bridge",
)
Send with images:
send_telegram_message(
chat_id="123456789",
token="<telegram-bot-token>",
text="Report attached",
image_paths=["./charts/btc.png", "./charts/eth.png"],
)
Discord webhook
from chatops_bridge.discord import send_discord_message
send_discord_message(
webhook_url="https://discord.com/api/webhooks/...",
content="Hello from chatops-bridge",
)
Return value is True on success and False on failure.
Discord env-based channel
from chatops_bridge.discord_channels import send_to_discord_env_channel
# export DISCORD_ALERT_WEBHOOK_URL=...
send_to_discord_env_channel("DISCORD_ALERT_WEBHOOK_URL", "Alert triggered")
# strict mode: fail fast if env var is missing
send_to_discord_env_channel("DISCORD_ALERT_WEBHOOK_URL", "Alert triggered", strict_env=True)
Useful when you want channel routing from environment variables instead of hardcoding webhook URLs.
Telegram Update Polling
from chatops_bridge.telegram import fetch_telegram_updates, extract_update_text
updates = fetch_telegram_updates(
token="<telegram-bot-token>",
offset=None,
timeout_seconds=10,
allowed_updates=["message", "edited_message"],
)
for update in updates:
text, message = extract_update_text(update)
if text:
print("message:", text)
Discord Slash Bot
chatops_bridge.discord_bot.start_discord_bot(...) starts a background thread for a Discord bot using your command list.
import discord
from chatops_bridge.discord_bot import DiscordBotConfig, SlashCommandSpec, start_discord_bot
def ping() -> str:
return "pong"
def report() -> dict:
return {"text": "Report done", "image_paths": ["./out/chart.png"]}
start_discord_bot(
token="<discord-bot-token>",
commands=[
SlashCommandSpec(name="ping", description="Health check", handler=ping),
SlashCommandSpec(name="report", description="Generate report", handler=report),
],
config=DiscordBotConfig(
intents=discord.Intents(guilds=True),
allow_dm_commands=False,
leave_unexpected_guild=True,
response_chunk_limit=1900,
max_images_per_response=10,
defer_thinking=True,
),
guild_id=None,
owner_user_id=None,
instance_key="primary",
)
You can also run the bot with commands=[] (or omit commands) when your app only needs Discord client events/background tasks.
instance_key is used to manage bot thread instances by key. Calling start_discord_bot again with the same key returns the existing live thread.
Slash Bot Example
See examples/discord_bot_example.py.
Telegram Poller Bot
chatops_bridge.telegram_poller.start_telegram_poller(...) starts a background polling thread that automatically handles Telegram updates and dispatches them to your command handlers.
from chatops_bridge.telegram_poller import TelegramCommandSpec, TelegramPollerConfig, start_telegram_poller
def handle_status(args: list[str]) -> str:
return "Status: OK"
def handle_trade(args: list[str]) -> str:
amount = float(args[0]) if args else 100.0
return f"Trading {amount} units"
start_telegram_poller(
token="<telegram-bot-token>",
commands=[
TelegramCommandSpec(
name="status",
description="Get bot status",
handler=handle_status,
),
TelegramCommandSpec(
name="trade",
description="Execute trade",
handler=handle_trade,
),
],
config=TelegramPollerConfig(
poll_timeout_seconds=30,
max_retries=3,
retry_delay_seconds=5,
allowed_updates=["message", "edited_message"],
offset_file="/tmp/telegram_offset.txt", # Persist offset on restart
),
logger=print, # Optional logger
)
The poller:
- Runs in background thread(s)
- Automatically saves offset to persist progress across restarts
- Retries on network errors with configurable backoff
- Filters update types (e.g., messages only, skip reactions)
- Parses
/command arg1 arg2style messages - Dispatches to appropriate handler
- Sends response back to the originating chat
Handlers receive a list of arguments and return str or dict (JSON-serialized if dict).
Telegram Poller Example
See examples/telegram_poller_example.py.
Common Environment Variables
DISCORD_BOT_TOKEN: bot token used by the slash-bot example.DISCORD_BOT_GUILD_ID: optional guild restriction.DISCORD_BOT_OWNER_USER_ID: optional owner-only restriction.TELEGRAM_BOT_TOKEN: polling bot token.TELEGRAM_BOT_OFFSET_FILE: optional path to persist polling offset (for restart safety).- Custom webhook URL variables (for env-based routing), for example:
DISCORD_ALERT_WEBHOOK_URLDISCORD_SIGNAL_WEBHOOK_URL
License
MIT
Contributing
We welcome contributions! Please see CONTRIBUTING.md for:
- Development setup
- Making changes and submitting PRs
- Release procedures
For questions, open an issue on GitHub.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chatops_bridge-0.1.1.tar.gz.
File metadata
- Download URL: chatops_bridge-0.1.1.tar.gz
- Upload date:
- Size: 12.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68e66e7cae274708bc872a484715172d590712ff96220344ea6b04df4947f94f
|
|
| MD5 |
61c0b494b28955380f0b97473e7c8102
|
|
| BLAKE2b-256 |
281447e22e783d66da33e1ddead9a3b04aeb226856f42b51bbcfcd49dbac7321
|
Provenance
The following attestation bundles were made for chatops_bridge-0.1.1.tar.gz:
Publisher:
publish.yml on trunghvbk-afataw/chatops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chatops_bridge-0.1.1.tar.gz -
Subject digest:
68e66e7cae274708bc872a484715172d590712ff96220344ea6b04df4947f94f - Sigstore transparency entry: 1317028614
- Sigstore integration time:
-
Permalink:
trunghvbk-afataw/chatops@5d01560f6599dcf72a3613ea949bf79a98fe2b6e -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/trunghvbk-afataw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5d01560f6599dcf72a3613ea949bf79a98fe2b6e -
Trigger Event:
push
-
Statement type:
File details
Details for the file chatops_bridge-0.1.1-py3-none-any.whl.
File metadata
- Download URL: chatops_bridge-0.1.1-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad1da358780bc42a4127bb97701fd109ceab7a836605d02ed1f1ac62719effa3
|
|
| MD5 |
168ab5e07d9d7e810a3d861557be9e9a
|
|
| BLAKE2b-256 |
78f011fa19d3d8dac4353092f23faecb50f95f2a7a54c3bac9085f7ee093a8d9
|
Provenance
The following attestation bundles were made for chatops_bridge-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on trunghvbk-afataw/chatops
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chatops_bridge-0.1.1-py3-none-any.whl -
Subject digest:
ad1da358780bc42a4127bb97701fd109ceab7a836605d02ed1f1ac62719effa3 - Sigstore transparency entry: 1317028618
- Sigstore integration time:
-
Permalink:
trunghvbk-afataw/chatops@5d01560f6599dcf72a3613ea949bf79a98fe2b6e -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/trunghvbk-afataw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5d01560f6599dcf72a3613ea949bf79a98fe2b6e -
Trigger Event:
push
-
Statement type: