FCHubFCHub.co

Drip Content

Schedule content to unlock over time after purchase using delay-based or fixed-date drip rules.

Drip content lets you release membership content on a schedule rather than all at once. Instead of dumping everything into a member's lap on day one, you can spread content out over days, weeks, or months — keeping members engaged and building anticipation.

How Drip Works

Every plan content rule has a drip type that controls when that content becomes available:

Drip TypeBehavior
ImmediateContent is available as soon as the membership is granted
DelayedContent unlocks X days after the membership is granted
Fixed DateContent unlocks on a specific calendar date

When a membership is granted, the AccessGrantService creates individual grants for each content rule. For delayed drip rules, the drip_available_at field is set to the grant date plus the delay days. For fixed-date rules, it's set to the specified date.

The AccessEvaluator checks the drip_available_at field during every access check. If the date is in the future, the user sees a "drip locked" message instead of the content.

Setting Up Drip Rules

Edit your plan's content rules

Go to Memberships > Plans, edit your plan, and switch to the Content Rules tab.

Configure drip timing

For each content rule, set the drip type:

  • Immediate — available right away (day 0)
  • Delayed — enter the number of days after purchase. For example, 7 means the content unlocks 7 days after the member joins
  • Fixed Date — pick a specific calendar date when the content should unlock

Set the sort order

Arrange your content rules in the order you want them to appear in the drip timeline. The sort order determines the display sequence in the admin calendar and the member's progress view.

Example Drip Schedule

Here's a typical 4-week course drip:

ContentDrip TypeDelayAvailable
Welcome & OrientationImmediate0Day 0
Module 1: BasicsImmediate0Day 0
Module 2: IntermediateDelayed7Day 7
Module 3: AdvancedDelayed14Day 14
Module 4: ExpertDelayed21Day 21
Final AssessmentDelayed28Day 28

Drip Evaluation

The DripEvaluator class handles drip-specific access checks. It provides:

Single Item Check

DripEvaluator::isAvailable($userId, $provider, $resourceType, $resourceId)

Returns an array with:

  • available — boolean, whether the content is unlocked
  • reasonno_grant, immediate, unlocked, or drip_locked
  • available_at — the unlock date (if drip locked)
  • days_left — days until unlock (if drip locked)

Full Timeline

DripEvaluator::getTimeline($userId, $planId)

Returns the complete drip timeline for a user's plan, with each item marked as:

  • unlocked — content is available
  • upcoming — content will unlock soon (date is set)
  • locked — content is not yet accessible

Items are sorted with unlocked first, then by sort order.

Plan Schedule Overview

DripEvaluator::getPlanDripSchedule($planId)

Returns the drip schedule for a plan without user context. This is used in the admin calendar view to show the overall content release schedule.

Email Notifications

When drip content unlocks, the plugin can send an email notification to the member. The DripScheduleService processes pending notifications via the hourly cron job fchub_memberships_drip_process.

Each notification includes:

  • The title of the unlocked content
  • A direct link to access it
  • The plan name
  • The next item in the drip sequence (if any)
  • The member's overall drip progress

Notifications are created when a membership is granted. The DripScheduleService::scheduleForGrant() method creates a notification row for each delayed or fixed-date rule, with notify_at set to the unlock date.

Retry Logic

If a notification fails to send, it's marked as failed with a retry count. The service retries up to 3 times before marking the notification as permanently failed and logging an error. The retry schedule is tracked via the retry_count and next_retry_at columns.

Disabling Drip Emails

You can disable drip unlock emails in Memberships > Settings by setting email_drip_unlocked to "No". The notifications will still be processed (for milestone tracking) but no emails will be sent.

Drip Milestones

The DripScheduleService tracks completion milestones at 25%, 50%, 75%, and 100%. When a member reaches a milestone, the plugin fires the fchub_memberships/drip_milestone_reached hook with the grant data, milestone percentage, and user ID.

Milestones are tracked per-grant in the grant's meta field under drip_milestones_fired. Each milestone fires only once per grant.

If FluentCRM is active, the DripMilestoneTrigger listens for this hook and can start automations — for example, sending a congratulations email at 50% or an upgrade offer at 100%.

Admin Calendar

The drip admin page shows a calendar view of upcoming content unlocks. This pulls data from the DripScheduleService::getCalendar() method, which queries the drip_notifications table for upcoming unlocks within a date range.

The calendar view shows:

  • Pending notifications grouped by date
  • The content title and resource type for each unlock
  • The notification status (pending, sent, failed)

You can also view the notification queue with filtering by status and retry failed notifications individually.

Drip Progress Frontend

Members can see their drip progress through:

  1. [fchub_drip_progress] shortcode — shows a progress bar with "X of Y items unlocked (Z%)"
  2. [fchub_my_memberships] shortcode — the full account page includes a content library with locked/unlocked status and unlock dates
  3. [fchub_membership_status display="full"] shortcode — includes drip progress for each plan

The progress calculation is:

percentage = (unlocked items / total items) * 100

Where an "unlocked" item has either no drip_available_at set or a drip_available_at in the past.

FluentCRM Smart Codes

Two FluentCRM smart codes relate to drip progress:

  • {{membership.drip_progress}} — text like "5 of 10 items unlocked"
  • {{membership.drip_percentage}} — number like "50"

These are useful in automation emails to show members how far along they are in their content journey.

On this page