Add in subjects from messages correctly
This commit is contained in:
@@ -88,15 +88,65 @@ export class ReportingService {
|
||||
}
|
||||
|
||||
const reportData = await response.json();
|
||||
console.log('[ReportingService] Raw report data:', JSON.stringify(reportData, null, 2));
|
||||
|
||||
// Cache the response for 10 minutes
|
||||
// Get campaign IDs from the report
|
||||
const campaignIds = reportData.data?.attributes?.results?.map(result =>
|
||||
result.groupings?.campaign_id
|
||||
).filter(Boolean) || [];
|
||||
|
||||
console.log('[ReportingService] Extracted campaign IDs:', campaignIds);
|
||||
|
||||
// Get campaign details including send time and subject lines
|
||||
const campaignDetails = await this.getCampaignDetails(campaignIds);
|
||||
console.log('[ReportingService] Campaign details:', JSON.stringify(campaignDetails, null, 2));
|
||||
|
||||
// Merge campaign details with report data
|
||||
const enrichedData = {
|
||||
data: reportData.data.attributes.results.map(result => {
|
||||
const campaignId = result.groupings.campaign_id;
|
||||
const details = campaignDetails.find(detail => detail.id === campaignId);
|
||||
const message = details?.included?.find(item => item.type === 'campaign-message');
|
||||
|
||||
return {
|
||||
id: campaignId,
|
||||
name: details.attributes.name,
|
||||
subject: details.attributes.subject,
|
||||
send_time: details.attributes.send_time,
|
||||
attributes: {
|
||||
statistics: {
|
||||
delivery_rate: result.statistics.delivery_rate,
|
||||
delivered: result.statistics.delivered,
|
||||
recipients: result.statistics.recipients,
|
||||
open_rate: result.statistics.open_rate,
|
||||
opens_unique: result.statistics.opens_unique,
|
||||
opens: result.statistics.opens,
|
||||
click_rate: result.statistics.click_rate,
|
||||
clicks_unique: result.statistics.clicks_unique,
|
||||
click_to_open_rate: result.statistics.click_to_open_rate,
|
||||
conversion_value: result.statistics.conversion_value,
|
||||
conversion_uniques: result.statistics.conversion_uniques
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const dateA = new Date(a.send_time);
|
||||
const dateB = new Date(b.send_time);
|
||||
return dateB - dateA; // Sort by date descending
|
||||
})
|
||||
};
|
||||
|
||||
console.log('[ReportingService] Enriched data:', JSON.stringify(enrichedData, null, 2));
|
||||
|
||||
// Cache the enriched response for 10 minutes
|
||||
try {
|
||||
await this.redisService.set(`${cacheKey}:raw`, reportData, 600);
|
||||
await this.redisService.set(`${cacheKey}:raw`, enrichedData, 600);
|
||||
} catch (cacheError) {
|
||||
console.warn('[ReportingService] Cache set error:', cacheError);
|
||||
}
|
||||
|
||||
return reportData;
|
||||
return enrichedData;
|
||||
})();
|
||||
|
||||
const result = await this._pendingReportRequest;
|
||||
@@ -111,127 +161,47 @@ export class ReportingService {
|
||||
}
|
||||
|
||||
async getCampaignDetails(campaignIds = []) {
|
||||
try {
|
||||
if (!Array.isArray(campaignIds) || campaignIds.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Process in batches of 5 to avoid rate limits
|
||||
const batchSize = 5;
|
||||
const campaignDetails = [];
|
||||
|
||||
for (let i = 0; i < campaignIds.length; i += batchSize) {
|
||||
const batch = campaignIds.slice(i, i + batchSize);
|
||||
|
||||
const batchPromises = batch.map(async (campaignId) => {
|
||||
try {
|
||||
// Try to get from cache first
|
||||
const cacheKey = this.redisService._getCacheKey('campaign_details', { campaignId });
|
||||
const cachedData = await this.redisService.get(`${cacheKey}:raw`);
|
||||
if (cachedData) {
|
||||
return cachedData;
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`${this.baseUrl}/campaigns/${campaignId}?include=campaign-messages`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Klaviyo-API-Key ${this.apiKey}`,
|
||||
'revision': this.apiRevision
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
console.error(`Error fetching campaign ${campaignId}:`, response.statusText);
|
||||
return null;
|
||||
}
|
||||
|
||||
const campaignData = await response.json();
|
||||
|
||||
// Cache individual campaign data for 1 hour
|
||||
await this.redisService.set(`${cacheKey}:raw`, campaignData, 3600);
|
||||
|
||||
return campaignData;
|
||||
} catch (error) {
|
||||
console.error(`Error processing campaign ${campaignId}:`, error);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
const batchResults = await Promise.all(batchPromises);
|
||||
campaignDetails.push(...batchResults.filter(Boolean));
|
||||
|
||||
// Add delay between batches if not the last batch
|
||||
if (i + batchSize < campaignIds.length) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
}
|
||||
|
||||
return campaignDetails;
|
||||
} catch (error) {
|
||||
console.error('[ReportingService] Error fetching campaign details:', error);
|
||||
throw error;
|
||||
if (!Array.isArray(campaignIds) || campaignIds.length === 0) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getEnrichedCampaignReports(params = {}) {
|
||||
try {
|
||||
// Get campaign reports first
|
||||
const reportData = await this.getCampaignReports(params);
|
||||
|
||||
// Extract campaign IDs from the report
|
||||
const campaignIds = reportData.data?.attributes?.results?.map(
|
||||
result => result.groupings?.campaign_id
|
||||
).filter(Boolean) || [];
|
||||
|
||||
// Get campaign details including messages
|
||||
const campaignDetails = await this.getCampaignDetails(campaignIds);
|
||||
|
||||
// Merge report data with campaign details
|
||||
const enrichedData = reportData.data?.attributes?.results?.map(report => {
|
||||
const campaignId = report.groupings?.campaign_id;
|
||||
const campaignDetail = campaignDetails.find(
|
||||
detail => detail.data?.id === campaignId
|
||||
const campaignDetails = await Promise.all(
|
||||
campaignIds.map(async (campaignId) => {
|
||||
const response = await fetch(
|
||||
`${this.baseUrl}/campaigns/${campaignId}?include=campaign-messages`,
|
||||
{
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': `Klaviyo-API-Key ${this.apiKey}`,
|
||||
'revision': this.apiRevision
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const campaignMessages = campaignDetail?.included?.filter(
|
||||
item => item.type === 'campaign-message'
|
||||
) || [];
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch campaign ${campaignId}: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
if (!data.data) {
|
||||
throw new Error(`Invalid response for campaign ${campaignId}`);
|
||||
}
|
||||
|
||||
const message = data.included?.find(item => item.type === 'campaign-message');
|
||||
|
||||
return {
|
||||
id: campaignId,
|
||||
name: campaignDetail?.data?.attributes?.name || "Unnamed Campaign",
|
||||
subject: campaignMessages[0]?.attributes?.content?.subject || "",
|
||||
send_time: report.groupings?.send_time,
|
||||
stats: {
|
||||
delivery_rate: report.statistics?.delivery_rate || 0,
|
||||
delivered: report.statistics?.delivered || 0,
|
||||
recipients: report.statistics?.recipients || 0,
|
||||
open_rate: report.statistics?.open_rate || 0,
|
||||
opens_unique: report.statistics?.opens_unique || 0,
|
||||
opens: report.statistics?.opens || 0,
|
||||
click_rate: report.statistics?.click_rate || 0,
|
||||
clicks_unique: report.statistics?.clicks_unique || 0,
|
||||
click_to_open_rate: report.statistics?.click_to_open_rate || 0,
|
||||
conversion_value: report.statistics?.conversion_value || 0,
|
||||
conversion_uniques: report.statistics?.conversion_uniques || 0
|
||||
id: data.data.id,
|
||||
type: data.data.type,
|
||||
attributes: {
|
||||
...data.data.attributes,
|
||||
name: data.data.attributes.name,
|
||||
send_time: data.data.attributes.send_time,
|
||||
subject: message?.attributes?.content?.subject
|
||||
}
|
||||
};
|
||||
}).filter(Boolean) || [];
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
data: enrichedData,
|
||||
meta: {
|
||||
total_count: enrichedData.length
|
||||
}
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error('[ReportingService] Error getting enriched campaign reports:', error);
|
||||
throw error;
|
||||
}
|
||||
return campaignDetails;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user