Catch at-risk Ghost members the moment Stripe flags trouble

By General Input

When a Ghost member's payment fails or they cancel, label them in Ghost and post a retention brief to Slack so you can win them back before they leave.

Integrations

  • Ghost
  • Stripe
  • Slack

Type

Agentic Task

Categories

  • Marketing
  • Operations

Build me an agent workflow that catches paid Ghost members the moment Stripe flags trouble, so I can intervene before they're gone.

Trigger: a Stripe webhook for the events invoice.payment_failed and customer.subscription.deleted. The same workflow should handle both event types.

For each incoming event:

1. If the Stripe event has livemode: false (i.e. test mode), stop and do nothing. We do not want test events polluting the retention channel.

2. Pull the customer id from the event (it lives at data.object.customer for invoice.payment_failed and data.object.customer for customer.subscription.deleted). Use Stripe's Retrieve Customer operation to fetch the customer's email, name, and any metadata or balance info that can stand in for lifetime value (e.g. total_spend metadata if present, otherwise the customer's balance or the invoice amount).

3. Use Ghost's Browse Members (Admin API) operation with the NQL filter email:"<that email>" to find the matching Ghost member. Capture their name, id, current labels, subscription tier (the plan or product name from the member's subscriptions array), and, if available on the member record, the URL of the most recently opened post.

4. Use Ghost's Update Member (Admin API) operation to add a label to that member. Use "at-risk" if the event was invoice.payment_failed, and "churned" if the event was customer.subscription.deleted. Preserve the member's existing labels rather than overwriting them.

5. Compose and send a Slack message via Send a Message to the channel #retention. Keep it short and skimmable. Include: the member's name and email, their tier, their lifetime value (or best available proxy from Stripe), the event reason in plain English ("payment failed on $X invoice" vs "subscription canceled"), the URL of the most recent Ghost post they opened if visible on the member record, and a one-sentence suggested next step (for example: "Send a 20% win-back offer" for a small failed payment, "Manual outreach worth it" for a high-LTV cancellation). The agent should pick the suggestion based on lifetime value and event type.

Edge cases:

- If no matching Ghost member is found for that email, skip the Update Member step but still post to Slack with whatever Stripe details we have, and note in the message that the member could not be located in Ghost. - If the same member triggers multiple events in quick succession (e.g. a payment_failed followed by a subscription_deleted), it's fine to post both messages, but make sure the labels in Ghost are additive, not overwritten. - Never include raw Stripe ids or JSON in the Slack message. Write it like a person would: short paragraph or 4-5 bullet lines.

Related prompts

Explore more prompts
Call overdue Xero customers with an AI collections agentWin back LiveChat visitors whose chats went unansweredLet support send one-off Loops emails without an engineerCustomer lifecycle inspector for Loops, Stripe and PostHogChat quality review board for LiveChat support leadsWin back no-show and cancelled appointments every morningLive Loop returns analytics with product-level drill-downMonth-end Stripe finance pack, stored and shared in SlackNewsletter pre-flight and approval board for Mailjet sendsTurn a prospect spreadsheet into personalized sequence enrollments