cdp-node
v5.2.0
Published
Codematic OpenCDP Node.js SDK
Readme
@codematic/cdp-node
A Node.js client library for Codematic's Customer Data Platform (CDP) with optional Customer.io integration.
See the CDP Documentation for more information.
Installation
npm install @codematic.io/cdp-node
# or
yarn add @codematic.io/cdp-nodePackage Variants
This SDK is available in two npm packages:
@codematic.io/cdp-node(recommended) - Scoped package for production usecdp-node- Unscoped package for legacy compatibility
Both packages contain identical functionality. Use the scoped version for new projects.
Features
- Send customer identification and event data to Codematic CDP
- Send transactional emails (transactional messaging and raw HTML)
- Send SMS messages
- Send WhatsApp messages
- Send push notifications
- Optional dual-write capability to Customer.io
- TypeScript support
- Simple error handling and logging
Usage
import { CDPClient } from '@codematic.io/cdp-node';
const client = new CDPClient({
cdpApiKey: 'your-cdp-api-key'
});
// Identify a user
await client.identify('user123', {
email: '[email protected]',
name: 'John Doe',
plan: 'premium'
});
// Track an event
await client.track('user123', 'purchase_completed', {
amount: 99.99,
item_id: 'prod-123'
});
// Send transactional email
await client.sendEmail({
to: '[email protected]',
identifiers: { id: 'user123' },
transactional_message_id: 'WELCOME_EMAIL',
subject: 'Welcome!',
body: 'Thank you for joining us!'
});
// Send push notification
await client.sendPush({
identifiers: { id: 'user123' },
transactional_message_id: 'WELCOME_PUSH',
title: 'Welcome!',
body: 'Thank you for joining us!'
});
// Send SMS
await client.sendSms({
identifiers: { id: 'user123' },
transactional_message_id: 'WELCOME_SMS',
body: 'Thank you for joining us!'
});
// Send WhatsApp
await client.sendWhatsApp({
identifiers: { id: 'user123' },
transactional_message_id: 'WELCOME_WHATSAPP',
template_variables: {
body: { '1': 'Jane' }
}
});Dual-write to Customer.io
const client = new CDPClient({
cdpApiKey: 'your-cdp-api-key',
sendToCustomerIo: true,
customerIo: {
siteId: 'your-customer-io-site-id',
apiKey: 'your-customer-io-api-key',
region: 'us' // or 'eu' for EU data centers
}
});
// Now all identify, track, and update calls will send data to both platformsSending Emails
The SDK supports both transactional messaging and raw email sending:
Transactional messaging Email (without body override)
await client.sendEmail({
to: '[email protected]',
identifiers: { id: 'user123' },
transactional_message_id: 'WELCOME_EMAIL',
message_data: { name: 'John' }
});Transactional messaging Email (with body and subject override)
await client.sendEmail({
to: '[email protected]',
identifiers: { id: 'user123' },
transactional_message_id: 'WELCOME_EMAIL',
subject: 'Welcome!',
body: 'Thank you for joining us!',
message_data: { name: 'John' }
});Raw Email (without transactional message id)
await client.sendEmail({
to: '[email protected]',
identifiers: { email: '[email protected]' },
from: '[email protected]',
subject: 'Raw Email Test',
body: '<h1>This is a raw HTML email</h1>',
body_plain: 'This is a plain text email',
reply_to: '[email protected]'
});Attachments
Attach up to 5 files (2 MB decoded in total) with SendEmailRequest.attach(). Buffers are base64-encoded for you:
import { readFileSync } from 'fs';
import { SendEmailRequest } from 'cdp-node';
const request = new SendEmailRequest({
to: '[email protected]',
identifiers: { id: 'user123' },
transactional_message_id: 'INVOICE_EMAIL',
});
request.attach('invoice.pdf', readFileSync('./invoice.pdf'));
request.attach('notes.txt', 'Plain text content'); // strings are base64-encoded by default
request.attach('report.csv', existingBase64, { encode: false }); // already base64, sent as-is
await client.sendEmail(request);You can also pass attachments directly as a map of filename to base64 content. The SDK validates attachments before sending: at most 5 files, at most 2 MB decoded in total, filenames without /, \ or .., and non-empty base64 content. The content type is inferred from the file extension.
Unsupported Fields Warning
Some fields are accepted by the API but not yet processed by the backend. When you use these fields, the SDK will log a warning:
send_at- Scheduled send timesend_to_unsubscribed- Send to unsubscribed userstracked- Email trackingdisable_css_preprocessing- CSS preprocessing controlheaders- Custom email headersdisable_message_retention- Message retention controlqueue_draft- Queue as draft
// This will log a warning about unsupported fields
await client.sendEmail({
to: '[email protected]',
identifiers: { id: 'user123' },
transactional_message_id: 'TEST',
subject: 'Test',
send_at: 1640995200, // ⚠️ Will log warning
tracked: true, // ⚠️ Will log warning
headers: JSON.stringify({ 'X-Custom': 'value' }) // ⚠️ Will log warning
});These fields are included for future compatibility but currently have no effect on email delivery.
Sending Push Notifications
The SDK supports sending push notifications using transactional message templates:
Basic Push Notification
await client.sendPush({
identifiers: { id: 'user123' },
transactional_message_id: 'WELCOME_PUSH',
title: 'Welcome!',
body: 'Thank you for joining us!'
});Push Notification with Message Data
await client.sendPush({
identifiers: { email: '[email protected]' },
transactional_message_id: 'ORDER_UPDATE',
message_data: {
order_id: '12345',
tracking_number: 'TRK123456',
items: [
{ name: 'Shoes', price: '59.99' }
]
}
});Push Notification with Customer.io ID
await client.sendPush({
identifiers: { cdp_id: 'cio-123' },
transactional_message_id: 'PROMOTION',
title: 'Special Offer!',
body: 'Get 20% off your next purchase'
});Sending SMS
The SDK supports both transactional messaging and raw SMS sending:
Transactional messaging SMS (without body override)
await client.sendSms({
identifiers: { id: 'user123' },
transactional_message_id: 'WELCOME_SMS',
message_data: { name: 'John' }
});Transactional messaging SMS (with body override)
await client.sendSms({
identifiers: { id: 'user123' },
transactional_message_id: 'WELCOME_SMS',
body: 'Thank you for joining us!',
message_data: { name: 'John' }
});Raw SMS (without transactional message id)
await client.sendSms({
identifiers: { id: 'user123' },
to: '+1234567890',
from: '+1987654321',
body: 'This is a raw SMS message'
});Sending WhatsApp
WhatsApp sends use a saved WhatsApp transactional. transactional_message_id is required.
await client.sendWhatsApp({
identifiers: { id: 'user123' },
transactional_message_id: 'ORDER_CONFIRMATION',
to: '+14155551234',
template_variables: {
body: { '1': '12345' }
},
message_data: { name: 'John' }
});Constructor options
interface CDPConfig {
// Required OpenCDP configuration
cdpApiKey: string;
cdpEndpoint?: string; // Optional custom endpoint
// Optional Customer.io configuration
sendToCustomerIo?: boolean;
customerIo?: {
siteId: string;
apiKey: string;
region?: 'us' | 'eu';
};
// Logging options
debug?: boolean;
cdpLogger?: Logger; // Custom logger. will default to console.log
}Development
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
npm run test - Submit a pull request
Deployment
For information about deploying this SDK to npm, see DEPLOYMENT.md.
This SDK is published to two npm packages:
@codematic.io/cdp-node(scoped, recommended)cdp-node(unscoped, legacy)
License
MIT
