193 lines
4.9 KiB
TypeScript
193 lines
4.9 KiB
TypeScript
import apiClient from './apiClient';
|
|
|
|
export interface Campaign {
|
|
id: number;
|
|
name: string;
|
|
subject: string;
|
|
html_content?: string;
|
|
text_content?: string;
|
|
campaign_type: string;
|
|
status: string;
|
|
segment_id?: number;
|
|
scheduled_at?: string;
|
|
sent_at?: string;
|
|
total_recipients: number;
|
|
total_sent: number;
|
|
total_delivered: number;
|
|
total_opened: number;
|
|
total_clicked: number;
|
|
total_bounced: number;
|
|
open_rate?: number;
|
|
click_rate?: number;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface CampaignSegment {
|
|
id: number;
|
|
name: string;
|
|
description?: string;
|
|
criteria: Record<string, any>;
|
|
estimated_count?: number;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface EmailTemplate {
|
|
id: number;
|
|
name: string;
|
|
subject: string;
|
|
html_content: string;
|
|
text_content?: string;
|
|
category?: string;
|
|
variables?: string[];
|
|
created_at: string;
|
|
}
|
|
|
|
export interface DripSequence {
|
|
id: number;
|
|
name: string;
|
|
description?: string;
|
|
trigger_event?: string;
|
|
step_count: number;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface CampaignAnalytics {
|
|
campaign_id: number;
|
|
total_recipients: number;
|
|
total_sent: number;
|
|
total_delivered: number;
|
|
total_opened: number;
|
|
total_clicked: number;
|
|
total_bounced: number;
|
|
total_unsubscribed: number;
|
|
open_rate: number;
|
|
click_rate: number;
|
|
bounce_rate: number;
|
|
status_breakdown: Record<string, number>;
|
|
}
|
|
|
|
class EmailCampaignService {
|
|
// Campaigns
|
|
async getCampaigns(params?: {
|
|
status?: string;
|
|
campaign_type?: string;
|
|
limit?: number;
|
|
offset?: number;
|
|
}): Promise<Campaign[]> {
|
|
const response = await apiClient.get('/email-campaigns', { params });
|
|
return response.data;
|
|
}
|
|
|
|
async getCampaign(campaignId: number): Promise<Campaign> {
|
|
const response = await apiClient.get(`/email-campaigns/${campaignId}`);
|
|
return response.data;
|
|
}
|
|
|
|
async createCampaign(data: {
|
|
name: string;
|
|
subject: string;
|
|
html_content: string;
|
|
text_content?: string;
|
|
campaign_type?: string;
|
|
segment_id?: number;
|
|
scheduled_at?: string;
|
|
template_id?: number;
|
|
from_name?: string;
|
|
from_email?: string;
|
|
reply_to_email?: string;
|
|
track_opens?: boolean;
|
|
track_clicks?: boolean;
|
|
}): Promise<{ campaign_id: number }> {
|
|
const response = await apiClient.post('/email-campaigns', data);
|
|
return response.data;
|
|
}
|
|
|
|
async updateCampaign(campaignId: number, data: Partial<{
|
|
name: string;
|
|
subject: string;
|
|
html_content: string;
|
|
text_content: string;
|
|
segment_id: number;
|
|
scheduled_at: string;
|
|
status: string;
|
|
}>): Promise<void> {
|
|
await apiClient.put(`/email-campaigns/${campaignId}`, data);
|
|
}
|
|
|
|
async sendCampaign(campaignId: number): Promise<{ sent: number; failed: number; total: number }> {
|
|
const response = await apiClient.post(`/email-campaigns/${campaignId}/send`);
|
|
return response.data.result;
|
|
}
|
|
|
|
async getCampaignAnalytics(campaignId: number): Promise<CampaignAnalytics> {
|
|
const response = await apiClient.get(`/email-campaigns/${campaignId}/analytics`);
|
|
return response.data;
|
|
}
|
|
|
|
// Segments
|
|
async getSegments(): Promise<CampaignSegment[]> {
|
|
const response = await apiClient.get('/email-campaigns/segments');
|
|
return response.data;
|
|
}
|
|
|
|
async createSegment(data: {
|
|
name: string;
|
|
description?: string;
|
|
criteria: Record<string, any>;
|
|
}): Promise<{ segment_id: number; estimated_count: number }> {
|
|
const response = await apiClient.post('/email-campaigns/segments', data);
|
|
return response.data;
|
|
}
|
|
|
|
// Templates
|
|
async getTemplates(category?: string): Promise<EmailTemplate[]> {
|
|
const response = await apiClient.get('/email-campaigns/templates', {
|
|
params: { category }
|
|
});
|
|
return response.data;
|
|
}
|
|
|
|
async createTemplate(data: {
|
|
name: string;
|
|
subject: string;
|
|
html_content: string;
|
|
text_content?: string;
|
|
category?: string;
|
|
variables?: string[];
|
|
}): Promise<{ template_id: number }> {
|
|
const response = await apiClient.post('/email-campaigns/templates', data);
|
|
return response.data;
|
|
}
|
|
|
|
// Drip Sequences
|
|
async getDripSequences(): Promise<DripSequence[]> {
|
|
const response = await apiClient.get('/email-campaigns/drip-sequences');
|
|
return response.data;
|
|
}
|
|
|
|
async createDripSequence(data: {
|
|
name: string;
|
|
description?: string;
|
|
trigger_event?: string;
|
|
}): Promise<{ sequence_id: number }> {
|
|
const response = await apiClient.post('/email-campaigns/drip-sequences', data);
|
|
return response.data;
|
|
}
|
|
|
|
async addDripStep(sequenceId: number, data: {
|
|
subject: string;
|
|
html_content: string;
|
|
text_content?: string;
|
|
delay_days?: number;
|
|
delay_hours?: number;
|
|
template_id?: number;
|
|
}): Promise<{ step_id: number }> {
|
|
const response = await apiClient.post(`/email-campaigns/drip-sequences/${sequenceId}/steps`, data);
|
|
return response.data;
|
|
}
|
|
}
|
|
|
|
export const emailCampaignService = new EmailCampaignService();
|
|
export default emailCampaignService;
|
|
|