@codematic/opencdp 5.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,279 @@
1
+ # @codematic/cdp-node
2
+
3
+ A Node.js client library for Codematic's Customer Data Platform (CDP) with optional Customer.io integration.
4
+
5
+ See the [CDP Documentation](https://docs.opencdp.io/) for more information.
6
+ ## Installation
7
+
8
+ ```bash
9
+ npm install @codematic.io/cdp-node
10
+ # or
11
+ yarn add @codematic.io/cdp-node
12
+ ```
13
+
14
+ ### Package Variants
15
+
16
+ This SDK is available in two npm packages:
17
+
18
+ - **`@codematic.io/cdp-node`** (recommended) - Scoped package for production use
19
+ - **`cdp-node`** - Unscoped package for legacy compatibility
20
+
21
+ Both packages contain identical functionality. Use the scoped version for new projects.
22
+
23
+ ### Features
24
+
25
+ - Send customer identification and event data to Codematic CDP
26
+ - Send transactional emails (transactional messaging and raw HTML)
27
+ - Send SMS messages
28
+ - Send push notifications
29
+ - Optional dual-write capability to Customer.io
30
+ - TypeScript support
31
+ - Simple error handling and logging
32
+
33
+ ### Usage
34
+
35
+ ```typescript
36
+ import { CDPClient } from '@codematic.io/cdp-node';
37
+
38
+ const client = new CDPClient({
39
+ cdpApiKey: 'your-cdp-api-key'
40
+ });
41
+
42
+ // Identify a user
43
+ await client.identify('user123', {
44
+ email: 'user@example.com',
45
+ name: 'John Doe',
46
+ plan: 'premium'
47
+ });
48
+
49
+ // Track an event
50
+ await client.track('user123', 'purchase_completed', {
51
+ amount: 99.99,
52
+ item_id: 'prod-123'
53
+ });
54
+
55
+ // Send transactional email
56
+ await client.sendEmail({
57
+ to: 'user@example.com',
58
+ identifiers: { id: 'user123' },
59
+ transactional_message_id: 'WELCOME_EMAIL',
60
+ subject: 'Welcome!',
61
+ body: 'Thank you for joining us!'
62
+ });
63
+
64
+ // Send push notification
65
+ await client.sendPush({
66
+ identifiers: { id: 'user123' },
67
+ transactional_message_id: 'WELCOME_PUSH',
68
+ title: 'Welcome!',
69
+ body: 'Thank you for joining us!'
70
+ });
71
+
72
+ // Send SMS
73
+ await client.sendSms({
74
+ identifiers: { id: 'user123' },
75
+ transactional_message_id: 'WELCOME_SMS',
76
+ body: 'Thank you for joining us!'
77
+ });
78
+ ```
79
+
80
+ ### Dual-write to Customer.io
81
+
82
+ ```typescript
83
+ const client = new CDPClient({
84
+ cdpApiKey: 'your-cdp-api-key',
85
+ sendToCustomerIo: true,
86
+ customerIo: {
87
+ siteId: 'your-customer-io-site-id',
88
+ apiKey: 'your-customer-io-api-key',
89
+ region: 'us' // or 'eu' for EU data centers
90
+ }
91
+ });
92
+
93
+ // Now all identify, track, and update calls will send data to both platforms
94
+ ```
95
+
96
+ ### Sending Emails
97
+
98
+ The SDK supports both transactional messaging and raw email sending:
99
+
100
+ #### Transactional messaging Email (without body override)
101
+ ```typescript
102
+ await client.sendEmail({
103
+ to: 'user@example.com',
104
+ identifiers: { id: 'user123' },
105
+ transactional_message_id: 'WELCOME_EMAIL',
106
+ message_data: { name: 'John' }
107
+ });
108
+ ```
109
+
110
+ #### Transactional messaging Email (with body and subject override)
111
+ ```typescript
112
+ await client.sendEmail({
113
+ to: 'user@example.com',
114
+ identifiers: { id: 'user123' },
115
+ transactional_message_id: 'WELCOME_EMAIL',
116
+ subject: 'Welcome!',
117
+ body: 'Thank you for joining us!',
118
+ message_data: { name: 'John' }
119
+ });
120
+ ```
121
+
122
+ #### Raw Email (without transactional message id)
123
+ ```typescript
124
+ await client.sendEmail({
125
+ to: 'user@example.com',
126
+ identifiers: { email: 'user@example.com' },
127
+ from: 'no-reply@aellacredit.com',
128
+ subject: 'Raw Email Test',
129
+ body: '<h1>This is a raw HTML email</h1>',
130
+ body_plain: 'This is a plain text email',
131
+ reply_to: 'support@aellacredit.com'
132
+ });
133
+ ```
134
+
135
+ #### Unsupported Fields Warning
136
+
137
+ 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:
138
+
139
+ - `send_at` - Scheduled send time
140
+ - `send_to_unsubscribed` - Send to unsubscribed users
141
+ - `tracked` - Email tracking
142
+ - `disable_css_preprocessing` - CSS preprocessing control
143
+ - `headers` - Custom email headers
144
+ - `disable_message_retention` - Message retention control
145
+ - `queue_draft` - Queue as draft
146
+ - `attachments` - Email attachments
147
+
148
+ ```typescript
149
+ // This will log a warning about unsupported fields
150
+ await client.sendEmail({
151
+ to: 'user@example.com',
152
+ identifiers: { id: 'user123' },
153
+ transactional_message_id: 'TEST',
154
+ subject: 'Test',
155
+ send_at: 1640995200, // ⚠️ Will log warning
156
+ tracked: true, // ⚠️ Will log warning
157
+ headers: JSON.stringify({ 'X-Custom': 'value' }) // ⚠️ Will log warning
158
+ });
159
+ ```
160
+
161
+ These fields are included for future compatibility but currently have no effect on email delivery.
162
+
163
+ ### Sending Push Notifications
164
+
165
+ The SDK supports sending push notifications using transactional message templates:
166
+
167
+ #### Basic Push Notification
168
+ ```typescript
169
+ await client.sendPush({
170
+ identifiers: { id: 'user123' },
171
+ transactional_message_id: 'WELCOME_PUSH',
172
+ title: 'Welcome!',
173
+ body: 'Thank you for joining us!'
174
+ });
175
+ ```
176
+
177
+ #### Push Notification with Message Data
178
+ ```typescript
179
+ await client.sendPush({
180
+ identifiers: { email: 'user@example.com' },
181
+ transactional_message_id: 'ORDER_UPDATE',
182
+ message_data: {
183
+ order_id: '12345',
184
+ tracking_number: 'TRK123456',
185
+ items: [
186
+ { name: 'Shoes', price: '59.99' }
187
+ ]
188
+ }
189
+ });
190
+ ```
191
+
192
+ #### Push Notification with Customer.io ID
193
+ ```typescript
194
+ await client.sendPush({
195
+ identifiers: { cdp_id: 'cio-123' },
196
+ transactional_message_id: 'PROMOTION',
197
+ title: 'Special Offer!',
198
+ body: 'Get 20% off your next purchase'
199
+ });
200
+ ```
201
+
202
+ ### Sending SMS
203
+
204
+ The SDK supports both transactional messaging and raw SMS sending:
205
+
206
+ #### Transactional messaging SMS (without body override)
207
+ ```typescript
208
+ await client.sendSms({
209
+ identifiers: { id: 'user123' },
210
+ transactional_message_id: 'WELCOME_SMS',
211
+ message_data: { name: 'John' }
212
+ });
213
+ ```
214
+
215
+ #### Transactional messaging SMS (with body override)
216
+ ```typescript
217
+ await client.sendSms({
218
+ identifiers: { id: 'user123' },
219
+ transactional_message_id: 'WELCOME_SMS',
220
+ body: 'Thank you for joining us!',
221
+ message_data: { name: 'John' }
222
+ });
223
+ ```
224
+
225
+ #### Raw SMS (without transactional message id)
226
+ ```typescript
227
+ await client.sendSms({
228
+ identifiers: { id: 'user123' },
229
+ to: '+1234567890',
230
+ from: '+1987654321',
231
+ body: 'This is a raw SMS message'
232
+ });
233
+ ```
234
+
235
+ ### Constructor options
236
+ ```typescript
237
+ interface CDPConfig {
238
+ // Required OpenCDP configuration
239
+ cdpApiKey: string;
240
+ cdpEndpoint?: string; // Optional custom endpoint
241
+
242
+ // Optional Customer.io configuration
243
+ sendToCustomerIo?: boolean;
244
+ customerIo?: {
245
+ siteId: string;
246
+ apiKey: string;
247
+ region?: 'us' | 'eu';
248
+ };
249
+
250
+ // Logging options
251
+ debug?: boolean;
252
+ cdpLogger?: Logger; // Custom logger. will default to console.log
253
+ }
254
+ ```
255
+
256
+ ## Development
257
+
258
+ ### Contributing
259
+
260
+ 1. Fork the repository
261
+ 2. Create a feature branch
262
+ 3. Make your changes
263
+ 4. Run tests: `npm run test`
264
+ 5. Submit a pull request
265
+
266
+ ### Deployment
267
+
268
+ For information about deploying this SDK to npm, see [DEPLOYMENT.md](./DEPLOYMENT.md).
269
+
270
+ This SDK is published to two npm packages:
271
+ - `@codematic.io/cdp-node` (scoped, recommended)
272
+ - `cdp-node` (unscoped, legacy)
273
+
274
+ ## License
275
+
276
+ MIT# opencdp-node-sdk
277
+
278
+
279
+ npm view OpenCDP
@@ -0,0 +1,87 @@
1
+ import { CDPConfig, SendEmailRequest, SendPushRequest, SendSmsRequest } from "./types";
2
+ interface DeviceRegistrationParameters {
3
+ deviceId: string;
4
+ name?: string;
5
+ platform: "android" | "ios" | "web";
6
+ osVersion?: string;
7
+ model?: string;
8
+ fcmToken: string;
9
+ apnToken?: string;
10
+ appVersion?: string;
11
+ last_active_at?: string;
12
+ attributes?: Record<string, any>;
13
+ }
14
+ export declare class CDPClient {
15
+ private config;
16
+ private readonly customerIoClient;
17
+ private readonly apiRoot;
18
+ private readonly sendToCustomerIo;
19
+ private readonly logger;
20
+ private limit;
21
+ private timeout;
22
+ private readonly axiosInstance;
23
+ constructor(config: CDPConfig);
24
+ /**
25
+ * Tests the connection to the OpenCDP API server.
26
+ * Sends a ping request to verify that the configured endpoint is reachable and valid.
27
+ *
28
+ * This method ensures that credentials, and network access are configured correctly.
29
+ * It does NOT establish a persistent connection.
30
+ *
31
+ * Do not ping before sending each request
32
+ * @throws Error only when config.failOnException === true and the connection fails due to invalid credentials, network issues, or timeouts.
33
+ */
34
+ ping(): Promise<void>;
35
+ validateConnection(): Promise<void>;
36
+ private limited;
37
+ /**
38
+ * Identify a person in the CDP
39
+ * This method is concurrency-limited using p-limit to avoid overwhelming traffic external traffic.
40
+ * @param identifier The person identifier
41
+ * @param properties Additional properties for the person
42
+ * @throws Error only when config.failOnException === true (e.g., when the identifier is empty or the request fails)
43
+ */
44
+ identify(identifier: string, properties?: Record<string, any>): Promise<void>;
45
+ /**
46
+ * Track an event for a person.
47
+ * @param identifier The person identifier
48
+ * @param eventName The event name
49
+ * @param properties Additional properties for the event
50
+ * @throws Error only when config.failOnException === true (e.g., when validation or request fails)
51
+ */
52
+ track(identifier: string, eventName: string, properties?: Record<string, any>): Promise<void>;
53
+ /**
54
+ * Register a device for a person. A device must be registered to send push notifications
55
+ * @param identifier
56
+ * @param deviceRegistrationParameters
57
+ * @throws Error only when config.failOnException === true (e.g., when validation or request fails)
58
+ */
59
+ registerDevice(identifier: string, deviceRegistrationParameters: DeviceRegistrationParameters): Promise<void>;
60
+ /**
61
+ * Send an email using the CDP transactional email service
62
+ * @param request The send email request parameters
63
+ * @returns Promise that resolves when the email is sent
64
+ * @throws Error only when config.failOnException === true and validation or the request fails
65
+ */
66
+ sendEmail(request: SendEmailRequest): Promise<Record<string, any>>;
67
+ /**
68
+ * Warns about unsupported fields that are accepted but not processed by the backend
69
+ * @param request The send email request parameters
70
+ */
71
+ private warnUnsupportedFields;
72
+ /**
73
+ * Send a push notification using the OpenCDP transactional push service
74
+ * @param request The send push request parameters
75
+ * @returns Promise that resolves when the push notification is sent
76
+ * @throws Error only when config.failOnException === true and validation or the request fails
77
+ */
78
+ sendPush(request: SendPushRequest): Promise<any>;
79
+ /**
80
+ * Send an SMS using the OpenCDP transactional SMS service
81
+ * @param request The send SMS request parameters
82
+ * @returns Promise that resolves when the SMS is sent
83
+ * @throws Error only when config.failOnException === true and validation or the request fails
84
+ */
85
+ sendSms(request: SendSmsRequest): Promise<any>;
86
+ }
87
+ export {};