Email Campaigns
Email campaigns allow OneLibro admins to send bulk marketing emails to targeted users. Create campaigns with custom audiences, track delivery metrics, and manage sending schedules—all from the admin dashboard.
Overview
The email campaigns system enables:
- Bulk Email Sending - Send to hundreds or thousands of users
- Audience Targeting - Filter recipients by signup date, activity status
- Template Selection - Choose from pre-built email templates
- Draft Management - Save campaigns as drafts before sending
- Send Scheduling - Send immediately or schedule for later (coming soon)
- Delivery Analytics - Track sent, delivered, opened, clicked, bounced
- Campaign History - View all past and current campaigns
Use Cases:
- Product announcements
- Feature launches
- User onboarding campaigns
- Re-engagement emails
- Seasonal promotions
- Company updates
Access
Requirements
- Admin Access: Only users with
is_admin = truecan create campaigns - Active Templates: At least one email template must exist and be active
URL
https://admin.yatheeshnagella.com/emails/campaigns
Campaigns Dashboard
Overview
The campaigns dashboard displays all campaigns with stats and filtering options.
URL: /admin/emails/campaigns
Dashboard Stats
Four key metrics displayed at the top:
1. Total Campaigns
- Count of all campaigns (all statuses)
- Includes drafts, scheduled, sent, cancelled
2. Sent
- Count of successfully sent campaigns
- Status = 'sent'
3. Scheduled
- Count of campaigns scheduled for future sending
- Status = 'scheduled'
4. Drafts
- Count of draft campaigns not yet sent
- Status = 'draft'
Campaigns Table
Columns Displayed:
| Column | Description |
|---|---|
| Campaign | Campaign name, subject line, template name |
| Status | Current status badge (draft, scheduled, sending, sent, cancelled) |
| Recipients | Total number of target recipients |
| Sent | Number sent / Total recipients + send date |
| Created | Campaign creation date |
| Actions | View details, delete (drafts only) |
Status Badges:
- 🕐 Draft (gray) - Not yet sent or scheduled
- 📅 Scheduled (blue) - Scheduled for future sending
- ⏳ Sending (yellow) - Currently being sent
- ✅ Sent (green) - Successfully sent
- ❌ Cancelled (red) - Campaign cancelled
Filters and Search
Search Bar:
- Search by campaign name or subject line
- Real-time filtering as you type
Status Filter Dropdown:
- All Statuses
- Draft
- Scheduled
- Sent
Pagination:
- 10 campaigns per page
- Previous/Next buttons for navigation
Creating a Campaign
Step-by-Step: Campaign Creation
1. Navigate to Campaigns:
- Go to Admin Dashboard
- Click Emails > Campaigns
- Click "New Campaign" button (top right)
2. Enter Campaign Details:
Campaign Name:
- Internal name for identification
- Not visible to recipients
- Example: "Beta Invite Campaign - January 2025"
Subject Line:
- Email subject recipients will see
- Keep under 50 characters for best open rates
- Use action-oriented language
- Example: "You're invited to join OneLibro!"
Template Selection:
- Choose from dropdown of active email templates
- Templates are pre-designed with React Email
- Shows template name and category
3. Target Audience:
Active Users Only (checkbox):
- ✅ Checked: Only send to active users (
is_active = true) - ❌ Unchecked: Send to all users (including inactive)
- Recommendation: Keep checked to avoid emailing inactive/deleted accounts
Signup Date Range (optional):
- Signed up after: Only users who signed up after this date
- Signed up before: Only users who signed up before this date
- Leave blank to include all signup dates
Examples:
Target: Users who signed up in January 2025
- Signed up after: 2025-01-01
- Signed up before: 2025-01-31
Target: Users who signed up in last 30 days
- Signed up after: 2024-12-25
- Signed up before: (leave blank)
Recipient Count:
- Displays in real-time as you adjust filters
- Updates automatically when you change audience filters
- Shows number of users matching criteria
- Warning: If count is 0, adjust filters before creating campaign
4. Send Test Email (optional but recommended):
- Enter your email address in test email field
- Click "Send Test"
- Verify template renders correctly
- Check subject line, content, links, formatting
- Test on different email clients (Gmail, Outlook, Apple Mail)
5. Create Campaign:
Save as Draft:
- Saves campaign without sending
- Can edit later
- No emails sent
Send Now:
- Sends to all recipients immediately
- Confirmation prompt shows recipient count
- Cannot be undone once sending starts
- Batch sending with rate limiting
Campaign Creation Workflow
[New Campaign Button]
↓
[Fill Campaign Details]
- Name
- Subject
- Template
↓
[Target Audience]
- Active users only?
- Signup date filters
- View recipient count
↓
[Send Test Email] (optional)
- Verify template
↓
[Save as Draft] OR [Send Now]
↓
[Campaign Created]
- Draft: Can edit/send later
- Sending: Emails being sent
↓
[Campaign Sent]
- View analytics
Audience Targeting
Filter Options
1. Active Users Only
Purpose: Exclude inactive or deleted accounts
When to Enable:
- Most campaigns (best practice)
- Product updates
- Feature announcements
When to Disable:
- Re-engagement campaigns targeting inactive users
- Win-back campaigns
Database Query:
WHERE is_active = true
2. Signup Date Range
Purpose: Target users by when they joined
Use Cases:
Recent Signups (Onboarding):
Signed up after: (7 days ago)
Signed up before: (today)
- Welcome series
- Getting started tips
- Early user feedback
Cohort Analysis:
Signed up after: 2025-01-01
Signed up before: 2025-01-31
- January 2025 cohort
- Monthly updates
- Cohort-specific features
Long-Time Users:
Signed up after: (blank)
Signed up before: 2024-01-01
- Users for 1+ year
- Loyalty rewards
- Advanced feature announcements
Database Query:
WHERE created_at >= 'signup_after'
AND created_at <= 'signup_before'
Target Audience Examples
Example 1: All Active Users
Active Users Only: ✅ Yes
Signed up after: (blank)
Signed up before: (blank)
Result: All active users, any signup date
Example 2: New Users (Last 7 Days)
Active Users Only: ✅ Yes
Signed up after: 2025-01-17
Signed up before: 2025-01-24
Result: Active users who joined in last week
Example 3: Inactive Users for Re-engagement
Active Users Only: ❌ No
Signed up after: (blank)
Signed up before: 2024-06-01
Result: All users (including inactive) who signed up before June 2024
Use Case: Re-engagement campaign for dormant accounts
Sending Campaigns
Send Now
How It Works:
- Click "Send Now" button
- Confirmation prompt: "This will send
{N}emails immediately. Continue?" - Click "OK" to confirm
- Campaign status changes to "Sending"
- Batch sending begins (rate-limited)
- Status changes to "Sent" when complete
Batch Sending:
- Emails sent in batches (e.g., 100 at a time)
- Delay between batches (e.g., 1 second)
- Prevents rate limiting from email provider
- Configurable batch size and delay
Example Timeline (1,000 recipients):
Batch 1 (100 emails): 0:00 - 0:05
[1 second delay]
Batch 2 (100 emails): 0:06 - 0:11
[1 second delay]
...
Batch 10 (100 emails): 0:54 - 0:59
Total Time: ~1 minute for 1,000 emails
Schedule for Later
Status: Coming Soon
Planned Features:
- Schedule campaigns for specific date/time
- Timezone selection
- Automatic sending at scheduled time
- Edit/cancel scheduled campaigns before send time
Campaign Analytics
Delivery Metrics
Total Recipients:
- Number of users targeted by audience filters
- Set when campaign created
Total Sent:
- Number of emails successfully sent to Resend
- May be less than recipients if some failed
Total Delivered:
- Number of emails confirmed delivered to inbox
- Reported by email provider (Resend)
- Delivery rate = (Delivered / Sent) × 100
Total Bounced:
- Number of emails that bounced (hard or soft bounce)
- Hard Bounce: Invalid email address, permanent failure
- Soft Bounce: Mailbox full, temporary failure
- Bounce rate = (Bounced / Sent) × 100
Opened (coming soon):
- Number of recipients who opened the email
- Tracked with invisible pixel
- Open rate = (Opened / Delivered) × 100
Clicked (coming soon):
- Number of recipients who clicked a link
- Tracked with redirect URLs
- Click rate = (Clicked / Delivered) × 100
Good vs. Bad Metrics
Healthy Campaign:
Total Recipients: 1,000
Total Sent: 1,000 (100%)
Total Delivered: 970 (97%)
Total Bounced: 30 (3%)
- Delivery rate > 95% = good
- Bounce rate < 5% = good
Problem Campaign:
Total Recipients: 1,000
Total Sent: 1,000 (100%)
Total Delivered: 800 (80%)
Total Bounced: 200 (20%)
- Delivery rate < 90% = investigate
- Bounce rate > 10% = clean email list
Viewing Campaign Details
1. Click on Campaign:
- In campaigns table, click the 👁️ (eye) icon
- Or click anywhere on campaign row
2. Campaign Details Page:
Campaign Info:
- Name
- Subject line
- Template used
- Creator (admin who created it)
- Creation date
Status & Timeline:
- Current status
- Scheduled date (if applicable)
- Sent date (if sent)
Audience Filters:
- Active users only: Yes/No
- Signup date range
Delivery Stats:
- Total recipients
- Sent
- Delivered
- Bounced
- Delivery rate
- Bounce rate
Actions:
- View email template preview (coming soon)
- Duplicate campaign (coming soon)
- Cancel sending (if scheduled)
- Delete (drafts only)
Managing Campaigns
Editing Campaigns
Drafts:
- Can be edited before sending
- Click campaign → Edit details
- Change name, subject, template, audience
Sent/Sending/Scheduled:
- Cannot be edited once sending has started
- Prevents confusion and delivery issues
- To make changes: Create new campaign with updated details
Deleting Campaigns
Who Can Delete:
- Only draft campaigns can be deleted
- Sent campaigns are permanent (for audit trail)
How to Delete:
- Go to campaigns dashboard
- Find draft campaign
- Click 🗑️ (trash) icon
- Confirm deletion
- Campaign permanently removed
Warning: Cannot be undone. Campaign data is deleted from database.
Cancelling Campaigns
Scheduled Campaigns (coming soon):
- Can cancel before scheduled send time
- Click "Cancel Campaign" button
- Status changes to "Cancelled"
- No emails sent
Sending Campaigns:
- Cannot cancel once sending has started
- Batch sending completes for all queued emails
Email Templates
Available Templates
Campaigns use pre-built email templates from the email_templates table.
Template Selection:
- Dropdown shows all active templates
- Displays: Template Name (Category)
- Example: "Welcome Email (Transactional)"
Common Templates:
- Welcome Email
- Product Update
- Feature Announcement
- Re-engagement
- Weekly Newsletter
- Seasonal Promotion
Creating New Templates
Process:
- Admin creates React Email template component
- Adds template to
email_templatestable - Sets
is_active = true - Template appears in campaign creation dropdown
Template Requirements:
- Built with
@react-email/components - Responsive design
- Unsubscribe link included
- Company branding
Best Practices
Campaign Creation
Naming Conventions:
- Use descriptive names: "Feature Launch - Budget Alerts - Jan 2025"
- Include date: Helps track campaigns over time
- Include purpose: "Re-engagement", "Onboarding", "Update"
Subject Lines:
- Keep under 50 characters (mobile optimization)
- Use action words: "Join", "Discover", "Get", "Try"
- Personalize when possible: "
{{name}}, you're invited!" - Avoid spam triggers: "FREE", "URGENT", all caps
- A/B test different subject lines
Examples:
- ✅ "Try our new budget tracking feature"
- ✅ "You're invited to OneLibro beta"
- ✅ "January spending insights are here"
- ❌ "FREE MONEY CLICK NOW!!!"
- ❌ "URGENT: ACT IMMEDIATELY"
Audience Targeting
Start Broad, Then Narrow:
- First campaign: All active users
- Analyze results (open rate, click rate)
- Segment based on engagement
- Future campaigns: Target high-engagement segments
Cohort Campaigns:
- Target users by signup month
- Send cohort-specific updates
- Track cohort performance over time
Avoid Over-Sending:
- Don't send more than 1 campaign per week
- Space out non-critical campaigns
- Respect user preferences (check notification settings)
Testing Before Sending
Always Send Test Emails:
- Send to yourself
- Check subject line in inbox
- Verify all links work
- Check responsive design (mobile, desktop)
- Test in multiple email clients (Gmail, Outlook, Apple Mail)
- Proofread for typos
Test Checklist:
- Subject line appears correctly
- Email renders on desktop
- Email renders on mobile
- All links work (no 404s)
- Unsubscribe link works
- Images load
- No typos or grammar errors
- Branding is correct
Monitoring After Sending
First Hour:
- Check delivery metrics
- Bounce rate should be < 5%
- If high bounce rate (> 10%), investigate email list quality
First Day:
- Monitor open rates
- Average: 15-25% for marketing emails
- If < 10%, review subject line and send time
First Week:
- Monitor click rates
- Average: 2-5% for marketing emails
- Review call-to-action effectiveness
Troubleshooting
High Bounce Rate
Causes:
- Invalid email addresses in database
- Typos when users signed up
- Users deleted email accounts
Solutions:
- Review bounced emails in Resend dashboard
- Remove hard-bounced emails from database
- Implement email validation on signup
- Regularly clean email list (remove inactive/bounced)
Low Open Rate
Causes:
- Weak subject line
- Poor send time (wrong timezone)
- Emails going to spam
- Audience not interested
Solutions:
- A/B test subject lines
- Send during business hours (9 AM - 5 PM)
- Check spam score with Mail Tester
- Improve email content relevance
- Segment audience better
Low Click Rate
Causes:
- Weak call-to-action
- Too many links (confusing)
- Links not obvious
- Content not relevant
Solutions:
- Use clear CTA buttons
- Limit to 1-2 primary CTAs
- Make links stand out (color, size)
- Improve content relevance
- Personalize email content
Emails Going to Spam
Causes:
- Missing SPF/DKIM records
- High spam complaint rate
- Spam trigger words in subject/content
- Low engagement (opens/clicks)
Solutions:
- Verify SPF, DKIM, DMARC records in DNS
- Avoid spam trigger words
- Include unsubscribe link (required by CAN-SPAM)
- Improve content quality
- Only send to engaged users
Database Schema
Email campaigns are stored in the email_campaigns table:
CREATE TABLE email_campaigns (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
subject TEXT NOT NULL,
template_key TEXT NOT NULL REFERENCES email_templates(template_key),
target_audience JSONB NOT NULL, -- Audience filter criteria
status TEXT DEFAULT 'draft', -- 'draft' | 'scheduled' | 'sending' | 'sent' | 'cancelled'
scheduled_at TIMESTAMPTZ,
sent_at TIMESTAMPTZ,
total_recipients INTEGER,
total_sent INTEGER,
total_delivered INTEGER,
total_bounced INTEGER,
created_at TIMESTAMPTZ DEFAULT NOW(),
created_by UUID REFERENCES users(id),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
Key Fields:
target_audience: JSON object with filter criteria (active_only, signup_after, signup_before)status: Current campaign statustotal_*: Delivery metrics updated as emails are sent
Related Features
- Admin Dashboard - Complete admin guide
- Email System - Email infrastructure details
- Notification Preferences - User email settings
Summary
Email campaigns in OneLibro provide:
- ✅ Bulk email sending to targeted audiences
- ✅ Audience filtering by activity status and signup date
- ✅ Draft and immediate send options
- ✅ Template-based email creation
- ✅ Delivery analytics (sent, delivered, bounced)
- ✅ Campaign management (view, delete drafts)
- ✅ Rate-limited batch sending
- ✅ Test email functionality
Create your first campaign today to engage users and grow OneLibro!