A Claude-powered chat widget that answers on the website only when the office is closed. tawk.to keeps business hours; this takes the night shift, captures a lead, and emails it to the office.
tawk.to has no supported API for pushing an agent message into a live chat — its REST API is beta, gated behind an access request, and shaped for admin and reporting (properties, tickets, stats), not conversation. So an AI answering inside the tawk widget isn't buildable. Rather than migrate the whole live-chat setup off a tool that works, this covers the hours tawk.to isn't staffed and leaves the daytime alone.
visitor -> widget.js (shadow DOM, on tribecabeverage.com)
| GET /api/status -- renders only if the office is closed
| POST /api/chat -- SSE stream of reply deltas
v
index.ts (Hono)
|-- agent.ts Gemini reply + lead extraction
|-- store.ts blob-backed transcripts and leads
+-- config.ts hours, model, business profile, guardrails
The two chat widgets can never appear at the same time: widget.js asks
/api/status before it renders anything, and /api/chat refuses to answer
during business hours even if something calls it directly.
<script src="https://tribeca_rep--01a039bce9a870efb2b97ddecd13d603.web.val.run/widget.js" defer></script>
Drop that in the site footer. Nothing about the tawk.to embed changes.
| Key | Required | What it does |
|---|---|---|
GEMINI_API_KEY | yes | From aistudio.google.com/apikey. Without it every chat returns the fallback message with the office phone number. |
LEADS_KEY | to view leads | Any random string. /leads?key=... then shows captured leads. The page stays closed until this is set — it holds customer PII. |
NOTIFY_EMAIL | no | Where lead emails go. Unset means the val owner. |
FORCE_BOT | no | "true" makes the bot answer around the clock. Testing only — the home page shows a warning banner while it's on. |
config.ts holds the products, pricing, service areas, and guardrails, copied
from Tribeca_Rep/tribeca-sms-sales-rep so both bots say the same things.
Change pricing in both places. The guardrails are the important part: no
invented prices, no promised delivery dates, no orders taken, escalate to
973-913-4568.
- Salesforce lookups.
tribeca-salesforce-agentcould let the bot answer "when is my next delivery" for existing customers. NeedsSALESFORCE_AGENT_URLandSALESFORCE_AGENT_KEYcopied over and a tool wired intoagent.ts. - Live handoff. There is none by design — if someone needs a human, the bot gives them the office number and the office follows up in the morning.