Files
cozsweet-frontend-nextjs/docs/backend/FRONTEND_PROACTIVE_WAKEUP_API.md
T
2026-06-30 10:49:14 +08:00

5.0 KiB

Elio Proactive Wakeup API

Target environment: pro pre-release.

Base URL:

https://proapi.banlv-ai.com

All endpoints require:

X-Admin-Token: <admin token>
Content-Type: application/json

ADMIN_VIEW_TOKEN can only read rules. Updating rules or running scans requires ADMIN_TOKEN.

Status

The proactive wakeup scheduler is deployed on pro, but real sending is guarded by environment flags:

ENABLE_PROACTIVE_WAKEUP=false
PROACTIVE_WAKEUP_DRY_RUN=true

With the current default, the hourly scheduler skips sending. The admin UI can still manually call dry-run for monitoring.

Rule Model

type ProactiveRule = {
  id: string;
  rule_key:
    | "global_anti_harassment"
    | "festival"
    | "social_post_share"
    | "dormant_wakeup";
  category: "guardrail" | "festival" | "social_post" | "dormant";
  enabled: boolean;
  priority: number;
  trigger_conditions: Record<string, unknown>;
  behavior_strategy: Record<string, unknown>;
  frequency_limit: Record<string, unknown>;
  created_at: string;
  updated_at: string;
};

Default rules:

Rule Purpose Main Limits
festival Valentine, Christmas, birthday personalized wakeup Max 1 per festival cycle
social_post_share Share Elio latest Facebook post Max 1 per FB post event
dormant_wakeup 48h inactivity wakeup Max 1 per dormant cycle
global_anti_harassment Stop waking users after 7 idle days Global suppression

List Rules

GET /api/admin/proactive/rules

Example:

curl -H "X-Admin-Token: $ADMIN_TOKEN" \
  https://proapi.banlv-ai.com/api/admin/proactive/rules

Response:

{
  "success": true,
  "data": [
    {
      "id": "8b14a3bf-6c01-4d0c-85b5-613399cb8f14",
      "rule_key": "dormant_wakeup",
      "category": "dormant",
      "enabled": true,
      "priority": 30,
      "trigger_conditions": {
        "min_idle_hours": 48,
        "min_user_messages": 5
      },
      "behavior_strategy": {
        "mode": "ai_dormant_wakeup",
        "tone": "soft_missing",
        "send_channel": "cozsweet"
      },
      "frequency_limit": {
        "cycle_scope": "dormant_period",
        "max_per_cycle": 1
      },
      "created_at": "2026-06-29T07:38:46.155433+00:00",
      "updated_at": "2026-06-29T10:52:11.041169+00:00"
    }
  ]
}

Update Rule

PATCH /api/admin/proactive/rules/{rule_key}

Allowed request fields:

type UpdateProactiveRuleRequest = {
  enabled?: boolean;
  priority?: number;
  trigger_conditions?: Record<string, unknown>;
  behavior_strategy?: Record<string, unknown>;
  frequency_limit?: Record<string, unknown>;
};

Example:

curl -X PATCH \
  -H "X-Admin-Token: $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"enabled":true}' \
  https://proapi.banlv-ai.com/api/admin/proactive/rules/dormant_wakeup

Response:

{
  "success": true,
  "data": {
    "rule_key": "dormant_wakeup",
    "enabled": true,
    "priority": 30,
    "trigger_conditions": {
      "min_idle_hours": 48,
      "min_user_messages": 5
    }
  }
}

Run Scan

POST /api/admin/proactive/run?dry_run=true

Query parameters:

Name Type Default Meaning
dry_run boolean true true previews eligible candidates; false sends and writes delivery records only when ENABLE_PROACTIVE_WAKEUP=true.

Example:

curl -X POST \
  -H "X-Admin-Token: $ADMIN_TOKEN" \
  "https://proapi.banlv-ai.com/api/admin/proactive/run?dry_run=true"

Current pro response with no eligible users:

{
  "success": true,
  "data": {
    "enabled": false,
    "dryRun": true,
    "candidates": 0,
    "sent": 0,
    "items": []
  }
}

When candidates exist, items contains rule/cycle context and, in dry-run mode, generated preview messages.

Frontend States

Handle these states in the admin UI:

State How to detect UI suggestion
Unauthorized HTTP 403, message=admin token required Ask operator to enter an admin token.
No candidates success=true, data.candidates=0 Show an empty state.
Dry-run preview data.dryRun=true, items.length>0 Show candidate list and preview text.
Sending disabled data.enabled=false Display that real sending is off in environment config.
Send executed data.dryRun=false, data.sent>0 Show sent count and delivery rows.
Partial failure Any item with status="failed" Show per-user failure reason and keep successful rows.

Notes

  • User eligibility requires cozsweet/web user messages >= 5 and last interaction older than the rule threshold.
  • The global anti-harassment rule suppresses wakeups once the user has been idle for 7 days.
  • Birthday wakeups require birthday data. The migration includes users.birthday; if the column is not present yet, birthday matching is skipped without breaking other rules.
  • Facebook post sharing requires inserting an elio_fb_post row into proactive_message_events.