UNPKG

beeswax-node-client

Version:

TypeScript/JavaScript client library for the Beeswax DSP API

340 lines 16.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CampaignMacros = void 0; const helpers_1 = require("../utils/helpers"); class CampaignMacros { constructor(client) { this.client = client; } /** * Create a full campaign with line items, creatives, and targeting */ async createFullCampaign(options) { try { // Step 1: Create campaign const campaignData = { advertiser_id: options.advertiser_id, campaign_name: options.campaign_name, campaign_budget: options.campaign_budget, start_date: options.start_date, end_date: options.end_date, budget_type: 2, // Ensure budget type is set active: false // Start inactive until everything is set up }; const campaignResponse = await this.client.campaigns.create(campaignData); if (!campaignResponse.success || !campaignResponse.payload) { throw new Error('Failed to create campaign'); } const campaign = campaignResponse.payload; const result = { campaign, line_items: [], creatives: [], creative_line_items: [], targeting_templates: [] }; // Step 2: Create targeting templates if provided if (options.targeting_templates) { for (const templateOptions of options.targeting_templates) { const templateData = { advertiser_id: options.advertiser_id, targeting_template_name: templateOptions.targeting_template_name, targeting: templateOptions.targeting, active: true }; const templateResponse = await this.client.targetingTemplates.create(templateData); if (templateResponse.success && templateResponse.payload) { result.targeting_templates?.push(templateResponse.payload); } } } // Step 3: Create line items and their associated creatives for (const lineItemOptions of options.line_items) { // Create line item using the helper method const lineItemResponse = await this.client.createLineItem({ campaign_id: campaign.campaign_id, line_item_name: lineItemOptions.line_item_name, line_item_budget: lineItemOptions.line_item_budget, cpm_bid: lineItemOptions.bid_price, // Note: targeting is now handled via targeting_expression_id active: false // Line items must be inactive until creatives are attached }); if (!lineItemResponse.success || !lineItemResponse.payload) { console.error('Failed to create line item:', lineItemOptions.line_item_name); continue; } const lineItem = lineItemResponse.payload; result.line_items.push(lineItem); // Create creatives for this line item if (lineItemOptions.creatives) { for (const creativeOptions of lineItemOptions.creatives) { // Upload asset if URL provided let creativeAssetId; if (creativeOptions.asset_url) { try { const asset = await this.client.uploadCreativeAsset({ advertiser_id: options.advertiser_id, sourceUrl: creativeOptions.asset_url, creative_asset_name: creativeOptions.creative_name }); creativeAssetId = asset.creative_asset_id; } catch (error) { console.error('Failed to upload creative asset:', error); } } // Create creative const creativeData = { advertiser_id: options.advertiser_id, creative_name: creativeOptions.creative_name, creative_type: creativeOptions.creative_type === 'display' ? 0 : creativeOptions.creative_type === 'video' ? 1 : creativeOptions.creative_type === 'native' ? 2 : 0, creative_template_id: creativeOptions.creative_template_id || 1, // Default to 1 for standard display width: creativeOptions.width, height: creativeOptions.height, click_url: creativeOptions.click_url || 'https://example.com', secure: true, active: false // Creatives need content before being activated }; if (creativeOptions.creative_attributes) { creativeData.creative_attributes = creativeOptions.creative_attributes; } if (creativeAssetId) { creativeData.creative_asset_id = creativeAssetId; } const creativeResponse = await this.client.creatives.create(creativeData); if (!creativeResponse.success || !creativeResponse.payload) { console.error('Failed to create creative:', creativeOptions.creative_name); continue; } const creative = creativeResponse.payload; result.creatives.push(creative); // Create creative-line item association const cliData = { creative_id: creative.creative_id, line_item_id: lineItem.line_item_id, active: true, weighting: 100 }; const cliResponse = await this.client.creativeLineItems.create(cliData); if (cliResponse.success && cliResponse.payload) { result.creative_line_items.push(cliResponse.payload); } } } } return { success: true, payload: result }; } catch (error) { console.error('Full campaign creation error:', error); return { success: false, message: error.message || 'Failed to create full campaign', errors: [JSON.stringify(error)] }; } } /** * Clone an existing campaign with all its components */ async cloneCampaign(campaignId, newName, options) { try { // Get original campaign const campaignResponse = await this.client.campaigns.find(campaignId); if (!campaignResponse.success || !campaignResponse.payload) { throw new Error('Campaign not found'); } const originalCampaign = campaignResponse.payload; // Create new campaign - exclude read-only fields const { campaign_id: _campaign_id, created_date: _created_date, updated_date: _updated_date, create_date: _create_date, update_date: _update_date, push_status: _push_status, push_update: _push_update, campaign_spend: _campaign_spend, buzz_key: _buzz_key, last_active: _last_active, ...campaignFields } = originalCampaign; const newCampaignData = { ...campaignFields, campaign_name: newName }; if (options?.start_date) { newCampaignData.start_date = options.start_date; } if (options?.end_date) { newCampaignData.end_date = options.end_date; } if (options?.budget_multiplier) { newCampaignData.campaign_budget = (originalCampaign.campaign_budget || 0) * options.budget_multiplier; } const newCampaignResponse = await this.client.campaigns.create(newCampaignData); if (!newCampaignResponse.success || !newCampaignResponse.payload) { throw new Error('Failed to create new campaign'); } const newCampaign = newCampaignResponse.payload; const result = { campaign: newCampaign, line_items: [], creatives: [], creative_line_items: [], targeting_templates: [] }; // Get and clone line items const lineItemsResponse = await this.client.lineItems.query({ campaign_id: campaignId }); if (lineItemsResponse.success && lineItemsResponse.payload) { for (const lineItem of lineItemsResponse.payload) { // Exclude read-only fields from line item const { line_item_id: _line_item_id, created_date: _created_date, updated_date: _updated_date, create_date: _create_date, update_date: _update_date, push_status: _push_status, push_update: _push_update, line_item_spend: _line_item_spend, line_item_impressions: _line_item_impressions, buzz_key: _buzz_key, last_active: _last_active, line_item_version: _line_item_version, has_skad_assignment: _has_skad_assignment, account_id: _account_id, ...lineItemFields } = lineItem; const newLineItemData = { ...lineItemFields, campaign_id: newCampaign.campaign_id }; if (options?.budget_multiplier) { newLineItemData.line_item_budget = (lineItem.line_item_budget || 0) * options.budget_multiplier; } const newLineItemResponse = await this.client.lineItems.create(newLineItemData); if (newLineItemResponse.success && newLineItemResponse.payload) { result.line_items.push(newLineItemResponse.payload); // Clone creative associations if requested if (options?.clone_creatives !== false) { const cliResponse = await this.client.creativeLineItems.query({ line_item_id: lineItem.line_item_id }); if (cliResponse.success && cliResponse.payload) { for (const cli of cliResponse.payload) { const newCliData = { creative_id: cli.creative_id, line_item_id: newLineItemResponse.payload.line_item_id, active: cli.active, weighting: cli.weighting }; const newCliResponse = await this.client.creativeLineItems.create(newCliData); if (newCliResponse.success && newCliResponse.payload) { result.creative_line_items.push(newCliResponse.payload); } } } } } // Small delay to avoid rate limiting await (0, helpers_1.delay)(100); } } return { success: true, payload: result }; } catch (error) { console.error('Clone campaign error:', error); return { success: false, message: error.message || 'Failed to clone campaign', errors: [JSON.stringify(error)] }; } } /** * Bulk update campaign status (pause/resume) */ async bulkUpdateCampaignStatus(campaignIds, active) { let updated = 0; let failed = 0; for (const campaignId of campaignIds) { try { const response = await this.client.campaigns.edit(campaignId, { active }); if (response.success) { updated++; } else { failed++; } } catch (_error) { failed++; } // Small delay to avoid rate limiting await (0, helpers_1.delay)(50); } return { success: true, payload: { updated, failed } }; } /** * Get campaign performance summary */ async getCampaignPerformance(campaignId, startDate, endDate) { try { // This would typically call a reporting endpoint // Since we don't have the exact API docs, this is a placeholder const reportData = { advertiser_id: 0, // Would need to get this from campaign report_name: `Campaign ${campaignId} Performance`, report_type: 'campaign_performance', dimensions: ['campaign_id', 'date'], metrics: ['impressions', 'clicks', 'conversions', 'spend'], filters: { campaign_id: campaignId }, start_date: startDate, end_date: endDate }; // Create and run report const reportResponse = await this.client.reports.create(reportData); return reportResponse; } catch (error) { return { success: false, message: error.message || 'Failed to get campaign performance', errors: [error.toString()] }; } } /** * Bulk create line items for a campaign */ async bulkCreateLineItems(campaignId, lineItems) { const created = []; const errors = []; // Get campaign to verify it exists and get advertiser_id const campaignResponse = await this.client.campaigns.find(campaignId); if (!campaignResponse.success || !campaignResponse.payload) { return { success: false, message: 'Campaign not found' }; } // const campaign = campaignResponse.payload; // Currently unused, kept for future use for (const item of lineItems) { try { const response = await this.client.createLineItem({ campaign_id: campaignId, line_item_name: item.name, line_item_budget: item.budget, cpm_bid: item.bid_price, // Note: targeting is now handled via targeting_expression_id active: false // Line items must be inactive until creatives are attached }); if (response.success && response.payload) { created.push(response.payload); } else { errors.push(`Failed to create line item: ${item.name}`); } } catch (error) { errors.push(`Error creating line item ${item.name}: ${error.message}`); } // Small delay to avoid rate limiting await (0, helpers_1.delay)(100); } return { success: errors.length === 0, payload: created, errors: errors.length > 0 ? errors : undefined }; } } exports.CampaignMacros = CampaignMacros; //# sourceMappingURL=CampaignMacros.js.map