--- name: customerio-core-feature description: | Implement Customer.io core feature integration. Use when implementing segments, transactional messages, data pipelines, or broadcast campaigns. Trigger with phrases like "customer.io segments", "customer.io transactional", "customer.io broadcast", "customer.io data pipeline". allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(pip:*), Grep version: 1.0.0 license: MIT author: Jeremy Longshore --- # Customer.io Core Feature Integration ## Overview Implement Customer.io core features: segments, transactional messaging, data pipelines, and broadcast campaigns. ## Prerequisites - Customer.io SDK configured - Understanding of customer data model - App API credentials for transactional emails ## Instructions ### Feature 1: Transactional Messages ```typescript // lib/customerio-transactional.ts import { APIClient, RegionUS, SendEmailRequest } from '@customerio/track'; const apiClient = new APIClient(process.env.CUSTOMERIO_APP_API_KEY!, { region: RegionUS }); interface TransactionalEmailOptions { to: string; transactionalMessageId: string; messageData?: Record; identifiers?: { id?: string; email?: string }; } export async function sendTransactionalEmail(options: TransactionalEmailOptions) { const request: SendEmailRequest = { to: options.to, transactional_message_id: options.transactionalMessageId, message_data: options.messageData, identifiers: options.identifiers }; return apiClient.sendEmail(request); } // Usage examples // Password reset await sendTransactionalEmail({ to: 'user@example.com', transactionalMessageId: 'password_reset', messageData: { reset_link: 'https://app.example.com/reset?token=abc123', expiry_hours: 24 } }); // Order confirmation await sendTransactionalEmail({ to: 'customer@example.com', transactionalMessageId: 'order_confirmation', messageData: { order_id: 'ORD-12345', items: [ { name: 'Product A', quantity: 2, price: 29.99 } ], total: 59.98 }, identifiers: { id: 'user-456' } }); ``` ### Feature 2: Segments ```typescript // lib/customerio-segments.ts import { TrackClient } from '@customerio/track'; // Update user attributes for segment membership export async function updateUserForSegments( client: TrackClient, userId: string, attributes: { // Engagement metrics last_active_at?: number; session_count?: number; total_time_spent?: number; // Business metrics total_revenue?: number; order_count?: number; average_order_value?: number; // Feature usage features_used?: string[]; premium_features_used?: boolean; // Risk indicators churn_risk_score?: number; days_since_last_login?: number; } ) { await client.identify(userId, attributes); } // Segment-triggering attribute updates const segmentExamples = { // High-value customer segment highValue: { total_revenue: 1000, order_count: 10 }, // At-risk segment atRisk: { days_since_last_login: 30, churn_risk_score: 0.8 }, // Power user segment powerUser: { session_count: 100, premium_features_used: true } }; ``` ### Feature 3: Anonymous Tracking ```typescript // lib/customerio-anonymous.ts import { TrackClient } from '@customerio/track'; export class AnonymousTracker { constructor(private client: TrackClient) {} // Track anonymous page views async trackPageView(anonymousId: string, page: string, referrer?: string) { await this.client.trackAnonymous({ anonymous_id: anonymousId, name: 'page_viewed', data: { page, referrer, timestamp: new Date().toISOString() } }); } // Merge anonymous activity when user signs up async mergeOnSignup(anonymousId: string, userId: string, email: string) { // First, identify the user with the anonymous_id await this.client.identify(userId, { email, anonymous_id: anonymousId, created_at: Math.floor(Date.now() / 1000) }); // Customer.io will automatically merge anonymous activity } } ``` ### Feature 4: Object Tracking (Companies/Accounts) ```typescript // lib/customerio-objects.ts import { TrackClient } from '@customerio/track'; export class ObjectTracker { constructor(private client: TrackClient) {} // Track company/account as an object async trackCompany(companyId: string, attributes: { name: string; plan: string; mrr: number; employee_count: number; industry?: string; }) { // Use object tracking for B2B scenarios await this.client.identify(`company:${companyId}`, { ...attributes, object_type: 'company', updated_at: Math.floor(Date.now() / 1000) }); } // Associate user with company async associateUserWithCompany(userId: string, companyId: string, role: string) { await this.client.identify(userId, { company_id: companyId, company_role: role }); } } ``` ### Feature 5: Data Pipeline Integration ```typescript // lib/customerio-data-pipeline.ts export interface DataPipelineConfig { source: 'segment' | 'rudderstack' | 'mparticle' | 'custom'; mappings: { userId: string; email: string; customAttributes: Record; }; } // Webhook handler for incoming CDP data export async function handleCDPWebhook( client: TrackClient, event: { type: 'identify' | 'track'; userId: string; traits?: Record; event?: string; properties?: Record; } ) { if (event.type === 'identify' && event.traits) { await client.identify(event.userId, event.traits); } else if (event.type === 'track' && event.event) { await client.track(event.userId, { name: event.event, data: event.properties }); } } ``` ## Output - Transactional email sending capability - Segment-ready user attributes - Anonymous to known user merging - B2B object tracking (companies) - CDP data pipeline integration ## Error Handling | Error | Cause | Solution | |-------|-------|----------| | Invalid template | Wrong message ID | Verify transactional_message_id in dashboard | | Missing required data | Template variables missing | Check message_data contains all variables | | Segment not updating | Attribute not matching | Verify attribute types and operators | ## Resources - [Transactional API](https://customer.io/docs/transactional-api/) - [Segments](https://customer.io/docs/segments/) - [Anonymous Events](https://customer.io/docs/anonymous-events/) ## Next Steps After implementing core features, proceed to `customerio-common-errors` to learn troubleshooting.