smartlead-mcp-by-leadmagic
Version:
💜 The Premier Model Context Protocol Server for SmartLead's Cold Email Automation Platform - Complete API coverage with 116+ tools for campaign management, lead tracking, smart delivery, and analytics. Beautiful purple-gradient installer, zero-config set
374 lines • 17.4 kB
JavaScript
/**
* SmartLead MCP Server - Campaign Statistics Client
*
* Client module for campaign statistics API endpoints.
* Handles campaign-specific statistics and performance metrics.
*
* @author LeadMagic Team
* @version 1.5.0
*/
import { BaseSmartLeadClient } from '../../client/base.js';
/**
* Campaign Statistics Client
*
* Provides methods for accessing SmartLead campaign statistics including:
* - Campaign performance metrics
* - Email delivery statistics
* - Response and engagement metrics
* - Time-based analytics
*/
export class StatisticsClient extends BaseSmartLeadClient {
// ================================
// CAMPAIGN STATISTICS METHODS
// ================================
/**
* Get campaign statistics
*/
async getCampaignStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics`, { params }), 'get campaign statistics');
return response.data;
}
/**
* Get campaign email statistics
*/
async getCampaignEmailStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/emails`, { params }), 'get campaign email statistics');
return response.data;
}
/**
* Get campaign response statistics
*/
async getCampaignResponseStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/responses`, { params }), 'get campaign response statistics');
return response.data;
}
/**
* Get campaign engagement statistics
*/
async getCampaignEngagementStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/engagement`, { params }), 'get campaign engagement statistics');
return response.data;
}
/**
* Get campaign conversion statistics
*/
async getCampaignConversionStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/conversions`, { params }), 'get campaign conversion statistics');
return response.data;
}
/**
* Get campaign time-based statistics
*/
async getCampaignTimeBasedStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/time-based`, { params }), 'get campaign time-based statistics');
return response.data;
}
/**
* Get campaign deliverability statistics
*/
async getCampaignDeliverabilityStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/deliverability`, { params }), 'get campaign deliverability statistics');
return response.data;
}
/**
* Get campaign sequence statistics
*/
async getCampaignSequenceStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/sequence`, { params }), 'get campaign sequence statistics');
return response.data;
}
/**
* Get campaign lead source statistics
*/
async getCampaignLeadSourceStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/lead-sources`, { params }), 'get campaign lead source statistics');
return response.data;
}
/**
* Get campaign A/B test statistics
*/
async getCampaignABTestStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/ab-tests`, { params }), 'get campaign A/B test statistics');
return response.data;
}
/**
* Export campaign statistics
*/
async exportCampaignStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/export`, { params }), 'export campaign statistics');
return response.data;
}
/**
* Get real-time campaign statistics
*/
async getRealTimeCampaignStatistics(campaignId) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/real-time`), 'get real-time campaign statistics');
return response.data;
}
/**
* Get campaign comparison statistics
*/
async getCampaignComparisonStatistics(campaignIds, params) {
const response = await this.withRetry(() => this.apiClient.post('/campaigns/statistics/compare', {
campaign_ids: campaignIds,
...params,
}), 'get campaign comparison statistics');
return response.data;
}
/**
* Get campaign benchmark statistics
*/
async getCampaignBenchmarkStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/benchmark`, { params }), 'get campaign benchmark statistics');
return response.data;
}
/**
* Get campaign statistics by date range
* GET /campaigns/{campaign_id}/statistics/date-range
*/
async getCampaignStatisticsByDateRange(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/date-range`, { params }), 'get campaign statistics by date range');
return response.data;
}
/**
* Get warmup stats by email account ID
* GET /email-accounts/{email_account_id}/warmup-stats
*/
async getWarmupStatsByEmailAccountId(emailAccountId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/email-accounts/${emailAccountId}/warmup-stats`, { params }), 'get warmup stats by email account ID');
return response.data;
}
/**
* Get campaign top level analytics
* GET /campaigns/{campaign_id}/analytics/top-level
*/
async getCampaignTopLevelAnalytics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/analytics/top-level`, { params }), 'get campaign top level analytics');
return response.data;
}
/**
* Get campaign top level analytics by date range
* GET /campaigns/{campaign_id}/analytics/top-level/date-range
*/
async getCampaignTopLevelAnalyticsByDateRange(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/analytics/top-level/date-range`, { params }), 'get campaign top level analytics by date range');
return response.data;
}
/**
* Get campaign lead statistics
* GET /campaigns/{campaign_id}/statistics/leads
*/
async getCampaignLeadStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/leads`, { params }), 'get campaign lead statistics');
return response.data;
}
/**
* Get campaign mailbox statistics
* GET /campaigns/{campaign_id}/statistics/mailboxes
*/
async getCampaignMailboxStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics/mailboxes`, { params }), 'get campaign mailbox statistics');
return response.data;
}
/**
* Download campaign data in various formats
* Uses the statistics endpoint to fetch and format campaign data
*
* @param {number} campaignId - The ID of the campaign to download data for
* @param {string} downloadType - The type of data to download (e.g., 'statistics', 'leads', 'responses')
* @param {'json' | 'csv'} format - The output format, defaults to 'json'
* @param {string} [userId] - Optional user ID for filtering (not currently supported by API)
* @returns {Promise<DownloadResponse>} Download response containing the data in requested format
* @throws {Error} If the campaign data cannot be retrieved
*
* @example
* // Download campaign statistics as JSON
* const jsonData = await client.downloadCampaignData(12345, 'statistics', 'json');
*
* @example
* // Download campaign data as CSV
* const csvData = await client.downloadCampaignData(12345, 'leads', 'csv');
* // csvData.data contains base64-encoded CSV content
*/
async downloadCampaignData(campaignId, downloadType, format = 'json', userId) {
try {
// Fetch statistics data based on download type
let allData = [];
let hasMore = true;
let offset = 0;
const limit = 500; // Max limit per request
// For now, all download types will use the general statistics endpoint
// In the future, we could use different endpoints based on downloadType
while (hasMore) {
const params = {
offset,
limit,
// Note: user_id is not supported by the statistics endpoint
};
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics`, { params }), 'download campaign statistics data');
if (response.data && response.data.data) {
const responseData = response.data
.data;
allData = allData.concat(responseData);
// Check if there are more records to fetch
const totalRecords = parseInt(String(response.data.total_stats)) || 0;
hasMore = offset + limit < totalRecords;
offset += limit;
}
else {
hasMore = false;
}
}
// Format the data based on requested format
if (format === 'csv') {
// Convert to CSV format
if (allData.length === 0) {
return {
format: 'csv',
encoding: 'utf-8',
filename: `campaign_${campaignId}_${downloadType}_${new Date().toISOString().split('T')[0]}.csv`,
mimeType: 'text/csv',
data: 'No data available',
size: 17,
};
}
// Get headers from the first object
const firstRow = allData[0];
const headers = Object.keys(firstRow);
let csvContent = headers.join(',') + '\n';
// Add data rows
for (const row of allData) {
const rowData = row;
const values = headers.map((header) => {
const value = rowData[header];
// Handle null/undefined
if (value === null || value === undefined)
return '';
// Escape quotes and wrap in quotes if contains comma, newline, or quotes
const stringValue = String(value);
if (stringValue.includes(',') ||
stringValue.includes('\n') ||
stringValue.includes('"')) {
return `"${stringValue.replace(/"/g, '""')}"`;
}
return stringValue;
});
csvContent += values.join(',') + '\n';
}
// Convert to base64 for transport
const buffer = Buffer.from(csvContent, 'utf-8');
const base64Data = buffer.toString('base64');
return {
format: 'csv',
encoding: 'base64',
filename: `campaign_${campaignId}_${downloadType}_${new Date().toISOString().split('T')[0]}.csv`,
mimeType: 'text/csv',
data: base64Data,
size: buffer.length,
};
}
else {
// Return JSON format
return {
format: 'json',
data: {
download_type: downloadType,
campaign_id: campaignId,
total_records: allData.length,
data: allData,
generated_at: new Date().toISOString(),
},
};
}
}
catch (error) {
// Re-throw the error to be handled by the retry mechanism
throw error;
}
}
/**
* View download statistics
* GET /download-statistics
*
* Retrieves download statistics with optional filtering by time period and grouping.
* Falls back to overall analytics if the download-statistics endpoint is not available.
*
* @param {string} [timePeriod] - Time period to filter by ('last_7_days', 'last_30_days', 'last_quarter')
* @param {string} [groupBy] - How to group the statistics ('date', 'campaign', 'user')
* @returns {Promise<SuccessResponse>} Download statistics or fallback analytics data
* @throws {Error} If statistics cannot be retrieved from any endpoint
*
* @example
* // Get download statistics for the last 7 days
* const stats = await client.viewDownloadStatistics('last_7_days', 'date');
*
* @example
* // Get all download statistics grouped by campaign
* const stats = await client.viewDownloadStatistics(undefined, 'campaign');
*/
async viewDownloadStatistics(timePeriod, groupBy) {
// First try the documented endpoint
const params = {};
if (timePeriod)
params.time_period = timePeriod;
if (groupBy)
params.group_by = groupBy;
try {
const response = await this.withRetry(() => this.apiClient.get('/download-statistics', { params }), 'view download statistics');
return response.data;
}
catch (error) {
// If the endpoint doesn't exist (404), try alternative approach
const httpError = error;
if (httpError.status === 404 || httpError.code === 'HTTP_404') {
console.log('[SmartLead] /download-statistics endpoint not found, using overall analytics as fallback');
// Use overall analytics with date filtering based on time period
const endDate = new Date().toISOString().split('T')[0];
let startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]; // Default to last 30 days
// Calculate start date based on time period
switch (timePeriod) {
case 'last_7_days':
startDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
break;
case 'last_30_days':
startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
break;
case 'last_quarter':
startDate = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
break;
// default case already set above
}
// Get overall analytics as fallback
const overallStatsResponse = await this.withRetry(() => this.apiClient.get('/analytics/overall-stats-v2', {
params: {
start_date: startDate,
end_date: endDate,
},
}), 'get overall analytics for download statistics');
// Format the response to simulate download statistics
const responseData = overallStatsResponse.data;
const data = responseData?.data || responseData || {};
const overallStats = data?.overall_stats || {};
return {
success: true,
message: 'Download statistics retrieved using overall analytics',
data: {
time_period: timePeriod || 'last_30_days',
group_by: groupBy || 'date',
statistics: {
total_campaigns: overallStats.campaigns || 0,
total_exports: 0, // Not available in overall stats
emails_sent: overallStats.sent || 0,
emails_opened: overallStats.opened || 0,
emails_replied: overallStats.replied || 0,
note: 'Using overall analytics as download statistics endpoint is not available',
},
},
};
}
// Re-throw other errors
throw error;
}
}
}
//# sourceMappingURL=client.js.map