Telegram + FastAPI ingestion core with pluggable publication backends
Project description
telegras
Standalone Telegram ingestion core extracted from tg-wp-bridge.
Parsed Telegram API
The generated Telegram Bot API models live in tg_api_parsed. They are copied from the reviewed telegram-api-extract artifacts and expose only the types used by telegras:
tg_api_parsed.Updatetg_api_parsed.WebhookInfotg_api_parsed.SetWebhookRequesttg_api_parsed.SendMessageRequesttg_api_parsed.GetMeResponse
CI & Releases
- CI:
ci.ymlrunsuv run pytest -qanduv run --extra docs mkdocs build --stricton pushes/PRs againstmain. - Releases:
publish.ymltriggers onpushtagsv*, builds the package, checks artifacts, and publishes to PyPI. Configure a PyPI trusted publisher (OIDC) sosecrets.PYPI_TOKENcan stay empty while GitHub forwards identity securely. If you prefer the classic API token, create a repository secret namedPYPI_TOKEN.
Local development
- Install:
uv pip install -e .[dev] - Run API:
uv run uvicorn telegras.app:app --reload - Run tests:
uv run pytest
Bot mode
Set BOT_MODE to control update transport:
webhook(default)polling
Examples:
BOT_MODE=webhook uv run uvicorn telegras.app:app --reloadBOT_MODE=polling uv run uvicorn telegras.app:app --reload
API submodule
telegras now includes a curated Telegram API runtime subset in telegras.api:
telegras.api.client.TelegramBotAPItelegras.api.getting_updates(Update,WebhookInfo,SetWebhookRequest)telegras.api.methods(SendMessageRequest,GetMeResponse)
This subset is extracted from reviewed generated specs in docs/telegram_api/ and used by telegras.telegram_api.
Webhook Attachments
Webhook attachments are composable match rules bound to handler identifiers.
Attachment schema
{
"name": "blog-channel",
"handler": "handlers.python:eval",
"handler_args": ["result = '{{ message.title }}'"],
"enabled": true,
"priority": 10,
"stop_on_match": false,
"when": {
"op": "all",
"children": [
{
"op": "leaf",
"leaf": {
"field": "chat.type",
"match": "eq",
"value": "channel"
}
},
{
"op": "leaf",
"leaf": {
"field": "message.text",
"match": "regex",
"value": "#blog\\b"
}
}
]
}
}
API endpoints
GET /v1/webhook-attachmentsPOST /v1/webhook-attachmentsDELETE /v1/webhook-attachments/{name}POST /v1/webhook-attachments/matchPOST /v1/webhook-attachments/execute
Protected introspection API
Set INTROSPECTION_TOKEN and call with Authorization: Bearer <token>.
GET /internal/introspection/configGET /internal/introspection/attachmentsPOST /internal/introspection/attachmentsPUT /internal/introspection/attachments/{name}DELETE /internal/introspection/attachments/{name}GET /internal/introspection/webhook-executionsGET /internal/introspection/handlersGET /internal/introspection/match-criteria
Exact examples
Register a shell listing handler:
{
"name": "list-temp",
"handler": "handlers.shell:ls",
"handler_args": ["/home", "/tmp"],
"when": {
"op": "leaf",
"leaf": {
"field": "chat.type",
"match": "eq",
"value": "group"
}
}
}
Register a Python eval handler with parse-result templates:
{
"name": "mail-on-title",
"handler": "handlers.python:eval",
"handler_args": [
"import mails",
"mails.send_mail('{{ message.title }}')",
"log.info(f\"full message: {{ message.full }}\")"
],
"when": {
"op": "all",
"children": [
{
"op": "leaf",
"leaf": {
"field": "chat.type",
"match": "eq",
"value": "group"
}
},
{
"op": "leaf",
"leaf": {
"field": "message.text",
"match": "contains",
"value": "urgent"
}
}
]
}
}
Register a grouped handler chain with parser extraction:
{
"name": "grouped-mail",
"handler_chain": [
{
"handler": "handlers.python:eval",
"handler_args": ["title = '{{ match.title }}'"]
},
{
"handler": "handlers.python:eval",
"handler_args": ["log.info('full=' + '{{ message.full }}')"]
}
],
"execution_mode": "sequential",
"stop_on_error": true,
"parse": {
"regex": {
"title": "^(?P<title>[^\\n]+)"
},
"parser_ref": null,
"allow_partial": true
},
"parse_mode": "warn",
"when": {
"op": "leaf",
"leaf": {
"field": "chat.type",
"match": "eq",
"value": "group"
}
}
}
Execute matching attachments for an incoming update:
{
"update": {
"update_id": 10001,
"message": {
"message_id": 33,
"date": 1700000000,
"chat": {
"id": 444,
"type": "group",
"title": "Ops"
},
"text": "Status report\nEverything looks green."
}
}
}
Built-in handlers
handlers.shell:ls- Args: path strings
- Result: map of path to directory entries (or error)
handlers.shell:sh- Args: shell command fragments, joined with
&& - Result:
returncode,stdout,stderr,command
- Args: shell command fragments, joined with
handlers.python:eval- Args: Python snippets executed in order
- Available variables:
message,chat,update,log - Result: serializable
localssnapshot
For the complete user guide to matcher expressions and handler execution, see:
docs/webhook-attachments.md
Template fields for handler_args
{{ ... }} placeholders are supported:
{{ message.title }}first line of text/caption{{ message.full }}full text/caption{{ message.text }}full text/caption{{ message.has_media }}boolean{{ message.media_type }}detected media kind{{ chat.id }}chat id{{ chat.type }}chat type{{ chat.title }}chat title{{ update.update_id }}Telegram update id{{ update.kind }}detected update kind{{ match.<key> }}parser output values
Telegram API extraction tooling
Extraction and generation scripts that parse Telegram HTML API docs were moved to:
docs/telegram_api_extraction/
Purpose and script-level documentation:
docs/telegram_api_extraction/README.md
Backward-compatible wrappers remain in docs/*.py.
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 telegras-0.3.0.tar.gz.
File metadata
- Download URL: telegras-0.3.0.tar.gz
- Upload date:
- Size: 625.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 |
8426a9029956f7dff165ab423ae7a8080f5227bc3b488bf992f397fab54c4c70
|
|
| MD5 |
2a011f2d46195c585dc0ed0517ffbccb
|
|
| BLAKE2b-256 |
18c87c77d52c78e23d39988c2c250fc25193877522261ed72b90f5b34348665f
|
Provenance
The following attestation bundles were made for telegras-0.3.0.tar.gz:
Publisher:
publish.yml on fkr-0/telegras
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
telegras-0.3.0.tar.gz -
Subject digest:
8426a9029956f7dff165ab423ae7a8080f5227bc3b488bf992f397fab54c4c70 - Sigstore transparency entry: 1058398095
- Sigstore integration time:
-
Permalink:
fkr-0/telegras@52d885401977e8c304b7407db3ec6ea1c648b9ca -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/fkr-0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@52d885401977e8c304b7407db3ec6ea1c648b9ca -
Trigger Event:
push
-
Statement type:
File details
Details for the file telegras-0.3.0-py3-none-any.whl.
File metadata
- Download URL: telegras-0.3.0-py3-none-any.whl
- Upload date:
- Size: 126.3 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 |
a1387ca6ec61b63a6e5b33f693847ff4b91a90529a33aed0e2b3744d0a740d7d
|
|
| MD5 |
b0d6d5de29508c914b854ca2d7c308d8
|
|
| BLAKE2b-256 |
b98bc96458252f4cb1bd5cd4720e14981ff142d0ccbd593ce954ae9e661266ea
|
Provenance
The following attestation bundles were made for telegras-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on fkr-0/telegras
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
telegras-0.3.0-py3-none-any.whl -
Subject digest:
a1387ca6ec61b63a6e5b33f693847ff4b91a90529a33aed0e2b3744d0a740d7d - Sigstore transparency entry: 1058398109
- Sigstore integration time:
-
Permalink:
fkr-0/telegras@52d885401977e8c304b7407db3ec6ea1c648b9ca -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/fkr-0
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@52d885401977e8c304b7407db3ec6ea1c648b9ca -
Trigger Event:
push
-
Statement type: