i built my group an ai ops team that lives in telegram
i stretched openclaw into a multi-persona ops team for the group i run. one agent per department. each with its own name, its own corporate email, its own scoped erpnext user, its own telegram bot. wired into erpnext and zabbix. this is what actually runs.
most "ai for the business" pitches are one chatbot trying to be everything. that does not survive contact with a real operation. what worked for me is the opposite. one agent per department. each with its own name, its own corporate email, its own scoped erpnext user, its own api key, its own telegram bot. they all live inside one telegram supergroup as topic channels, and they do real work for the small group of operating companies i run ops for.
what openclaw actually is
the runtime under all this is openclaw. open source, self-hosted, tagline "the ai that actually does things." it runs locally on a box you own. out of the box it's a personal ai assistant: one persona, persistent memory, background cron-style scheduling, a skills framework for extending the agent with tools, and chat integrations across telegram, whatsapp, discord, slack, signal. the designed use case is one user, one assistant, many tools.
i bent it into something else: one operator, many personas, one shared host, each persona bound to a department. nothing in openclaw stops you from running multiple personas against the same runtime. once you realize that, the whole "ai ops team" idea writes itself.
the setup
- one vps, one unix user, everything file-backed. a single
tar.gzof the config dir is the whole backup. - one telegram supergroup for the company
- one topic per department: sales & finance, alerts, coding & it, procurement & supply chain, executive, reporting, daily reports, operations, general
- one openclaw persona bound to each topic
- each persona has its own:
- name and corporate email on the company domain
- real user account in erpnext with a scoped role profile
- api key / api secret for the erpnext rest api
- telegram bot token, handle, and allowlist of humans who can talk to it
- sqlite memory file (openclaw gives each persona its own memory context)
- cron schedule for any proactive jobs it should run
- persona file holding its rules: who it is, who it's helping, what it will and will not do, formatting standards, data-handling rules
the important part: permissions live where the real work happens, not in a prompt. the sales agent cannot read supplier ledgers because its erpnext user does not have that role. no amount of clever prompting gets around it.
how they're wired to erpnext
- every agent has a real erpnext user, never a shared admin account. the role profile is scoped to exactly what that job needs. the sales agent reads sales invoices, payments, pos, stock. it cannot touch supplier data. the procurement agent is the mirror image. the executive pa has a read-only profile across the whole erp.
- every agent has its own api key / api secret and talks to erpnext over the rest api as that user. no magic proxy. no shared token. same mechanism any external app would use.
- every action an agent takes shows up in the erpnext audit log under its own username. when a sales agent edits a draft at 06:03, the audit trail shows that exact username at that exact minute. that's the operational guarantee you want.
- when an agent hits a permission wall, erpnext returns
403and the agent reports it in its topic. that's a feature, not a bug. permission violations should surface, not be papered over in a prompt. - the coding & it agent is the special one. it has a developer account on the erpnext instance, ssh to the frappe bench, and a dedicated working directory. when i need a new doctype, a workflow, a print format, a client script, a migration, or a server hook, it writes the code, applies it on a branch, runs
bench migrateon a staging site, and posts back the diff and the deploy log. i review before anything touches production. that rule is the first line in its persona file.
how it's wired to zabbix
infrastructure lives in its own persona, bound to the alerts topic. it holds a zabbix api token in an env file (not in the prompt) and runs on an openclaw cron schedule every thirty minutes.
the job is simple on paper: hit problem.get, classify by severity, walk the triggers to their hosts, build a clean markdown report inside a code block so it reads on dark-mode telegram, and post only if something is wrong. silence is the point. nobody wants another bot that says "all good" every half hour.
at end of day, a second cron wakes the same persona for a full health report: every host, cpu/ram/disk, open problems, overall grade. that one posts no matter what, because end-of-day silence is worse than a clean report.
a real day
- 00:00 the daily sales persona runs the group-wide sales report. per branch, per operating company, totals, lowest and highest site called out. posts into the daily reports topic inside a code block so the columns line up on dark-mode telegram.
- 02:05 / 02:10 / 02:15 per-entity daily passes run back-to-back, one persona per operating company. each one calls a python script under
scripts/sales, captures the output, announces to the same topic. staggering by five minutes keeps the erpnext site from taking the full load at once. - every 30 minutes the infra persona runs the zabbix check. silent unless something is wrong.
- 18:00 the infra persona posts the end-of-day health report to alerts: every host, resource highlights, open problems, one-line summary.
- during business hours the ceo dms his personal pa persona. calendar, today's revenue so far, summarize this supplier pdf, draft an email, pull a customer's outstanding balance. the pa has broad read access across the erp but a strict rule: never post into any group topic unless explicitly told to. it stays in his dm unless instructed otherwise.
- when anyone needs code they @-mention the coding & it persona in its topic. it reads the request, plans, writes the patch, applies it to a branch, runs the migration on staging, and reports back the diff and the deploy log. if staging fails, it stops. no "fix-forward on prod."
- procurement & operations have their own personas bound to their own topics. they answer questions about stock levels, supplier invoices, open purchase orders, goods receipts, delivery status. each one has erpnext permissions scoped to its department.
every flow is a real llm turn. not a shell script dressed up. the agent reasons, calls tools, reports back. when a job times out (and some do), the operator sees lastRunStatus: error, consecutiveErrors: n, lastDurationMs: ... on that specific job in a json file. no mystery.
why one persona per department, not one big assistant
the first instinct is always "just make one smart assistant." i tried. it does not survive a real operation.
- permissions are not prompts. "do not share supplier info in the sales group" is a soft rule a prompt can violate. a separate erpnext user for the sales persona that cannot read supplier docs at all is a hard rule. the hard rule survives jailbreaks, prompt injection, and careless copy-paste.
- topics are how humans already think. the finance team does not want to scroll past infra alerts to see sales. the ops team does not want sales noise in alerts. telegram topics already map one-to-one to how the group organizes itself. binding one persona per topic keeps the surface stable.
- failure isolation. if the coding persona gets stuck in a loop and burns tokens, i kill that persona, not the whole system. the sales report still goes out at midnight. the ceo's pa still answers.
- memory separation. openclaw gives each persona its own memory file. the sales persona remembers branch conventions. the coding persona remembers which doctypes we're iterating on. nothing bleeds between them. when a persona misremembers something, i reset that one file without touching any other.
- identity is a constraint. every persona has a real corporate email, a real erpnext user, a real bot handle. they appear in the erpnext user list. their actions show up in the audit log under a real username. that is the operational guarantee.
one big chatbot with nine roles crammed into a single system prompt isn't simpler. it's the illusion of simpler. the first time one role needs different permissions or different routing, you start regex-matching against yourself.
what breaks
honest list, from actually running this:
- llm turns inside cron are not shell scripts. they are variable latency and variable cost. give each job its own timeout, not a global one. my 18:00 health report still times out on slow api days at 180s. the fix is smaller per-call work, not a bigger timeout.
- do not paste credentials into agent prompts. the easy thing is to embed a bearer or an ssh password into the cron payload so the agent "knows what to curl." the second you do that, the credential is in your jobs file, in nightly tarballs, in any disk image, in any backup share. put secrets in env files the agent reads at runtime. rotate anything you pasted by accident.
- back up sqlite memory files cold. tar on a live sqlite is torn roughly one percent of the time. run
.backupto a temp path first, then tar that path. - telegram topic ids are fragile. if a topic gets renamed or moved, the cron delivery target breaks silently. pin topic ids in config. alert yourself when two consecutive deliveries fail.
- the coding agent needs a staging path, always. writes go to a branch, migrate on staging, wait for human review. never straight to production. this rule goes first in the persona file, not in the readme.
- every persona speaks "as someone". if you tell your agents never to claim to be ai, you need to mean it, and you need to decide in advance whether a bot handle looks like a bot or a colleague. flipping this later is a mess.
the part that actually matters
this setup didn't replace the team. it moved the team off repetitive queries and onto decisions. nobody types "can you pull yesterday's sales for branch x" anymore. the number is already in the topic. nobody asks "is the server ok". silence means yes. the ceo does not wait for me to answer what's already in the erp. his pa does.
the right way to think about it: an ai ops team is not a product you buy. it's an org chart you write in files. one persona file per role. one corporate email per role. one erpnext user per role. one telegram bot per role. one cron schedule per role. one memory file per role. one backup command for the whole thing.
once you frame it that way, the work stops being about "adding ai to the business" and starts being about hiring. i hired a team of specialists using openclaw. they show up on time, post in the right topic, respect their erp permissions, and never ask for a raise.
— d.