IF THIS FEELS LIKE CHURN,
THEN DO THIS.
If-this-then-that, but the 'this' is a feeling. Build automations off signals, not keywords. Act on intent, not just action.
BUILD LIKE A KID. SHIP LIKE AN ADULT.
New call ends
CHURN_RISK > 0.7
Slack brief to CS lead
COPY. TWEAK. SHIP.
CHURN WHISPER
If CHURN_RISK > 0.7, drop a brief in CS lead's Slack.
UPSELL PING
If EXPANSION_SIGNAL > 0.8, create an opp and tag the AE.
SILENCE SWEEP
If account silent 14d, trigger a personalized check-in.
ESCALATION LIFT
If angry tone detected, route ticket to a senior IC — not a bot.
FEEDBACK DIGEST
Every Monday, a rolled-up view of what customers actually said.
ADVOCATE SPOT
If sentiment > 0.85 for 3 weeks, ping marketing for a testimonial.
BILLING RESCUE
If payment failure + high-LTV, generate a CSM-signed apology draft.
QBR BUILDER
Assembles a customer QBR deck from 90 days of conversations.
RENEWAL RADAR
60 days out: risk-score every account up for renewal. Ranked.
WE WON'T EMAIL YOUR CEO'S MOM.
Dry-runs by default. Approvals for anything customer-facing. Scope limits per recipe. Automation should feel like cruise control — not a runaway train.
- ✓Dry-run every new recipe for 7 days
- ✓Approval required for 'send external email'
- ✓Per-recipe rate limits
- ✓Per-action kill switch
OR JUST WRITE CODE.
Recipes compile to code. Fork them, rewrite them, call your own APIs. Works like a webhook.
export default async function onChurnRisk({ call, account }) {
if (call.signals.churn_risk < 0.7) return
await slack.post("#cs-leads", {
text: `🚨 ${account.name} — churn risk ${call.signals.churn_risk}`,
brief: call.summary,
})
await crm.tag(account.id, "RESCUE_NOW")
}