Project Description
A gamified, location-aware marketing and engagement platform for Mad Monkey Creations. The project combines QR codes, short links, email automation, and workflow orchestration to create a scavenger-hunt-style experience featuring "Benny the Monkey" that drives brand engagement, email list growth, and repeat customer interaction.
Primary Goal
Email List Growth - Build a verified, engaged email list through gamified QR code interactions and contest entries
Key Objectives
- Brand Engagement - Create memorable, interactive experiences with the Mad Monkey brand
- Email List Growth - Primary goal: build high-quality, double opt-in subscriber list
- Repeat Customer Interaction - Encourage multiple touchpoints and ongoing engagement
- Physical-to-Digital Traffic Conversion - Drive real-world QR scans to digital engagement
- Contest Entries - Monthly drawings for free Mad Monkey tee-shirts
- Location-Based Marketing - Track where Benny has been and target campaigns by city/region
How It Works
User Journey
- Discovery - User finds a QR code card at a venue or receives a "traveler" card
- Scan - User scans QR code with phone (https://mmlnk.us/T##)
- Redirect - Short URL redirects to n8n webhook that logs the scan
- Landing Page - User lands on mad-monkey-creations.com/benny
- Form Submission - User enters name, email, and where they found Benny
- Double Opt-In - Verification email sent via Listmonk
- Confirmation - User confirms subscription and is entered into monthly contest
- Welcome Email - Automated welcome message sent
- Story Drip - Day 1: Story email about where Benny has been
- Reward - Day 3: Discount code (BANANAS10) sent
- Monthly Drawing - Random verified entry selected for free tee-shirt
Card Types
Nest Cards
Stationary cards placed at fixed venues (coffee shops, stores, etc.)
Quantity: 200-300 cards
Purpose: Generate consistent local traffic
Traveler Cards
Mobile cards that move from person to person with a "move code"
Quantity: 50-100 cards
Purpose: Viral spread and long-distance tracking
Card Design
- Size: Business card (3.5" x 2")
- Material: PVC for durability
- Front: Big Benny graphic + "Track My Monkey"
- Back: QR code + short URL + instructions + move code (for travelers)
- Call-to-Action: "Scan. Tell us where. Confirm email. Monthly winner!"
Technology Stack
n8n
v1.107.4
Self-hosted workflow automation engine
PostgreSQL
v16
Primary database for all data
Shlink
Stable
URL shortening service (FOSS)
Listmonk
Latest
Open-source email marketing
Traefik
Active
Reverse proxy with SSL/TLS
Docker
-
Container orchestration
ForwardMail.net
-
Email delivery service
Node.js
v24.12.0
Runtime environment
mini-qr
-
QR code generator
System Architecture
Infrastructure - Single Docker Host
Docker Host: bennybeen (10.0.0.250)
External IP: 76.150.65.61 (dynamic - see DNS-UPDATE-PROCESS.md)
Project Path: /home/bennybeen/mad-monkey/
Admin Whitelist: 10.0.0.157
| Component | Port on 10.0.0.250 | Domain | Status |
|---|---|---|---|
| PostgreSQL | 5432 | Internal only | Active |
| n8n | 5678 | n8n.mad-monkey-creations.com, hooks.mad-monkey-creations.com | Active |
| Shlink | 8081 | mmlnk.us, admin.mmlnk.us | Active |
| Traefik | 80, 443, 8080 | Internal routing | Active |
| Listmonk | 9000 | list.mad-monkey-creations.com | Active |
| Landing Page | 80 (nginx) | adventure.mad-monkey-creations.com | Active |
Data Flow
Scan → Entry → Verification Flow
- User scans QR code → https://mmlnk.us/T42
- Shlink redirects → https://hooks.mad-monkey-creations.com/scan?qr_id=T42
- n8n logs scan → Inserts to PostgreSQL
scanstable (IP, UA, timestamp, geo) - n8n returns 302 → https://mad-monkey-creations.com/benny?qr_id=T42
- User fills form → Name, Email, "Where did you find Benny?"
- Form POSTs to n8n → https://hooks.mad-monkey-creations.com/entry
- n8n validates & stores → Inserts to
entriestable (verified=false) - n8n calls Listmonk API → Creates/updates subscriber with tags
- Listmonk sends double opt-in email → User clicks confirmation link
- Listmonk webhook to n8n → /listmonk/confirm
- n8n marks verified → Updates
entries.verified=true - n8n triggers drip → Welcome email, Story email (Day 1), Reward email (Day 3)
Database Schema
Core Tables (Current)
| Table | Purpose | Key Fields | Status |
|---|---|---|---|
subscribers |
Primary subscriber data | id, qr_id, email (UNIQUE), name, found_location, subscribe_adventures, subscribe_marketing, token, verified, verified_at, listmonk_id, created_at | Active |
contest_entries |
Monthly contest entries | id, subscriber_id (FK), month (YYYY-MM), winner, created_at | Active |
scan_tokens |
One-time QR tokens | id, token (UNIQUE), qr_id, used, used_at, expires_at, created_at | Active |
Deprecated Tables
| Table | Original Purpose | Status |
|---|---|---|
entries |
Old contest entries (replaced by subscribers + contest_entries) | Deprecated |
users |
Old subscriber profiles (replaced by subscribers) | Deprecated |
cards |
QR card inventory (future use) | Planned |
scans |
Scan event logs (future use) | Planned |
Automation Workflows
n8n Workflows (All Active)
| Workflow | ID | Description | Status |
|---|---|---|---|
| 1. Scan Intake | XjqHOdsNzN1Gg4n6 |
Log QR scans, generate tokens, redirect to landing page | Active |
| 2. Email Capture | AeiltZEKb4YvAbQG |
Process form submissions, validate tokens, create Listmonk subscribers, send welcome email | Active |
| 3. Confirmation | eoW1DejeZlfPA3l1 |
Handle Listmonk webhook, mark verified, create contest entry | Active |
| 4. Story & Reward Drip | YSzXpljWCgHFQo0g |
Automated email sequence: Day 1 Story (Template 6), Day 3 Reward (Template 7) | Active |
| 5. Monthly Winner Selection | cKATiI2Kh5UhIBIX |
Cron (1st of month, 9 AM) - Select random verified entry, send winner email (Template 8) | Active |
Future Workflows (Not Yet Implemented)
- Re-engagement - Send nudge emails to inactive subscribers
- Stuck/Stagnant Card Detection - Alert when cards haven't been scanned in 10+ days
Key Performance Indicators
Tracking Metrics
- QR scans per location
- Form starts vs completions
- Double opt-in confirmation rate
- Email delivery success rate
- Stuck card rate (>10 days no scan)
- Stagnant card rate (>45 days no scan)
- Rescue mission success rate
- Monthly contest entries
- Campaign ROI
- Email open rates and click-through rates
- Repeat engagement (scans per card, time between scans)
Security & Privacy
Data Protection
- No PII stored beyond email and name
- IP addresses anonymized (last octet removed for IPv4)
- HTTPS everywhere with Let's Encrypt certificates
- Least-privilege API keys
- Credentials stored as environment variables (never hard-coded)
- Regular API key rotation
Compliance
- Email opt-in only (double opt-in required)
- CAN-SPAM compliant unsubscribe links in every email
- GDPR-aware data minimization
- Privacy policy and contest rules linked on forms
- Clear consent checkbox on forms
Security Measures
- Rate limiting by email/IP/device
- CAPTCHA for high-volume sources (Cloudflare Turnstile or hCaptcha)
- Monthly entry limit per email
- IP velocity checks
- VPN/proxy detection with additional validation
- Admin endpoints IP-restricted (/rest on admin.mmlnk.us)
- Database backups encrypted
- Webhook signature validation (planned)
Deployment Phases
| Phase | Description | Status |
|---|---|---|
| Phase 1 | Infrastructure Setup (DNS, databases, containers) | Complete |
| Phase 2 | n8n Workflow Creation and Testing | BLOCKED |
| Phase 3 | QR Card Production (10 test cards) | Not Started |
| Phase 4 | End-to-End Testing | Not Started |
| Phase 5 | Pilot Launch (20-50 cards) | Not Started |
| Phase 6 | Full Deployment (200-300 cards) | Not Started |
Project Status - BLOCKED
Current Phase: Phase 2 - Completion (BLOCKED)
Blocking Issue: Duplicate opt-in emails being sent. Users receive both custom Template 10 email (broken opt-in URL) AND default Listmonk opt-in email (works). Need to fix before continuing Phase 2 testing.
What's Complete:
- All Docker containers deployed on BennyBeen (10.0.0.250)
- NGINX SSL Proxy (10.0.0.251) configured with Let's Encrypt
- All 5 n8n workflows active and tested
- Listmonk configured with ForwardMail.net SMTP
- Landing page deployed at adventure.mad-monkey-creations.com
- End-to-end flow validated (Execution #102 SUCCESS)
Next Steps (After Blocking Issue Resolved):
- Complete end-to-end test with real email confirmation
- Validate drip campaign timing (24h/48h waits)
- Test monthly winner selection workflow
- Generate 10 test QR codes