| 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 <jeremy@intentsolutions.io> |
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
// 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<string, any>;
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
// 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
// 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)
// 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
// lib/customerio-data-pipeline.ts
export interface DataPipelineConfig {
source: 'segment' | 'rudderstack' | 'mparticle' | 'custom';
mappings: {
userId: string;
email: string;
customAttributes: Record<string, string>;
};
}
// Webhook handler for incoming CDP data
export async function handleCDPWebhook(
client: TrackClient,
event: {
type: 'identify' | 'track';
userId: string;
traits?: Record<string, any>;
event?: string;
properties?: Record<string, any>;
}
) {
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
Next Steps
After implementing core features, proceed to customerio-common-errors to learn troubleshooting.