Lightweight Telegram Bot API broadcast engine for Python
Project description
tgcast
Lightweight Telegram Bot API broadcast engine for Python.
- Self-contained — no external server, just
pip installand go - Priority queues with weighted round-robin (5:3:1) and starvation prevention
- Rate limiting — global + per-chat token buckets, auto-adapts to Telegram 429
- Campaigns — broadcast to millions in batches, crash-safe with idempotent enqueue
- SQLite — WAL mode, single-file, zero config
- Templates — YAML with locale fallback, or plug in your own renderer
- Media — send photos and documents (file_id, URL, or local path)
Intended use: transactional notifications and opt-in messaging. Please respect Telegram Bot API policies.
Install
pip install tgcast
For YAML templates:
pip install tgcast[templates]
Requires Python 3.11+.
Quickstart
import os
import signal
from tgcast import Telecast, Task
eng = Telecast(bot_token=os.environ["BOT_TOKEN"])
eng.start()
task_id = eng.enqueue(Task(
chat_id=123456789,
text="Hello from tgcast!",
))
print(f"Enqueued: {task_id}")
signal.pause()
eng.shutdown()
Or as a context manager:
with Telecast(bot_token="...") as eng:
eng.enqueue(Task(chat_id=123, text="Hi!"))
See examples/ for more.
API
# Lifecycle
eng = Telecast(bot_token="...", store_dsn="tgcast.db")
eng.start()
eng.shutdown()
# Tasks
task_id = eng.enqueue(Task(...))
status = eng.task_status(task_id)
# Campaigns
cid = eng.create_campaign(CampaignConfig(name="...", template_key="..."))
eng.add_recipients(cid, [Recipient(chat_id=1), ...])
eng.start_campaign(cid)
eng.pause_campaign(cid)
stats = eng.campaign_stats(cid)
# Dead-letter queue
tasks, total = eng.dlq_list(limit=20, offset=0)
eng.dlq_requeue(task_id)
Templates
YAML with locale fallback (exact -> base -> en):
welcome:
en: "Hello, {name}!"
ru: "Привет, {name}!"
eng = Telecast(
bot_token="...",
templates_path="templates.yaml",
)
eng.enqueue(Task(
chat_id=123,
template_key="welcome",
locale="ru",
vars={"name": "Иван"},
))
Or a custom renderer:
class MyRenderer:
def render(self, key: str, locale: str, vars: dict) -> str:
return f"Hi {vars['name']}!"
eng = Telecast(bot_token="...", template_renderer=MyRenderer())
Media
from tgcast import Telecast, Task, TaskKind
eng.enqueue(Task(
chat_id=123,
kind=TaskKind.SEND_PHOTO,
photo="https://cdn.example.com/banner.jpg",
caption="Check this out!",
))
eng.enqueue(Task(
chat_id=123,
kind=TaskKind.SEND_DOCUMENT,
document="/path/to/report.pdf",
caption="Monthly report",
))
photo and document accept file_id, URL, or local file path.
Configuration
All parameters have sensible defaults. Only bot_token is required.
| Parameter | Default | Description |
|---|---|---|
bot_token |
— | Telegram Bot API token |
store_dsn |
tgcast.db |
SQLite database path |
templates_path |
— | YAML templates file |
templates_data |
— | YAML templates as bytes |
template_renderer |
— | Custom renderer (overrides YAML) |
global_rps |
25 |
Global messages/sec |
per_chat_rps |
1 |
Per-chat messages/sec |
max_concurrency |
8 |
Worker pool size |
lease_ttl |
30 |
Task lease duration (seconds) |
max_retries |
5 |
Max retries before DLQ |
base_backoff |
1 |
Initial retry delay (seconds) |
max_backoff |
300 |
Max retry delay (seconds) |
logger |
logging.getLogger("tgcast") |
Custom logger |
Idempotency
Set Task.idempotency_key to prevent duplicate sends:
eng.enqueue(Task(
chat_id=123,
text="Order confirmed",
idempotency_key="order:456:confirmation",
))
Campaign tasks auto-generate keys: campaign:{id}:{chat_id}.
License
MIT
Project details
Release history Release notifications | RSS feed
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 tgcast-0.1.1.tar.gz.
File metadata
- Download URL: tgcast-0.1.1.tar.gz
- Upload date:
- Size: 20.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a01635d6255961b96eaec5e2cd8eac1c6844c38c739c9d9942ac5ae331b2b2b
|
|
| MD5 |
ec9e9809d1273e288e2ee652f8a06697
|
|
| BLAKE2b-256 |
7df92077fbbc6b422d9f1ca76f54a2c1acd9f9e2de8d16a797b4211ce2df4701
|
Provenance
The following attestation bundles were made for tgcast-0.1.1.tar.gz:
Publisher:
publish.yml on Seinarukiro2/telecast-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tgcast-0.1.1.tar.gz -
Subject digest:
5a01635d6255961b96eaec5e2cd8eac1c6844c38c739c9d9942ac5ae331b2b2b - Sigstore transparency entry: 1199625030
- Sigstore integration time:
-
Permalink:
Seinarukiro2/telecast-python@ed59de0af6d3a8ee1aba26a8976ff405f37f4324 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Seinarukiro2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ed59de0af6d3a8ee1aba26a8976ff405f37f4324 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tgcast-0.1.1-py3-none-any.whl.
File metadata
- Download URL: tgcast-0.1.1-py3-none-any.whl
- Upload date:
- Size: 19.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
455cf7443542baa333b8227986d9a3484e2c4ae57a9aed4ba9f888ad7ec601fa
|
|
| MD5 |
dcce6fc870cc779127b8ec2931dbfd01
|
|
| BLAKE2b-256 |
6db10ed060417cc5e366333755fe80f6163a832a95c289bc1ea2626248d8c1c8
|
Provenance
The following attestation bundles were made for tgcast-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on Seinarukiro2/telecast-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tgcast-0.1.1-py3-none-any.whl -
Subject digest:
455cf7443542baa333b8227986d9a3484e2c4ae57a9aed4ba9f888ad7ec601fa - Sigstore transparency entry: 1199625088
- Sigstore integration time:
-
Permalink:
Seinarukiro2/telecast-python@ed59de0af6d3a8ee1aba26a8976ff405f37f4324 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Seinarukiro2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ed59de0af6d3a8ee1aba26a8976ff405f37f4324 -
Trigger Event:
release
-
Statement type: