work / FIG. 02

← all systems

AI Call Processor & Analytics Agent

demo build

Cake manufacturer, ~200 support calls a day. Calls are transcribed with PII redaction, classified by an LLM into a structured data table — and a chat agent on Telegram and web answers "how many negative calls this week?" in seconds.

CALLS~200/dayTRANSCRIBEPII redactedCLASSIFYLLMDATA TABLEevery callCHAT AGENTTG + web~30 s/callsweeper re-drives stuck records
FIG. 02 — call analytics pipeline100% coverage
End-to-end demo: a call → transcription → classification → chat-agent answer

The scenario

A cake manufacturer scenario: an online bakery running phone orders and delivery, roughly 200 customer calls a day — feedback, complaints, order questions. Before automation, one employee listened to every call by hand, scored the tone, tagged a category and logged it in a report. At 200 calls a day that ate 8–10 working hours, so only 30–40% of calls actually got reviewed — the rest were skipped by default.

Pain Consequence
8–10 hours/day of manual listening Complaints get a response the next day, or later
No aggregated statistics No visibility into negative-call %, trends by category
No fast lookup Impossible to answer “what went wrong last week” in 30 seconds
Subjective scoring Different reviewers, different tone judgments
30–40% coverage Most feedback is never seen

What I built

Six n8n workflows sharing one Google Sheets queue and one n8n Data Table.

Calls: Processor (schedule every 2 minutes, 17 nodes) pulls a call URL from the queue, takes an atomic lock, sends it to AssemblyAI for Ukrainian transcription with speaker diarization and PII redaction, classifies it with an LLM into sentiment + category, and writes the result to the Data Table. Calls under 10 seconds are filtered out before they ever reach the LLM.

Calls: Stats Tool and Calls: Drill Down Tool are sub-workflows the agent calls as tools — one returns aggregates (totals, % negative, top categories), the other returns specific matching calls filtered by date range, sentiment, category and limit. The drill-down tool exists as its own sub-workflow specifically because n8n’s built-in Data Table tool for AI agents mixed up filter operator names (_le vs _lte) in testing — a hand-written Code-node filter replaced it.

Calls: Agent is the chat interface — a Telegram bot and a basic-auth web chat, both backed by the same LangChain agent with per-channel memory, so a manager can ask “how many negative calls this week?” or “show me 3 quality complaints” and get an answer with real examples, not a canned summary.

Calls: Errors and Calls: Sweeper keep the pipeline honest. Errors sends a Telegram alert with the execution link on any failure. Sweeper runs hourly, finds rows stuck in “Processing” for more than 15 minutes — an AssemblyAI callback that never arrived — and resets them, so the system recovers without anyone touching it.

Architecture

The diagram above matches the running workflows: a Google Sheets queue feeds the Processor, which hands transcription to AssemblyAI and classification to Gemini, writes to a Data Table, and lets the Agent read that table through two specialized tools — with Sweeper and Errors watching the whole pipeline for stalls and failures.

Hard lessons that shaped it

  • Async beats polling. AssemblyAI transcribes over a webhook callback, and the workflow uses n8n’s Wait/Resume pattern instead of polling for status: the execution serializes to the database and wakes on the callback, so one worker can hold hundreds of “sleeping” calls at once without burning capacity.
  • A Sheets lock has to be atomic, or two runs double-process the same call. appendOrUpdate with matching columns turned out to be enough of a primitive to make the queue concurrency-safe without a separate lock table.
  • Two specialized tools beat one universal one. Splitting Stats (aggregates) from Drill Down (specific rows) gave the agent a clean decision tree. A single do-everything tool was harder for the model to use correctly.
  • The model swap mattered more than prompt tuning. Switching classification from a free general-purpose model to Gemini 2.5 Flash raised valid-JSON output from ~85% to ~99% — the single biggest reliability gain in the build.
  • Store the pointer, not the payload. The Data Table keeps transcript_id, not the full transcript text — storage-aware design that stretches n8n’s 50 MB Data Table limit to roughly a year of data at this call volume.

Results

Metrics are measured in test runs — this is a demo build, not a client testimonial.

Metric Before After
Manual review time 8–10 h/day 0
Time from call to classification ~7 hours 30–60 seconds
Call coverage 30–40% 100%
Time to answer an analytics question 15–30 min manually 3–5 seconds via chat agent
End-to-end execution time ~26 seconds (measured)
Pipeline running cost ~$8–12/month (AssemblyAI + OpenRouter)

contact

Have a process that eats your team's hours?

Describe it in a couple of sentences — I'll reply with an automation plan: what to build, what it touches, and what it will save.

telegram@shuriken_86mailtomahinko86@gmail.com

responseusually within one working day

// this form runs on my own n8n — a person replies, not an autoresponder