Telegram transport
Use the first-party Telegram transport to talk to a normal Kward session from a
private Telegram chat. The example lives under examples/plugins/ and uses the
Telegram Bot API's long-polling interface.
The transport runs as trusted local Ruby code. Install it only on a machine where the bot can safely access its configured workspace and Kward tools.
Install the plugin
Copy the packaged plugin into the user plugin directory:
mkdir -p ~/.kward/plugins
cp -R examples/plugins/telegram ~/.kward/plugins/
Kward loads the package through ~/.kward/plugins/telegram/plugin.rb.
Installing the plugin does not connect to Telegram. Start it explicitly with
kward transport run com.kward.telegram.
Configuration
Configure one fixed workspace and explicit numeric allowlists:
{
"transports": {
"com.kward.telegram": {
"workspace": "/Users/me/src/project",
"allowed_user_ids": [123456789],
"allowed_chat_ids": [123456789],
"poll_timeout_seconds": 25
}
}
}
Do not put the bot token in the config file. Set it in the environment of the foreground process instead:
export TELEGRAM_BOT_TOKEN='replace-with-the-token-from-botfather'
The plugin also accepts the transport-specific secret name exposed by the
host, but TELEGRAM_BOT_TOKEN is the recommended explicit variable.
Run it
First check that Kward discovers the plugin:
kward transport list
Then run the personal-assistant transport in the foreground:
kward transport run com.kward.telegram
To override the workspace configured for this process:
kward transport run com.kward.telegram /Users/me/src/project
# or:
kward --working-directory /Users/me/src/project transport run com.kward.telegram
The plugin also registers com.kward.telegram.isolated. It uses the generic
isolated_chat execution profile: no tools, no plugin commands, no memory, no
attachments, and no approval interactions. Configure that transport with a
separate empty workspace:
{
"transports": {
"com.kward.telegram.isolated": {
"workspace": "/var/lib/kward-chat/workspace",
"allowed_user_ids": [123456789],
"allowed_chat_ids": [123456789],
"poll_timeout_seconds": 25
}
}
}
For stronger separation, run it with a dedicated home and config directory that contain only this plugin:
HOME=/var/lib/kward-chat \
KWARD_CONFIG_PATH=/var/lib/kward-chat/.kward/config.json \
TELEGRAM_BOT_TOKEN="$TELEGRAM_BOT_TOKEN" \
kward transport run com.kward.telegram.isolated
The process removes any existing Telegram webhook, validates the bot token, and begins long polling. Run only one polling process for a bot token; multiple pollers conflict with each other. Supervise the process externally for restart-on-failure behavior.
Current scope
The adapter supports:
- private text messages,
- one or more explicitly allowlisted numeric users and chats,
- fixed workspace routing,
- normal Kward session persistence,
- idempotent Telegram update claims,
- final responses split at Telegram's message length limit,
- tool approval buttons and single-question choice buttons for the personal transport.
The isolated transport intentionally has no tool or interaction capabilities.
It intentionally does not yet support groups, media uploads, webhooks, streaming message edits, inline mode, or multiple independent workspace policies.
The transport allowlist is enforced before external messages reach a Kward session. Keep the first deployment restricted to one user, one private chat, one workspace, and conservative tool permissions. Never use incoming Telegram text to select a workspace or tool scope.
Account setup boundary
The code is ready for account setup, but no Telegram account, bot token, or
network test is required to run the automated tests. After creating a bot,
set TELEGRAM_BOT_TOKEN, replace the placeholder numeric IDs, and test the
foreground process with a private chat first.
See the official Telegram Bot API for BotFather setup, polling behavior, message limits, and callback queries.