{"id":"44c4e2d1-e771-4a6e-ae5a-f4094289580d","entityType":"agent","slug":"clawhub-earlvanze-renatus-icm","name":"Renatus Icm","canonicalUrl":"https://www.xpersona.co/agent/clawhub-earlvanze-renatus-icm","canonicalPath":"/agent/clawhub-earlvanze-renatus-icm","generatedAt":"2026-10-10T03:39:45.891Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-09T20:49:14.416Z","emptyReason":null},"description":"Manage Renatus event campaigns by setting up landing pages, running email blasts, handling guest registrations, exporting leads, and syncing unsubscribes. Skill: Renatus Icm Owner: earlvanze Summary: Manage Renatus event campaigns by setting up landing pages, running email blasts, handling guest registrations, exporting leads, and syncing unsubscribes. Tags: latest:2.1.5 Version history: v2.1.5 | 2026-07-22T17:34:06.286Z | user Add sanitized Renatus Back Office order-entry API reference and safety preflight. v2.1.4 | 2026-04-04T18:43:14.351Z | user Add Bitwarden/Browse","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 2K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s17e9q72w7rrtswh8zeszvr87s8476ga:renatus-icm","sourceUrl":"https://clawhub.ai/earlvanze/renatus-icm","homepage":"https://clawhub.ai/earlvanze/skills/renatus-icm","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/earlvanze/renatus-icm","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/earlvanze/skills/renatus-icm","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":40,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Manage Renatus event campaigns by setting up landing pages, running email blasts, handling guest registrations, exporting leads, and syncing unsubscribes. Skill"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T20:49:14.416Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T20:49:14.416Z","emptyReason":null},"stars":null,"forks":null,"downloads":2010,"packageName":null,"latestVersion":"2.1.5","tractionLabel":"2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T20:49:14.416Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T20:49:14.416Z","lastCrawledAt":"2026-10-09T20:49:14.416Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T20:49:14.416Z","lastVerifiedAt":null,"highlights":[{"version":"2.1.5","createdAt":"2026-07-22T17:34:06.286Z","changelog":"Add sanitized Renatus Back Office order-entry API reference and safety preflight.","fileCount":21,"zipByteSize":68753},{"version":"2.1.4","createdAt":"2026-04-04T18:43:14.351Z","changelog":"Add Bitwarden/Browser Relay auth section, fix get_events() to read raw JSON, push 42 events to calendar","fileCount":20,"zipByteSize":65817},{"version":"2.1.3","createdAt":"2026-04-04T14:38:00.001Z","changelog":"**Summary: Improved credential handling and documentation for safer, more reliable event campaign management.** - Updated SKILL.md with a dedicated ⚠️ Credentials & Security section, listing all required environment variables and key security practices. - Simplified and clarified environment variable requirements, emphasizing safe credential handling (do not commit secrets to code). - Enhanced documentation around Chrome/Brave CDP access and potential risks with admin/destructive scripts. - No changes to core automation scripts (`add_event.py`, `generate_event_page.py`), but related usage and requirements clarified in documentation. - Streamlined descriptions and prerequisites for common workflows, making setup and operations clearer and more secure for users.","fileCount":19,"zipByteSize":63744},{"version":"2.1.2","createdAt":"2026-04-04T14:33:09.119Z","changelog":"renatus-icm v2.1.2 - Updated `scripts/renatus_leads.py` with new changes or improvements. - Removed the sample event landing page: `assets/site/commercial/index.html`. - No user-facing workflow changes noted.","fileCount":19,"zipByteSize":62732},{"version":"2.1.1","createdAt":"2026-04-04T12:24:52.875Z","changelog":"renatus-icm 2.1.1 - Improved event confirmation page UI in `assets/site/confirmation.html`. - Updated `scripts/add_event.py` for better event handling and landing page generation.","fileCount":null,"zipByteSize":null},{"version":"2.1.0","createdAt":"2026-04-04T11:30:19.685Z","changelog":"renatus-icm v2.1.0 - Improved event landing page confirmation (assets/site/confirmation.html) for registrants. - Updated generate_event_page.py script for enhanced event detail extraction and page rendering.","fileCount":20,"zipByteSize":66017},{"version":"2.0.0","createdAt":"2026-04-04T11:23:03.885Z","changelog":"Renatus ICM 2.0.0 introduces multi-event automation for event marketing. - Added scripts to auto-generate an event calendar (`generate_calendar.py`) and automate adding/scraping new events with one command (`add_event.py`). - `config.json` now supports and stores multiple events (`events[]`), enabling calendar and batch operations. - Updated documentation with new workflows for generating an events calendar and one-step event setup. - Refactored `config_loader.py` and `generate_event_page.py` to support enhanced multi-event configuration.","fileCount":20,"zipByteSize":64860},{"version":"1.3.0","createdAt":"2026-04-04T11:15:17.221Z","changelog":"- Added centralized configuration support via config.json and new config_loader.py. - All scripts now automatically read from config.json, falling back to environment variables. - Updated SKILL.md documentation for the new configuration method and environment variable usage. - Improved consistency across event, email, and lead scripts for configuration management.","fileCount":18,"zipByteSize":56652}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17e9q72w7rrtswh8zeszvr87s8476ga:renatus-icm","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T03:39:45.887Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-earlvanze-renatus-icm/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-09T20:49:14.416Z","emptyReason":null},"readme":"Skill: Renatus Icm\n\nOwner: earlvanze\n\nSummary: Manage Renatus event campaigns by setting up landing pages, running email blasts, handling guest registrations, exporting leads, and syncing unsubscribes.\n\nTags: latest:2.1.5\n\nVersion history:\n\nv2.1.5 | 2026-07-22T17:34:06.286Z | user\n\nAdd sanitized Renatus Back Office order-entry API reference and safety preflight.\n\nv2.1.4 | 2026-04-04T18:43:14.351Z | user\n\nAdd Bitwarden/Browser Relay auth section, fix get_events() to read raw JSON, push 42 events to calendar\n\nv2.1.3 | 2026-04-04T14:38:00.001Z | auto\n\n**Summary: Improved credential handling and documentation for safer, more reliable event campaign management.**\n\n- Updated SKILL.md with a dedicated ⚠️ Credentials & Security section, listing all required environment variables and key security practices.\n- Simplified and clarified environment variable requirements, emphasizing safe credential handling (do not commit secrets to code).\n- Enhanced documentation around Chrome/Brave CDP access and potential risks with admin/destructive scripts.\n- No changes to core automation scripts (`add_event.py`, `generate_event_page.py`), but related usage and requirements clarified in documentation.\n- Streamlined descriptions and prerequisites for common workflows, making setup and operations clearer and more secure for users.\n\nv2.1.2 | 2026-04-04T14:33:09.119Z | auto\n\nrenatus-icm v2.1.2\n\n- Updated `scripts/renatus_leads.py` with new changes or improvements.\n- Removed the sample event landing page: `assets/site/commercial/index.html`.\n- No user-facing workflow changes noted.\n\nv2.1.1 | 2026-04-04T12:24:52.875Z | auto\n\nrenatus-icm 2.1.1\n\n- Improved event confirmation page UI in `assets/site/confirmation.html`.\n- Updated `scripts/add_event.py` for better event handling and landing page generation.\n\nv2.1.0 | 2026-04-04T11:30:19.685Z | auto\n\nrenatus-icm v2.1.0\n\n- Improved event landing page confirmation (assets/site/confirmation.html) for registrants.\n- Updated generate_event_page.py script for enhanced event detail extraction and page rendering.\n\nv2.0.0 | 2026-04-04T11:23:03.885Z | auto\n\nRenatus ICM 2.0.0 introduces multi-event automation for event marketing.\n\n- Added scripts to auto-generate an event calendar (`generate_calendar.py`) and automate adding/scraping new events with one command (`add_event.py`).\n- `config.json` now supports and stores multiple events (`events[]`), enabling calendar and batch operations.\n- Updated documentation with new workflows for generating an events calendar and one-step event setup.\n- Refactored `config_loader.py` and `generate_event_page.py` to support enhanced multi-event configuration.\n\nv1.3.0 | 2026-04-04T11:15:17.221Z | auto\n\n- Added centralized configuration support via config.json and new config_loader.py.\n- All scripts now automatically read from config.json, falling back to environment variables.\n- Updated SKILL.md documentation for the new configuration method and environment variable usage.\n- Improved consistency across event, email, and lead scripts for configuration management.\n\nv1.2.1 | 2026-04-04T11:01:03.538Z | auto\n\n### renatus-icm 1.2.1\n\n- Updated Supabase setup documentation in `references/supabase-setup.md`.\n- No functional/code changes to workflows or scripts.\n\nv1.2.0 | 2026-04-04T10:11:10.951Z | auto\n\nRenatus-ICM 1.2.0\n\n- Updated event landing page sample URL for clarity in documentation.\n- Standardized example phone numbers for better privacy and consistency.\n- Minor documentation improvements across SKILL.md and reference materials.\n- No functional or workflow changes; all script and process usage remain as before.\n\nv1.1.0 | 2026-04-04T03:27:47.025Z | auto\n\nrenatus-icm 1.1.0\n\n- Added script: scripts/generate_email_template.py for generating email templates.\n- No changes to existing workflows or core documentation.\n\nv1.0.0 | 2026-04-04T03:25:45.926Z | auto\n\nInitial release of Renatus ICM skill — a complete toolkit for running Renatus event marketing campaigns:\n\n- Set up event landing pages with automated data extraction from Renatus back office\n- Manage event registrations via Supabase Edge Functions and browser-based scripts\n- Send commercial email campaigns with bounce and unsubscribe handling\n- Export and download leads securely through Supabase admin functions\n- Sync unsubscribes to Renatus weekly with cron-script automation\n- Provides detailed setup instructions and quick-reference workflows for ICMs\n\nArchive index:\n\nArchive v2.1.5: 21 files, 68753 bytes\n\nFiles: _meta.json (130b), assets/sample_leads.csv (263b), assets/site/confirmation.html (7458b), assets/site/unsubscribe.html (6910b), references/email-campaign.md (4901b), references/event-page-setup.md (3967b), references/order-entry-backoffice-api.md (6112b), references/supabase-setup.md (3275b), references/workflows.md (7614b), scripts/add_event.py (11276b), scripts/config_loader.py (7396b), scripts/generate_calendar.py (9141b), scripts/generate_email_template.py (21843b), scripts/generate_event_page.py (26753b), scripts/renatus_delete_lead.py (10067b), scripts/renatus_leads.py (8915b), scripts/renatus_register_guest.py (18183b), scripts/send_commercial_email_batches.py (10803b), scripts/weekly_unsubscribe_sync.sh (8115b), skill-card.md (2958b), SKILL.md (11752b)\n\nFile v2.1.5:SKILL.md\n\n---\nname: renatus-icm\ndescription: Manage Renatus event marketing campaigns as an ICM. Use when running event registration campaigns, sending commercial email blasts, setting up event landing pages, exporting leads from Supabase, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Requires: Renatus credentials, Supabase project, SMTP sender account. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\".\n---\n\n## ⚠️ Credentials & Security\n\n**Required environment variables** (declare these before running any script):\n\n| Variable | Purpose | Minimum Scope |\n|---|---|---|\n| `RENATUS_USERNAME` | Renatus back office login | ICM-level account |\n| `RENATUS_PASSWORD` | Renatus back office login | ICM-level account |\n| `SUPABASE_URL` | Supabase project URL | Read leads |\n| `LEAD_ADMIN_TOKEN` | Supabase admin export | `anon` key or limited service role |\n| `SENDER_EMAIL` | From address for campaigns | Send-only SMTP account |\n| `SENDER_PASSWORD` | SMTP auth for email | Send-only |\n| `SUPABASE_SERVICE_ROLE_KEY` | Supabase admin actions (destructive) | Service role — do not use for read-only ops |\n\n**Security recommendations:**\n- Use a dedicated Supabase project for testing — do not supply your production `service_role_key`\n- Create a least-privilege Supabase anon key scoped to `funnel_leads` table reads only\n- Use a separate Chrome/Brave **profile** for CDP access (not your main browser session)\n- `renatus_delete_lead.py` performs deletions — always run with `--dry-run` first\n- Rotate credentials after use; revoke tokens that were shared or exposed\n- Do not commit real credentials to `config.json` — use the `.example` file and environment variables\n\n**CDP access:** Scripts connect to `http://127.0.0.1:9222` to inspect your browser's localStorage/cookies for Renatus auth tokens. This requires Chrome/Brave launched with `--remote-debugging-port=9222`. The skill does not extract your master Renatus password from CDP — it reads existing session tokens only.\n\n---\nname: renatus-icm\ndescription: Run a Renatus event marketing campaign as an ICM (Independent Campaign Manager). Use when managing Renatus event registrations, sending commercial email campaigns, setting up event landing pages, downloading/exporting leads, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Handles: Supabase Edge Function registration (submit-renatus-registration), gws/gog email sending (commercial-core-day1), bounce detection and SMS recovery, CDP browser registration/delete scripts, weekly unsubscribe cron, and lead export via lead-admin-export. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\", \"handle Renatus unsubscribes\".\n---\n# Renatus ICM Skill\n\nComplete toolkit for running a Renatus event marketing campaign: event page setup, email campaigns, lead management, and unsubscribe sync.\n\n## Workflows Quick Reference\n\nSee [references/workflows.md](references/workflows.md) for detailed step-by-step:\n- **New Event Setup** → [event-page-setup.md](references/event-page-setup.md)\n- **Email Campaign** → [email-campaign.md](references/email-campaign.md)\n- **CDP Registration** → scripts `renatus_register_guest.py`, `renatus_delete_lead.py`\n- **Back Office Order Entry** → [order-entry-backoffice-api.md](references/order-entry-backoffice-api.md)\n- **Lead Export** → Supabase lead-admin-export edge function\n- **Unsubscribe Sync** → `weekly_unsubscribe_sync.sh`\n\n## Architecture Overview\n## Generate a New Event Landing Page\n\n```bash\npython3 scripts/generate_event_page.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\n\nRequirements: Chrome/Brave CDP + active Renatus session. The script extracts event name, date(s), location, speakers, and session details from the backoffice page — then renders a complete ready-to-deploy HTML file. Preview before saving with `--dry-run`.\n\n\n\n```\nEvent Landing Page (HTML)\n  ↓ form submit\nSupabase Edge Function: submit-renatus-registration\n  ↓ server-side Renatus API (no CORS)\nRenatus Back Office (lead created + registered)\n  ↓ insert\nSupabase: funnel_leads table\n  ↓\nlead-admin-export edge function ← ICM exports here\n```\n\n**Key URLs:**\n- Landing page: `https://YOUR_REGISTRATION_PAGE/` (example)\n- Supabase edge: `https://<REF>.supabase.co/submit-renatus-registration`\n- Lead export: `https://<REF>.supabase.co/lead-admin-export`\n- Renatus back office: `https://backoffice.myrenatus.com`\n\n## Email Campaign\n\n### Send Batch\n```bash\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n```\nResume from next batch: change `--start N`. Skip already-sent via `--skip-sent` (default on). See [email-campaign.md](references/email-campaign.md) for bounce handling, unsubscribe sync, and template customization.\n\n### Prerequisites\n- `gws` CLI authenticated as sender account\n- `renatus_leads.csv` with `email` column\n- `commercial-core-day1.html` template\n\n## Browser-Based Registration (CDP)\n\nRequires Chrome/Brave with `--remote-debugging-port=9222` and active Renatus session.\n\n### Register Guest (dry run)\n```bash\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(555) 555-5555\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8\n```\n\n### Execute Registration\nAdd `--execute` to perform writes.\n\n### Delete Lead (unsubscribe)\n```bash\npython3 scripts/renatus_delete_lead.py --email jane@example.com --execute\n```\n\n\n### Generate Events Calendar\n```bash\npython3 scripts/generate_calendar.py --output site/calendar.html\npython3 scripts/generate_calendar.py --dry-run\n```\nReads `events[]` from `config.json`, generates a calendar page listing all active events with registration links.\n\n### Add Event (One-Command Setup)\n```bash\npython3 scripts/add_event.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\nScrapes event from Renatus → adds to `config.json` → generates landing page in one step. Requires Chrome/Brave CDP + active Renatus session.\n\n### Download Leads from Supabase\n```bash\npython3 scripts/renatus_leads.py --export\n# Or: SUPABASE_URL=... LEAD_ADMIN_TOKEN=... python3 scripts/renatus_leads.py --export\n```\nExports to `workspace/renatus_leads.csv` + `renatus_leads.json`. Set `SUPABASE_URL` and `LEAD_ADMIN_TOKEN` env vars, or pass `--ref` + `--token` flags. Use `--convert-json` to convert an existing JSON export to CSV format.\n\n## Lead Export\n\n### Supabase Admin Export\n```bash\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://<REF>.supabase.co/functions/v1/lead-admin-export?limit=500\"\n```\n\nToken = `LEAD_ADMIN_TOKEN` secret in Supabase. See [supabase-setup.md](references/supabase-setup.md) for setup.\n\n### Download via Agent\nIf running as an OpenClaw agent:\n```bash\n# From workspace: logs/email_send_log.json tracks sent emails\n# Download leads to: workspace/renatus_leads.csv\n```\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n```bash\ncp config.json.example config.json\n# edit config.json with your Supabase URL, Renatus credentials, sender account, etc.\n```\n\nAlternatively, set `RENATUS_*` environment variables. Scripts check (in order): `config.json` → env vars → defaults.\n\nEnvironment variables: `RENATUS_SUPABASE_REF`, `RENATUS_SUPABASE_URL`, `RENATUS_LEAD_TOKEN`, `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `RENATUS_SENDER`, `RENATUS_PROVIDER`, `RENATUS_TEMPLATE`, `RENATUS_UNSUB_URL`, `RENATUS_SITE_URL`, `RENATUS_REGISTRATION_URL`.\n\n**Important:** `config.json` is gitignored. Your personal config stays private; `config.json.example` is what other ICMs receive.\n\n\n---\n\n## Supabase Setup (New ICM)\n\nSee [supabase-setup.md](references/supabase-setup.md) for full setup:\n1. Link project: `supabase link --project-ref <REF>`\n2. Push migrations: `supabase db push`\n3. Deploy functions: `submit-renatus-registration`, `lead-admin-export`\n4. Set secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `LEAD_ADMIN_TOKEN`\n5. Verify: submit test registration → check `funnel_leads` + Renatus back office\n\n## Supabase Edge Function Reference\n\n### submit-renatus-registration\nPublic POST endpoint. Registers a lead in Renatus via server-side API (bypasses CORS). Auto-detects public-eligible sessions (no IMA/education requirements). Required secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`.\n\n### lead-admin-export\nAdmin GET endpoint. Requires `x-admin-token` header. Params: `?partner=&limit=`.\n\n### capture-lead\nGeneral-purpose public lead intake with Turnstile bot protection. Insert into `funnel_leads`.\n\n## Key Secrets (Supabase)\n\n| Secret | Required | Purpose |\n|---|---|---|\n| `RENATUS_USERNAME` | Registration | Back office login |\n| `RENATUS_PASSWORD` | Registration | Back office password |\n| `RENATUS_EVENT_ID` | Registration | Default event GUID |\n| `LEAD_ADMIN_TOKEN` | Export | Admin export auth |\n| `SUPABASE_URL` | Always | Project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | Always | DB access |\n\n## Unsubscribe Sync (Weekly Cron)\n\n```bash\n# Add to crontab\n0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh\n\n# Manual run\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\nRequirements: Chrome CDP at 9222 + active Renatus session. See [email-campaign.md](references/email-campaign.md).\n\n## Bounce Recovery\n\n```bash\n# Detect bounces\npython3 scripts/handle_bounced_emails.py --check\n\n# Export SMS-ready contacts\npython3 scripts/handle_bounced_emails.py --export-sms\n\n# Manually mark bounce\npython3 scripts/handle_bounced_emails.py --mark-bounced user@example.com\n```\n\n## Authentication: Two Options\n\n### Option A — Browser Relay (Recommended for CDP scripts)\nUse your existing logged-in Brave/Chrome session via Browser Relay (OpenClaw extension).\n\n1. Open Brave → click the **OpenClaw Browser Relay** extension icon on any Renatus tab\n2. Scripts connect to `http://127.0.0.1:9222` via Playwright CDP\n3. No credentials needed in config — reads existing session tokens from localStorage/cookies\n4. Requires the OpenClaw Browser Relay extension with an active tab\n\n**CDP scripts affected:** `renatus_register_guest.py`, `renatus_delete_lead.py`, `generate_event_page.py`, `add_event.py`\n\n### Option B — Env Vars (Recommended for non-CDP scripts)\nSet credentials as environment variables — never in chat or config files.\n\n```bash\nexport RENATUS_USERNAME=\"earlvanze@gmail.com\"\nexport RENATUS_PASSWORD=\"YOUR_PASSWORD\"\nexport RENATUS_EVENT_ID=\"0817966f-b9bb-448e-bbb8-b4160115bcc8\"\nexport LEAD_ADMIN_TOKEN=\"YOUR_SUPABASE_TOKEN\"\n```\n\nOr use a `.env` file loaded by your shell profile. Scripts read from env vars via `config_loader.py`.\n\n**Non-CDP scripts:** `renatus_leads.py`, `send_commercial_email_batches.py`, `generate_calendar.py`, `generate_email_template.py`\n\n### Security Rules\n- **Never paste credentials in chat** — use env vars or `.env` files\n- **Bitwarden CLI** (`bw`) for programmatic credential access: `bw get password \"Renatus\"`\n- CDP reads do not extract your master password — only existing session tokens\n- Config file (`config.json`) should use `[REDACTED — see Nextcloud/secrets]` for credential placeholders\n- Rotate credentials after any shared exposure\n\nFile v2.1.5:_meta.json\n\n{\n  \"ownerId\": \"kn7a5vdq619nymw8zq4aq95b49846rhq\",\n  \"slug\": \"renatus-icm\",\n  \"version\": \"2.1.5\",\n  \"publishedAt\": 1784741646286\n}\n\nFile v2.1.5:references/email-campaign.md\n\n# Email Campaign Guide\n\n## Overview\n\nCommercial email campaigns are sent from `YOUR_SENDER@gmail.com` via gws CLI. The email template is `commercial-core-day1.html`. Campaigns target leads from `renatus_leads.csv` and track delivery via `logs/email_send_log.json`.\n\n## Campaign Assets\n\n| File | Purpose |\n|---|---|\n| `email/commercial-core-day1.html` | HTML email template |\n| `renatus_leads.csv` | Lead list (export via `renatus_leads.py --export`) |\n| `logs/email_send_log.json` | Sent log (resumable sends) |\n| `logs/bounced_emails.json` | Bounced email tracking |\n\n### Getting the Leads CSV\n```bash\n# Export fresh from Supabase\npython3 scripts/renatus_leads.py --export\n\n# Convert existing JSON to CSV (if you have old JSON export)\npython3 scripts/renatus_leads.py --convert-json\n```\n\n## Sending Emails\n\n### Prerequisites\n- `gws` CLI authenticated as `YOUR_SENDER@gmail.com`\n- `renatus_leads.csv` exists with at least `email` column\n- `commercial-core-day1.html` template\n\n### Dry Run (Preview)\n```bash\npython3 scripts/send_commercial_email_batches.py --dry-run\n```\n\n### Send in Batches (with Resume)\n```bash\n# First batch\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n\n# Resume from batch 2\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 20 --send\n\n# Resume from batch 3\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 40 --send\n```\n\n### Batch Script Flags\n| Flag | Default | Description |\n|---|---|---|\n| `--batch-size` | 20 | Emails per batch |\n| `--start` | 0 | Starting index |\n| `--dry-run` | — | Preview without sending |\n| `--send` | — | Actually send |\n| `--delay` | 2.0 | Seconds between sends |\n\n## Personalizing the Template\n\nThe template uses `{{recipient_email}}` as a placeholder for the unsubscribe link target.\n\n### Adding Personalized Unsubscribe URL\nReplace `{{recipient_email}}` with a base64-encoded unsubscribe URL:\n\n```python\nimport base64\n\ndef encode_unsubscribe_url(email: str, base_url: str = \"https://YOUR_DOMAIN/unsubscribe.html\") -> str:\n    encoded = base64.urlsafe_b64encode(email.encode()).decode().rstrip('=')\n    return f\"{base_url}?e={encoded}\"\n```\n\n### Unsubscribe URL in Email Template\n```html\n<a href=\"https://YOUR_DOMAIN/unsubscribe.html?e={{recipient_email}}\"\n   style=\"color: #999999; font-size: 12px;\">\n  Unsubscribe\n</a>\n```\n\nWhen the user clicks unsubscribe, their email is pre-filled and they confirm removal.\n\n## Subject Line Options\n\nTested subject lines for Commercial Core:\n1. `They turned $7K into $103M. Learn how (April 16)`\n2. `Commercial real estate: free training from $100M operators`\n3. `[Only 9 days] Learn commercial underwriting from operators`\n4. `From skeptical to 90+ doors in 8 months (free training)`\n\n## Bounce Handling\n\n### Check for Bounces\n```bash\npython3 scripts/handle_bounced_emails.py --check\n```\n\n### Export Bounced Contacts with Phone Numbers for SMS\n```bash\npython3 scripts/handle_bounced_emails.py --export-sms\n# Output: logs/sms_followup_list.csv\n```\n\n### Manually Mark an Email as Bounced\n```bash\npython3 scripts/handle_bounced_emails.py --mark-bounced user@example.com\n```\n\n## Unsubscribe Sync (Weekly Automation)\n\nThe `weekly_unsubscribe_sync.sh` script syncs unsubscribes from the web form to Renatus.\n\n### Setup Cron Job\n```bash\n# Run every Sunday at 2 AM\n0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh >> /home/umbrel/.openclaw/workspace/logs/unsubscribe_cron.log 2>&1\n```\n\n### Manual Run\n```bash\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\n\n### Requirements\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Logged into `backoffice.myrenatus.com`\n- Unsubscribes stored in `data/unsubscribes_<timestamp>.txt`\n\n## Deleting Leads from Renatus\n\n### Single Lead (Dry Run)\n```bash\npython3 scripts/renatus_delete_lead.py --email user@example.com\n```\n\n### Single Lead (Execute)\n```bash\npython3 scripts/renatus_delete_lead.py --email user@example.com --execute\n```\n\n### Bulk Delete from File\n```bash\npython3 scripts/renatus_delete_lead.py --file unsubscribes.txt --execute\n```\n\n### Process Unsubscribe File\n```bash\npython3 scripts/process_unsubscribes.py --file unsubscribes.txt --execute\n```\n\n## Lead Download (Supabase Admin Export)\n\n```bash\nTOKEN=\"your_lead_admin_token\"\nREF=\"your_project_ref\"\n\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" | \\\n  jq '.rows[] | {name, email, phone: .metadata.phone}' > leads_export.csv\n```\n\n## CSV Format (renatus_leads.csv)\n\nExpected columns:\n- `email` (required) — recipient address\n- `name` (optional) — full name or first name\n- `phone` (optional) — for SMS bounce recovery\n- `dateCreated` (optional) — lead creation date\n\nExample:\n```csv\nemail,name,phone,dateCreated\njane@example.com,Jane Smith,5185551212,2026-03-01\njohn@example.com,John Doe,,2026-03-02\n```\n\nFile v2.1.5:references/event-page-setup.md\n\n# Event Page Setup Guide\n\n## Overview\n\nThe event landing page is a static HTML form at `site/commercial/index.html` (or similar path on your hostinger/YOUR_DOMAIN deployment). It submits directly to a Supabase Edge Function which registers the lead in Renatus Back Office.\n\n## Page Structure\n\n### Registration Form Fields\n- `firstName` (required)\n- `lastName` (required)\n- `email` (required)\n- `phone` (required)\n- `website` (honeypot — hidden, must be empty)\n- `source_page` (auto-populated from `window.location.href`)\n\n### Submit Endpoint\n```\nPOST https://<PROJECT_REF>.supabase.co/submit-renatus-registration\n```\n\n### Request Body\n```json\n{\n  \"firstName\": \"Jane\",\n  \"lastName\": \"Smith\",\n  \"email\": \"jane@example.com\",\n  \"phone\": \"(555) 555-5555\",\n  \"website\": \"\",\n  \"source_page\": \"https://YOUR_DOMAIN/commercial/\"\n}\n```\n\n### Success Response\n```json\n{\n  \"ok\": true,\n  \"eventId\": \"0817966f-b9bb-448e-bbb8-b4160115bcc8\",\n  \"eventName\": \"Commercial Core - Live Education\",\n  \"registrationId\": \"...\",\n  \"leadId\": \"...\",\n  \"guestUserId\": \"...\",\n  \"registeredSessions\": [\"Session Name 1\", \"Session Name 2\"]\n}\n```\n\n### Error Response\n```json\n{ \"error\": \"Error message\", \"details\": \"optional details\" }\n```\n\n## Setting Up a New Event Page\n\n### 1. Copy the Template\nCopy `site/commercial/index.html` to a new directory, e.g., `site/<event-slug>/index.html`\n\n### 2. Update the Edge Function URL\nIn the `<script>` section, update:\n```javascript\nconst EDGE_URL = 'https://<PROJECT_REF>.supabase.co/submit-renatus-registration';\n```\n\n### 3. Update Event Details\nUpdate the visible event details in the HTML (date, location, speakers, description).\n\n### 4. Update the Event ID\nEither:\n- Set `RENATUS_EVENT_ID` secret in Supabase (affects all form submissions)\n- Add `eventId` field to the form and pass it in the payload\n\n### 5. Get the Event GUID from Renatus\n1. Log into `backoffice.myrenatus.com`\n2. Navigate to Events\n3. Open the event\n4. Copy the event GUID from the URL or API response\n\n### 6. Verify Registration Flow\nSubmit a test registration and confirm:\n- Lead appears in `funnel_leads` table\n- Lead appears in Renatus Back Office\n- Email confirmation is sent by Renatus\n\n## Customizing the Landing Page\n\n### Styling\nThe page uses CSS custom properties for easy theming:\n```css\n:root {\n  --bg: #0f172a;\n  --card: #111827;\n  --accent: #22c55e;\n  --text: #e5e7eb;\n}\n```\n\n### Adding a Second Event (In-Person Option)\nModify the `feesPayload` to include multiple sessions, or use separate event pages with different event IDs.\n\n### Redirect to Confirmation Page\nAfter successful form submission:\n```javascript\nif (resp.ok) {\n  window.location.href = '/confirmation.html';\n}\n```\n\n## Hosting Options\n\n### Option A: Deploy with your hosting scripts\n```bash\npython3 scripts/deploy_hostinger.py\n```\n\n### Option B: Manual FTP Upload\nUpload `site/commercial/` directory to your web host's `public_html/` or equivalent.\n\n### Option C: Subdirectory on Existing Site\nUpload to `public_html/commercial/` — page will be at `https://yourdomain.com/commercial/`\n\n## Confirmation Page\nAfter successful registration, redirect users to a confirmation page. The confirmation page shows event details and next steps. See `site/confirmation.html` for the template.\n\n## Troubleshooting\n\n### \"Registration could not be completed\"\n- Check browser console for specific error\n- Verify Supabase Edge Function URL is correct\n- Check Supabase function logs in the dashboard\n\n### Lead not appearing in Renatus\n- Verify `RENATUS_USERNAME` and `RENATUS_PASSWORD` secrets are set\n- Check function logs for authentication errors (401 = bad credentials)\n- Confirm event GUID is valid and event is published in Renatus\n\n### Public sessions not found\n- Event may only have education-gated sessions\n- Check `isPublicEligibleSession` in the edge function — sessions requiring IMA, Xtream Education, or other credentials are excluded\n- Contact Renatus to create a public-eligible session for the event\n\nFile v2.1.5:references/order-entry-backoffice-api.md\n\n# Renatus Back Office Order Entry API\n\nThis reference is a sanitized, capture-derived map of the Renatus **Orders** page. It records endpoint paths, parameter names, status counts, and JSON key shapes only. It contains no captured credentials, identifiers, addresses, payment data, or response records.\n\n## Safety Boundary\n\n- The capture showed authenticated browser transport through `backoffice.myrenatus.com`; use a current, logged-in Chrome/Brave CDP session. Do not reuse values from the HAR.\n- Read calls use `GET /api/queryproxy/execute?url=<target-path>` with target-specific parameters appended to the proxy request.\n- Command calls use `POST /api/commandproxy/execute?url=<target-path>` with JSON bodies. The observed browser requests used `x-requested-with` and an XSRF header.\n- `POST` endpoints below can create a lead or save an order. They are external actions: run a dry-run/read preflight first and do not call them unless the user explicitly approves the exact customer, products, payment method, and submission state.\n- Do not replay captured payloads. Build values from the live browser session and the authorized order only.\n\n## Capture Scope\n\nThe July 22, 2026 order-entry capture contains 78 network entries. All 50 query-proxy calls and all four command-proxy calls returned HTTP 200. It covers the Orders page, lead/customer selection, product and payment lookup, and one successful order-container save.\n\n## Read Endpoints\n\n| Target path | Parameters observed | Use |\n|---|---|---|\n| `/api/orders/customersList` | `Value` | Customer search/list |\n| `/api/orders/sellersList` | `Value` | Seller search/list |\n| `/api/orders/containers/search` | `CurrentPage`, `PageSize`, `SortDirection`, `SortField`, `TotalCount`, `UserId`, `StatusFilter[n][Join]`, `StatusFilter[n][Data][Item]`, `StatusFilter[n][Data][Operation]` | Existing order-container list |\n| `/api/orders/products` | — | Product catalog |\n| `/api/orders/agreements` | — | Agreement catalog |\n| `/api/orders/availableproductsforcustomer` | `BuyerLeadId`, `IsInternational`, `LeadCountryCode` | Products eligible for the selected customer |\n| `/api/orderpayments/downpayments` | `CountryCode`, `ProductIds[]` | Down-payment options for selected products |\n| `/api/paymentMethod/getUserPaymentMethods` | `CurrentDate`, `UserId` | Saved payment methods |\n| `/api/marketinglead/validatelead` | `Value` | Lead validation |\n| `/api/userprofile/current` | — | Current authenticated user |\n\nThe page also loads campaign/status, settings, domain, notification, grid-filter, and event-status data. Those calls are contextual UI support, not required order-entry mutations.\n\n## Observed Command Endpoints and Payload Shapes\n\n### `POST /api/marketingLead/customerbyleadid`\n\nObserved twice, returning HTTP 200. JSON shape:\n\n```json\n{ \"Value\": \"string\", \"Key\": \"string\" }\n```\n\n### `POST /api/guestRegistration/addcustomer`\n\nObserved once, returning HTTP 200. This can create a customer/lead. JSON key shape:\n\n```text\nLeadId, OwnerId, Phone{CountryId, Number},\nAddress{AddressLine1, AddressLine2, City, State, PostalCode, Country},\nEmail, FirstName, LastName, SourceId,\nIsGuest, IsCustomer, OptIn, CanSms, IsInternationalCustomer\n```\n\n### `POST /api/orders/saveordercontainer`\n\nObserved once, returning HTTP 200. This is the order write. Its JSON body has the top-level shape:\n\n```text\nRequest{\n  CustomerUserId,\n  Customer{CustomerUserId, CustomerId, Email, FirstName, LastName, Phone{}, Address{}, ParentId, ParentName, Name, IsGuest, Owner, OwnerId, SourceId, ConsentTypeId, IsInternationalCustomer, ...},\n  Orders[{OrderId, OrderItems[{OrderId, Id, ProductId, ProductLogo, ProductDescription, IsCommissionable, ProductName, ProductTypeId, AssignedCost, RegularCost, DiscountedCost, DownPaymentAmount, CourseProductTypes, PaymentCycles, HasBilling, TaxRate, ...}]}],\n  PaymentOptions[{PaymentMethodId, CCNumber, CCName, CCSecurityCode, CCExpiration, CCCardType, Amount, LastFour, PaymentInfo, TypeId, Type, Address{}, SaveForFuture, IsCardForBilling, IsExisting, ...}],\n  BillingItem, Payments, IsSubmitted, IsOrderForMyself, IsBillingOrder, IsOrderInEditMode,\n  AggrementSignedInLanguage, AggrementSignedByName,\n  OrderAgreements[{OrderId, ProductId, ProductTypeId, AgreementId, AgreementFileName, AgreementTypeId, AgreementTypeName, LastActionById, LastActionByName, AgreementSigned}],\n  IgnoreSignature, IPAddress, SavedDateTime, SendEmailToCustomer, EnteredByUserProfileId\n}\n```\n\n`PaymentOptions` includes payment-related fields. Do not log, copy, or persist their values outside the live approved transaction.\n\n## Observed Order-Entry Sequence\n\nThe relevant successful sequence was:\n\n1. Load customer/seller and existing order-container lists.\n2. Load `/api/orders/products` and `/api/orders/agreements`.\n3. Resolve a selected customer with `customerbyleadid`.\n4. Create a customer through `guestRegistration/addcustomer` when needed.\n5. Resolve the created/selected customer again with `customerbyleadid`.\n6. Read eligible products, down-payment options, and saved payment methods.\n7. Save the assembled order through `saveordercontainer`.\n\n## Operational Preflight and Verification\n\n1. Confirm the browser is open to `backoffice.myrenatus.com` and the intended staff user is logged in.\n2. Confirm the target customer, products, prices, agreements, payment method, email preference, and whether the order is a draft or submitted order.\n3. Perform only the read endpoints first; stop on authentication, CSRF, validation, or data-mismatch failures.\n4. Before `saveordercontainer`, obtain explicit authorization for the exact write. Never infer payment or submission values.\n5. After a successful write, re-read `/api/orders/containers/search` and verify the expected order state exactly once. Do not retry a write after a timeout until server state is checked.\n\n## Known Limits\n\nThis capture establishes route and request-key shapes, but it is not a reusable payment or order template. It does not authorize automated ordering, and it must not be used to reconstruct customer, payment, or agreement values from captured traffic.\n\nFile v2.1.5:references/supabase-setup.md\n\n# Supabase Setup for Renatus ICM\n\n## Overview\n\nSupabase project: `YOUR_PROJECT_NAME` (EU-West-1 — or any region)\n\nStores lead registrations from the public event landing page and exposes an admin export endpoint for ICMs to download leads.\n\n## 1. Link and Push Migrations\n\n```bash\ncd supabase\nsupabase link --project-ref <PROJECT_REF>\nsupabase db push --include-all\n```\n\n## 2. Deploy Edge Functions\n\n```bash\nsupabase functions deploy submit-renatus-registration --project-ref <PROJECT_REF>\nsupabase functions deploy lead-admin-export --project-ref <PROJECT_REF>\nsupabase functions deploy capture-lead --project-ref <PROJECT_REF>\nsupabase functions deploy stripe-webhook --project-ref <PROJECT_REF>\n```\n\n## 3. Set Required Secrets\n\n```bash\nsupabase secrets set \\\n  RENATUS_USERNAME=\"<renatus_backoffice_email>\" \\\n  RENATUS_PASSWORD=\"<renatus_backoffice_password>\" \\\n  RENATUS_EVENT_ID=\"<default_event_guid>\" \\\n  SUPABASE_URL=\"https://<PROJECT_REF>.supabase.co\" \\\n  SUPABASE_SERVICE_ROLE_KEY=\"<service_role_key>\" \\\n  LEAD_ADMIN_TOKEN=\"<secure_random_token_for_admin_export>\" \\\n  --project-ref <PROJECT_REF>\n```\n\n## 4. Key Tables\n\n### funnel_leads\n```sql\ncreate table if not exists public.funnel_leads (\n  id uuid primary key default gen_random_uuid(),\n  created_at timestamptz not null default now(),\n  source_page text,\n  name text,\n  email text,\n  company text,\n  notes text,\n  cta_type text,\n  metadata jsonb not null default '{}'::jsonb\n);\n```\n\n### funnel_leads metadata field\nContains: `event_id`, `registration_id`, `lead_id`, `guest_user_id`, `registered_sessions`, `phone`\n\n## 5. Key Edge Functions\n\n### submit-renatus-registration\n- **URL:** `https://<PROJECT_REF>.functions.supabase.co/submit-renatus-registration`\n- **Method:** POST\n- **Auth:** Public (honeypot + Turnstile bot protection)\n- **Session eligibility:** Auto-detects public-eligible sessions (no IMA/education requirements)\n- **Response:** `{ ok, eventId, eventName, registrationId, leadId, guestUserId, registeredSessions }`\n\n### lead-admin-export\n- **URL:** `https://<PROJECT_REF>.functions.supabase.co/lead-admin-export`\n- **Method:** GET\n- **Auth:** `x-admin-token: <LEAD_ADMIN_TOKEN>` header\n- **Params:** `?partner=<optional_partner_slug>&limit=<1-500>`\n- **Response:** `{ ok, count, rows: [...] }`\n\n## 6. Configure Stripe Webhook (Optional)\n\nEndpoint: `https://<PROJECT_REF>.functions.supabase.co/stripe-webhook`\nListen for: `checkout.session.completed`\n\n## 7. Verify End-to-End\n\n1. Submit lead form at `/commercial/index.html`\n2. Confirm row in `funnel_leads`\n3. Verify lead in Renatus Back Office\n4. Export: `curl -H \"x-admin-token: $TOKEN\" \"https://<REF>.functions.supabase.co/lead-admin-export?limit=10\"`\n\n## Required Secrets Reference\n\n| Variable | Required | Description |\n|---|---|---|\n| `RENATUS_USERNAME` | Yes | Renatus back office email |\n| `RENATUS_PASSWORD` | Yes | Renatus back office password |\n| `RENATUS_EVENT_ID` | No | Default event GUID |\n| `SUPABASE_URL` | Yes | Project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | Yes | Service role key |\n| `LEAD_ADMIN_TOKEN` | Yes (export) | Admin export bearer token |\n| `STRIPE_SECRET_KEY` | Payments | Stripe secret key |\n| `STRIPE_WEBHOOK_SECRET` | Payments | Stripe webhook secret |\n| `TURNSTILE_SECRET_KEY` | No | Cloudflare Turnstile |\n\nFile v2.1.5:references/workflows.md\n\n# Renatus ICM Workflows\n\n## Table of Contents\n1. [New Event Setup](#1-new-event-setup)\n2. [Launch Email Campaign](#2-launch-email-campaign)\n3. [Bounce Recovery via SMS](#3-bounce-recovery-via-sms)\n4. [Weekly Unsubscribe Sync](#4-weekly-unsubscribe-sync)\n5. [Lead Download and Analysis](#5-lead-download-and-analysis)\n6. [Direct Browser Registration (CDP)](#6-direct-browser-registration-cdp)\n\n---\n\n## 1. New Event Setup\n\n### Step 1: Get Event GUID from Renatus\n1. Log into `backoffice.myrenatus.com`\n2. Go to Events → find the event\n3. Copy the event GUID from the URL or API\n\n### Step 2: Update Supabase Edge Function Secret\n```bash\nsupabase secrets set RENATUS_EVENT_ID=\"<new_event_guid>\" --project-ref <PROJECT_REF>\n```\n\n### Step 3: Update Landing Page\n1. Copy `site/commercial/index.html` to new event directory\n2. Update event details (date, time, location, speakers)\n3. Update `EDGE_URL` in the script if using a different Supabase project\n4. Deploy via FTP or `deploy_hostinger.py`\n\n### Step 4: Update Email Template\nCopy `email/commercial-core-day1.html` and update:\n- Event date and time\n- Event name\n- Instructor names\n- Subject line options\n\n### Step 5: Test Registration\nSubmit a test registration and verify:\n- [ ] `funnel_leads` row created in Supabase\n- [ ] Lead appears in Renatus Back Office\n- [ ] Email confirmation received\n\n---\n\n## 2. Launch Email Campaign\n\n### Day 0: Prepare\n```\n1. Update email template with correct event details\n2. Prepare renatus_leads.csv (export from Supabase or existing list)\n3. Verify gws CLI: gws gmail list --account YOUR_SENDER@gmail.com\n4. Send test email to self: python3 scripts/send_commercial_email_batches.py --limit 1 --send\n```\n\n### Day 1: Send First Batch\n```\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n```\n\n### Ongoing: Monitor and Resume\n```\n# After batch 1, check for bounces\npython3 scripts/handle_bounced_emails.py --check\n\n# Send next batch\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 20 --send\n\n# Repeat until complete\n```\n\n### Post-Campaign: Sync Unsubscribes\n```\n# Run after campaign has been live for a few days\nbash scripts/weekly_unsubscribe_sync.sh\n```\n\n---\n\n## 3. Bounce Recovery via SMS\n\nWhen emails bounce, recover by SMS if phone number is available.\n\n### Step 1: Detect Bounces\n```bash\npython3 scripts/handle_bounced_emails.py --check\n```\n\n### Step 2: Export SMS List\n```bash\npython3 scripts/handle_bounced_emails.py --export-sms\n# Output: logs/sms_followup_list.csv\n```\n\n### Step 3: Send SMS\nReview `logs/sms_followup_list.csv` and send SMS manually or via WhatsApp:\n\n```\nHi {name}, your email bounced. Please reply with your updated email to receive info about our free Commercial Real Estate Training on April 16. -Renatus\n```\n\n---\n\n## 4. Weekly Unsubscribe Sync\n\nAutomates removal of unsubscribed leads from Renatus.\n\n### Setup\n```bash\n# Add to crontab\ncrontab -e\n# Add: 0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh\n```\n\n### Manual Run\n```bash\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\n\n### Prerequisites\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Active login session at `backoffice.myrenatus.com`\n\n---\n\n## 5. Lead Download and Analysis\n\n### Export from Supabase\n```bash\n# Set credentials\nexport SUPABASE_URL=\"https://<REF>.supabase.co\"\nexport LEAD_ADMIN_TOKEN=\"<your_token>\"\n\n# Download all leads\npython3 scripts/renatus_leads.py --export\n\n# Or inline\npython3 scripts/renatus_leads.py --ref <REF> --token <TOKEN> --export\n\n# Convert existing JSON to CSV\npython3 scripts/renatus_leads.py --convert-json\n```\n\n### Supabase Admin Export (cURL)\n```bash\nTOKEN=\"...\"\nREF=\"...\"\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq '.rows[] | {name, email, phone: .metadata.phone, sessions: .metadata.registered_sessions}'\n```\n\n### Export from Supabase\n```bash\nTOKEN=\"...\"\nREF=\"...\"\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq '.rows[] | {name, email, phone: .metadata.phone, sessions: .metadata.registered_sessions}'\n```\n\n### Convert to CSV\n```bash\ncurl -s -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq -r '.rows[] | [.name, .email, (.metadata.phone // \"\"), (.metadata.registered_sessions | join(\"; \"))] | @csv' \\\n  > leads.csv\n```\n\n### Registration Rate\n```python\n# Count total vs registered\ntotal_leads = len(leads)\nregistered = sum(1 for l in leads if l.get('metadata', {}).get('lead_id'))\nprint(f\"Registration rate: {registered}/{total_leads} ({100*registered/total_leads:.1f}%)\")\n```\n\n---\n\n## 6. Direct Browser Registration (CDP)\n\nUse `renatus_register_guest.py` for direct registration via a live authenticated browser session. Useful when:\n- The Supabase edge function is down\n- Registering a lead not from the web form\n- Registering for a specific session (not just public-eligible)\n\n### Prerequisites\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Active Renatus session in the browser\n\n### Usage\n```bash\n# Dry run (test registration)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8\n\n# Execute (actually register)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --execute\n\n# Register for all sessions (not just first)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --all-sessions --execute\n\n# Register for specific session(s)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --session-guid <SESSION_GUID_1> \\\n  --session-guid <SESSION_GUID_2> \\\n  --execute\n```\n\n### CDP URL\n```bash\n--cdp-url http://127.0.0.1:9222  # Default\n--cdp-url http://<remote_ip>:9222  # Remote browser\n```\n\n### Output\n- Dry run: shows which sessions would be registered, event details\n- Execute: shows `leadId`, `guestUserId`, `registrationId`, session IDs\n\n---\n\n## Quick Reference: Renatus API Flow\n\nThe edge function and CDP scripts both perform the same API flow:\n\n```\n1. POST /Token                    → get access_token + cookies\n2. GET  /Home/index               → extract __RequestVerificationToken (CSRF)\n3. GET  /api/queryproxy/execute?url=/api/userprofile/current?  → ownerUserId\n4. GET  /api/queryproxy/execute?url=/api/event/getsavedevent?  → event + sessions\n5. POST /api/commandproxy/execute?url=/api/guestRegistration/addcustomer?  → leadId, guestUserId\n6. POST /api/commandproxy/execute?url=/api/registration/fees?  → session costs\n7. POST /api/commandproxy/execute?url=/api/eventRegistration/registerForEvent?  → final registration\n```\n\n### Public-Eligible Sessions\nSessions are \"public-eligible\" if they have NO requirements:\n- `RequireActiveIMA`\n- `RequireXtreamEducation`\n- `RequireNoEducation`\n- `RequireOneStarQualify` / `RequireThreeStarQualify` / `RequireFiveStarQualify`\n- `RequireEssentialEducation` / `RequireProfitEducation` / `RequireAdvancedEducation`\n- `RequireGeniusIn21DaysEducation`\n- `IsLeadOnly` / `IsNonLeadOnly`\n\nIf an event has no public-eligible sessions, contact Renatus to create one.\n\nFile v2.1.5:skill-card.md\n\n## Description:\n\nManage Renatus event marketing campaigns as an ICM, including event registration campaigns, commercial email blasts, event landing pages, Supabase lead exports, unsubscribe syncing, and browser-based guest registration via CDP.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[earlvanze](https://clawhub.ai/user/earlvanze)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nIndependent campaign managers and supporting operators use this skill to set up Renatus event pages, send campaign email, register guests, export leads, and process unsubscribes across Renatus, Supabase, and local campaign assets.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can operate as a privileged campaign-admin tool that handles browser session tokens, Renatus credentials, Supabase tokens, lead exports, and email-sending accounts.\n\nMitigation: Use a dedicated browser profile for CDP, avoid production service-role keys, prefer least-privilege tokens, and rotate credentials after use or exposure.\n\nRisk: Lead deletion, unsubscribe automation, mass email, and guest registration can affect real contacts and compliance obligations.\n\nMitigation: Run dry-run or test flows first, verify consent and unsubscribe handling before sending email, and review campaign logs before broad execution.\n\nRisk: The security summary notes unsafe or incomplete controls around admin exports, scheduled unsubscribe automation, and missing or unaudited Supabase functions.\n\nMitigation: Review or replace the unsubscribe workflow, do not deploy missing or unaudited Supabase functions, and validate admin export controls in a dedicated test project.\n\n## Reference(s):\n\n- [Renatus ICM Workflows](artifact/references/workflows.md)\n- [Email Campaign Guide](artifact/references/email-campaign.md)\n- [Event Page Setup Guide](artifact/references/event-page-setup.md)\n- [Supabase Setup for Renatus ICM](artifact/references/supabase-setup.md)\n- [Renatus Back Office Order Entry API](artifact/references/order-entry-backoffice-api.md)\n- [ClawHub skill release page](https://clawhub.ai/earlvanze/skills/renatus-icm)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, files, guidance]\n\n**Output Format:** [Markdown guidance with shell commands, configuration snippets, generated HTML files, and CSV or JSON lead-export artifacts.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Outputs may depend on privileged browser sessions, Renatus credentials, Supabase tokens, SMTP or gws access, and local campaign configuration.]\n\n## Skill Version(s):\n\n2.1.5 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v2.1.4: 20 files, 65817 bytes\n\nFiles: assets/sample_leads.csv (263b), assets/site/confirmation.html (7458b), assets/site/unsubscribe.html (6910b), references/email-campaign.md (4901b), references/event-page-setup.md (3967b), references/supabase-setup.md (3275b), references/workflows.md (7614b), scripts/add_event.py (11276b), scripts/config_loader.py (7396b), scripts/generate_calendar.py (9141b), scripts/generate_email_template.py (21843b), scripts/generate_event_page.py (26753b), scripts/renatus_delete_lead.py (10067b), scripts/renatus_leads.py (8915b), scripts/renatus_register_guest.py (18183b), scripts/send_commercial_email_batches.py (10803b), scripts/weekly_unsubscribe_sync.sh (8115b), skill-card.md (2818b), SKILL.md (11644b), _meta.json (130b)\n\nFile v2.1.4:SKILL.md\n\n---\nname: renatus-icm\ndescription: Manage Renatus event marketing campaigns as an ICM. Use when running event registration campaigns, sending commercial email blasts, setting up event landing pages, exporting leads from Supabase, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Requires: Renatus credentials, Supabase project, SMTP sender account. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\".\n---\n\n## ⚠️ Credentials & Security\n\n**Required environment variables** (declare these before running any script):\n\n| Variable | Purpose | Minimum Scope |\n|---|---|---|\n| `RENATUS_USERNAME` | Renatus back office login | ICM-level account |\n| `RENATUS_PASSWORD` | Renatus back office login | ICM-level account |\n| `SUPABASE_URL` | Supabase project URL | Read leads |\n| `LEAD_ADMIN_TOKEN` | Supabase admin export | `anon` key or limited service role |\n| `SENDER_EMAIL` | From address for campaigns | Send-only SMTP account |\n| `SENDER_PASSWORD` | SMTP auth for email | Send-only |\n| `SUPABASE_SERVICE_ROLE_KEY` | Supabase admin actions (destructive) | Service role — do not use for read-only ops |\n\n**Security recommendations:**\n- Use a dedicated Supabase project for testing — do not supply your production `service_role_key`\n- Create a least-privilege Supabase anon key scoped to `funnel_leads` table reads only\n- Use a separate Chrome/Brave **profile** for CDP access (not your main browser session)\n- `renatus_delete_lead.py` performs deletions — always run with `--dry-run` first\n- Rotate credentials after use; revoke tokens that were shared or exposed\n- Do not commit real credentials to `config.json` — use the `.example` file and environment variables\n\n**CDP access:** Scripts connect to `http://127.0.0.1:9222` to inspect your browser's localStorage/cookies for Renatus auth tokens. This requires Chrome/Brave launched with `--remote-debugging-port=9222`. The skill does not extract your master Renatus password from CDP — it reads existing session tokens only.\n\n---\nname: renatus-icm\ndescription: Run a Renatus event marketing campaign as an ICM (Independent Campaign Manager). Use when managing Renatus event registrations, sending commercial email campaigns, setting up event landing pages, downloading/exporting leads, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Handles: Supabase Edge Function registration (submit-renatus-registration), gws/gog email sending (commercial-core-day1), bounce detection and SMS recovery, CDP browser registration/delete scripts, weekly unsubscribe cron, and lead export via lead-admin-export. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\", \"handle Renatus unsubscribes\".\n---\n# Renatus ICM Skill\n\nComplete toolkit for running a Renatus event marketing campaign: event page setup, email campaigns, lead management, and unsubscribe sync.\n\n## Workflows Quick Reference\n\nSee [references/workflows.md](references/workflows.md) for detailed step-by-step:\n- **New Event Setup** → [event-page-setup.md](references/event-page-setup.md)\n- **Email Campaign** → [email-campaign.md](references/email-campaign.md)\n- **CDP Registration** → scripts `renatus_register_guest.py`, `renatus_delete_lead.py`\n- **Lead Export** → Supabase lead-admin-export edge function\n- **Unsubscribe Sync** → `weekly_unsubscribe_sync.sh`\n\n## Architecture Overview\n## Generate a New Event Landing Page\n\n```bash\npython3 scripts/generate_event_page.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\n\nRequirements: Chrome/Brave CDP + active Renatus session. The script extracts event name, date(s), location, speakers, and session details from the backoffice page — then renders a complete ready-to-deploy HTML file. Preview before saving with `--dry-run`.\n\n\n\n```\nEvent Landing Page (HTML)\n  ↓ form submit\nSupabase Edge Function: submit-renatus-registration\n  ↓ server-side Renatus API (no CORS)\nRenatus Back Office (lead created + registered)\n  ↓ insert\nSupabase: funnel_leads table\n  ↓\nlead-admin-export edge function ← ICM exports here\n```\n\n**Key URLs:**\n- Landing page: `https://YOUR_REGISTRATION_PAGE/` (example)\n- Supabase edge: `https://<REF>.supabase.co/submit-renatus-registration`\n- Lead export: `https://<REF>.supabase.co/lead-admin-export`\n- Renatus back office: `https://backoffice.myrenatus.com`\n\n## Email Campaign\n\n### Send Batch\n```bash\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n```\nResume from next batch: change `--start N`. Skip already-sent via `--skip-sent` (default on). See [email-campaign.md](references/email-campaign.md) for bounce handling, unsubscribe sync, and template customization.\n\n### Prerequisites\n- `gws` CLI authenticated as sender account\n- `renatus_leads.csv` with `email` column\n- `commercial-core-day1.html` template\n\n## Browser-Based Registration (CDP)\n\nRequires Chrome/Brave with `--remote-debugging-port=9222` and active Renatus session.\n\n### Register Guest (dry run)\n```bash\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(555) 555-5555\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8\n```\n\n### Execute Registration\nAdd `--execute` to perform writes.\n\n### Delete Lead (unsubscribe)\n```bash\npython3 scripts/renatus_delete_lead.py --email jane@example.com --execute\n```\n\n\n### Generate Events Calendar\n```bash\npython3 scripts/generate_calendar.py --output site/calendar.html\npython3 scripts/generate_calendar.py --dry-run\n```\nReads `events[]` from `config.json`, generates a calendar page listing all active events with registration links.\n\n### Add Event (One-Command Setup)\n```bash\npython3 scripts/add_event.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\nScrapes event from Renatus → adds to `config.json` → generates landing page in one step. Requires Chrome/Brave CDP + active Renatus session.\n\n### Download Leads from Supabase\n```bash\npython3 scripts/renatus_leads.py --export\n# Or: SUPABASE_URL=... LEAD_ADMIN_TOKEN=... python3 scripts/renatus_leads.py --export\n```\nExports to `workspace/renatus_leads.csv` + `renatus_leads.json`. Set `SUPABASE_URL` and `LEAD_ADMIN_TOKEN` env vars, or pass `--ref` + `--token` flags. Use `--convert-json` to convert an existing JSON export to CSV format.\n\n## Lead Export\n\n### Supabase Admin Export\n```bash\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://<REF>.supabase.co/functions/v1/lead-admin-export?limit=500\"\n```\n\nToken = `LEAD_ADMIN_TOKEN` secret in Supabase. See [supabase-setup.md](references/supabase-setup.md) for setup.\n\n### Download via Agent\nIf running as an OpenClaw agent:\n```bash\n# From workspace: logs/email_send_log.json tracks sent emails\n# Download leads to: workspace/renatus_leads.csv\n```\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n```bash\ncp config.json.example config.json\n# edit config.json with your Supabase URL, Renatus credentials, sender account, etc.\n```\n\nAlternatively, set `RENATUS_*` environment variables. Scripts check (in order): `config.json` → env vars → defaults.\n\nEnvironment variables: `RENATUS_SUPABASE_REF`, `RENATUS_SUPABASE_URL`, `RENATUS_LEAD_TOKEN`, `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `RENATUS_SENDER`, `RENATUS_PROVIDER`, `RENATUS_TEMPLATE`, `RENATUS_UNSUB_URL`, `RENATUS_SITE_URL`, `RENATUS_REGISTRATION_URL`.\n\n**Important:** `config.json` is gitignored. Your personal config stays private; `config.json.example` is what other ICMs receive.\n\n\n---\n\n## Supabase Setup (New ICM)\n\nSee [supabase-setup.md](references/supabase-setup.md) for full setup:\n1. Link project: `supabase link --project-ref <REF>`\n2. Push migrations: `supabase db push`\n3. Deploy functions: `submit-renatus-registration`, `lead-admin-export`\n4. Set secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `LEAD_ADMIN_TOKEN`\n5. Verify: submit test registration → check `funnel_leads` + Renatus back office\n\n## Supabase Edge Function Reference\n\n### submit-renatus-registration\nPublic POST endpoint. Registers a lead in Renatus via server-side API (bypasses CORS). Auto-detects public-eligible sessions (no IMA/education requirements). Required secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`.\n\n### lead-admin-export\nAdmin GET endpoint. Requires `x-admin-token` header. Params: `?partner=&limit=`.\n\n### capture-lead\nGeneral-purpose public lead intake with Turnstile bot protection. Insert into `funnel_leads`.\n\n## Key Secrets (Supabase)\n\n| Secret | Required | Purpose |\n|---|---|---|\n| `RENATUS_USERNAME` | Registration | Back office login |\n| `RENATUS_PASSWORD` | Registration | Back office password |\n| `RENATUS_EVENT_ID` | Registration | Default event GUID |\n| `LEAD_ADMIN_TOKEN` | Export | Admin export auth |\n| `SUPABASE_URL` | Always | Project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | Always | DB access |\n\n## Unsubscribe Sync (Weekly Cron)\n\n```bash\n# Add to crontab\n0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh\n\n# Manual run\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\nRequirements: Chrome CDP at 9222 + active Renatus session. See [email-campaign.md](references/email-campaign.md).\n\n## Bounce Recovery\n\n```bash\n# Detect bounces\npython3 scripts/handle_bounced_emails.py --check\n\n# Export SMS-ready contacts\npython3 scripts/handle_bounced_emails.py --export-sms\n\n# Manually mark bounce\npython3 scripts/handle_bounced_emails.py --mark-bounced user@example.com\n```\n\n## Authentication: Two Options\n\n### Option A — Browser Relay (Recommended for CDP scripts)\nUse your existing logged-in Brave/Chrome session via Browser Relay (OpenClaw extension).\n\n1. Open Brave → click the **OpenClaw Browser Relay** extension icon on any Renatus tab\n2. Scripts connect to `http://127.0.0.1:9222` via Playwright CDP\n3. No credentials needed in config — reads existing session tokens from localStorage/cookies\n4. Requires the OpenClaw Browser Relay extension with an active tab\n\n**CDP scripts affected:** `renatus_register_guest.py`, `renatus_delete_lead.py`, `generate_event_page.py`, `add_event.py`\n\n### Option B — Env Vars (Recommended for non-CDP scripts)\nSet credentials as environment variables — never in chat or config files.\n\n```bash\nexport RENATUS_USERNAME=\"earlvanze@gmail.com\"\nexport RENATUS_PASSWORD=\"YOUR_PASSWORD\"\nexport RENATUS_EVENT_ID=\"0817966f-b9bb-448e-bbb8-b4160115bcc8\"\nexport LEAD_ADMIN_TOKEN=\"YOUR_SUPABASE_TOKEN\"\n```\n\nOr use a `.env` file loaded by your shell profile. Scripts read from env vars via `config_loader.py`.\n\n**Non-CDP scripts:** `renatus_leads.py`, `send_commercial_email_batches.py`, `generate_calendar.py`, `generate_email_template.py`\n\n### Security Rules\n- **Never paste credentials in chat** — use env vars or `.env` files\n- **Bitwarden CLI** (`bw`) for programmatic credential access: `bw get password \"Renatus\"`\n- CDP reads do not extract your master password — only existing session tokens\n- Config file (`config.json`) should use `[REDACTED — see Nextcloud/secrets]` for credential placeholders\n- Rotate credentials after any shared exposure\n\nFile v2.1.4:_meta.json\n\n{\n  \"ownerId\": \"kn7a5vdq619nymw8zq4aq95b49846rhq\",\n  \"slug\": \"renatus-icm\",\n  \"version\": \"2.1.4\",\n  \"publishedAt\": 1775328194351\n}\n\nFile v2.1.4:references/email-campaign.md\n\n# Email Campaign Guide\n\n## Overview\n\nCommercial email campaigns are sent from `YOUR_SENDER@gmail.com` via gws CLI. The email template is `commercial-core-day1.html`. Campaigns target leads from `renatus_leads.csv` and track delivery via `logs/email_send_log.json`.\n\n## Campaign Assets\n\n| File | Purpose |\n|---|---|\n| `email/commercial-core-day1.html` | HTML email template |\n| `renatus_leads.csv` | Lead list (export via `renatus_leads.py --export`) |\n| `logs/email_send_log.json` | Sent log (resumable sends) |\n| `logs/bounced_emails.json` | Bounced email tracking |\n\n### Getting the Leads CSV\n```bash\n# Export fresh from Supabase\npython3 scripts/renatus_leads.py --export\n\n# Convert existing JSON to CSV (if you have old JSON export)\npython3 scripts/renatus_leads.py --convert-json\n```\n\n## Sending Emails\n\n### Prerequisites\n- `gws` CLI authenticated as `YOUR_SENDER@gmail.com`\n- `renatus_leads.csv` exists with at least `email` column\n- `commercial-core-day1.html` template\n\n### Dry Run (Preview)\n```bash\npython3 scripts/send_commercial_email_batches.py --dry-run\n```\n\n### Send in Batches (with Resume)\n```bash\n# First batch\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n\n# Resume from batch 2\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 20 --send\n\n# Resume from batch 3\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 40 --send\n```\n\n### Batch Script Flags\n| Flag | Default | Description |\n|---|---|---|\n| `--batch-size` | 20 | Emails per batch |\n| `--start` | 0 | Starting index |\n| `--dry-run` | — | Preview without sending |\n| `--send` | — | Actually send |\n| `--delay` | 2.0 | Seconds between sends |\n\n## Personalizing the Template\n\nThe template uses `{{recipient_email}}` as a placeholder for the unsubscribe link target.\n\n### Adding Personalized Unsubscribe URL\nReplace `{{recipient_email}}` with a base64-encoded unsubscribe URL:\n\n```python\nimport base64\n\ndef encode_unsubscribe_url(email: str, base_url: str = \"https://YOUR_DOMAIN/unsubscribe.html\") -> str:\n    encoded = base64.urlsafe_b64encode(email.encode()).decode().rstrip('=')\n    return f\"{base_url}?e={encoded}\"\n```\n\n### Unsubscribe URL in Email Template\n```html\n<a href=\"https://YOUR_DOMAIN/unsubscribe.html?e={{recipient_email}}\"\n   style=\"color: #999999; font-size: 12px;\">\n  Unsubscribe\n</a>\n```\n\nWhen the user clicks unsubscribe, their email is pre-filled and they confirm removal.\n\n## Subject Line Options\n\nTested subject lines for Commercial Core:\n1. `They turned $7K into $103M. Learn how (April 16)`\n2. `Commercial real estate: free training from $100M operators`\n3. `[Only 9 days] Learn commercial underwriting from operators`\n4. `From skeptical to 90+ doors in 8 months (free training)`\n\n## Bounce Handling\n\n### Check for Bounces\n```bash\npython3 scripts/handle_bounced_emails.py --check\n```\n\n### Export Bounced Contacts with Phone Numbers for SMS\n```bash\npython3 scripts/handle_bounced_emails.py --export-sms\n# Output: logs/sms_followup_list.csv\n```\n\n### Manually Mark an Email as Bounced\n```bash\npython3 scripts/handle_bounced_emails.py --mark-bounced user@example.com\n```\n\n## Unsubscribe Sync (Weekly Automation)\n\nThe `weekly_unsubscribe_sync.sh` script syncs unsubscribes from the web form to Renatus.\n\n### Setup Cron Job\n```bash\n# Run every Sunday at 2 AM\n0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh >> /home/umbrel/.openclaw/workspace/logs/unsubscribe_cron.log 2>&1\n```\n\n### Manual Run\n```bash\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\n\n### Requirements\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Logged into `backoffice.myrenatus.com`\n- Unsubscribes stored in `data/unsubscribes_<timestamp>.txt`\n\n## Deleting Leads from Renatus\n\n### Single Lead (Dry Run)\n```bash\npython3 scripts/renatus_delete_lead.py --email user@example.com\n```\n\n### Single Lead (Execute)\n```bash\npython3 scripts/renatus_delete_lead.py --email user@example.com --execute\n```\n\n### Bulk Delete from File\n```bash\npython3 scripts/renatus_delete_lead.py --file unsubscribes.txt --execute\n```\n\n### Process Unsubscribe File\n```bash\npython3 scripts/process_unsubscribes.py --file unsubscribes.txt --execute\n```\n\n## Lead Download (Supabase Admin Export)\n\n```bash\nTOKEN=\"your_lead_admin_token\"\nREF=\"your_project_ref\"\n\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" | \\\n  jq '.rows[] | {name, email, phone: .metadata.phone}' > leads_export.csv\n```\n\n## CSV Format (renatus_leads.csv)\n\nExpected columns:\n- `email` (required) — recipient address\n- `name` (optional) — full name or first name\n- `phone` (optional) — for SMS bounce recovery\n- `dateCreated` (optional) — lead creation date\n\nExample:\n```csv\nemail,name,phone,dateCreated\njane@example.com,Jane Smith,5185551212,2026-03-01\njohn@example.com,John Doe,,2026-03-02\n```\n\nFile v2.1.4:references/event-page-setup.md\n\n# Event Page Setup Guide\n\n## Overview\n\nThe event landing page is a static HTML form at `site/commercial/index.html` (or similar path on your hostinger/YOUR_DOMAIN deployment). It submits directly to a Supabase Edge Function which registers the lead in Renatus Back Office.\n\n## Page Structure\n\n### Registration Form Fields\n- `firstName` (required)\n- `lastName` (required)\n- `email` (required)\n- `phone` (required)\n- `website` (honeypot — hidden, must be empty)\n- `source_page` (auto-populated from `window.location.href`)\n\n### Submit Endpoint\n```\nPOST https://<PROJECT_REF>.supabase.co/submit-renatus-registration\n```\n\n### Request Body\n```json\n{\n  \"firstName\": \"Jane\",\n  \"lastName\": \"Smith\",\n  \"email\": \"jane@example.com\",\n  \"phone\": \"(555) 555-5555\",\n  \"website\": \"\",\n  \"source_page\": \"https://YOUR_DOMAIN/commercial/\"\n}\n```\n\n### Success Response\n```json\n{\n  \"ok\": true,\n  \"eventId\": \"0817966f-b9bb-448e-bbb8-b4160115bcc8\",\n  \"eventName\": \"Commercial Core - Live Education\",\n  \"registrationId\": \"...\",\n  \"leadId\": \"...\",\n  \"guestUserId\": \"...\",\n  \"registeredSessions\": [\"Session Name 1\", \"Session Name 2\"]\n}\n```\n\n### Error Response\n```json\n{ \"error\": \"Error message\", \"details\": \"optional details\" }\n```\n\n## Setting Up a New Event Page\n\n### 1. Copy the Template\nCopy `site/commercial/index.html` to a new directory, e.g., `site/<event-slug>/index.html`\n\n### 2. Update the Edge Function URL\nIn the `<script>` section, update:\n```javascript\nconst EDGE_URL = 'https://<PROJECT_REF>.supabase.co/submit-renatus-registration';\n```\n\n### 3. Update Event Details\nUpdate the visible event details in the HTML (date, location, speakers, description).\n\n### 4. Update the Event ID\nEither:\n- Set `RENATUS_EVENT_ID` secret in Supabase (affects all form submissions)\n- Add `eventId` field to the form and pass it in the payload\n\n### 5. Get the Event GUID from Renatus\n1. Log into `backoffice.myrenatus.com`\n2. Navigate to Events\n3. Open the event\n4. Copy the event GUID from the URL or API response\n\n### 6. Verify Registration Flow\nSubmit a test registration and confirm:\n- Lead appears in `funnel_leads` table\n- Lead appears in Renatus Back Office\n- Email confirmation is sent by Renatus\n\n## Customizing the Landing Page\n\n### Styling\nThe page uses CSS custom properties for easy theming:\n```css\n:root {\n  --bg: #0f172a;\n  --card: #111827;\n  --accent: #22c55e;\n  --text: #e5e7eb;\n}\n```\n\n### Adding a Second Event (In-Person Option)\nModify the `feesPayload` to include multiple sessions, or use separate event pages with different event IDs.\n\n### Redirect to Confirmation Page\nAfter successful form submission:\n```javascript\nif (resp.ok) {\n  window.location.href = '/confirmation.html';\n}\n```\n\n## Hosting Options\n\n### Option A: Deploy with your hosting scripts\n```bash\npython3 scripts/deploy_hostinger.py\n```\n\n### Option B: Manual FTP Upload\nUpload `site/commercial/` directory to your web host's `public_html/` or equivalent.\n\n### Option C: Subdirectory on Existing Site\nUpload to `public_html/commercial/` — page will be at `https://yourdomain.com/commercial/`\n\n## Confirmation Page\nAfter successful registration, redirect users to a confirmation page. The confirmation page shows event details and next steps. See `site/confirmation.html` for the template.\n\n## Troubleshooting\n\n### \"Registration could not be completed\"\n- Check browser console for specific error\n- Verify Supabase Edge Function URL is correct\n- Check Supabase function logs in the dashboard\n\n### Lead not appearing in Renatus\n- Verify `RENATUS_USERNAME` and `RENATUS_PASSWORD` secrets are set\n- Check function logs for authentication errors (401 = bad credentials)\n- Confirm event GUID is valid and event is published in Renatus\n\n### Public sessions not found\n- Event may only have education-gated sessions\n- Check `isPublicEligibleSession` in the edge function — sessions requiring IMA, Xtream Education, or other credentials are excluded\n- Contact Renatus to create a public-eligible session for the event\n\nFile v2.1.4:references/supabase-setup.md\n\n# Supabase Setup for Renatus ICM\n\n## Overview\n\nSupabase project: `YOUR_PROJECT_NAME` (EU-West-1 — or any region)\n\nStores lead registrations from the public event landing page and exposes an admin export endpoint for ICMs to download leads.\n\n## 1. Link and Push Migrations\n\n```bash\ncd supabase\nsupabase link --project-ref <PROJECT_REF>\nsupabase db push --include-all\n```\n\n## 2. Deploy Edge Functions\n\n```bash\nsupabase functions deploy submit-renatus-registration --project-ref <PROJECT_REF>\nsupabase functions deploy lead-admin-export --project-ref <PROJECT_REF>\nsupabase functions deploy capture-lead --project-ref <PROJECT_REF>\nsupabase functions deploy stripe-webhook --project-ref <PROJECT_REF>\n```\n\n## 3. Set Required Secrets\n\n```bash\nsupabase secrets set \\\n  RENATUS_USERNAME=\"<renatus_backoffice_email>\" \\\n  RENATUS_PASSWORD=\"<renatus_backoffice_password>\" \\\n  RENATUS_EVENT_ID=\"<default_event_guid>\" \\\n  SUPABASE_URL=\"https://<PROJECT_REF>.supabase.co\" \\\n  SUPABASE_SERVICE_ROLE_KEY=\"<service_role_key>\" \\\n  LEAD_ADMIN_TOKEN=\"<secure_random_token_for_admin_export>\" \\\n  --project-ref <PROJECT_REF>\n```\n\n## 4. Key Tables\n\n### funnel_leads\n```sql\ncreate table if not exists public.funnel_leads (\n  id uuid primary key default gen_random_uuid(),\n  created_at timestamptz not null default now(),\n  source_page text,\n  name text,\n  email text,\n  company text,\n  notes text,\n  cta_type text,\n  metadata jsonb not null default '{}'::jsonb\n);\n```\n\n### funnel_leads metadata field\nContains: `event_id`, `registration_id`, `lead_id`, `guest_user_id`, `registered_sessions`, `phone`\n\n## 5. Key Edge Functions\n\n### submit-renatus-registration\n- **URL:** `https://<PROJECT_REF>.functions.supabase.co/submit-renatus-registration`\n- **Method:** POST\n- **Auth:** Public (honeypot + Turnstile bot protection)\n- **Session eligibility:** Auto-detects public-eligible sessions (no IMA/education requirements)\n- **Response:** `{ ok, eventId, eventName, registrationId, leadId, guestUserId, registeredSessions }`\n\n### lead-admin-export\n- **URL:** `https://<PROJECT_REF>.functions.supabase.co/lead-admin-export`\n- **Method:** GET\n- **Auth:** `x-admin-token: <LEAD_ADMIN_TOKEN>` header\n- **Params:** `?partner=<optional_partner_slug>&limit=<1-500>`\n- **Response:** `{ ok, count, rows: [...] }`\n\n## 6. Configure Stripe Webhook (Optional)\n\nEndpoint: `https://<PROJECT_REF>.functions.supabase.co/stripe-webhook`\nListen for: `checkout.session.completed`\n\n## 7. Verify End-to-End\n\n1. Submit lead form at `/commercial/index.html`\n2. Confirm row in `funnel_leads`\n3. Verify lead in Renatus Back Office\n4. Export: `curl -H \"x-admin-token: $TOKEN\" \"https://<REF>.functions.supabase.co/lead-admin-export?limit=10\"`\n\n## Required Secrets Reference\n\n| Variable | Required | Description |\n|---|---|---|\n| `RENATUS_USERNAME` | Yes | Renatus back office email |\n| `RENATUS_PASSWORD` | Yes | Renatus back office password |\n| `RENATUS_EVENT_ID` | No | Default event GUID |\n| `SUPABASE_URL` | Yes | Project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | Yes | Service role key |\n| `LEAD_ADMIN_TOKEN` | Yes (export) | Admin export bearer token |\n| `STRIPE_SECRET_KEY` | Payments | Stripe secret key |\n| `STRIPE_WEBHOOK_SECRET` | Payments | Stripe webhook secret |\n| `TURNSTILE_SECRET_KEY` | No | Cloudflare Turnstile |\n\nFile v2.1.4:references/workflows.md\n\n# Renatus ICM Workflows\n\n## Table of Contents\n1. [New Event Setup](#1-new-event-setup)\n2. [Launch Email Campaign](#2-launch-email-campaign)\n3. [Bounce Recovery via SMS](#3-bounce-recovery-via-sms)\n4. [Weekly Unsubscribe Sync](#4-weekly-unsubscribe-sync)\n5. [Lead Download and Analysis](#5-lead-download-and-analysis)\n6. [Direct Browser Registration (CDP)](#6-direct-browser-registration-cdp)\n\n---\n\n## 1. New Event Setup\n\n### Step 1: Get Event GUID from Renatus\n1. Log into `backoffice.myrenatus.com`\n2. Go to Events → find the event\n3. Copy the event GUID from the URL or API\n\n### Step 2: Update Supabase Edge Function Secret\n```bash\nsupabase secrets set RENATUS_EVENT_ID=\"<new_event_guid>\" --project-ref <PROJECT_REF>\n```\n\n### Step 3: Update Landing Page\n1. Copy `site/commercial/index.html` to new event directory\n2. Update event details (date, time, location, speakers)\n3. Update `EDGE_URL` in the script if using a different Supabase project\n4. Deploy via FTP or `deploy_hostinger.py`\n\n### Step 4: Update Email Template\nCopy `email/commercial-core-day1.html` and update:\n- Event date and time\n- Event name\n- Instructor names\n- Subject line options\n\n### Step 5: Test Registration\nSubmit a test registration and verify:\n- [ ] `funnel_leads` row created in Supabase\n- [ ] Lead appears in Renatus Back Office\n- [ ] Email confirmation received\n\n---\n\n## 2. Launch Email Campaign\n\n### Day 0: Prepare\n```\n1. Update email template with correct event details\n2. Prepare renatus_leads.csv (export from Supabase or existing list)\n3. Verify gws CLI: gws gmail list --account YOUR_SENDER@gmail.com\n4. Send test email to self: python3 scripts/send_commercial_email_batches.py --limit 1 --send\n```\n\n### Day 1: Send First Batch\n```\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n```\n\n### Ongoing: Monitor and Resume\n```\n# After batch 1, check for bounces\npython3 scripts/handle_bounced_emails.py --check\n\n# Send next batch\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 20 --send\n\n# Repeat until complete\n```\n\n### Post-Campaign: Sync Unsubscribes\n```\n# Run after campaign has been live for a few days\nbash scripts/weekly_unsubscribe_sync.sh\n```\n\n---\n\n## 3. Bounce Recovery via SMS\n\nWhen emails bounce, recover by SMS if phone number is available.\n\n### Step 1: Detect Bounces\n```bash\npython3 scripts/handle_bounced_emails.py --check\n```\n\n### Step 2: Export SMS List\n```bash\npython3 scripts/handle_bounced_emails.py --export-sms\n# Output: logs/sms_followup_list.csv\n```\n\n### Step 3: Send SMS\nReview `logs/sms_followup_list.csv` and send SMS manually or via WhatsApp:\n\n```\nHi {name}, your email bounced. Please reply with your updated email to receive info about our free Commercial Real Estate Training on April 16. -Renatus\n```\n\n---\n\n## 4. Weekly Unsubscribe Sync\n\nAutomates removal of unsubscribed leads from Renatus.\n\n### Setup\n```bash\n# Add to crontab\ncrontab -e\n# Add: 0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh\n```\n\n### Manual Run\n```bash\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\n\n### Prerequisites\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Active login session at `backoffice.myrenatus.com`\n\n---\n\n## 5. Lead Download and Analysis\n\n### Export from Supabase\n```bash\n# Set credentials\nexport SUPABASE_URL=\"https://<REF>.supabase.co\"\nexport LEAD_ADMIN_TOKEN=\"<your_token>\"\n\n# Download all leads\npython3 scripts/renatus_leads.py --export\n\n# Or inline\npython3 scripts/renatus_leads.py --ref <REF> --token <TOKEN> --export\n\n# Convert existing JSON to CSV\npython3 scripts/renatus_leads.py --convert-json\n```\n\n### Supabase Admin Export (cURL)\n```bash\nTOKEN=\"...\"\nREF=\"...\"\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq '.rows[] | {name, email, phone: .metadata.phone, sessions: .metadata.registered_sessions}'\n```\n\n### Export from Supabase\n```bash\nTOKEN=\"...\"\nREF=\"...\"\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq '.rows[] | {name, email, phone: .metadata.phone, sessions: .metadata.registered_sessions}'\n```\n\n### Convert to CSV\n```bash\ncurl -s -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq -r '.rows[] | [.name, .email, (.metadata.phone // \"\"), (.metadata.registered_sessions | join(\"; \"))] | @csv' \\\n  > leads.csv\n```\n\n### Registration Rate\n```python\n# Count total vs registered\ntotal_leads = len(leads)\nregistered = sum(1 for l in leads if l.get('metadata', {}).get('lead_id'))\nprint(f\"Registration rate: {registered}/{total_leads} ({100*registered/total_leads:.1f}%)\")\n```\n\n---\n\n## 6. Direct Browser Registration (CDP)\n\nUse `renatus_register_guest.py` for direct registration via a live authenticated browser session. Useful when:\n- The Supabase edge function is down\n- Registering a lead not from the web form\n- Registering for a specific session (not just public-eligible)\n\n### Prerequisites\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Active Renatus session in the browser\n\n### Usage\n```bash\n# Dry run (test registration)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8\n\n# Execute (actually register)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --execute\n\n# Register for all sessions (not just first)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --all-sessions --execute\n\n# Register for specific session(s)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --session-guid <SESSION_GUID_1> \\\n  --session-guid <SESSION_GUID_2> \\\n  --execute\n```\n\n### CDP URL\n```bash\n--cdp-url http://127.0.0.1:9222  # Default\n--cdp-url http://<remote_ip>:9222  # Remote browser\n```\n\n### Output\n- Dry run: shows which sessions would be registered, event details\n- Execute: shows `leadId`, `guestUserId`, `registrationId`, session IDs\n\n---\n\n## Quick Reference: Renatus API Flow\n\nThe edge function and CDP scripts both perform the same API flow:\n\n```\n1. POST /Token                    → get access_token + cookies\n2. GET  /Home/index               → extract __RequestVerificationToken (CSRF)\n3. GET  /api/queryproxy/execute?url=/api/userprofile/current?  → ownerUserId\n4. GET  /api/queryproxy/execute?url=/api/event/getsavedevent?  → event + sessions\n5. POST /api/commandproxy/execute?url=/api/guestRegistration/addcustomer?  → leadId, guestUserId\n6. POST /api/commandproxy/execute?url=/api/registration/fees?  → session costs\n7. POST /api/commandproxy/execute?url=/api/eventRegistration/registerForEvent?  → final registration\n```\n\n### Public-Eligible Sessions\nSessions are \"public-eligible\" if they have NO requirements:\n- `RequireActiveIMA`\n- `RequireXtreamEducation`\n- `RequireNoEducation`\n- `RequireOneStarQualify` / `RequireThreeStarQualify` / `RequireFiveStarQualify`\n- `RequireEssentialEducation` / `RequireProfitEducation` / `RequireAdvancedEducation`\n- `RequireGeniusIn21DaysEducation`\n- `IsLeadOnly` / `IsNonLeadOnly`\n\nIf an event has no public-eligible sessions, contact Renatus to create one.\n\nFile v2.1.4:skill-card.md\n\n## Description: <br>\nManage Renatus event marketing campaigns as an ICM, including event registration campaigns, commercial email blasts, event landing pages, Supabase lead exports, unsubscribe sync, and browser-based guest registration via CDP. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[earlvanze](https://clawhub.ai/user/earlvanze) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal Renatus ICM users and campaign operators use this skill to set up event pages, send commercial email campaigns, register guests, export lead data, and sync unsubscribes across Renatus and Supabase workflows. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can reuse live browser sessions through CDP. <br>\nMitigation: Use a dedicated low-privilege browser profile and do not expose a main browser profile over CDP. <br>\nRisk: The skill can export and store lead data and campaign logs. <br>\nMitigation: Keep lead exports and logs private, use least-privilege Renatus and Supabase credentials, and avoid production service-role keys unless strictly necessary. <br>\nRisk: The skill can send bulk commercial email and delete records. <br>\nMitigation: Run dry runs before sending or deleting, review batch inputs before execution, and keep destructive actions gated by explicit execution flags. <br>\nRisk: The unsubscribe cron workflow can remove records on a schedule. <br>\nMitigation: Do not enable the cron workflow until the backend unsubscribe flow and deletion safeguards are verified. <br>\n\n\n## Reference(s): <br>\n- [ClawHub Skill Page](https://clawhub.ai/earlvanze/renatus-icm) <br>\n- [Renatus ICM Workflows](references/workflows.md) <br>\n- [Email Campaign Guide](references/email-campaign.md) <br>\n- [Event Page Setup Guide](references/event-page-setup.md) <br>\n- [Supabase Setup for Renatus ICM](references/supabase-setup.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Guidance, Markdown, Shell commands, Code, Configuration, Files] <br>\n**Output Format:** [Markdown guidance with shell commands, configuration steps, generated HTML/email assets, CSV/JSON lead exports, and operational scripts] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Can send bulk email, access browser session tokens through local CDP, export lead data, and delete records when execution flags and credentials are supplied.] <br>\n\n## Skill Version(s): <br>\n2.1.4 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v2.1.3: 19 files, 63744 bytes\n\nFiles: assets/sample_leads.csv (263b), assets/site/confirmation.html (7458b), assets/site/unsubscribe.html (6910b), references/email-campaign.md (4901b), references/event-page-setup.md (3967b), references/supabase-setup.md (3275b), references/workflows.md (7614b), scripts/add_event.py (11276b), scripts/config_loader.py (7044b), scripts/generate_calendar.py (8914b), scripts/generate_email_template.py (21843b), scripts/generate_event_page.py (26753b), scripts/renatus_delete_lead.py (10067b), scripts/renatus_leads.py (8915b), scripts/renatus_register_guest.py (18183b), scripts/send_commercial_email_batches.py (10803b), scripts/weekly_unsubscribe_sync.sh (8115b), SKILL.md (10024b), _meta.json (130b)\n\nFile v2.1.3:SKILL.md\n\n---\nname: renatus-icm\ndescription: Manage Renatus event marketing campaigns as an ICM. Use when running event registration campaigns, sending commercial email blasts, setting up event landing pages, exporting leads from Supabase, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Requires: Renatus credentials, Supabase project, SMTP sender account. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\".\n---\n\n## ⚠️ Credentials & Security\n\n**Required environment variables** (declare these before running any script):\n\n| Variable | Purpose | Minimum Scope |\n|---|---|---|\n| `RENATUS_USERNAME` | Renatus back office login | ICM-level account |\n| `RENATUS_PASSWORD` | Renatus back office login | ICM-level account |\n| `SUPABASE_URL` | Supabase project URL | Read leads |\n| `LEAD_ADMIN_TOKEN` | Supabase admin export | `anon` key or limited service role |\n| `SENDER_EMAIL` | From address for campaigns | Send-only SMTP account |\n| `SENDER_PASSWORD` | SMTP auth for email | Send-only |\n| `SUPABASE_SERVICE_ROLE_KEY` | Supabase admin actions (destructive) | Service role — do not use for read-only ops |\n\n**Security recommendations:**\n- Use a dedicated Supabase project for testing — do not supply your production `service_role_key`\n- Create a least-privilege Supabase anon key scoped to `funnel_leads` table reads only\n- Use a separate Chrome/Brave **profile** for CDP access (not your main browser session)\n- `renatus_delete_lead.py` performs deletions — always run with `--dry-run` first\n- Rotate credentials after use; revoke tokens that were shared or exposed\n- Do not commit real credentials to `config.json` — use the `.example` file and environment variables\n\n**CDP access:** Scripts connect to `http://127.0.0.1:9222` to inspect your browser's localStorage/cookies for Renatus auth tokens. This requires Chrome/Brave launched with `--remote-debugging-port=9222`. The skill does not extract your master Renatus password from CDP — it reads existing session tokens only.\n\n---\nname: renatus-icm\ndescription: Run a Renatus event marketing campaign as an ICM (Independent Campaign Manager). Use when managing Renatus event registrations, sending commercial email campaigns, setting up event landing pages, downloading/exporting leads, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Handles: Supabase Edge Function registration (submit-renatus-registration), gws/gog email sending (commercial-core-day1), bounce detection and SMS recovery, CDP browser registration/delete scripts, weekly unsubscribe cron, and lead export via lead-admin-export. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\", \"handle Renatus unsubscribes\".\n---\n\n# Renatus ICM Skill\n\nComplete toolkit for running a Renatus event marketing campaign: event page setup, email campaigns, lead management, and unsubscribe sync.\n\n## Workflows Quick Reference\n\nSee [references/workflows.md](references/workflows.md) for detailed step-by-step:\n- **New Event Setup** → [event-page-setup.md](references/event-page-setup.md)\n- **Email Campaign** → [email-campaign.md](references/email-campaign.md)\n- **CDP Registration** → scripts `renatus_register_guest.py`, `renatus_delete_lead.py`\n- **Lead Export** → Supabase lead-admin-export edge function\n- **Unsubscribe Sync** → `weekly_unsubscribe_sync.sh`\n\n## Architecture Overview\n## Generate a New Event Landing Page\n\n```bash\npython3 scripts/generate_event_page.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\n\nRequirements: Chrome/Brave CDP + active Renatus session. The script extracts event name, date(s), location, speakers, and session details from the backoffice page — then renders a complete ready-to-deploy HTML file. Preview before saving with `--dry-run`.\n\n\n\n```\nEvent Landing Page (HTML)\n  ↓ form submit\nSupabase Edge Function: submit-renatus-registration\n  ↓ server-side Renatus API (no CORS)\nRenatus Back Office (lead created + registered)\n  ↓ insert\nSupabase: funnel_leads table\n  ↓\nlead-admin-export edge function ← ICM exports here\n```\n\n**Key URLs:**\n- Landing page: `https://YOUR_REGISTRATION_PAGE/` (example)\n- Supabase edge: `https://<REF>.supabase.co/submit-renatus-registration`\n- Lead export: `https://<REF>.supabase.co/lead-admin-export`\n- Renatus back office: `https://backoffice.myrenatus.com`\n\n## Email Campaign\n\n### Send Batch\n```bash\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n```\nResume from next batch: change `--start N`. Skip already-sent via `--skip-sent` (default on). See [email-campaign.md](references/email-campaign.md) for bounce handling, unsubscribe sync, and template customization.\n\n### Prerequisites\n- `gws` CLI authenticated as sender account\n- `renatus_leads.csv` with `email` column\n- `commercial-core-day1.html` template\n\n## Browser-Based Registration (CDP)\n\nRequires Chrome/Brave with `--remote-debugging-port=9222` and active Renatus session.\n\n### Register Guest (dry run)\n```bash\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(555) 555-5555\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8\n```\n\n### Execute Registration\nAdd `--execute` to perform writes.\n\n### Delete Lead (unsubscribe)\n```bash\npython3 scripts/renatus_delete_lead.py --email jane@example.com --execute\n```\n\n\n### Generate Events Calendar\n```bash\npython3 scripts/generate_calendar.py --output site/calendar.html\npython3 scripts/generate_calendar.py --dry-run\n```\nReads `events[]` from `config.json`, generates a calendar page listing all active events with registration links.\n\n### Add Event (One-Command Setup)\n```bash\npython3 scripts/add_event.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\nScrapes event from Renatus → adds to `config.json` → generates landing page in one step. Requires Chrome/Brave CDP + active Renatus session.\n\n### Download Leads from Supabase\n```bash\npython3 scripts/renatus_leads.py --export\n# Or: SUPABASE_URL=... LEAD_ADMIN_TOKEN=... python3 scripts/renatus_leads.py --export\n```\nExports to `workspace/renatus_leads.csv` + `renatus_leads.json`. Set `SUPABASE_URL` and `LEAD_ADMIN_TOKEN` env vars, or pass `--ref` + `--token` flags. Use `--convert-json` to convert an existing JSON export to CSV format.\n\n## Lead Export\n\n### Supabase Admin Export\n```bash\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://<REF>.supabase.co/functions/v1/lead-admin-export?limit=500\"\n```\n\nToken = `LEAD_ADMIN_TOKEN` secret in Supabase. See [supabase-setup.md](references/supabase-setup.md) for setup.\n\n### Download via Agent\nIf running as an OpenClaw agent:\n```bash\n# From workspace: logs/email_send_log.json tracks sent emails\n# Download leads to: workspace/renatus_leads.csv\n```\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n```bash\ncp config.json.example config.json\n# edit config.json with your Supabase URL, Renatus credentials, sender account, etc.\n```\n\nAlternatively, set `RENATUS_*` environment variables. Scripts check (in order): `config.json` → env vars → defaults.\n\nEnvironment variables: `RENATUS_SUPABASE_REF`, `RENATUS_SUPABASE_URL`, `RENATUS_LEAD_TOKEN`, `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `RENATUS_SENDER`, `RENATUS_PROVIDER`, `RENATUS_TEMPLATE`, `RENATUS_UNSUB_URL`, `RENATUS_SITE_URL`, `RENATUS_REGISTRATION_URL`.\n\n**Important:** `config.json` is gitignored. Your personal config stays private; `config.json.example` is what other ICMs receive.\n\n\n---\n\n## Supabase Setup (New ICM)\n\nSee [supabase-setup.md](references/supabase-setup.md) for full setup:\n1. Link project: `supabase link --project-ref <REF>`\n2. Push migrations: `supabase db push`\n3. Deploy functions: `submit-renatus-registration`, `lead-admin-export`\n4. Set secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `LEAD_ADMIN_TOKEN`\n5. Verify: submit test registration → check `funnel_leads` + Renatus back office\n\n## Supabase Edge Function Reference\n\n### submit-renatus-registration\nPublic POST endpoint. Registers a lead in Renatus via server-side API (bypasses CORS). Auto-detects public-eligible sessions (no IMA/education requirements). Required secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`.\n\n### lead-admin-export\nAdmin GET endpoint. Requires `x-admin-token` header. Params: `?partner=&limit=`.\n\n### capture-lead\nGeneral-purpose public lead intake with Turnstile bot protection. Insert into `funnel_leads`.\n\n## Key Secrets (Supabase)\n\n| Secret | Required | Purpose |\n|---|---|---|\n| `RENATUS_USERNAME` | Registration | Back office login |\n| `RENATUS_PASSWORD` | Registration | Back office password |\n| `RENATUS_EVENT_ID` | Registration | Default event GUID |\n| `LEAD_ADMIN_TOKEN` | Export | Admin export auth |\n| `SUPABASE_URL` | Always | Project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | Always | DB access |\n\n## Unsubscribe Sync (Weekly Cron)\n\n```bash\n# Add to crontab\n0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh\n\n# Manual run\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\nRequirements: Chrome CDP at 9222 + active Renatus session. See [email-campaign.md](references/email-campaign.md).\n\n## Bounce Recovery\n\n```bash\n# Detect bounces\npython3 scripts/handle_bounced_emails.py --check\n\n# Export SMS-ready contacts\npython3 scripts/handle_bounced_emails.py --export-sms\n\n# Manually mark bounce\npython3 scripts/handle_bounced_emails.py --mark-bounced user@example.com\n```\n\nFile v2.1.3:_meta.json\n\n{\n  \"ownerId\": \"kn7a5vdq619nymw8zq4aq95b49846rhq\",\n  \"slug\": \"renatus-icm\",\n  \"version\": \"2.1.3\",\n  \"publishedAt\": 1775313480001\n}\n\nFile v2.1.3:references/email-campaign.md\n\n# Email Campaign Guide\n\n## Overview\n\nCommercial email campaigns are sent from `YOUR_SENDER@gmail.com` via gws CLI. The email template is `commercial-core-day1.html`. Campaigns target leads from `renatus_leads.csv` and track delivery via `logs/email_send_log.json`.\n\n## Campaign Assets\n\n| File | Purpose |\n|---|---|\n| `email/commercial-core-day1.html` | HTML email template |\n| `renatus_leads.csv` | Lead list (export via `renatus_leads.py --export`) |\n| `logs/email_send_log.json` | Sent log (resumable sends) |\n| `logs/bounced_emails.json` | Bounced email tracking |\n\n### Getting the Leads CSV\n```bash\n# Export fresh from Supabase\npython3 scripts/renatus_leads.py --export\n\n# Convert existing JSON to CSV (if you have old JSON export)\npython3 scripts/renatus_leads.py --convert-json\n```\n\n## Sending Emails\n\n### Prerequisites\n- `gws` CLI authenticated as `YOUR_SENDER@gmail.com`\n- `renatus_leads.csv` exists with at least `email` column\n- `commercial-core-day1.html` template\n\n### Dry Run (Preview)\n```bash\npython3 scripts/send_commercial_email_batches.py --dry-run\n```\n\n### Send in Batches (with Resume)\n```bash\n# First batch\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n\n# Resume from batch 2\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 20 --send\n\n# Resume from batch 3\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 40 --send\n```\n\n### Batch Script Flags\n| Flag | Default | Description |\n|---|---|---|\n| `--batch-size` | 20 | Emails per batch |\n| `--start` | 0 | Starting index |\n| `--dry-run` | — | Preview without sending |\n| `--send` | — | Actually send |\n| `--delay` | 2.0 | Seconds between sends |\n\n## Personalizing the Template\n\nThe template uses `{{recipient_email}}` as a placeholder for the unsubscribe link target.\n\n### Adding Personalized Unsubscribe URL\nReplace `{{recipient_email}}` with a base64-encoded unsubscribe URL:\n\n```python\nimport base64\n\ndef encode_unsubscribe_url(email: str, base_url: str = \"https://YOUR_DOMAIN/unsubscribe.html\") -> str:\n    encoded = base64.urlsafe_b64encode(email.encode()).decode().rstrip('=')\n    return f\"{base_url}?e={encoded}\"\n```\n\n### Unsubscribe URL in Email Template\n```html\n<a href=\"https://YOUR_DOMAIN/unsubscribe.html?e={{recipient_email}}\"\n   style=\"color: #999999; font-size: 12px;\">\n  Unsubscribe\n</a>\n```\n\nWhen the user clicks unsubscribe, their email is pre-filled and they confirm removal.\n\n## Subject Line Options\n\nTested subject lines for Commercial Core:\n1. `They turned $7K into $103M. Learn how (April 16)`\n2. `Commercial real estate: free training from $100M operators`\n3. `[Only 9 days] Learn commercial underwriting from operators`\n4. `From skeptical to 90+ doors in 8 months (free training)`\n\n## Bounce Handling\n\n### Check for Bounces\n```bash\npython3 scripts/handle_bounced_emails.py --check\n```\n\n### Export Bounced Contacts with Phone Numbers for SMS\n```bash\npython3 scripts/handle_bounced_emails.py --export-sms\n# Output: logs/sms_followup_list.csv\n```\n\n### Manually Mark an Email as Bounced\n```bash\npython3 scripts/handle_bounced_emails.py --mark-bounced user@example.com\n```\n\n## Unsubscribe Sync (Weekly Automation)\n\nThe `weekly_unsubscribe_sync.sh` script syncs unsubscribes from the web form to Renatus.\n\n### Setup Cron Job\n```bash\n# Run every Sunday at 2 AM\n0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh >> /home/umbrel/.openclaw/workspace/logs/unsubscribe_cron.log 2>&1\n```\n\n### Manual Run\n```bash\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\n\n### Requirements\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Logged into `backoffice.myrenatus.com`\n- Unsubscribes stored in `data/unsubscribes_<timestamp>.txt`\n\n## Deleting Leads from Renatus\n\n### Single Lead (Dry Run)\n```bash\npython3 scripts/renatus_delete_lead.py --email user@example.com\n```\n\n### Single Lead (Execute)\n```bash\npython3 scripts/renatus_delete_lead.py --email user@example.com --execute\n```\n\n### Bulk Delete from File\n```bash\npython3 scripts/renatus_delete_lead.py --file unsubscribes.txt --execute\n```\n\n### Process Unsubscribe File\n```bash\npython3 scripts/process_unsubscribes.py --file unsubscribes.txt --execute\n```\n\n## Lead Download (Supabase Admin Export)\n\n```bash\nTOKEN=\"your_lead_admin_token\"\nREF=\"your_project_ref\"\n\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" | \\\n  jq '.rows[] | {name, email, phone: .metadata.phone}' > leads_export.csv\n```\n\n## CSV Format (renatus_leads.csv)\n\nExpected columns:\n- `email` (required) — recipient address\n- `name` (optional) — full name or first name\n- `phone` (optional) — for SMS bounce recovery\n- `dateCreated` (optional) — lead creation date\n\nExample:\n```csv\nemail,name,phone,dateCreated\njane@example.com,Jane Smith,5185551212,2026-03-01\njohn@example.com,John Doe,,2026-03-02\n```\n\nFile v2.1.3:references/event-page-setup.md\n\n# Event Page Setup Guide\n\n## Overview\n\nThe event landing page is a static HTML form at `site/commercial/index.html` (or similar path on your hostinger/YOUR_DOMAIN deployment). It submits directly to a Supabase Edge Function which registers the lead in Renatus Back Office.\n\n## Page Structure\n\n### Registration Form Fields\n- `firstName` (required)\n- `lastName` (required)\n- `email` (required)\n- `phone` (required)\n- `website` (honeypot — hidden, must be empty)\n- `source_page` (auto-populated from `window.location.href`)\n\n### Submit Endpoint\n```\nPOST https://<PROJECT_REF>.supabase.co/submit-renatus-registration\n```\n\n### Request Body\n```json\n{\n  \"firstName\": \"Jane\",\n  \"lastName\": \"Smith\",\n  \"email\": \"jane@example.com\",\n  \"phone\": \"(555) 555-5555\",\n  \"website\": \"\",\n  \"source_page\": \"https://YOUR_DOMAIN/commercial/\"\n}\n```\n\n### Success Response\n```json\n{\n  \"ok\": true,\n  \"eventId\": \"0817966f-b9bb-448e-bbb8-b4160115bcc8\",\n  \"eventName\": \"Commercial Core - Live Education\",\n  \"registrationId\": \"...\",\n  \"leadId\": \"...\",\n  \"guestUserId\": \"...\",\n  \"registeredSessions\": [\"Session Name 1\", \"Session Name 2\"]\n}\n```\n\n### Error Response\n```json\n{ \"error\": \"Error message\", \"details\": \"optional details\" }\n```\n\n## Setting Up a New Event Page\n\n### 1. Copy the Template\nCopy `site/commercial/index.html` to a new directory, e.g., `site/<event-slug>/index.html`\n\n### 2. Update the Edge Function URL\nIn the `<script>` section, update:\n```javascript\nconst EDGE_URL = 'https://<PROJECT_REF>.supabase.co/submit-renatus-registration';\n```\n\n### 3. Update Event Details\nUpdate the visible event details in the HTML (date, location, speakers, description).\n\n### 4. Update the Event ID\nEither:\n- Set `RENATUS_EVENT_ID` secret in Supabase (affects all form submissions)\n- Add `eventId` field to the form and pass it in the payload\n\n### 5. Get the Event GUID from Renatus\n1. Log into `backoffice.myrenatus.com`\n2. Navigate to Events\n3. Open the event\n4. Copy the event GUID from the URL or API response\n\n### 6. Verify Registration Flow\nSubmit a test registration and confirm:\n- Lead appears in `funnel_leads` table\n- Lead appears in Renatus Back Office\n- Email confirmation is sent by Renatus\n\n## Customizing the Landing Page\n\n### Styling\nThe page uses CSS custom properties for easy theming:\n```css\n:root {\n  --bg: #0f172a;\n  --card: #111827;\n  --accent: #22c55e;\n  --text: #e5e7eb;\n}\n```\n\n### Adding a Second Event (In-Person Option)\nModify the `feesPayload` to include multiple sessions, or use separate event pages with different event IDs.\n\n### Redirect to Confirmation Page\nAfter successful form submission:\n```javascript\nif (resp.ok) {\n  window.location.href = '/confirmation.html';\n}\n```\n\n## Hosting Options\n\n### Option A: Deploy with your hosting scripts\n```bash\npython3 scripts/deploy_hostinger.py\n```\n\n### Option B: Manual FTP Upload\nUpload `site/commercial/` directory to your web host's `public_html/` or equivalent.\n\n### Option C: Subdirectory on Existing Site\nUpload to `public_html/commercial/` — page will be at `https://yourdomain.com/commercial/`\n\n## Confirmation Page\nAfter successful registration, redirect users to a confirmation page. The confirmation page shows event details and next steps. See `site/confirmation.html` for the template.\n\n## Troubleshooting\n\n### \"Registration could not be completed\"\n- Check browser console for specific error\n- Verify Supabase Edge Function URL is correct\n- Check Supabase function logs in the dashboard\n\n### Lead not appearing in Renatus\n- Verify `RENATUS_USERNAME` and `RENATUS_PASSWORD` secrets are set\n- Check function logs for authentication errors (401 = bad credentials)\n- Confirm event GUID is valid and event is published in Renatus\n\n### Public sessions not found\n- Event may only have education-gated sessions\n- Check `isPublicEligibleSession` in the edge function — sessions requiring IMA, Xtream Education, or other credentials are excluded\n- Contact Renatus to create a public-eligible session for the event\n\nFile v2.1.3:references/supabase-setup.md\n\n# Supabase Setup for Renatus ICM\n\n## Overview\n\nSupabase project: `YOUR_PROJECT_NAME` (EU-West-1 — or any region)\n\nStores lead registrations from the public event landing page and exposes an admin export endpoint for ICMs to download leads.\n\n## 1. Link and Push Migrations\n\n```bash\ncd supabase\nsupabase link --project-ref <PROJECT_REF>\nsupabase db push --include-all\n```\n\n## 2. Deploy Edge Functions\n\n```bash\nsupabase functions deploy submit-renatus-registration --project-ref <PROJECT_REF>\nsupabase functions deploy lead-admin-export --project-ref <PROJECT_REF>\nsupabase functions deploy capture-lead --project-ref <PROJECT_REF>\nsupabase functions deploy stripe-webhook --project-ref <PROJECT_REF>\n```\n\n## 3. Set Required Secrets\n\n```bash\nsupabase secrets set \\\n  RENATUS_USERNAME=\"<renatus_backoffice_email>\" \\\n  RENATUS_PASSWORD=\"<renatus_backoffice_password>\" \\\n  RENATUS_EVENT_ID=\"<default_event_guid>\" \\\n  SUPABASE_URL=\"https://<PROJECT_REF>.supabase.co\" \\\n  SUPABASE_SERVICE_ROLE_KEY=\"<service_role_key>\" \\\n  LEAD_ADMIN_TOKEN=\"<secure_random_token_for_admin_export>\" \\\n  --project-ref <PROJECT_REF>\n```\n\n## 4. Key Tables\n\n### funnel_leads\n```sql\ncreate table if not exists public.funnel_leads (\n  id uuid primary key default gen_random_uuid(),\n  created_at timestamptz not null default now(),\n  source_page text,\n  name text,\n  email text,\n  company text,\n  notes text,\n  cta_type text,\n  metadata jsonb not null default '{}'::jsonb\n);\n```\n\n### funnel_leads metadata field\nContains: `event_id`, `registration_id`, `lead_id`, `guest_user_id`, `registered_sessions`, `phone`\n\n## 5. Key Edge Functions\n\n### submit-renatus-registration\n- **URL:** `https://<PROJECT_REF>.functions.supabase.co/submit-renatus-registration`\n- **Method:** POST\n- **Auth:** Public (honeypot + Turnstile bot protection)\n- **Session eligibility:** Auto-detects public-eligible sessions (no IMA/education requirements)\n- **Response:** `{ ok, eventId, eventName, registrationId, leadId, guestUserId, registeredSessions }`\n\n### lead-admin-export\n- **URL:** `https://<PROJECT_REF>.functions.supabase.co/lead-admin-export`\n- **Method:** GET\n- **Auth:** `x-admin-token: <LEAD_ADMIN_TOKEN>` header\n- **Params:** `?partner=<optional_partner_slug>&limit=<1-500>`\n- **Response:** `{ ok, count, rows: [...] }`\n\n## 6. Configure Stripe Webhook (Optional)\n\nEndpoint: `https://<PROJECT_REF>.functions.supabase.co/stripe-webhook`\nListen for: `checkout.session.completed`\n\n## 7. Verify End-to-End\n\n1. Submit lead form at `/commercial/index.html`\n2. Confirm row in `funnel_leads`\n3. Verify lead in Renatus Back Office\n4. Export: `curl -H \"x-admin-token: $TOKEN\" \"https://<REF>.functions.supabase.co/lead-admin-export?limit=10\"`\n\n## Required Secrets Reference\n\n| Variable | Required | Description |\n|---|---|---|\n| `RENATUS_USERNAME` | Yes | Renatus back office email |\n| `RENATUS_PASSWORD` | Yes | Renatus back office password |\n| `RENATUS_EVENT_ID` | No | Default event GUID |\n| `SUPABASE_URL` | Yes | Project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | Yes | Service role key |\n| `LEAD_ADMIN_TOKEN` | Yes (export) | Admin export bearer token |\n| `STRIPE_SECRET_KEY` | Payments | Stripe secret key |\n| `STRIPE_WEBHOOK_SECRET` | Payments | Stripe webhook secret |\n| `TURNSTILE_SECRET_KEY` | No | Cloudflare Turnstile |\n\nFile v2.1.3:references/workflows.md\n\n# Renatus ICM Workflows\n\n## Table of Contents\n1. [New Event Setup](#1-new-event-setup)\n2. [Launch Email Campaign](#2-launch-email-campaign)\n3. [Bounce Recovery via SMS](#3-bounce-recovery-via-sms)\n4. [Weekly Unsubscribe Sync](#4-weekly-unsubscribe-sync)\n5. [Lead Download and Analysis](#5-lead-download-and-analysis)\n6. [Direct Browser Registration (CDP)](#6-direct-browser-registration-cdp)\n\n---\n\n## 1. New Event Setup\n\n### Step 1: Get Event GUID from Renatus\n1. Log into `backoffice.myrenatus.com`\n2. Go to Events → find the event\n3. Copy the event GUID from the URL or API\n\n### Step 2: Update Supabase Edge Function Secret\n```bash\nsupabase secrets set RENATUS_EVENT_ID=\"<new_event_guid>\" --project-ref <PROJECT_REF>\n```\n\n### Step 3: Update Landing Page\n1. Copy `site/commercial/index.html` to new event directory\n2. Update event details (date, time, location, speakers)\n3. Update `EDGE_URL` in the script if using a different Supabase project\n4. Deploy via FTP or `deploy_hostinger.py`\n\n### Step 4: Update Email Template\nCopy `email/commercial-core-day1.html` and update:\n- Event date and time\n- Event name\n- Instructor names\n- Subject line options\n\n### Step 5: Test Registration\nSubmit a test registration and verify:\n- [ ] `funnel_leads` row created in Supabase\n- [ ] Lead appears in Renatus Back Office\n- [ ] Email confirmation received\n\n---\n\n## 2. Launch Email Campaign\n\n### Day 0: Prepare\n```\n1. Update email template with correct event details\n2. Prepare renatus_leads.csv (export from Supabase or existing list)\n3. Verify gws CLI: gws gmail list --account YOUR_SENDER@gmail.com\n4. Send test email to self: python3 scripts/send_commercial_email_batches.py --limit 1 --send\n```\n\n### Day 1: Send First Batch\n```\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n```\n\n### Ongoing: Monitor and Resume\n```\n# After batch 1, check for bounces\npython3 scripts/handle_bounced_emails.py --check\n\n# Send next batch\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 20 --send\n\n# Repeat until complete\n```\n\n### Post-Campaign: Sync Unsubscribes\n```\n# Run after campaign has been live for a few days\nbash scripts/weekly_unsubscribe_sync.sh\n```\n\n---\n\n## 3. Bounce Recovery via SMS\n\nWhen emails bounce, recover by SMS if phone number is available.\n\n### Step 1: Detect Bounces\n```bash\npython3 scripts/handle_bounced_emails.py --check\n```\n\n### Step 2: Export SMS List\n```bash\npython3 scripts/handle_bounced_emails.py --export-sms\n# Output: logs/sms_followup_list.csv\n```\n\n### Step 3: Send SMS\nReview `logs/sms_followup_list.csv` and send SMS manually or via WhatsApp:\n\n```\nHi {name}, your email bounced. Please reply with your updated email to receive info about our free Commercial Real Estate Training on April 16. -Renatus\n```\n\n---\n\n## 4. Weekly Unsubscribe Sync\n\nAutomates removal of unsubscribed leads from Renatus.\n\n### Setup\n```bash\n# Add to crontab\ncrontab -e\n# Add: 0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh\n```\n\n### Manual Run\n```bash\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\n\n### Prerequisites\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Active login session at `backoffice.myrenatus.com`\n\n---\n\n## 5. Lead Download and Analysis\n\n### Export from Supabase\n```bash\n# Set credentials\nexport SUPABASE_URL=\"https://<REF>.supabase.co\"\nexport LEAD_ADMIN_TOKEN=\"<your_token>\"\n\n# Download all leads\npython3 scripts/renatus_leads.py --export\n\n# Or inline\npython3 scripts/renatus_leads.py --ref <REF> --token <TOKEN> --export\n\n# Convert existing JSON to CSV\npython3 scripts/renatus_leads.py --convert-json\n```\n\n### Supabase Admin Export (cURL)\n```bash\nTOKEN=\"...\"\nREF=\"...\"\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq '.rows[] | {name, email, phone: .metadata.phone, sessions: .metadata.registered_sessions}'\n```\n\n### Export from Supabase\n```bash\nTOKEN=\"...\"\nREF=\"...\"\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq '.rows[] | {name, email, phone: .metadata.phone, sessions: .metadata.registered_sessions}'\n```\n\n### Convert to CSV\n```bash\ncurl -s -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq -r '.rows[] | [.name, .email, (.metadata.phone // \"\"), (.metadata.registered_sessions | join(\"; \"))] | @csv' \\\n  > leads.csv\n```\n\n### Registration Rate\n```python\n# Count total vs registered\ntotal_leads = len(leads)\nregistered = sum(1 for l in leads if l.get('metadata', {}).get('lead_id'))\nprint(f\"Registration rate: {registered}/{total_leads} ({100*registered/total_leads:.1f}%)\")\n```\n\n---\n\n## 6. Direct Browser Registration (CDP)\n\nUse `renatus_register_guest.py` for direct registration via a live authenticated browser session. Useful when:\n- The Supabase edge function is down\n- Registering a lead not from the web form\n- Registering for a specific session (not just public-eligible)\n\n### Prerequisites\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Active Renatus session in the browser\n\n### Usage\n```bash\n# Dry run (test registration)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8\n\n# Execute (actually register)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --execute\n\n# Register for all sessions (not just first)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --all-sessions --execute\n\n# Register for specific session(s)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --session-guid <SESSION_GUID_1> \\\n  --session-guid <SESSION_GUID_2> \\\n  --execute\n```\n\n### CDP URL\n```bash\n--cdp-url http://127.0.0.1:9222  # Default\n--cdp-url http://<remote_ip>:9222  # Remote browser\n```\n\n### Output\n- Dry run: shows which sessions would be registered, event details\n- Execute: shows `leadId`, `guestUserId`, `registrationId`, session IDs\n\n---\n\n## Quick Reference: Renatus API Flow\n\nThe edge function and CDP scripts both perform the same API flow:\n\n```\n1. POST /Token                    → get access_token + cookies\n2. GET  /Home/index               → extract __RequestVerificationToken (CSRF)\n3. GET  /api/queryproxy/execute?url=/api/userprofile/current?  → ownerUserId\n4. GET  /api/queryproxy/execute?url=/api/event/getsavedevent?  → event + sessions\n5. POST /api/commandproxy/execute?url=/api/guestRegistration/addcustomer?  → leadId, guestUserId\n6. POST /api/commandproxy/execute?url=/api/registration/fees?  → session costs\n7. POST /api/commandproxy/execute?url=/api/eventRegistration/registerForEvent?  → final registration\n```\n\n### Public-Eligible Sessions\nSessions are \"public-eligible\" if they have NO requirements:\n- `RequireActiveIMA`\n- `RequireXtreamEducation`\n- `RequireNoEducation`\n- `RequireOneStarQualify` / `RequireThreeStarQualify` / `RequireFiveStarQualify`\n- `RequireEssentialEducation` / `RequireProfitEducation` / `RequireAdvancedEducation`\n- `RequireGeniusIn21DaysEducation`\n- `IsLeadOnly` / `IsNonLeadOnly`\n\nIf an event has no public-eligible sessions, contact Renatus to create one.\n\nArchive v2.1.2: 19 files, 62732 bytes\n\nFiles: assets/sample_leads.csv (263b), assets/site/confirmation.html (7458b), assets/site/unsubscribe.html (6910b), references/email-campaign.md (4901b), references/event-page-setup.md (3967b), references/supabase-setup.md (3275b), references/workflows.md (7614b), scripts/add_event.py (10848b), scripts/config_loader.py (7044b), scripts/generate_calendar.py (8914b), scripts/generate_email_template.py (21843b), scripts/generate_event_page.py (26325b), scripts/renatus_delete_lead.py (10067b), scripts/renatus_leads.py (8915b), scripts/renatus_register_guest.py (18183b), scripts/send_commercial_email_batches.py (10803b), scripts/weekly_unsubscribe_sync.sh (8115b), SKILL.md (7885b), _meta.json (130b)\n\nFile v2.1.2:SKILL.md\n\n---\nname: renatus-icm\ndescription: Run a Renatus event marketing campaign as an ICM (Independent Campaign Manager). Use when managing Renatus event registrations, sending commercial email campaigns, setting up event landing pages, downloading/exporting leads, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Handles: Supabase Edge Function registration (submit-renatus-registration), gws/gog email sending (commercial-core-day1), bounce detection and SMS recovery, CDP browser registration/delete scripts, weekly unsubscribe cron, and lead export via lead-admin-export. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\", \"handle Renatus unsubscribes\".\n---\n\n# Renatus ICM Skill\n\nComplete toolkit for running a Renatus event marketing campaign: event page setup, email campaigns, lead management, and unsubscribe sync.\n\n## Workflows Quick Reference\n\nSee [references/workflows.md](references/workflows.md) for detailed step-by-step:\n- **New Event Setup** → [event-page-setup.md](references/event-page-setup.md)\n- **Email Campaign** → [email-campaign.md](references/email-campaign.md)\n- **CDP Registration** → scripts `renatus_register_guest.py`, `renatus_delete_lead.py`\n- **Lead Export** → Supabase lead-admin-export edge function\n- **Unsubscribe Sync** → `weekly_unsubscribe_sync.sh`\n\n## Architecture Overview\n## Generate a New Event Landing Page\n\n```bash\npython3 scripts/generate_event_page.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\n\nRequirements: Chrome/Brave CDP + active Renatus session. The script extracts event name, date(s), location, speakers, and session details from the backoffice page — then renders a complete ready-to-deploy HTML file. Preview before saving with `--dry-run`.\n\n\n\n```\nEvent Landing Page (HTML)\n  ↓ form submit\nSupabase Edge Function: submit-renatus-registration\n  ↓ server-side Renatus API (no CORS)\nRenatus Back Office (lead created + registered)\n  ↓ insert\nSupabase: funnel_leads table\n  ↓\nlead-admin-export edge function ← ICM exports here\n```\n\n**Key URLs:**\n- Landing page: `https://YOUR_REGISTRATION_PAGE/` (example)\n- Supabase edge: `https://<REF>.supabase.co/submit-renatus-registration`\n- Lead export: `https://<REF>.supabase.co/lead-admin-export`\n- Renatus back office: `https://backoffice.myrenatus.com`\n\n## Email Campaign\n\n### Send Batch\n```bash\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n```\nResume from next batch: change `--start N`. Skip already-sent via `--skip-sent` (default on). See [email-campaign.md](references/email-campaign.md) for bounce handling, unsubscribe sync, and template customization.\n\n### Prerequisites\n- `gws` CLI authenticated as sender account\n- `renatus_leads.csv` with `email` column\n- `commercial-core-day1.html` template\n\n## Browser-Based Registration (CDP)\n\nRequires Chrome/Brave with `--remote-debugging-port=9222` and active Renatus session.\n\n### Register Guest (dry run)\n```bash\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(555) 555-5555\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8\n```\n\n### Execute Registration\nAdd `--execute` to perform writes.\n\n### Delete Lead (unsubscribe)\n```bash\npython3 scripts/renatus_delete_lead.py --email jane@example.com --execute\n```\n\n\n### Generate Events Calendar\n```bash\npython3 scripts/generate_calendar.py --output site/calendar.html\npython3 scripts/generate_calendar.py --dry-run\n```\nReads `events[]` from `config.json`, generates a calendar page listing all active events with registration links.\n\n### Add Event (One-Command Setup)\n```bash\npython3 scripts/add_event.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\nScrapes event from Renatus → adds to `config.json` → generates landing page in one step. Requires Chrome/Brave CDP + active Renatus session.\n\n### Download Leads from Supabase\n```bash\npython3 scripts/renatus_leads.py --export\n# Or: SUPABASE_URL=... LEAD_ADMIN_TOKEN=... python3 scripts/renatus_leads.py --export\n```\nExports to `workspace/renatus_leads.csv` + `renatus_leads.json`. Set `SUPABASE_URL` and `LEAD_ADMIN_TOKEN` env vars, or pass `--ref` + `--token` flags. Use `--convert-json` to convert an existing JSON export to CSV format.\n\n## Lead Export\n\n### Supabase Admin Export\n```bash\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://<REF>.supabase.co/functions/v1/lead-admin-export?limit=500\"\n```\n\nToken = `LEAD_ADMIN_TOKEN` secret in Supabase. See [supabase-setup.md](references/supabase-setup.md) for setup.\n\n### Download via Agent\nIf running as an OpenClaw agent:\n```bash\n# From workspace: logs/email_send_log.json tracks sent emails\n# Download leads to: workspace/renatus_leads.csv\n```\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n```bash\ncp config.json.example config.json\n# edit config.json with your Supabase URL, Renatus credentials, sender account, etc.\n```\n\nAlternatively, set `RENATUS_*` environment variables. Scripts check (in order): `config.json` → env vars → defaults.\n\nEnvironment variables: `RENATUS_SUPABASE_REF`, `RENATUS_SUPABASE_URL`, `RENATUS_LEAD_TOKEN`, `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `RENATUS_SENDER`, `RENATUS_PROVIDER`, `RENATUS_TEMPLATE`, `RENATUS_UNSUB_URL`, `RENATUS_SITE_URL`, `RENATUS_REGISTRATION_URL`.\n\n**Important:** `config.json` is gitignored. Your personal config stays private; `config.json.example` is what other ICMs receive.\n\n\n---\n\n## Supabase Setup (New ICM)\n\nSee [supabase-setup.md](references/supabase-setup.md) for full setup:\n1. Link project: `supabase link --project-ref <REF>`\n2. Push migrations: `supabase db push`\n3. Deploy functions: `submit-renatus-registration`, `lead-admin-export`\n4. Set secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `LEAD_ADMIN_TOKEN`\n5. Verify: submit test registration → check `funnel_leads` + Renatus back office\n\n## Supabase Edge Function Reference\n\n### submit-renatus-registration\nPublic POST endpoint. Registers a lead in Renatus via server-side API (bypasses CORS). Auto-detects public-eligible sessions (no IMA/education requirements). Required secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`.\n\n### lead-admin-export\nAdmin GET endpoint. Requires `x-admin-token` header. Params: `?partner=&limit=`.\n\n### capture-lead\nGeneral-purpose public lead intake with Turnstile bot protection. Insert into `funnel_leads`.\n\n## Key Secrets (Supabase)\n\n| Secret | Required | Purpose |\n|---|---|---|\n| `RENATUS_USERNAME` | Registration | Back office login |\n| `RENATUS_PASSWORD` | Registration | Back office password |\n| `RENATUS_EVENT_ID` | Registration | Default event GUID |\n| `LEAD_ADMIN_TOKEN` | Export | Admin export auth |\n| `SUPABASE_URL` | Always | Project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | Always | DB access |\n\n## Unsubscribe Sync (Weekly Cron)\n\n```bash\n# Add to crontab\n0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh\n\n# Manual run\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\nRequirements: Chrome CDP at 9222 + active Renatus session. See [email-campaign.md](references/email-campaign.md).\n\n## Bounce Recovery\n\n```bash\n# Detect bounces\npython3 scripts/handle_bounced_emails.py --check\n\n# Export SMS-ready contacts\npython3 scripts/handle_bounced_emails.py --export-sms\n\n# Manually mark bounce\npython3 scripts/handle_bounced_emails.py --mark-bounced user@example.com\n```\n\nFile v2.1.2:_meta.json\n\n{\n  \"ownerId\": \"kn7a5vdq619nymw8zq4aq95b49846rhq\",\n  \"slug\": \"renatus-icm\",\n  \"version\": \"2.1.2\",\n  \"publishedAt\": 1775313189119\n}\n\nFile v2.1.2:references/email-campaign.md\n\n# Email Campaign Guide\n\n## Overview\n\nCommercial email campaigns are sent from `YOUR_SENDER@gmail.com` via gws CLI. The email template is `commercial-core-day1.html`. Campaigns target leads from `renatus_leads.csv` and track delivery via `logs/email_send_log.json`.\n\n## Campaign Assets\n\n| File | Purpose |\n|---|---|\n| `email/commercial-core-day1.html` | HTML email template |\n| `renatus_leads.csv` | Lead list (export via `renatus_leads.py --export`) |\n| `logs/email_send_log.json` | Sent log (resumable sends) |\n| `logs/bounced_emails.json` | Bounced email tracking |\n\n### Getting the Leads CSV\n```bash\n# Export fresh from Supabase\npython3 scripts/renatus_leads.py --export\n\n# Convert existing JSON to CSV (if you have old JSON export)\npython3 scripts/renatus_leads.py --convert-json\n```\n\n## Sending Emails\n\n### Prerequisites\n- `gws` CLI authenticated as `YOUR_SENDER@gmail.com`\n- `renatus_leads.csv` exists with at least `email` column\n- `commercial-core-day1.html` template\n\n### Dry Run (Preview)\n```bash\npython3 scripts/send_commercial_email_batches.py --dry-run\n```\n\n### Send in Batches (with Resume)\n```bash\n# First batch\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n\n# Resume from batch 2\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 20 --send\n\n# Resume from batch 3\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 40 --send\n```\n\n### Batch Script Flags\n| Flag | Default | Description |\n|---|---|---|\n| `--batch-size` | 20 | Emails per batch |\n| `--start` | 0 | Starting index |\n| `--dry-run` | — | Preview without sending |\n| `--send` | — | Actually send |\n| `--delay` | 2.0 | Seconds between sends |\n\n## Personalizing the Template\n\nThe template uses `{{recipient_email}}` as a placeholder for the unsubscribe link target.\n\n### Adding Personalized Unsubscribe URL\nReplace `{{recipient_email}}` with a base64-encoded unsubscribe URL:\n\n```python\nimport base64\n\ndef encode_unsubscribe_url(email: str, base_url: str = \"https://YOUR_DOMAIN/unsubscribe.html\") -> str:\n    encoded = base64.urlsafe_b64encode(email.encode()).decode().rstrip('=')\n    return f\"{base_url}?e={encoded}\"\n```\n\n### Unsubscribe URL in Email Template\n```html\n<a href=\"https://YOUR_DOMAIN/unsubscribe.html?e={{recipient_email}}\"\n   style=\"color: #999999; font-size: 12px;\">\n  Unsubscribe\n</a>\n```\n\nWhen the user clicks unsubscribe, their email is pre-filled and they confirm removal.\n\n## Subject Line Options\n\nTested subject lines for Commercial Core:\n1. `They turned $7K into $103M. Learn how (April 16)`\n2. `Commercial real estate: free training from $100M operators`\n3. `[Only 9 days] Learn commercial underwriting from operators`\n4. `From skeptical to 90+ doors in 8 months (free training)`\n\n## Bounce Handling\n\n### Check for Bounces\n```bash\npython3 scripts/handle_bounced_emails.py --check\n```\n\n### Export Bounced Contacts with Phone Numbers for SMS\n```bash\npython3 scripts/handle_bounced_emails.py --export-sms\n# Output: logs/sms_followup_list.csv\n```\n\n### Manually Mark an Email as Bounced\n```bash\npython3 scripts/handle_bounced_emails.py --mark-bounced user@example.com\n```\n\n## Unsubscribe Sync (Weekly Automation)\n\nThe `weekly_unsubscribe_sync.sh` script syncs unsubscribes from the web form to Renatus.\n\n### Setup Cron Job\n```bash\n# Run every Sunday at 2 AM\n0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh >> /home/umbrel/.openclaw/workspace/logs/unsubscribe_cron.log 2>&1\n```\n\n### Manual Run\n```bash\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\n\n### Requirements\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Logged into `backoffice.myrenatus.com`\n- Unsubscribes stored in `data/unsubscribes_<timestamp>.txt`\n\n## Deleting Leads from Renatus\n\n### Single Lead (Dry Run)\n```bash\npython3 scripts/renatus_delete_lead.py --email user@example.com\n```\n\n### Single Lead (Execute)\n```bash\npython3 scripts/renatus_delete_lead.py --email user@example.com --execute\n```\n\n### Bulk Delete from File\n```bash\npython3 scripts/renatus_delete_lead.py --file unsubscribes.txt --execute\n```\n\n### Process Unsubscribe File\n```bash\npython3 scripts/process_unsubscribes.py --file unsubscribes.txt --execute\n```\n\n## Lead Download (Supabase Admin Export)\n\n```bash\nTOKEN=\"your_lead_admin_token\"\nREF=\"your_project_ref\"\n\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" | \\\n  jq '.rows[] | {name, email, phone: .metadata.phone}' > leads_export.csv\n```\n\n## CSV Format (renatus_leads.csv)\n\nExpected columns:\n- `email` (required) — recipient address\n- `name` (optional) — full name or first name\n- `phone` (optional) — for SMS bounce recovery\n- `dateCreated` (optional) — lead creation date\n\nExample:\n```csv\nemail,name,phone,dateCreated\njane@example.com,Jane Smith,5185551212,2026-03-01\njohn@example.com,John Doe,,2026-03-02\n```\n\nFile v2.1.2:references/event-page-setup.md\n\n# Event Page Setup Guide\n\n## Overview\n\nThe event landing page is a static HTML form at `site/commercial/index.html` (or similar path on your hostinger/YOUR_DOMAIN deployment). It submits directly to a Supabase Edge Function which registers the lead in Renatus Back Office.\n\n## Page Structure\n\n### Registration Form Fields\n- `firstName` (required)\n- `lastName` (required)\n- `email` (required)\n- `phone` (required)\n- `website` (honeypot — hidden, must be empty)\n- `source_page` (auto-populated from `window.location.href`)\n\n### Submit Endpoint\n```\nPOST https://<PROJECT_REF>.supabase.co/submit-renatus-registration\n```\n\n### Request Body\n```json\n{\n  \"firstName\": \"Jane\",\n  \"lastName\": \"Smith\",\n  \"email\": \"jane@example.com\",\n  \"phone\": \"(555) 555-5555\",\n  \"website\": \"\",\n  \"source_page\": \"https://YOUR_DOMAIN/commercial/\"\n}\n```\n\n### Success Response\n```json\n{\n  \"ok\": true,\n  \"eventId\": \"0817966f-b9bb-448e-bbb8-b4160115bcc8\",\n  \"eventName\": \"Commercial Core - Live Education\",\n  \"registrationId\": \"...\",\n  \"leadId\": \"...\",\n  \"guestUserId\": \"...\",\n  \"registeredSessions\": [\"Session Name 1\", \"Session Name 2\"]\n}\n```\n\n### Error Response\n```json\n{ \"error\": \"Error message\", \"details\": \"optional details\" }\n```\n\n## Setting Up a New Event Page\n\n### 1. Copy the Template\nCopy `site/commercial/index.html` to a new directory, e.g., `site/<event-slug>/index.html`\n\n### 2. Update the Edge Function URL\nIn the `<script>` section, update:\n```javascript\nconst EDGE_URL = 'https://<PROJECT_REF>.supabase.co/submit-renatus-registration';\n```\n\n### 3. Update Event Details\nUpdate the visible event details in the HTML (date, location, speakers, description).\n\n### 4. Update the Event ID\nEither:\n- Set `RENATUS_EVENT_ID` secret in Supabase (affects all form submissions)\n- Add `eventId` field to the form and pass it in the payload\n\n### 5. Get the Event GUID from Renatus\n1. Log into `backoffice.myrenatus.com`\n2. Navigate to Events\n3. Open the event\n4. Copy the event GUID from the URL or API response\n\n### 6. Verify Registration Flow\nSubmit a test registration and confirm:\n- Lead appears in `funnel_leads` table\n- Lead appears in Renatus Back Office\n- Email confirmation is sent by Renatus\n\n## Customizing the Landing Page\n\n### Styling\nThe page uses CSS custom properties for easy theming:\n```css\n:root {\n  --bg: #0f172a;\n  --card: #111827;\n  --accent: #22c55e;\n  --text: #e5e7eb;\n}\n```\n\n### Adding a Second Event (In-Person Option)\nModify the `feesPayload` to include multiple sessions, or use separate event pages with different event IDs.\n\n### Redirect to Confirmation Page\nAfter successful form submission:\n```javascript\nif (resp.ok) {\n  window.location.href = '/confirmation.html';\n}\n```\n\n## Hosting Options\n\n### Option A: Deploy with your hosting scripts\n```bash\npython3 scripts/deploy_hostinger.py\n```\n\n### Option B: Manual FTP Upload\nUpload `site/commercial/` directory to your web host's `public_html/` or equivalent.\n\n### Option C: Subdirectory on Existing Site\nUpload to `public_html/commercial/` — page will be at `https://yourdomain.com/commercial/`\n\n## Confirmation Page\nAfter successful registration, redirect users to a confirmation page. The confirmation page shows event details and next steps. See `site/confirmation.html` for the template.\n\n## Troubleshooting\n\n### \"Registration could not be completed\"\n- Check browser console for specific error\n- Verify Supabase Edge Function URL is correct\n- Check Supabase function logs in the dashboard\n\n### Lead not appearing in Renatus\n- Verify `RENATUS_USERNAME` and `RENATUS_PASSWORD` secrets are set\n- Check function logs for authentication errors (401 = bad credentials)\n- Confirm event GUID is valid and event is published in Renatus\n\n### Public sessions not found\n- Event may only have education-gated sessions\n- Check `isPublicEligibleSession` in the edge function — sessions requiring IMA, Xtream Education, or other credentials are excluded\n- Contact Renatus to create a public-eligible session for the event\n\nFile v2.1.2:references/supabase-setup.md\n\n# Supabase Setup for Renatus ICM\n\n## Overview\n\nSupabase project: `YOUR_PROJECT_NAME` (EU-West-1 — or any region)\n\nStores lead registrations from the public event landing page and exposes an admin export endpoint for ICMs to download leads.\n\n## 1. Link and Push Migrations\n\n```bash\ncd supabase\nsupabase link --project-ref <PROJECT_REF>\nsupabase db push --include-all\n```\n\n## 2. Deploy Edge Functions\n\n```bash\nsupabase functions deploy submit-renatus-registration --project-ref <PROJECT_REF>\nsupabase functions deploy lead-admin-export --project-ref <PROJECT_REF>\nsupabase functions deploy capture-lead --project-ref <PROJECT_REF>\nsupabase functions deploy stripe-webhook --project-ref <PROJECT_REF>\n```\n\n## 3. Set Required Secrets\n\n```bash\nsupabase secrets set \\\n  RENATUS_USERNAME=\"<renatus_backoffice_email>\" \\\n  RENATUS_PASSWORD=\"<renatus_backoffice_password>\" \\\n  RENATUS_EVENT_ID=\"<default_event_guid>\" \\\n  SUPABASE_URL=\"https://<PROJECT_REF>.supabase.co\" \\\n  SUPABASE_SERVICE_ROLE_KEY=\"<service_role_key>\" \\\n  LEAD_ADMIN_TOKEN=\"<secure_random_token_for_admin_export>\" \\\n  --project-ref <PROJECT_REF>\n```\n\n## 4. Key Tables\n\n### funnel_leads\n```sql\ncreate table if not exists public.funnel_leads (\n  id uuid primary key default gen_random_uuid(),\n  created_at timestamptz not null default now(),\n  source_page text,\n  name text,\n  email text,\n  company text,\n  notes text,\n  cta_type text,\n  metadata jsonb not null default '{}'::jsonb\n);\n```\n\n### funnel_leads metadata field\nContains: `event_id`, `registration_id`, `lead_id`, `guest_user_id`, `registered_sessions`, `phone`\n\n## 5. Key Edge Functions\n\n### submit-renatus-registration\n- **URL:** `https://<PROJECT_REF>.functions.supabase.co/submit-renatus-registration`\n- **Method:** POST\n- **Auth:** Public (honeypot + Turnstile bot protection)\n- **Session eligibility:** Auto-detects public-eligible sessions (no IMA/education requirements)\n- **Response:** `{ ok, eventId, eventName, registrationId, leadId, guestUserId, registeredSessions }`\n\n### lead-admin-export\n- **URL:** `https://<PROJECT_REF>.functions.supabase.co/lead-admin-export`\n- **Method:** GET\n- **Auth:** `x-admin-token: <LEAD_ADMIN_TOKEN>` header\n- **Params:** `?partner=<optional_partner_slug>&limit=<1-500>`\n- **Response:** `{ ok, count, rows: [...] }`\n\n## 6. Configure Stripe Webhook (Optional)\n\nEndpoint: `https://<PROJECT_REF>.functions.supabase.co/stripe-webhook`\nListen for: `checkout.session.completed`\n\n## 7. Verify End-to-End\n\n1. Submit lead form at `/commercial/index.html`\n2. Confirm row in `funnel_leads`\n3. Verify lead in Renatus Back Office\n4. Export: `curl -H \"x-admin-token: $TOKEN\" \"https://<REF>.functions.supabase.co/lead-admin-export?limit=10\"`\n\n## Required Secrets Reference\n\n| Variable | Required | Description |\n|---|---|---|\n| `RENATUS_USERNAME` | Yes | Renatus back office email |\n| `RENATUS_PASSWORD` | Yes | Renatus back office password |\n| `RENATUS_EVENT_ID` | No | Default event GUID |\n| `SUPABASE_URL` | Yes | Project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | Yes | Service role key |\n| `LEAD_ADMIN_TOKEN` | Yes (export) | Admin export bearer token |\n| `STRIPE_SECRET_KEY` | Payments | Stripe secret key |\n| `STRIPE_WEBHOOK_SECRET` | Payments | Stripe webhook secret |\n| `TURNSTILE_SECRET_KEY` | No | Cloudflare Turnstile |\n\nFile v2.1.2:references/workflows.md\n\n# Renatus ICM Workflows\n\n## Table of Contents\n1. [New Event Setup](#1-new-event-setup)\n2. [Launch Email Campaign](#2-launch-email-campaign)\n3. [Bounce Recovery via SMS](#3-bounce-recovery-via-sms)\n4. [Weekly Unsubscribe Sync](#4-weekly-unsubscribe-sync)\n5. [Lead Download and Analysis](#5-lead-download-and-analysis)\n6. [Direct Browser Registration (CDP)](#6-direct-browser-registration-cdp)\n\n---\n\n## 1. New Event Setup\n\n### Step 1: Get Event GUID from Renatus\n1. Log into `backoffice.myrenatus.com`\n2. Go to Events → find the event\n3. Copy the event GUID from the URL or API\n\n### Step 2: Update Supabase Edge Function Secret\n```bash\nsupabase secrets set RENATUS_EVENT_ID=\"<new_event_guid>\" --project-ref <PROJECT_REF>\n```\n\n### Step 3: Update Landing Page\n1. Copy `site/commercial/index.html` to new event directory\n2. Update event details (date, time, location, speakers)\n3. Update `EDGE_URL` in the script if using a different Supabase project\n4. Deploy via FTP or `deploy_hostinger.py`\n\n### Step 4: Update Email Template\nCopy `email/commercial-core-day1.html` and update:\n- Event date and time\n- Event name\n- Instructor names\n- Subject line options\n\n### Step 5: Test Registration\nSubmit a test registration and verify:\n- [ ] `funnel_leads` row created in Supabase\n- [ ] Lead appears in Renatus Back Office\n- [ ] Email confirmation received\n\n---\n\n## 2. Launch Email Campaign\n\n### Day 0: Prepare\n```\n1. Update email template with correct event details\n2. Prepare renatus_leads.csv (export from Supabase or existing list)\n3. Verify gws CLI: gws gmail list --account YOUR_SENDER@gmail.com\n4. Send test email to self: python3 scripts/send_commercial_email_batches.py --limit 1 --send\n```\n\n### Day 1: Send First Batch\n```\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n```\n\n### Ongoing: Monitor and Resume\n```\n# After batch 1, check for bounces\npython3 scripts/handle_bounced_emails.py --check\n\n# Send next batch\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 20 --send\n\n# Repeat until complete\n```\n\n### Post-Campaign: Sync Unsubscribes\n```\n# Run after campaign has been live for a few days\nbash scripts/weekly_unsubscribe_sync.sh\n```\n\n---\n\n## 3. Bounce Recovery via SMS\n\nWhen emails bounce, recover by SMS if phone number is available.\n\n### Step 1: Detect Bounces\n```bash\npython3 scripts/handle_bounced_emails.py --check\n```\n\n### Step 2: Export SMS List\n```bash\npython3 scripts/handle_bounced_emails.py --export-sms\n# Output: logs/sms_followup_list.csv\n```\n\n### Step 3: Send SMS\nReview `logs/sms_followup_list.csv` and send SMS manually or via WhatsApp:\n\n```\nHi {name}, your email bounced. Please reply with your updated email to receive info about our free Commercial Real Estate Training on April 16. -Renatus\n```\n\n---\n\n## 4. Weekly Unsubscribe Sync\n\nAutomates removal of unsubscribed leads from Renatus.\n\n### Setup\n```bash\n# Add to crontab\ncrontab -e\n# Add: 0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh\n```\n\n### Manual Run\n```bash\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\n\n### Prerequisites\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Active login session at `backoffice.myrenatus.com`\n\n---\n\n## 5. Lead Download and Analysis\n\n### Export from Supabase\n```bash\n# Set credentials\nexport SUPABASE_URL=\"https://<REF>.supabase.co\"\nexport LEAD_ADMIN_TOKEN=\"<your_token>\"\n\n# Download all leads\npython3 scripts/renatus_leads.py --export\n\n# Or inline\npython3 scripts/renatus_leads.py --ref <REF> --token <TOKEN> --export\n\n# Convert existing JSON to CSV\npython3 scripts/renatus_leads.py --convert-json\n```\n\n### Supabase Admin Export (cURL)\n```bash\nTOKEN=\"...\"\nREF=\"...\"\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq '.rows[] | {name, email, phone: .metadata.phone, sessions: .metadata.registered_sessions}'\n```\n\n### Export from Supabase\n```bash\nTOKEN=\"...\"\nREF=\"...\"\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq '.rows[] | {name, email, phone: .metadata.phone, sessions: .metadata.registered_sessions}'\n```\n\n### Convert to CSV\n```bash\ncurl -s -H \"x-admin-token: $TOKEN\" \\\n  \"https://$REF.supabase.co/functions/v1/lead-admin-export?limit=500\" \\\n  | jq -r '.rows[] | [.name, .email, (.metadata.phone // \"\"), (.metadata.registered_sessions | join(\"; \"))] | @csv' \\\n  > leads.csv\n```\n\n### Registration Rate\n```python\n# Count total vs registered\ntotal_leads = len(leads)\nregistered = sum(1 for l in leads if l.get('metadata', {}).get('lead_id'))\nprint(f\"Registration rate: {registered}/{total_leads} ({100*registered/total_leads:.1f}%)\")\n```\n\n---\n\n## 6. Direct Browser Registration (CDP)\n\nUse `renatus_register_guest.py` for direct registration via a live authenticated browser session. Useful when:\n- The Supabase edge function is down\n- Registering a lead not from the web form\n- Registering for a specific session (not just public-eligible)\n\n### Prerequisites\n- Chrome/Brave with `--remote-debugging-port=9222`\n- Active Renatus session in the browser\n\n### Usage\n```bash\n# Dry run (test registration)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8\n\n# Execute (actually register)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --execute\n\n# Register for all sessions (not just first)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --all-sessions --execute\n\n# Register for specific session(s)\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(518) 555-1212\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8 \\\n  --session-guid <SESSION_GUID_1> \\\n  --session-guid <SESSION_GUID_2> \\\n  --execute\n```\n\n### CDP URL\n```bash\n--cdp-url http://127.0.0.1:9222  # Default\n--cdp-url http://<remote_ip>:9222  # Remote browser\n```\n\n### Output\n- Dry run: shows which sessions would be registered, event details\n- Execute: shows `leadId`, `guestUserId`, `registrationId`, session IDs\n\n---\n\n## Quick Reference: Renatus API Flow\n\nThe edge function and CDP scripts both perform the same API flow:\n\n```\n1. POST /Token                    → get access_token + cookies\n2. GET  /Home/index               → extract __RequestVerificationToken (CSRF)\n3. GET  /api/queryproxy/execute?url=/api/userprofile/current?  → ownerUserId\n4. GET  /api/queryproxy/execute?url=/api/event/getsavedevent?  → event + sessions\n5. POST /api/commandproxy/execute?url=/api/guestRegistration/addcustomer?  → leadId, guestUserId\n6. POST /api/commandproxy/execute?url=/api/registration/fees?  → session costs\n7. POST /api/commandproxy/execute?url=/api/eventRegistration/registerForEvent?  → final registration\n```\n\n### Public-Eligible Sessions\nSessions are \"public-eligible\" if they have NO requirements:\n- `RequireActiveIMA`\n- `RequireXtreamEducation`\n- `RequireNoEducation`\n- `RequireOneStarQualify` / `RequireThreeStarQualify` / `RequireFiveStarQualify`\n- `RequireEssentialEducation` / `RequireProfitEducation` / `RequireAdvancedEducation`\n- `RequireGeniusIn21DaysEducation`\n- `IsLeadOnly` / `IsNonLeadOnly`\n\nIf an event has no public-eligible sessions, contact Renatus to create one.\n\nArchive v2.1.0: 20 files, 66017 bytes\n\nFiles: assets/sample_leads.csv (263b), assets/site/commercial/index.html (9495b), assets/site/confirmation.html (7420b), assets/site/unsubscribe.html (6910b), references/email-campaign.md (4901b), references/event-page-setup.md (3967b), references/supabase-setup.md (3275b), references/workflows.md (7614b), scripts/add_event.py (10860b), scripts/config_loader.py (7044b), scripts/generate_calendar.py (8914b), scripts/generate_email_template.py (21843b), scripts/generate_event_page.py (26325b), scripts/renatus_delete_lead.py (10067b), scripts/renatus_leads.py (8903b), scripts/renatus_register_guest.py (18183b), scripts/send_commercial_email_batches.py (10803b), scripts/weekly_unsubscribe_sync.sh (8115b), SKILL.md (7885b), _meta.json (130b)\n\nFile v2.1.0:SKILL.md\n\n---\nname: renatus-icm\ndescription: Run a Renatus event marketing campaign as an ICM (Independent Campaign Manager). Use when managing Renatus event registrations, sending commercial email campaigns, setting up event landing pages, downloading/exporting leads, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Handles: Supabase Edge Function registration (submit-renatus-registration), gws/gog email sending (commercial-core-day1), bounce detection and SMS recovery, CDP browser registration/delete scripts, weekly unsubscribe cron, and lead export via lead-admin-export. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\", \"handle Renatus unsubscribes\".\n---\n\n# Renatus ICM Skill\n\nComplete toolkit for running a Renatus event marketing campaign: event page setup, email campaigns, lead management, and unsubscribe sync.\n\n## Workflows Quick Reference\n\nSee [references/workflows.md](references/workflows.md) for detailed step-by-step:\n- **New Event Setup** → [event-page-setup.md](references/event-page-setup.md)\n- **Email Campaign** → [email-campaign.md](references/email-campaign.md)\n- **CDP Registration** → scripts `renatus_register_guest.py`, `renatus_delete_lead.py`\n- **Lead Export** → Supabase lead-admin-export edge function\n- **Unsubscribe Sync** → `weekly_unsubscribe_sync.sh`\n\n## Architecture Overview\n## Generate a New Event Landing Page\n\n```bash\npython3 scripts/generate_event_page.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\n\nRequirements: Chrome/Brave CDP + active Renatus session. The script extracts event name, date(s), location, speakers, and session details from the backoffice page — then renders a complete ready-to-deploy HTML file. Preview before saving with `--dry-run`.\n\n\n\n```\nEvent Landing Page (HTML)\n  ↓ form submit\nSupabase Edge Function: submit-renatus-registration\n  ↓ server-side Renatus API (no CORS)\nRenatus Back Office (lead created + registered)\n  ↓ insert\nSupabase: funnel_leads table\n  ↓\nlead-admin-export edge function ← ICM exports here\n```\n\n**Key URLs:**\n- Landing page: `https://YOUR_REGISTRATION_PAGE/` (example)\n- Supabase edge: `https://<REF>.supabase.co/submit-renatus-registration`\n- Lead export: `https://<REF>.supabase.co/lead-admin-export`\n- Renatus back office: `https://backoffice.myrenatus.com`\n\n## Email Campaign\n\n### Send Batch\n```bash\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n```\nResume from next batch: change `--start N`. Skip already-sent via `--skip-sent` (default on). See [email-campaign.md](references/email-campaign.md) for bounce handling, unsubscribe sync, and template customization.\n\n### Prerequisites\n- `gws` CLI authenticated as sender account\n- `renatus_leads.csv` with `email` column\n- `commercial-core-day1.html` template\n\n## Browser-Based Registration (CDP)\n\nRequires Chrome/Brave with `--remote-debugging-port=9222` and active Renatus session.\n\n### Register Guest (dry run)\n```bash\npython3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(555) 555-5555\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8\n```\n\n### Execute Registration\nAdd `--execute` to perform writes.\n\n### Delete Lead (unsubscribe)\n```bash\npython3 scripts/renatus_delete_lead.py --email jane@example.com --execute\n```\n\n\n### Generate Events Calendar\n```bash\npython3 scripts/generate_calendar.py --output site/calendar.html\npython3 scripts/generate_calendar.py --dry-run\n```\nReads `events[]` from `config.json`, generates a calendar page listing all active events with registration links.\n\n### Add Event (One-Command Setup)\n```bash\npython3 scripts/add_event.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html\n```\nScrapes event from Renatus → adds to `config.json` → generates landing page in one step. Requires Chrome/Brave CDP + active Renatus session.\n\n### Download Leads from Supabase\n```bash\npython3 scripts/renatus_leads.py --export\n# Or: SUPABASE_URL=... LEAD_ADMIN_TOKEN=... python3 scripts/renatus_leads.py --export\n```\nExports to `workspace/renatus_leads.csv` + `renatus_leads.json`. Set `SUPABASE_URL` and `LEAD_ADMIN_TOKEN` env vars, or pass `--ref` + `--token` flags. Use `--convert-json` to convert an existing JSON export to CSV format.\n\n## Lead Export\n\n### Supabase Admin Export\n```bash\ncurl -H \"x-admin-token: $TOKEN\" \\\n  \"https://<REF>.supabase.co/functions/v1/lead-admin-export?limit=500\"\n```\n\nToken = `LEAD_ADMIN_TOKEN` secret in Supabase. See [supabase-setup.md](references/supabase-setup.md) for setup.\n\n### Download via Agent\nIf running as an OpenClaw agent:\n```bash\n# From workspace: logs/email_send_log.json tracks sent emails\n# Download leads to: workspace/renatus_leads.csv\n```\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n## Configuration (config.json)\n\nCopy `config.json.example` to `config.json` and fill in your values. Scripts auto-load it:\n\n```bash\ncp config.json.example config.json\n# edit config.json with your Supabase URL, Renatus credentials, sender account, etc.\n```\n\nAlternatively, set `RENATUS_*` environment variables. Scripts check (in order): `config.json` → env vars → defaults.\n\nEnvironment variables: `RENATUS_SUPABASE_REF`, `RENATUS_SUPABASE_URL`, `RENATUS_LEAD_TOKEN`, `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `RENATUS_SENDER`, `RENATUS_PROVIDER`, `RENATUS_TEMPLATE`, `RENATUS_UNSUB_URL`, `RENATUS_SITE_URL`, `RENATUS_REGISTRATION_URL`.\n\n**Important:** `config.json` is gitignored. Your personal config stays private; `config.json.example` is what other ICMs receive.\n\n\n---\n\n## Supabase Setup (New ICM)\n\nSee [supabase-setup.md](references/supabase-setup.md) for full setup:\n1. Link project: `supabase link --project-ref <REF>`\n2. Push migrations: `supabase db push`\n3. Deploy functions: `submit-renatus-registration`, `lead-admin-export`\n4. Set secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`, `LEAD_ADMIN_TOKEN`\n5. Verify: submit test registration → check `funnel_leads` + Renatus back office\n\n## Supabase Edge Function Reference\n\n### submit-renatus-registration\nPublic POST endpoint. Registers a lead in Renatus via server-side API (bypasses CORS). Auto-detects public-eligible sessions (no IMA/education requirements). Required secrets: `RENATUS_USERNAME`, `RENATUS_PASSWORD`, `RENATUS_EVENT_ID`.\n\n### lead-admin-export\nAdmin GET endpoint. Requires `x-admin-token` header. Params: `?partner=&limit=`.\n\n### capture-lead\nGeneral-purpose public lead intake with Turnstile bot protection. Insert into `funnel_leads`.\n\n## Key Secrets (Supabase)\n\n| Secret | Required | Purpose |\n|---|---|---|\n| `RENATUS_USERNAME` | Registration | Back office login |\n| `RENATUS_PASSWORD` | Registration | Back office password |\n| `RENATUS_EVENT_ID` | Registration | Default event GUID |\n| `LEAD_ADMIN_TOKEN` | Export | Admin export auth |\n| `SUPABASE_URL` | Always | Project URL |\n| `SUPABASE_SERVICE_ROLE_KEY` | Always | DB access |\n\n## Unsubscribe Sync (Weekly Cron)\n\n```bash\n# Add to crontab\n0 2 * * 0 /home/umbrel/.openclaw/workspace/scripts/weekly_unsubscribe_sync.sh\n\n# Manual run\nCDP_URL=http://127.0.0.1:9222 bash scripts/weekly_unsubscribe_sync.sh\n```\nRequirements: Chrome CDP at 9222 + active Renatus session. See [email-campaign.md](references/email-campaign.md).\n\n## Bounce Recovery\n\n```bash\n# Detect bounces\npython3 scripts/\n\nArchive v2.0.0: 20 files, 64860 bytes\n\nFiles: assets/sample_leads.csv (263b), assets/site/commercial/index.html (9495b), assets/site/confirmation.html (5366b), assets/site/unsubscribe.html (6910b), references/email-campaign.md (4901b), references/event-page-setup.md (3967b), references/supabase-setup.md (3275b), references/workflows.md (7614b), scripts/add_event.py (10860b), scripts/config_loader.py (7044b), scripts/generate_calendar.py (8914b), scripts/generate_email_template.py (21843b), scripts/generate_event_page.py (24526b), scripts/renatus_delete_lead.py (10067b), scripts/renatus_leads.py (8903b), scripts/renatus_register_guest.py (18183b), scripts/send_commercial_email_batches.py (10803b), scripts/weekly_unsubscribe_sync.sh (8115b), SKILL.md (7885b), _meta.json (130b)\n\nArchive v1.3.0: 18 files, 56652 bytes\n\nFiles: assets/sample_leads.csv (263b), assets/site/commercial/index.html (9495b), assets/site/confirmation.html (5366b), assets/site/unsubscribe.html (6910b), references/email-campaign.md (4901b), references/event-page-setup.md (3967b), references/supabase-setup.md (3275b), references/workflows.md (7614b), scripts/config_loader.py (6465b), scripts/generate_email_template.py (21843b), scripts/generate_event_page.py (23387b), scripts/renatus_delete_lead.py (10067b), scripts/renatus_leads.py (8903b), scripts/renatus_register_guest.py (18183b), scripts/send_commercial_email_batches.py (10803b), scripts/weekly_unsubscribe_sync.sh (8115b), SKILL.md (7278b), _meta.json (130b)\n\nArchive v1.2.1: 17 files, 54028 bytes\n\nFiles: assets/sample_leads.csv (263b), assets/site/commercial/index.html (9495b), assets/site/confirmation.html (5366b), assets/site/unsubscribe.html (6910b), references/email-campaign.md (4901b), references/event-page-setup.md (3967b), references/supabase-setup.md (3275b), references/workflows.md (7614b), scripts/generate_email_template.py (21687b), scripts/generate_event_page.py (23235b), scripts/renatus_delete_lead.py (10067b), scripts/renatus_leads.py (8296b), scripts/renatus_register_guest.py (18183b), scripts/send_commercial_email_batches.py (12605b), scripts/weekly_unsubscribe_sync.sh (8115b), SKILL.md (6357b), _meta.json (130b)\n\nArchive v1.2.0: 17 files, 54016 bytes\n\nFiles: assets/sample_leads.csv (263b), assets/site/commercial/index.html (9495b), assets/site/confirmation.html (5366b), assets/site/unsubscribe.html (6910b), references/email-campaign.md (4901b), references/event-page-setup.md (3967b), references/supabase-setup.md (3261b), references/workflows.md (7614b), scripts/generate_email_template.py (21687b), scripts/generate_event_page.py (23235b), scripts/renatus_delete_lead.py (10067b), scripts/renatus_leads.py (8296b), scripts/renatus_register_guest.py (18183b), scripts/send_commercial_email_batches.py (12605b), scripts/weekly_unsubscribe_sync.sh (8115b), SKILL.md (6357b), _meta.json (130b)","readmeExcerpt":"Skill: Renatus Icm Owner: earlvanze Summary: Manage Renatus event campaigns by setting up landing pages, running email blasts, handling guest registrations, exporting leads, and syncing unsubscribes. Tags: latest:2.1.5 Version history: v2.1.5 | 2026-07-22T17:34:06.286Z | user Add sanitized Renatus Back Office order-entry API reference and safety preflight. v2.1.4 | 2026-04-04T18:43:14.351Z | user Add Bitwarden/Browse","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"python3 scripts/generate_event_page.py   --event-url \"https://backoffice.myrenatus.com/Events/EventDetails?eventId=...\"   --output site/my-event/index.html"},{"language":"text","snippet":"Event Landing Page (HTML)\n  ↓ form submit\nSupabase Edge Function: submit-renatus-registration\n  ↓ server-side Renatus API (no CORS)\nRenatus Back Office (lead created + registered)\n  ↓ insert\nSupabase: funnel_leads table\n  ↓\nlead-admin-export edge function ← ICM exports here"},{"language":"bash","snippet":"python3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send"},{"language":"bash","snippet":"python3 scripts/renatus_register_guest.py \\\n  --first-name Jane --last-name Smith \\\n  --email jane@example.com --phone \"(555) 555-5555\" \\\n  --event-id 0817966f-b9bb-448e-bbb8-b4160115bcc8"},{"language":"bash","snippet":"python3 scripts/renatus_delete_lead.py --email jane@example.com --execute"},{"language":"bash","snippet":"python3 scripts/generate_calendar.py --output site/calendar.html\npython3 scripts/generate_calendar.py --dry-run"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: renatus-icm\ndescription: Manage Renatus event marketing campaigns as an ICM. Use when running event registration campaigns, sending commercial email blasts, setting up event landing pages, exporting leads from Supabase, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Requires: Renatus credentials, Supabase project, SMTP sender account. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\".\n---\n\n## ⚠️ Credentials & Security\n\n**Required environment variables** (declare these before running any script):\n\n| Variable | Purpose | Minimum Scope |\n|---|---|---|\n| `RENATUS_USERNAME` | Renatus back office login | ICM-level account |\n| `RENATUS_PASSWORD` | Renatus back office login | ICM-level account |\n| `SUPABASE_URL` | Supabase project URL | Read leads |\n| `LEAD_ADMIN_TOKEN` | Supabase admin export | `anon` key or limited service role |\n| `SENDER_EMAIL` | From address for campaigns | Send-only SMTP account |\n| `SENDER_PASSWORD` | SMTP auth for email | Send-only |\n| `SUPABASE_SERVICE_ROLE_KEY` | Supabase admin actions (destructive) | Service role — do not use for read-only ops |\n\n**Security recommendations:**\n- Use a dedicated Supabase project for testing — do not supply your production `service_role_key`\n- Create a least-privilege Supabase anon key scoped to `funnel_leads` table reads only\n- Use a separate Chrome/Brave **profile** for CDP access (not your main browser session)\n- `renatus_delete_lead.py` performs deletions — always run with `--dry-run` first\n- Rotate credentials after use; revoke tokens that were shared or exposed\n- Do not commit real credentials to `config.json` — use the `.example` file and environment variables\n\n**CDP access:** Scripts connect to `http://127.0.0.1:9222` to inspect your browser's localStorage/cookies for Renatus auth tokens. This requires Chrome/Brave launched with `--remote-debugging-port=9222`. The skill does not extract your master Renatus password from CDP — it reads existing session tokens only.\n\n---\nname: renatus-icm\ndescription: Run a Renatus event marketing campaign as an ICM (Independent Campaign Manager). Use when managing Renatus event registrations, sending commercial email campaigns, setting up event landing pages, downloading/exporting leads, syncing unsubscribes to Renatus, or performing browser-based guest registration via CDP. Handles: Supabase Edge Function registration (submit-renatus-registration), gws/gog email sending (commercial-core-day1), bounce detection and SMS recovery, CDP browser registration/delete scripts, weekly unsubscribe cron, and lead export via lead-admin-export. Trigger phrases: \"run a Renatus event campaign\", \"send Renatus email campaign\", \"register a guest for Renatus\", \"download Renatus leads\", \"set up event landing page\", \"handle Renatus unsubscribes\".\n---\n# Renatus ICM Skill\n\nComplete toolkit for running a Renatus ev"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7a5vdq619nymw8zq4aq95b49846rhq\",\n  \"slug\": \"renatus-icm\",\n  \"version\": \"2.1.5\",\n  \"publishedAt\": 1784741646286\n}"},{"path":"references/email-campaign.md","content":"# Email Campaign Guide\n\n## Overview\n\nCommercial email campaigns are sent from `YOUR_SENDER@gmail.com` via gws CLI. The email template is `commercial-core-day1.html`. Campaigns target leads from `renatus_leads.csv` and track delivery via `logs/email_send_log.json`.\n\n## Campaign Assets\n\n| File | Purpose |\n|---|---|\n| `email/commercial-core-day1.html` | HTML email template |\n| `renatus_leads.csv` | Lead list (export via `renatus_leads.py --export`) |\n| `logs/email_send_log.json` | Sent log (resumable sends) |\n| `logs/bounced_emails.json` | Bounced email tracking |\n\n### Getting the Leads CSV\n```bash\n# Export fresh from Supabase\npython3 scripts/renatus_leads.py --export\n\n# Convert existing JSON to CSV (if you have old JSON export)\npython3 scripts/renatus_leads.py --convert-json\n```\n\n## Sending Emails\n\n### Prerequisites\n- `gws` CLI authenticated as `YOUR_SENDER@gmail.com`\n- `renatus_leads.csv` exists with at least `email` column\n- `commercial-core-day1.html` template\n\n### Dry Run (Preview)\n```bash\npython3 scripts/send_commercial_email_batches.py --dry-run\n```\n\n### Send in Batches (with Resume)\n```bash\n# First batch\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 0 --send\n\n# Resume from batch 2\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 20 --send\n\n# Resume from batch 3\npython3 scripts/send_commercial_email_batches.py --batch-size 20 --start 40 --send\n```\n\n### Batch Script Flags\n| Flag | Default | Description |\n|---|---|---|\n| `--batch-size` | 20 | Emails per batch |\n| `--start` | 0 | Starting index |\n| `--dry-run` | — | Preview without sending |\n| `--send` | — | Actually send |\n| `--delay` | 2.0 | Seconds between sends |\n\n## Personalizing the Template\n\nThe template uses `{{recipient_email}}` as a placeholder for the unsubscribe link target.\n\n### Adding Personalized Unsubscribe URL\nReplace `{{recipient_email}}` with a base64-encoded unsubscribe URL:\n\n```python\nimport base64\n\ndef encode_unsubscribe_url(email: str, base_url: str = \"https://YOUR_DOMAIN/unsubscribe.html\") -> str:\n    encoded = base64.urlsafe_b64encode(email.encode()).decode().rstrip('=')\n    return f\"{base_url}?e={encoded}\"\n```\n\n### Unsubscribe URL in Email Template\n```html\n<a href=\"https://YOUR_DOMAIN/unsubscribe.html?e={{recipient_email}}\"\n   style=\"color: #999999; font-size: 12px;\">\n  Unsubscribe\n</a>\n```\n\nWhen the user clicks unsubscribe, their email is pre-filled and they confirm removal.\n\n## Subject Line Options\n\nTested subject lines for Commercial Core:\n1. `They turned $7K into $103M. Learn how (April 16)`\n2. `Commercial real estate: free training from $100M operators`\n3. `[Only 9 days] Learn commercial underwriting from operators`\n4. `From skeptical to 90+ doors in 8 months (free training)`\n\n## Bounce Handling\n\n### Check for Bounces\n```bash\npython3 scripts/handle_bounced_emails.py --check\n```\n\n### Export Bounced Contacts with Phone Numbers for SMS\n```bash\npython3 scripts/handle_bounced_emails.py --export-sms\n# Output: logs/sms_fo"},{"path":"references/event-page-setup.md","content":"# Event Page Setup Guide\n\n## Overview\n\nThe event landing page is a static HTML form at `site/commercial/index.html` (or similar path on your hostinger/YOUR_DOMAIN deployment). It submits directly to a Supabase Edge Function which registers the lead in Renatus Back Office.\n\n## Page Structure\n\n### Registration Form Fields\n- `firstName` (required)\n- `lastName` (required)\n- `email` (required)\n- `phone` (required)\n- `website` (honeypot — hidden, must be empty)\n- `source_page` (auto-populated from `window.location.href`)\n\n### Submit Endpoint\n```\nPOST https://<PROJECT_REF>.supabase.co/submit-renatus-registration\n```\n\n### Request Body\n```json\n{\n  \"firstName\": \"Jane\",\n  \"lastName\": \"Smith\",\n  \"email\": \"jane@example.com\",\n  \"phone\": \"(555) 555-5555\",\n  \"website\": \"\",\n  \"source_page\": \"https://YOUR_DOMAIN/commercial/\"\n}\n```\n\n### Success Response\n```json\n{\n  \"ok\": true,\n  \"eventId\": \"0817966f-b9bb-448e-bbb8-b4160115bcc8\",\n  \"eventName\": \"Commercial Core - Live Education\",\n  \"registrationId\": \"...\",\n  \"leadId\": \"...\",\n  \"guestUserId\": \"...\",\n  \"registeredSessions\": [\"Session Name 1\", \"Session Name 2\"]\n}\n```\n\n### Error Response\n```json\n{ \"error\": \"Error message\", \"details\": \"optional details\" }\n```\n\n## Setting Up a New Event Page\n\n### 1. Copy the Template\nCopy `site/commercial/index.html` to a new directory, e.g., `site/<event-slug>/index.html`\n\n### 2. Update the Edge Function URL\nIn the `<script>` section, update:\n```javascript\nconst EDGE_URL = 'https://<PROJECT_REF>.supabase.co/submit-renatus-registration';\n```\n\n### 3. Update Event Details\nUpdate the visible event details in the HTML (date, location, speakers, description).\n\n### 4. Update the Event ID\nEither:\n- Set `RENATUS_EVENT_ID` secret in Supabase (affects all form submissions)\n- Add `eventId` field to the form and pass it in the payload\n\n### 5. Get the Event GUID from Renatus\n1. Log into `backoffice.myrenatus.com`\n2. Navigate to Events\n3. Open the event\n4. Copy the event GUID from the URL or API response\n\n### 6. Verify Registration Flow\nSubmit a test registration and confirm:\n- Lead appears in `funnel_leads` table\n- Lead appears in Renatus Back Office\n- Email confirmation is sent by Renatus\n\n## Customizing the Landing Page\n\n### Styling\nThe page uses CSS custom properties for easy theming:\n```css\n:root {\n  --bg: #0f172a;\n  --card: #111827;\n  --accent: #22c55e;\n  --text: #e5e7eb;\n}\n```\n\n### Adding a Second Event (In-Person Option)\nModify the `feesPayload` to include multiple sessions, or use separate event pages with different event IDs.\n\n### Redirect to Confirmation Page\nAfter successful form submission:\n```javascript\nif (resp.ok) {\n  window.location.href = '/confirmation.html';\n}\n```\n\n## Hosting Options\n\n### Option A: Deploy with your hosting scripts\n```bash\npython3 scripts/deploy_hostinger.py\n```\n\n### Option B: Manual FTP Upload\nUpload `site/commercial/` directory to your web host's `public_html/` or equivalent.\n\n### Option C: Subdirectory on Existing Site\nUpload to `public_html/commercial/` — page wi"},{"path":"references/order-entry-backoffice-api.md","content":"# Renatus Back Office Order Entry API\n\nThis reference is a sanitized, capture-derived map of the Renatus **Orders** page. It records endpoint paths, parameter names, status counts, and JSON key shapes only. It contains no captured credentials, identifiers, addresses, payment data, or response records.\n\n## Safety Boundary\n\n- The capture showed authenticated browser transport through `backoffice.myrenatus.com`; use a current, logged-in Chrome/Brave CDP session. Do not reuse values from the HAR.\n- Read calls use `GET /api/queryproxy/execute?url=<target-path>` with target-specific parameters appended to the proxy request.\n- Command calls use `POST /api/commandproxy/execute?url=<target-path>` with JSON bodies. The observed browser requests used `x-requested-with` and an XSRF header.\n- `POST` endpoints below can create a lead or save an order. They are external actions: run a dry-run/read preflight first and do not call them unless the user explicitly approves the exact customer, products, payment method, and submission state.\n- Do not replay captured payloads. Build values from the live browser session and the authorized order only.\n\n## Capture Scope\n\nThe July 22, 2026 order-entry capture contains 78 network entries. All 50 query-proxy calls and all four command-proxy calls returned HTTP 200. It covers the Orders page, lead/customer selection, product and payment lookup, and one successful order-container save.\n\n## Read Endpoints\n\n| Target path | Parameters observed | Use |\n|---|---|---|\n| `/api/orders/customersList` | `Value` | Customer search/list |\n| `/api/orders/sellersList` | `Value` | Seller search/list |\n| `/api/orders/containers/search` | `CurrentPage`, `PageSize`, `SortDirection`, `SortField`, `TotalCount`, `UserId`, `StatusFilter[n][Join]`, `StatusFilter[n][Data][Item]`, `StatusFilter[n][Data][Operation]` | Existing order-container list |\n| `/api/orders/products` | — | Product catalog |\n| `/api/orders/agreements` | — | Agreement catalog |\n| `/api/orders/availableproductsforcustomer` | `BuyerLeadId`, `IsInternational`, `LeadCountryCode` | Products eligible for the selected customer |\n| `/api/orderpayments/downpayments` | `CountryCode`, `ProductIds[]` | Down-payment options for selected products |\n| `/api/paymentMethod/getUserPaymentMethods` | `CurrentDate`, `UserId` | Saved payment methods |\n| `/api/marketinglead/validatelead` | `Value` | Lead validation |\n| `/api/userprofile/current` | — | Current authenticated user |\n\nThe page also loads campaign/status, settings, domain, notification, grid-filter, and event-status data. Those calls are contextual UI support, not required order-entry mutations.\n\n## Observed Command Endpoints and Payload Shapes\n\n### `POST /api/marketingLead/customerbyleadid`\n\nObserved twice, returning HTTP 200. JSON shape:\n\n```json\n{ \"Value\": \"string\", \"Key\": \"string\" }\n```\n\n### `POST /api/guestRegistration/addcustomer`\n\nObserved once, returning HTTP 200. This can create a customer/lead. JSON key shape:\n\n```text\nLeadId, Owne"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Manage Renatus event campaigns by setting up landing pages, running email blasts, handling guest registrations, exporting leads, and syncing unsubscribes. Skill: Renatus Icm Owner: earlvanze Summary: Manage Renatus event campaigns by setting up landing pages, running email blasts, handling guest registrations, exporting leads, and syncing unsubscribes. Tags: latest:2.1.5 Version history: v2.1.5 | 2026-07-22T17:34:06.286Z | user Add sanitized Renatus Back Office order-entry API reference and safety preflight. v2.1.4 | 2026-04-04T18:43:14.351Z | user Add Bitwarden/Browse","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1484,"uniquenessScore":47,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T20:49:14.416Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T20:49:14.416Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T03:39:45.891Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}