Skip to main content
A bot on Splox is not an integration you switch on. It is a program in your harness — a loop that polls Telegram and hands each message to your agent — and you get it by asking for it. It runs as long as the machine does, and it answers with the same agent, on the same machine, that you talk to in a chat. This page also carries the one failure worth knowing about before you ask for any program at all. It cost a working bot a full day of never answering anybody.

The part you have to do yourself

Make the bot. Message @BotFather on Telegram, send /newbot, answer two questions, and it hands you a token that looks like 123456789:AAH.... This is one of the very few steps in these tutorials your agent cannot do for you: it needs a Telegram account, which needs a phone number, which is a person. A minute of your time, once. Put the token where the machine can read it. Open Connections → Secrets and add it as TELEGRAM_BOT_TOKEN.
The Connections Secrets tab with TELEGRAM_BOT_TOKEN saved

Environment secrets are injected into the machine's shells; the value is never shown again

Secrets are encrypted key/value pairs injected as environment variables into the sandbox, for every chat. Nothing writes a token into a file in git. See Connections.

What you say

Then it is one message:
Nothing in that message is about Python. The three things worth naming are the ones a bot is wrong without: where the token is, who answers, and that one person keeps one conversation.

The one line that matters: who answers

The old program in the harness declared a bot-only agent of its own:
That works, and it is almost always not what you want. A private agent declared inside a bot has its own prompt, its own tool list, and none of the things your actual assistant has grown — the memory, the custom tools, the hooks. You get a second, dimmer version of your agent living behind a Telegram handle. Asked for messages “answered by you”, the agent deleted its own throwaway Support and delegated instead:
program("splox").assistant hands back the very agent declared in programs/splox/main.py — the one a chat in the app reaches, with its tools, its skills and its hooks. The program is the delivery loop; the harness is the brain.chat_id is what makes one Telegram chat one conversation: the run’s .chat_id is stored per person and handed back on their next message, so they continue instead of starting over. The map and the update offset live in a JSON file on the machine, so a restart does not lose anybody’s thread or answer a message twice.
A Splox chat where the agent replaces the bot's private agent with the harness Assistant and publishes version 10

Version 10: the throwaway agent gone, the loop delegating, and two publish rules learned the hard way

Two things the push taught, both worth knowing in advance: a stray __pycache__/*.pyc will get committed if you are not looking, and the publish gate refuses a root .gitignore — the tree takes programs, tools, evals and root documents, so an ignore file belongs inside the program directory, where a program may be any shape it likes.

The failure worth reading

An earlier version of this bot was published, started, and printed polling as @… to its log. Everything looked right. It had never answered a single message, and the state file that would have proved otherwise did not exist. The platform’s error was this:
The cause is a single line in the wrong place. The program read the token at the top of the file, next to the imports:
Your main.py is not only run as a process. The platform imports it whenever it needs to ask who an agent is — and that import happens in a context that does not carry your machine’s secrets. So the loop ran fine, took a message, asked the platform to run its agent, and the platform could not import the file to find out who that agent was. The bot polled forever and answered nobody. The fix is to read the secret where it is used, and the comment the agent left behind says why better than a rule would:
Never read a secret at import time in a program’s main.py. Read it inside the function that uses it. This applies to every program, not only bots — the same import happens for a nightly job, a webhook, a mailbox watcher. The symptom is nasty because the loop itself keeps running and logging happily.

Checking on it

Ask your agent. It is on the machine the bot runs on, so “is the bot polling, and has anybody messaged it?” is answered by looking: the process, /tmp/telegram.log, and the state file with one entry per person.
What is not shown on this page is a screenshot of Telegram itself, because the account behind this bot belongs to a person and these tutorials were driven by asking rather than by tapping a phone. The publish, the delegation and the polling are all shown above; the last hop is the Bot API’s, and it is the part you will see first.

Next

Patterns

A router, a nightly job and a fan-out over many items, in the same shape as this one.

Programs

What the platform reads out of a program, what it never opens, and how a program calls its agents.