Some checks failed
BotServer CI / build (push) Failing after 13s
13 KiB
13 KiB
Campaigns App Improvements - Part 2
Additional Features (Continued)
11. Drip Campaign Automation
What: Multi-step automated email sequences
Implementation:
<div class="drip-campaign-builder">
<div class="drip-timeline">
<div class="drip-step" data-step="1">
<div class="step-header">
<span class="step-number">1</span>
<input type="text" placeholder="Step name" value="Welcome Email">
</div>
<div class="step-content">
<select name="trigger">
<option value="immediate">Send immediately</option>
<option value="delay">Wait X days</option>
<option value="condition">Wait for condition</option>
</select>
<input type="number" name="delay_days" placeholder="Days">
<textarea name="content" placeholder="Email content"></textarea>
</div>
<button onclick="addDripStep()">+ Add Step</button>
</div>
</div>
</div>
<script>
function addDripStep() {
const timeline = document.querySelector('.drip-timeline');
const stepCount = timeline.querySelectorAll('.drip-step').length + 1;
const newStep = document.createElement('div');
newStep.className = 'drip-step';
newStep.dataset.step = stepCount;
newStep.innerHTML = `
<div class="step-header">
<span class="step-number">${stepCount}</span>
<input type="text" placeholder="Step name">
</div>
<div class="step-content">
<select name="trigger">
<option value="delay">Wait X days</option>
<option value="condition">Wait for condition</option>
</select>
<input type="number" name="delay_days" placeholder="Days">
<textarea name="content" placeholder="Email content"></textarea>
</div>
<button onclick="removeDripStep(${stepCount})">Remove</button>
`;
timeline.appendChild(newStep);
}
</script>
12. Unsubscribe Management
What: Handle opt-outs and preferences
Implementation:
<!-- Unsubscribe page -->
<div class="unsubscribe-page">
<h2>Manage Your Preferences</h2>
<div class="preference-options">
<label>
<input type="checkbox" name="marketing_emails" checked>
Marketing emails
</label>
<label>
<input type="checkbox" name="product_updates" checked>
Product updates
</label>
<label>
<input type="checkbox" name="newsletters" checked>
Newsletters
</label>
</div>
<div class="frequency-control">
<label>Email frequency</label>
<select name="frequency">
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option>
</select>
</div>
<div class="unsubscribe-actions">
<button onclick="savePreferences()">Save Preferences</button>
<button onclick="unsubscribeAll()" class="danger">Unsubscribe from All</button>
</div>
</div>
<!-- Backend tracking -->
<script>
async function unsubscribeAll() {
const token = new URLSearchParams(window.location.search).get('token');
await fetch('/api/crm/unsubscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token, unsubscribe_all: true })
});
showMessage('You have been unsubscribed from all campaigns.');
}
</script>
13. Campaign Duplication
What: Clone existing campaigns for quick setup
Implementation:
async function duplicateCampaign(campaignId) {
const response = await fetch(`/api/crm/campaigns/${campaignId}`);
const campaign = await response.json();
// Modify name
campaign.name = `${campaign.name} (Copy)`;
campaign.status = 'draft';
delete campaign.id;
delete campaign.created_at;
// Create new campaign
const newCampaign = await fetch('/api/crm/campaigns', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(campaign)
});
// Refresh list
htmx.ajax('GET', '/api/crm/campaigns', '#campaignsList');
}
14. Campaign Scheduling Calendar
What: Visual calendar for scheduled campaigns
Implementation:
<div class="campaign-calendar">
<div class="calendar-header">
<button onclick="previousMonth()">←</button>
<h3 id="calendar-month">March 2026</h3>
<button onclick="nextMonth()">→</button>
</div>
<div class="calendar-grid">
<!-- Days of week -->
<div class="calendar-day-header">Sun</div>
<div class="calendar-day-header">Mon</div>
<div class="calendar-day-header">Tue</div>
<div class="calendar-day-header">Wed</div>
<div class="calendar-day-header">Thu</div>
<div class="calendar-day-header">Fri</div>
<div class="calendar-day-header">Sat</div>
<!-- Calendar days with campaigns -->
<div class="calendar-day" data-date="2026-03-15">
<span class="day-number">15</span>
<div class="day-campaigns">
<div class="campaign-pill" data-id="123">
Welcome Series
</div>
</div>
</div>
<!-- ... more days -->
</div>
</div>
<style>
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 1px;
background: var(--border);
}
.calendar-day {
background: var(--surface);
min-height: 100px;
padding: 8px;
}
.campaign-pill {
background: var(--accent);
color: var(--bg);
padding: 4px 8px;
border-radius: 4px;
font-size: 11px;
margin-top: 4px;
cursor: pointer;
}
</style>
15. Email Deliverability Monitoring
What: Track bounce rates and spam complaints
Implementation:
<div class="deliverability-dashboard">
<h3>Email Health</h3>
<div class="health-metrics">
<div class="health-metric">
<span class="metric-label">Bounce Rate</span>
<span class="metric-value">2.3%</span>
<div class="metric-bar">
<div class="metric-fill" style="width: 2.3%; background: green;"></div>
</div>
<span class="metric-status good">Good (< 5%)</span>
</div>
<div class="health-metric">
<span class="metric-label">Spam Complaints</span>
<span class="metric-value">0.1%</span>
<div class="metric-bar">
<div class="metric-fill" style="width: 0.1%; background: green;"></div>
</div>
<span class="metric-status good">Good (< 0.5%)</span>
</div>
<div class="health-metric">
<span class="metric-label">Unsubscribe Rate</span>
<span class="metric-value">1.8%</span>
<div class="metric-bar">
<div class="metric-fill" style="width: 1.8%; background: yellow;"></div>
</div>
<span class="metric-status warning">Monitor (< 2%)</span>
</div>
</div>
<div class="bounce-details">
<h4>Recent Bounces</h4>
<table>
<thead>
<tr>
<th>Email</th>
<th>Type</th>
<th>Reason</th>
<th>Date</th>
</tr>
</thead>
<tbody hx-get="/api/crm/bounces" hx-trigger="load">
</tbody>
</table>
</div>
</div>
Performance Optimizations
16. Pagination for Large Lists
<div class="campaigns-pagination">
<button hx-get="/api/crm/campaigns?page=1" hx-target="#campaignsList">First</button>
<button hx-get="/api/crm/campaigns?page={{prev_page}}" hx-target="#campaignsList">Previous</button>
<span>Page {{current_page}} of {{total_pages}}</span>
<button hx-get="/api/crm/campaigns?page={{next_page}}" hx-target="#campaignsList">Next</button>
<button hx-get="/api/crm/campaigns?page={{total_pages}}" hx-target="#campaignsList">Last</button>
</div>
17. Infinite Scroll
<div class="campaigns-grid"
hx-get="/api/crm/campaigns?page=1"
hx-trigger="load"
hx-swap="innerHTML">
</div>
<div hx-get="/api/crm/campaigns?page=2"
hx-trigger="intersect once"
hx-swap="beforeend"
hx-target=".campaigns-grid">
</div>
18. Campaign Search
<div class="campaign-search">
<input type="text"
placeholder="Search campaigns..."
hx-get="/api/crm/campaigns/search"
hx-trigger="keyup changed delay:300ms"
hx-target="#campaignsList"
hx-include="[name='status'],[name='channel']">
<select name="status" hx-get="/api/crm/campaigns" hx-trigger="change" hx-target="#campaignsList">
<option value="">All Statuses</option>
<option value="draft">Draft</option>
<option value="scheduled">Scheduled</option>
<option value="running">Running</option>
<option value="completed">Completed</option>
</select>
<select name="channel" hx-get="/api/crm/campaigns" hx-trigger="change" hx-target="#campaignsList">
<option value="">All Channels</option>
<option value="email">Email</option>
<option value="whatsapp">WhatsApp</option>
<option value="social">Social</option>
</select>
</div>
Backend Requirements
API Endpoints Needed
GET /api/crm/campaigns?page={page}&status={status}&channel={channel}
POST /api/crm/campaigns
GET /api/crm/campaigns/{id}
PUT /api/crm/campaigns/{id}
DELETE /api/crm/campaigns/{id}
POST /api/crm/campaigns/{id}/launch
POST /api/crm/campaigns/{id}/pause
POST /api/crm/campaigns/{id}/duplicate
GET /api/crm/lists
POST /api/crm/lists
GET /api/crm/lists/{id}/contacts
POST /api/crm/lists/{id}/contacts
GET /api/crm/templates
POST /api/crm/templates
GET /api/crm/templates/{id}
PUT /api/crm/templates/{id}
GET /api/crm/analytics/sent
GET /api/crm/analytics/open-rate
GET /api/crm/analytics/click-rate
GET /api/crm/analytics/conversion-rate
GET /api/crm/analytics/top-campaigns
GET /api/crm/bounces
POST /api/crm/unsubscribe
Database Schema Additions
-- Campaign tracking
CREATE TABLE campaign_sends (
id UUID PRIMARY KEY,
campaign_id UUID REFERENCES campaigns(id),
contact_id UUID,
sent_at TIMESTAMP,
opened_at TIMESTAMP,
clicked_at TIMESTAMP,
converted_at TIMESTAMP,
bounced BOOLEAN DEFAULT FALSE,
bounce_reason TEXT,
unsubscribed BOOLEAN DEFAULT FALSE
);
-- Contact lists
CREATE TABLE contact_lists (
id UUID PRIMARY KEY,
name VARCHAR(255),
description TEXT,
created_at TIMESTAMP,
contact_count INTEGER DEFAULT 0
);
CREATE TABLE list_contacts (
list_id UUID REFERENCES contact_lists(id),
contact_id UUID,
added_at TIMESTAMP,
PRIMARY KEY (list_id, contact_id)
);
-- Templates
CREATE TABLE message_templates (
id UUID PRIMARY KEY,
name VARCHAR(255),
channel VARCHAR(50),
subject TEXT,
content TEXT,
variables JSONB,
created_at TIMESTAMP
);
-- A/B Tests
CREATE TABLE ab_tests (
id UUID PRIMARY KEY,
campaign_id UUID REFERENCES campaigns(id),
variant_a_content TEXT,
variant_b_content TEXT,
variant_a_percentage INTEGER,
variant_b_percentage INTEGER,
success_metric VARCHAR(50),
winner VARCHAR(1), -- 'A' or 'B'
completed_at TIMESTAMP
);
-- Unsubscribes
CREATE TABLE unsubscribes (
id UUID PRIMARY KEY,
email VARCHAR(255),
campaign_id UUID,
unsubscribed_at TIMESTAMP,
reason TEXT
);
Implementation Priority
-
Critical (Do First):
- Fix backend API endpoints
- Add campaign card HTML template
- Fix form submission and list refresh
- Fix channel filtering
-
High Priority:
- Campaign builder wizard
- Contact list management
- Message template editor
- Campaign analytics dashboard
-
Medium Priority:
- A/B testing
- WhatsApp integration
- Drip campaign automation
- Unsubscribe management
-
Nice to Have:
- Campaign duplication
- Scheduling calendar
- Deliverability monitoring
- Infinite scroll
Testing Checklist
- Create new campaign via wizard
- Upload contact list from CSV
- Create message template with variables
- Schedule campaign for future date
- Launch campaign immediately
- View campaign analytics
- Filter campaigns by status/channel
- Search campaigns by name
- Duplicate existing campaign
- Set up A/B test
- Create drip campaign sequence
- Handle unsubscribe requests
- Track bounces and spam complaints
- Send WhatsApp campaign with media
- View campaign calendar
Integration Points
With CRM App
- Import contacts from CRM deals/accounts
- Track campaign responses in deal activities
- Create deals from campaign conversions
With Bot Conversations
- Trigger campaigns from bot conversations
- Use bot data to personalize messages
- Track campaign responses in bot analytics
With Email Service
- Integrate with SendGrid/Mailgun/SES
- Handle webhooks for opens/clicks/bounces
- Manage sender reputation
With WhatsApp Business API
- Send template messages
- Handle incoming responses
- Track delivery status