Notifications and Bots
Akritas sends notifications after a successful alert investigation. Telegram and Mattermost can also use the normal Chat investigation loop as bidirectional bot interfaces. Prepare Change and Apply are not available through bots.
Three receiver types are supported:
webhookreceives the complete versioned JSON envelope;telegramsends compact text through the Telegram Bot APIsendMessage;mattermostcreates a post through the Mattermost REST API using a bot account.
Quick start
Copy the example and connect it through a service option:
cp configs/akritas/notifications.example.json \
configs/akritas/notifications.local.json
export AKRITAS_NOTIFICATIONS_CONFIG=configs/akritas/notifications.local.json
The same path can be supplied through notifications_config in the main JSON
configuration or with -notifications-config. The normal CLI, environment,
service configuration, and default precedence applies. An empty path disables
notifications and bot ingress.
The notification configuration is a separate strict version 1 JSON file. It
accepts 1 to 16 receivers and an optional timeout up to 1m, with a default of
10s. Unknown fields, duplicate names, and missing environment variables stop
startup. The example also contains bounded queue and history settings for bot
chat.
Generic webhook
{
"version": 1,
"receivers": [{
"name": "automation",
"type": "webhook",
"url_env": "AKRITAS_INCIDENT_WEBHOOK_URL",
"bearer_token_env": "AKRITAS_INCIDENT_WEBHOOK_TOKEN",
"hmac_secret_env": "AKRITAS_INCIDENT_WEBHOOK_HMAC_SECRET"
}]
}
Either url or url_env is required. Bearer and HMAC authentication are
optional and can be enabled together. X-Akritas-Signature has the form
sha256=<hex> and covers the exact JSON body. Akritas also sends
X-Akritas-Event, X-Akritas-Delivery, and, when available,
X-Akritas-Run-ID.
The envelope contains event: incident.investigated, a unique delivery ID, a
UTC timestamp, and an incident object with the model, canonical alert,
answer, selected skills, tool activity, capability gaps, validated
investigation, and Run budget. The maximum payload is 512 KiB. A receiver must
treat model text as untrusted data, not instructions.
Telegram
Create a bot, keep its token in a secret-backed environment variable, and add the bot to the group. In a direct chat, the user must message the bot first because a bot cannot initiate the conversation.
{
"name": "telegram-ops",
"type": "telegram",
"bot_token_env": "AKRITAS_TELEGRAM_BOT_TOKEN",
"chat_id_env": "AKRITAS_TELEGRAM_CHAT_ID",
"message_thread_id_env": "AKRITAS_TELEGRAM_THREAD_ID",
"inbound_mode": "polling"
}
chat_id can be stored directly in the configuration or resolved through
chat_id_env. Optional message_thread_id or message_thread_id_env selects
a topic. base_url defaults to https://api.telegram.org; change it only for
a self-hosted Bot API server.
In polling mode, Akritas calls getUpdates with a 30-second long-poll
timeout. It needs no public endpoint or webhook secret. Without an explicit
allowlist, only messages from the configured chat_id are accepted. For more
complex access, configure allowed_conversation_ids,
allowed_conversation_ids_env, allowed_user_ids, or
allowed_user_ids_env.
Telegram polling and webhook modes are mutually exclusive. Akritas does not
automatically delete a previously registered provider webhook; call
deleteWebhook when necessary. The poller uses bounded backoff during
temporary network failures and advances its offset only after a message enters
the local queue.
For webhook mode, replace inbound_mode and add a secret and allowlist:
{
"inbound_mode": "webhook",
"inbound_secret_env": "AKRITAS_TELEGRAM_WEBHOOK_SECRET",
"allowed_conversation_ids_env": "AKRITAS_TELEGRAM_ALLOWED_CHAT_IDS"
}
Register the provider webhook separately:
curl --fail-with-body \
-X POST "https://api.telegram.org/bot${AKRITAS_TELEGRAM_BOT_TOKEN}/setWebhook" \
--data-urlencode "url=https://akritas.example/api/v1/bots/telegram/telegram-ops/webhook" \
--data-urlencode "secret_token=${AKRITAS_TELEGRAM_WEBHOOK_SECRET}" \
--data-urlencode 'allowed_updates=["message"]'
Akritas verifies the official
X-Telegram-Bot-Api-Secret-Token,
chat and user allowlists, and is_bot. History is isolated by chat and topic.
Mattermost
Create a Mattermost bot account, add it to the required team and channel, and grant permission to create posts. Akritas requires the bot access token:
{
"name": "mattermost-ops",
"type": "mattermost",
"base_url_env": "AKRITAS_MATTERMOST_URL",
"bot_token_env": "AKRITAS_MATTERMOST_BOT_TOKEN",
"channel_id_env": "AKRITAS_MATTERMOST_CHANNEL_ID",
"inbound_secret_env": "AKRITAS_MATTERMOST_OUTGOING_WEBHOOK_TOKEN",
"allowed_conversation_ids_env": "AKRITAS_MATTERMOST_ALLOWED_CHANNEL_IDS",
"allowed_user_ids_env": "AKRITAS_MATTERMOST_ALLOWED_USER_IDS"
}
Create an outgoing webhook or slash command with this callback:
https://akritas.example/api/v1/bots/mattermost/mattermost-ops/webhook
The integration token must match inbound_secret_env. An outgoing webhook
works in public channels; use a slash command for a private channel or direct
message. The bot account sends replies through the REST API. An explicit user
allowlist is required and must not contain the bot's own ID, which would permit
a feedback loop.
Chat lifecycle
Bot ingress does not use the common AKRITAS_API_KEY. Telegram polling uses
the bot token over TLS and applies allowlists; webhook adapters verify a
separate provider secret and the same allowlists. After verification, Akritas
places the update in a bounded memory queue. One worker invokes the normal RAG,
skills, planning, and read-only tool loop and sends the response through the
provider.
Conversation history lives only in process memory. Defaults are 20 messages
and 64 KiB per session, a 24-hour TTL, at most 256 sessions, and a queue of 64
updates. Configure these limits with bot_history_messages,
bot_history_bytes, bot_session_ttl, bot_max_sessions, and
bot_queue_size. A restart clears history and the in-memory duplicate cache.
Commands are /help, /new, /reset, /status, and /ask <question>.
Ordinary text is treated as a question. Long answers are split into multiple
messages. Successful Runs use source telegram_bot or mattermost_bot, and
delivery creates the bot_reply audit event. Prompts and answers are not
stored in audit.
Failure semantics
Receivers run in parallel and best effort. One failure does not block other
receivers. Akritas makes one attempt and has no persistent queue or automatic
retry. Each receiver status is recorded in the notification_delivery audit
event.
A delivery failure does not change an already successful investigation into a failed job, so a provider retry does not rerun the model merely because Telegram or Mattermost was unavailable. For guaranteed delivery, point the generic webhook at an external durable queue or outbox.
Chat adapters do not send raw tool results. They use a fixed compact message,
neutralize @, collapse line breaks inside fields, and escape Mattermost
Markdown. Telegram messages are limited to 4,000 Unicode characters and
Mattermost messages to 16,000; truncated messages contain an explicit marker.