At-risk customer alert
Your helpdesk posts new tickets and low satisfaction ratings to a webhook. Claude scores each one for churn risk from the language, the account’s plan and the history you send. Most score low and stop there. High-risk ones get a brief for the account owner (what’s wrong, what the customer is worth, a suggested save play and a draft reply) posted to Slack within a minute.
- Score churn risk Claude API · Haiku 4.5
- High risk? Condition
- Brief the owner Claude API · Sonnet 5
- Alert in Slack Shell
What each step does
Score churn risk
Claude API · Haiku 4.5Rates the risk as high, medium or low with the signals behind it.
High risk?
ConditionStops here unless the risk is high.
Brief the owner
Claude API · Sonnet 5Writes the alert: what’s wrong, what the account is worth, a save play and a draft reply.
Alert in Slack
ShellPosts the alert for the account owner.
From copy to first run
- Copy the pipeline JSON with the button above.
- In Jimothy, open Pipelines → New pipeline, paste it under “Or import a pipeline JSON” and click Import.
- Fill in the variables below under Pipeline settings → Variables.
- Triggers → Add trigger → Webhook. Post new tickets and low CSAT ratings with title (subject), description (message), key, and the extra fields below.
Send the extra fields customer, plan, arr, accountOwner and history (recent tickets or notes). They reach the prompts as {{issue.raw.arr}} and so on.
What to fill in
The prompts and commands read these as {{vars.<name>}}. The examples are placeholders: replace them with your own.
| Variable | What to put in it | Example |
|---|---|---|
savePlays | What your team can offer to keep an unhappy customer. The brief suggests from these. | Call from a VP within 24 hours. Engineering ETA on the underlying bug. One month credit… |
slackWebhookUrl | A Slack incoming webhook for the channel account owners watch. | — |
Show the pipeline JSON
{
"jimothyPipeline": 1,
"name": "At-risk customer alert",
"description": "Scores tickets and CSAT ratings for churn risk and alerts the account owner when it’s high.",
"icon": "workflow",
"color": "#ca8a04",
"repo": {
"mode": "scratch"
},
"concurrency": 5,
"variables": {
"savePlays": "Call from a VP within 24 hours. Engineering ETA on the underlying bug. One month credit (up to $5,000 ARR accounts). Dedicated onboarding session. Extended trial of a higher plan.",
"slackWebhookUrl": ""
},
"steps": [
{
"id": "score",
"name": "Score churn risk",
"type": "agent",
"description": "Rates the risk as high, medium or low with the signals behind it.",
"harnessId": "anthropic-api",
"model": "claude-haiku-4-5",
"timeoutMinutes": 3,
"retries": 1,
"passPattern": "^\\s*RISK:\\s*(high|medium|low)\\b",
"prompt": "Customer: {{issue.raw.customer | default:\"(unknown)\"}}, plan {{issue.raw.plan | default:\"unknown\"}}, ARR {{issue.raw.arr | default:\"unknown\"}}\nRecent history: {{issue.raw.history | default:\"(none sent)\"}}\n\nNew message ({{issue.key}}): {{issue.title}}\n{{issue.description | default:\"(empty)\"}}\n\nRate the risk that this customer churns. High means explicit talk of leaving, cancelling, evaluating alternatives or escalating, or repeated failures with strong frustration. Answer in exactly this format:\nRISK: high, medium or low\nSIGNALS: the phrases or facts that drove the rating"
},
{
"id": "high",
"name": "High risk?",
"type": "condition",
"description": "Stops here unless the risk is high.",
"dependsOn": [
"score"
],
"condition": {
"match": "all",
"rules": [
{
"value": "{{steps.score.output}}",
"op": "matches",
"compare": "RISK:\\s*high"
}
]
}
},
{
"id": "brief",
"name": "Brief the owner",
"type": "agent",
"description": "Writes the alert: what’s wrong, what the account is worth, a save play and a draft reply.",
"harnessId": "anthropic-api",
"model": "claude-sonnet-5",
"dependsOn": [
"high"
],
"timeoutMinutes": 5,
"prompt": "{{steps.score.output}}\n\nCustomer: {{issue.raw.customer | default:\"(unknown)\"}}, plan {{issue.raw.plan | default:\"unknown\"}}, ARR {{issue.raw.arr | default:\"unknown\"}}, owner {{issue.raw.accountOwner | default:\"unassigned\"}}\nHistory: {{issue.raw.history | default:\"(none sent)\"}}\nMessage ({{issue.key}}): {{issue.title}}\n{{issue.description}}\n\nSave plays we can offer: {{vars.savePlays}}\n\nWrite a Slack alert (*bold*, - bullets), under 200 words: *At risk: <customer> (<ARR>)*, owner, what's wrong in two lines, the save play you recommend from the list and why, and a short draft reply for the owner to send personally."
},
{
"id": "post",
"name": "Alert in Slack",
"type": "shell",
"description": "Posts the alert for the account owner.",
"dependsOn": [
"brief"
],
"timeoutMinutes": 2,
"command": "printf '{\"text\":%s}' {{steps.brief.output | json}} | curl -fsS -X POST -H 'Content-Type: application/json' --data @- {{vars.slackWebhookUrl}}"
}
]
}More for support, and beyond
Bug report → engineering ticket
Turns a customer’s bug report into an engineering-ready GitHub issue: reproduction steps, the code likely involved and possible duplicates.
SupportHelp article from a solved ticket
When an agent tags a solved ticket for the knowledge base, drafts a help article from the conversation, or an update to the existing one.
SupportWeekly support trends
Reads the week’s ticket export and reports the top themes, what’s rising, and which docs or bugs would cut volume most.