.env as FLOW_MESSAGING_KEY (with FLOW_CLAIM_TOKEN), offers to set up your coding agent (skill, AGENTS.md, MCP server; it asks you first), and prints the sandbox link and join code. It asks before setting up your coding agent; --yes skips the question. The steps below do the same by hand and then build the agent.
1
Get a test key
Already have one in The answer holds Test keys reach only the shared sandbox, so nothing reaches anyone who has not joined it. This key allows 1 contact and 50 messages on the Telegram sandbox and expires after 7 days; sign in with GitHub (The answer includes
FLOW_MESSAGING_KEY? Skip this step. Otherwise get one in one call, with no account:key (fk_test_...) and claim_token (fct_...), both shown once, plus your app (with its sandbox_join_code) and the sandbox senders. Save them:npx @flow-engineer/messaging login) to keep the app and send 100 messages to each of 3 contacts. See Keys and sign-in.Check the key, and read your app’s sandbox join code and what is left of its allowance:app.sandbox_join_code, for example wild-otter-04508705, and allowance.2
Join the sandbox from your phone
List the sandbox senders your key can use (today, the Telegram sandbox bot):Each shared sender has an Your app now has a conversation with you, and you receive a
address.link and a join_code. Open the link on your phone:- Telegram: the link is
https://t.me/<bot>?start=<code>. Open it and tap Start. That’s it, you’ve joined. - If the link can’t be used (for example you found the bot by searching for it): send the sender’s
join_codeto it, for example:
conversation.started event. The join code is how a shared sandbox sender knows which app a person belongs to, so no stranger is ever messaged. See Senders.3
Receive a message and reply
Run one of these, then send any message to the sandbox sender from your phone. Each program waits for The send answers
message.received events and answers into the same conversation.202 with the queued message. Its progress may arrive as message.sent, message.delivered and message.read events, depending on what the channel reports. To know how a send ended, wait for message.sent or message.failed: every channel reports one of them.4
Answer with your model
Replace the echo with your agent. In TypeScript, pass the model’s stream straight to Without the SDK, split the answer at paragraph breaks and send each part as its own message, as Streaming replies describes.
reply(): it keeps the typing indicator on and sends the answer as chat bubbles while the model writes.TypeScript
What you built
- A test-mode agent that answers anyone who joined your app on the Telegram sandbox. The code does not change per channel: it answers the same way on your own Telegram bot or an iMessage line.
- It reads events from the live stream (TypeScript) or the event log (HTTP). In production most agents use webhooks instead, and can answer straight in the webhook response.
Next steps
Events and webhooks
Signed deliveries, retries, ordering, and replying in the response.
Local development
Receive events on your laptop with no public URL through the live stream.
Content types
Media, voice notes, buttons, reactions and what each channel shows.
Going live
A live key, your own Telegram bot, and iMessage lines.