Auto-fire Loops re-engagement emails to inactive PostHog users

By General Input

Every weekday morning, find paid and trial users who have stopped activating, fire the right Loops re-engagement email, and post a Slack recap for growth.

Integrations

  • PostHog
  • Loops.so
  • Slack Bot

Type

Agentic Task

Categories

  • Marketing
  • Product

Build me an agent workflow that runs every weekday morning and automatically re-engages paid and trial users who are quietly slipping away. PostHog supplies the behavior signal, Loops sends the right email automatically, and Slack is the audit trail.

Trigger: cron, every weekday at 9am in my workspace timezone. PostHog is not a poll provider and inactivity is the absence of events, so a clock-paced sweep is the right shape.

Step 1 — Find at-risk users in PostHog. Use the Execute HogQL Query operation against the last 30 days of events. Return one row per user where: they had at least one event in the last 30 days (so they are a real user), AND they have NOT triggered our key activation event in the past 14 days. Join with person properties so the result includes email, plan tier, signup date, last event name, and days since last active. I will tell you the activation event name and the plan property name during setup.

Step 2 — Reason about each row and bucket the user into exactly one cohort:

• trial-never-activated: plan = trial, never fired the activation event, signed up more than 24 hours ago.

• paid-going-quiet: plan is paid, was active in the last 30 days, no activation event in the past 14 days.

• power-user-cooling-off: plan is paid, previously high activity volume, sudden drop in the past 14 days.

Drop anyone that looks like noise before sending: already canceled, internal or test accounts (email domain matches our own company domain or contains the word test), or signed up within the last 24 hours. If a user fits none of the three cohorts cleanly, drop them.

Step 3 — For each kept user, push to Loops in this order: call Find Contact on Loops by email to confirm the contact exists; if it does not exist, skip that user (do not create a new Loops contact just to email them). Then call Update Contact and write back these custom properties: daysSinceLastActive (number), lastEventName (string), inactiveCohort (the cohort label), plan (string). Then call Send Event with an eventName matching the cohort: inactivity_detected_trial, inactivity_detected_paid, or inactivity_detected_power_user. The Loops email automations are set up in advance keyed to these event names so the right pre-built email fires automatically.

Idempotency and cooldown: pass an Idempotency-Key on the Loops Send Event call so re-running the workflow within 24 hours does not double-send. Additionally, before sending, look at the existing inactiveCohort value returned by Find Contact: if it already matches the cohort we are about to send and was set within the last 24 hours, skip the send. Users should never be hit twice in 24 hours for the same cohort.

Step 4 — Post a Slack Bot message to a growth channel (I will pick the channel during setup) summarizing the run: total users flagged today and per-cohort counts; the top five highest-value at-risk accounts (sort paid above trial, then by signup date oldest first); and a one-line diff versus yesterday, for example 'paid-going-quiet up 3, power-user-cooling-off flat, trial-never-activated down 2'. The Slack post is the audit trail so growth can sanity-check the emails that just went out; it is not where actions happen.

Setup notes to surface to me when the workflow is built: I must create the three Loops email automations keyed to inactivity_detected_trial, inactivity_detected_paid, and inactivity_detected_power_user before going live. I also need to confirm the PostHog activation event name and the plan-tier property name. Until those are in place, run the workflow in dry-run mode (compute the cohorts and post the Slack recap, but skip the Loops Send Event call).

Related prompts

Explore more prompts
Let support send one-off Loops emails without an engineerA brand asset library your marketing team actually searchesTurn Mailjet email clicks into ranked HubSpot follow-upsClean out the Looker dashboards and Looks nobody opensLiveKit live operations console for room moderationWake up dormant Keap leads with a researched reasonCustomer lifecycle inspector for Loops, Stripe and PostHogLiveChat coverage board for planning next week's shiftsPhone routing control panel for LiveKit voice agentsLinkedIn Ads budget pacing dashboard for every client account