I Turned a Telegram Group Into a Software Project
One private Telegram group = one project: an idea interview in chat, gated task cards for an agent fleet, command-only deploys, and APKs delivered as files. Built and shipped in a single working session.

How I turned a private Telegram group into a full project workspace
I run a fleet of coding agents that build and ship my projects. But every project still started the same way: me, at a laptop, opening a terminal. Last week I removed that step. I built a Telegram bot that turns any private group chat into a full project workspace. The whole thing happened in one working session, and I can be precise about what that session contained: a structured design interview, five incremental commits, a live smoke test in a real group, and an adversarial review, all driven from a single agent conversation.
The idea: a group chat as the project
The concept is simple. One private Telegram group equals one project. You add the bot, and from that moment the group is the project's front door:

Before any code, the design went through the same process I use for every sizable feature: a grill interview. My coding agent asks me questions one at a time, ordered by decision weight (architecture before scope, scope before UX), and every question arrives with a recommended answer and a one-line reason, so my job is mostly to confirm or veto. The decisions get committed to the repo as a versioned spec file, which the implementation is later reviewed against.
The key architectural decision from that interview was what the bot is not. It is not an agent. It never writes code, never scaffolds a repo by hand, never deploys anything itself. It is a thin chat front-end over the machinery I already have: a task board, a fleet of executor agents on a VM, and GitHub Actions pipelines. The bot translates conversation into that machinery and translates the machinery's output back into chat. All the new code is routing and rendering; the heavy lifting was already built.
Design decisions that mattered
A few decisions from the interview shaped everything downstream.

Groups, not channels. In Telegram, channel posts are anonymous. There is no sender ID, which kills any allowlist-based authorization, and there are no reply threads to anchor a conversation about a specific task. Private groups give you both: every message carries the sender's user ID for the allowlist, and a reply to a task card can be treated as an edit of that exact draft. That one fact decided the entire interaction model.
Repos have roles. A mobile project is never one repo. It's a game or app repo plus a backend repo. So a project owns a set of repos, each bound with a role: backend, app, game, or web. Commands and task routing address roles, not repo names. "The button is misaligned" routes to the app repo; "login fails on the server" routes to the backend. The confirmation card always shows the target repo, so a misroute gets caught by a human tap, not discovered after an agent worked in the wrong codebase.
Nothing reaches GitHub without a tap. Every action that creates something (a task, a spec, a new repo) goes through a confirmation card with explicit buttons. The routing is two-tier by cost: gpt-4o-mini classifies each message as a question, a task, a big vague idea, or plain chat, and Claude Sonnet writes the actual issue text in English; voice notes go through Whisper first. A false positive from the classifier costs nothing, since the worst case is a card I dismiss. A false negative is equally cheap: the message just gets treated as chat, nothing fires, and I repeat it as an explicit command.
Deploys happen only on command. This one I made a hard rule in the spec: the bot never deploys on its own initiative. Not after a merged pull request, not after a green build, not on a schedule, and never inferred from a vague message. If the router smells deploy intent in free text, it answers "deploys are command-only" and points at /deploy. The command itself is just a trigger for the repo's existing GitHub Actions workflow, the same pipeline a push to main runs, so the deploy logic stays versioned, auditable, and works with or without the bot.
The database enforces the invariants, not the code. "At most one active interview per group" is a partial unique index. "Every proactive event is reported exactly once" is a primary key on the seen-events table; the tick posts a message only when the insert succeeds. I've been burned before by invariants that lived in application code and quietly stopped being true. A constraint can't be skipped.
The physical limits of a chat as a UI
Telegram's Bot API sets hard boundaries that shaped the delivery paths. A bot can send a file up to 50 MB and download one up to 20 MB. So the APK path works like this: the build runs in GitHub Actions (GameCI for Unity projects), the bot pulls the artifact, unzips it, and if the APK is 50 MB or less it lands in the chat as a tappable file. Bigger than that, it goes to private object storage and the chat gets a signed link that lives for seven days. Incoming files over 20 MB the bot honestly refuses and asks for a link instead.
Photos and voice messages are first-class input: a screenshot with the caption "fix this" becomes task context. The image is mirrored to storage and its link is embedded in the issue by deterministic code, not by hoping the drafting model includes it, so the executor agent can always open it. Voice is transcribed and routed exactly like typed text.
The bot registered itself
My favorite moment of the build: the agent created its own Telegram bot. Bot registration goes through BotFather, Telegram's official bot-creation chat, which has no API. So the agent drove it through a Telethon userbot session authorized on my own account (the same session I already use to read channels): sent the newbot command, answered the name prompts, parsed the token out of BotFather's reply, and then disabled privacy mode, because without that, bots in groups only see commands and the whole free-text router would be blind.

Then it smoke-tested itself the same way: created a real group with the userbot, invited the bot, sent commands, and read the replies. That live test immediately caught a real bug. The bot politely responded to the "bot was added to the group" service message, which carries no text, by asking what the idea was about. Service messages are now ignored.
A live bot with a public webhook and a GitHub write token is exactly the class of change I don't trust myself to review alone. So before calling it done, I turned another agent loose on it.
Then I let another agent try to tear it apart
My standing rule for changes that touch authentication surfaces is a mandatory adversarial review. The setup is specific: a separate agent in a fresh context, with read access and a test runner but no ability to edit files, receives a list of security claims I make about the code and is prompted to refute them. This time the list had eight claims: the webhook fails closed without its secret header, non-allowlisted users can trigger nothing, a double-tap can't create two issues, the GitHub token can't leak into chat or logs, the tick reports each event exactly once, workflows are dispatched only by explicit commands, crafted input can't inject into SQL, storage paths, or HTML, and errors still return 200 to Telegram so there are no retry storms. The reviewer wrote its own reproductions to test each one.
It came back with ten findings. Two were real race conditions I had missed completely:
The other eight were the characteristic shape of LLM-integration bugs, and each one teaches the same lesson from a different angle. An enum value invented by the drafting model (a task "type" outside the allowed list) crashed the flow after the GitHub issue was already created, leaving half-state that the double-tap guard then refused to retry: validate model output before the first irreversible side effect, not after. Attachment links reached the issue body only if the drafting model chose to include them: anything that must happen should be code, and the model only decorates. The webhook secret was compared with a plain string comparison instead of the constant-time helper the codebase already had. All ten were fixed the same day, and the hermetic test suite grew to 29 tests, including ones proving the webhook fails closed without its secret header.
The lesson I keep re-learning: tests written by the author share the author's blind spots. Both races lived in code I had written hours earlier, next to correct dedup logic I had written for the neighboring path. I didn't need more of my own tests. I needed an adversary.
One more guard earned its keep the same evening: my CI has a migration guard that fails the build if a database migration lacks a manifest entry describing how to detect it in the live schema. It failed exactly as designed on the two new migrations until they were registered.
What this changes
The cost side is small enough to ignore. On current GitHub Actions pricing, an Android build on a Linux runner costs $0.006 per minute, roughly ten to fifteen cents per build. The expensive part of mobile CI is iOS: macOS runners at $0.062 per minute put an iOS build at a dollar or two. When I estimated a typical month for one mobile project (thirty Android and thirty iOS builds), it came out around 35 to 50 dollars, almost all of it macOS minutes. The bot's own runtime is a webhook on infrastructure I already pay for, plus fractions of a cent per message for classification.

But the real change is where projects can start. An idea used to mean "when I'm back at the laptop." Now it means opening a group chat, typing three sentences, answering interview questions while walking, and tapping confirm on a card. The fleet takes it from there, and the deploy link or the APK comes back to the same chat where the idea was born.
One process decision closed the session. The bot makes starting a project one tap, and cheap starts are how a fleet quietly fills with half-projects nobody asked for. So the rule is written down where the agents read it: proposing is the machine's job, initiating is mine.
FAQ
What happens when the group has no repo at all?
That's the bootstrap path: the interview runs first, and on confirmation the bot creates the private repos (one per role for a mobile project), files bootstrap tasks for the agent fleet to scaffold and wire CI, and binds the group to the new repos automatically.
Why not deploy automatically after a merged pull request?
Repo-level CI still does that where it's configured; the rule constrains the bot. A chat router acting on inferred intent is exactly the component you don't want holding deploy authority, so the bot's deploys need the explicit /deploy command and everything else is refused by design.
Which models does the bot actually use?
gpt-4o-mini for message classification (cheap and fast, and a wrong guess only costs a dismissed card), Claude Sonnet for interview questions and English issue drafts, and Whisper for voice transcription.
What limits does Telegram impose on file delivery?
A bot may upload files up to 50 MB and download incoming files up to 20 MB. Larger APKs are delivered as signed links that expire after seven days; larger incoming files have to arrive as links.
What did the adversarial review actually catch?
Ten findings against eight security claims, including two race conditions (a deploy reported twice when five-minute ticks overlap a slow APK delivery, and a double-tap on interview finalize creating duplicate specs). All were fixed the same day the review ran.
Related reading
Maksym Tytarenko
AI & SaaS Development Expert at Tytarenko AI Agency
Related Articles
AI Automation Architectures for Bootstrapped SaaS: Open-Source Patterns to Match Enterprise Scale
Bootstrapped SaaS teams can deploy open-source AI architectures—data, orchestration, agent layers—to automate marketing, support, and ops at $100/month, matching VC-scale efficiency. Detailed patterns include RAG workflows, CrewAI orchestration, and safety gates with tradeoffs in latency and cost. CTOs gain concrete implementations to reduce solo ops overhead.
6 min readAI & MLGraph engineering is easy. Not blowing your budget on one workflow is the hard part
Everyone is teaching how to fan a Claude Code workflow out to 1,000 agents. Nobody teaches the chapter where the bill arrives. How a minor audit became 287 agents and 15.3M tokens, and the pre-execution guard + model routing ladder that keep my fleet honest.
10 min readAI & MLThe Surface Writes the Prompt: Codex vs Claude Code vs Claude.ai, Side by Side
A side-by-side read of the Codex Desktop, Claude Code, and claude.ai system prompts: the coding-agent prompts resemble each other more than either resembles the consumer chat — evidence that the product surface, not the vendor, shapes prompt architecture.
9 min readReady to Build Your AI-Powered Solution?
Let's discuss how we can help you leverage AI to transform your business.
Get in Touch