Public project
Zoho Workflow Agent
Reassigning fifty accounts in Zoho used to mean fifty trips through the same screens, about a minute each, most of an hour gone. It now takes about two minutes. I built this for my own workload, and a small team at the company I work for now uses it daily. It runs against a live CRM, so every field it touches is audited and any change can be undone by asking.
GitHub repository| Task | By hand | With the agent |
|---|---|---|
| Reassign owners across 50 accounts | 40 to 60 minutes | About 2 minutes |
| Schedule 100 personalized emails | 2 to 3 hours | Drafting time only |
| Update a field on every contact under an account | One visit per record | One instruction |
Times are hands-on attention rather than wall clock. The queue still takes as long as it takes; the difference is that nobody has to sit in front of it while it runs.
Context
CRM work is full of repetitive multi-record edits: reassigning owners across a list, creating follow-up tasks, updating the same field on fifty accounts. It is the kind of work that is too varied to script and too dull to do well by hand.
Doing it manually means opening each record in turn. Doing it with ordinary browser automation means fighting the per-user and per-org differences in Zoho URLs, which is why the writes go through the API instead.
The important part is not only calling an LLM. It is the control layer around the LLM.
I wanted the agent to behave like a careful operator: understand the task, show the intended action, wait for review where needed, then verify the result.
I built the system on my own, including the Chrome control layer, working from public documentation on driving the browser rather than an existing framework.
How it works
One entry point is enough. Give it a contact, an account, or a deal name and it backtracks across the mirrored tables to resolve the related records.
Every action is written to an audit trail, so a change can be traced later and reversed on request.
Writes go through the Zoho API rather than by clicking through the CRM, so owners, fields, and follow-up tasks can be set on Leads, Contacts, Accounts, and Deals.
Requests are written in plain language. There is no command syntax to learn, and no need to name which skill the agent should use.
Tool calls are tiered: local lookups against the mirror stay cheap, and the calls that touch the live CRM are separated out.
After a write the agent reads the record back and syncs the mirror, so a run does not end on a response that merely looked successful.
A workflow taught once is stored as a skill guide with trigger keywords and recalled automatically when a later request matches.
What it replaces
Reassigning fifty accounts to a new owner is about a minute of clicking per account. Call it forty minutes to an hour of work that requires attention but no judgment. The agent does the same job in roughly two minutes, and the person who asked for it is doing something else while it runs.
The email queue is the bigger one. A hundred personalized emails a day is normal here, and personalized means each one has its own draft rather than a template with a name merged into it. Done by hand that is a two to three hour block. The agent works through the queue instead, and the cost drops to writing the drafts and glancing at the run now and then.
Neither number comes from the agent being fast. It comes from the work no longer needing a person parked in front of it. That is the part worth automating: high volume, low judgment, repeated daily.
Teaching a workflow
Scheduling an email is the clearest case. It is not one action: open the record, click compose, wait for the popup to render, fill the fields, set a send time, confirm. Every step depends on the one before it, and none of it is obvious to a model seeing the screen for the first time.
So I teach it once. Using the Teach a workflow button I walk the agent through the sequence in detail, go here, click this, wait for that, and it records the method as a named skill guide with its own trigger keywords.
After that I never mention the skill again. I say “schedule this email to her for tomorrow” in the same loose way I would prompt any model, the request matches the stored triggers, and the agent pulls its own recorded method back out of the database and follows it. Guides are versioned and there is no limit on how many are kept, so the agent gets more capable by being taught rather than by being rewritten.
One name is enough
Requests start from whatever the person happens to know: a contact, a company, a deal name. The agent takes that single entry point and backtracks through the mirrored tables to assemble everything around it, the account the contact sits under, the deals attached to that account, and every other contact underneath it.
That resolved set is what makes bulk work possible. Once the agent has established the company from one name, “reassign all the other contacts under it” is a single instruction rather than five trips through the CRM. Hand it a list of fifty people and the same resolution runs for each one.
Because the writes go through the API rather than the interface, the same instruction can set an owner, change a field, or create a follow-up task across Leads, Contacts, Accounts, and Deals without a browser session ever being opened.
Nothing it does is permanent
This runs against a CRM that a team depends on, so the design assumes mistakes. Every field the agent touches is written to an audit trail before and after, which means any change can be traced to the request that caused it and undone.
Undoing it happens in the same place as everything else. When a run finishes you can say that it was wrong and ask for the change to be reversed, or corrected to something else, in the same chat and the same plain language as the original instruction. There is no separate admin screen to learn.
Email carries a stricter rule. The agent can schedule a message and nothing more, with a minimum gap before it goes out, and it has no path to send one immediately. A wrongly assigned owner is a field you can set back. A sent email is not, so the system is built to never be able to make that particular mistake.
Challenges
Keeping a six-step tool trace legible while the agent moves between skill lookup, record resolution, API writes, and verification.
Tuning skill auto-trigger so a guide fires on the workflow it was taught for and not on a task that merely resembles it.
Resolving one loosely-specified name into the right contact, account, and deal without silently acting on the wrong record.
Building the Chrome control layer from public documentation rather than an existing framework, and keeping it stable enough for people other than me to rely on.
Making the README public without exposing internal implementation details or sensitive files.