@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 +279 -0
- package/dist/cjs/client.d.ts +87 -0
- package/dist/cjs/client.js +890 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/types.d.ts +122 -0
- package/dist/cjs/types.js +40 -0
- package/dist/esm/client.d.ts +87 -0
- package/dist/esm/client.js +883 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/types.d.ts +122 -0
- package/dist/esm/types.js +36 -0
- package/package.json +40 -0
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 {};
|