Most small businesses do not need to rip out their SaaS chatbot. It answers FAQs, it shows menus, it works. What it usually cannot do is the business-specific part: deciding who owns a lead, writing a complete record into the CRM, and holding risky replies for approval.
When I help an owner with custom AI vs an off-the-shelf chatbot, the hybrid version for small business, the build is usually a thin service behind the existing bot. Here is the pattern.
The shape
Customer -> SaaS chatbot (FAQs, menus)
-> webhook on "handoff" event
-> handoff service
-> CRM upsert (idempotent)
-> route to owner
-> approval queue if risky
-> notify owner
The handoff service
RISKY = {"price", "refund", "complaint", "custom_order"}
def on_handoff(event):
key = f"{event.channel}:{event.conversation_id}:{event.handoff_id}"
if not seen.insert_if_absent(key):
return "duplicate" # vendor retried the webhook
contact = crm.upsert(phone=normalise(event.phone), name=event.name)
intent = classify(event.transcript) # rules first, small model if needed
fields = extract(event.transcript, ["product", "timing", "budget_hint"])
owner = route(intent, fields) # your rules, not the vendor's
task = crm.create_task(contact, owner, fields, due_in_minutes=30)
if intent in RISKY:
approvals.enqueue(task, draft_reply(event))
notify(owner, task)
return "ok"
Note the idempotency key. Most chatbot vendors retry webhooks on timeouts, and without it you get two tasks and two notifications for the same customer.
Why this works
- The bot keeps doing what it is good at. No migration, no retraining staff on a new widget.
- Your rules live in your code. Routing by product, branch or language is yours to change.
- Duplicates are handled once, at the edge, instead of being cleaned up in the CRM later.
- Risky replies wait in an approval queue instead of going out automatically.
What to check in your chatbot vendor first
- Does it fire a webhook on handoff, with the transcript and contact fields?
- Can it receive a "human has taken over" signal, so the bot stops replying?
- Can you export conversations and contacts?
If the answer to the first question is no, that is the point where replacing the front end becomes worth discussing. If it is yes, start with the thin layer and see how far it takes you.
Testing it
Save a handful of real transcripts with personal details removed and replay them against on_handoff in a test environment. Check the owner, the fields and whether risky ones landed in the approval queue. Run the same webhook twice and confirm you get one task.
Disclosure: I co-founded NxFlowAI (Mumbai). Before building anything like this, we map one workflow in a 72-hour audit.
Top comments (0)