Webhook Matchers and Handlers¶
telegras uses webhook attachments to decide what to do with each incoming Telegram update.
An attachment combines:
when: match criteria expressionparse(optional): parse/extract structured values from message text- handler binding:
handlerorhandler_chain+handler_args - execution controls: priority, enabled flag, execution mode
Mental model¶
- Update arrives.
- Attachment matcher (
when) is evaluated. - If matched, optional parser runs and emits
match.*values. - Bound handler(s) execute with rendered args.
- Execution result is persisted and visible via introspection endpoints.
Match expression (when)¶
Use composable boolean expressions:
leaf: one conditionall: logical AND over childrenany: logical OR over childrennot: negation over one child
Example:
{
"op": "all",
"children": [
{"op": "leaf", "leaf": {"field": "chat.type", "match": "eq", "value": "group"}},
{"op": "leaf", "leaf": {"field": "message.text", "match": "contains", "value": "urgent"}}
]
}
Handlers¶
Single handler:
{
"handler": "handlers.shell:sh",
"handler_args": ["echo {{ message.title }}"]
}
Grouped handler chain:
{
"handler_chain": [
{"handler": "handlers.python:eval", "handler_args": ["title='{{ message.title }}'"]},
{"handler": "handlers.shell:ls", "handler_args": ["/tmp"]}
],
"execution_mode": "sequential",
"stop_on_error": true
}
Parser output and templates¶
Attachment parsers can enrich context with extracted fields available as {{ match.<name> }}.
Example parser:
{
"parse": {
"regex": {
"title": "^(?P<title>[^\\n]+)",
"tag": "#(?P<tag>[a-z0-9_-]+)"
},
"allow_partial": true
},
"parse_mode": "warn"
}
Then use:
{{ match.title }}{{ match.tag }}
Built-in template values also include message.*, chat.*, and update.*.
Minimal full attachment example¶
{
"name": "ops-alert",
"handler": "handlers.python:eval",
"handler_args": ["result='{{ match.title }}'"],
"enabled": true,
"priority": 20,
"when": {
"op": "all",
"children": [
{"op": "leaf", "leaf": {"field": "chat.type", "match": "eq", "value": "group"}},
{"op": "leaf", "leaf": {"field": "message.text", "match": "regex", "value": "#ops"}}
]
},
"parse": {"regex": {"title": "^(?P<title>[^\\n]+)"}},
"parse_mode": "warn"
}
APIs¶
- Public attachment APIs:
GET /v1/webhook-attachmentsPOST /v1/webhook-attachmentsDELETE /v1/webhook-attachments/{name}POST /v1/webhook-attachments/matchPOST /v1/webhook-attachments/execute- Introspection helper:
GET /internal/introspection/match-criteria