@sendmailos/sdk 1.1.1 → 1.2.1
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 +353 -4
- package/dist/index.d.mts +860 -6
- package/dist/index.d.ts +860 -6
- package/dist/index.js +685 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +685 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -54,9 +54,10 @@ var EmailsResource = class {
|
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* Send a transactional email
|
|
57
|
-
*
|
|
57
|
+
*
|
|
58
58
|
* @example
|
|
59
59
|
* ```ts
|
|
60
|
+
* // Business account (single-tenant)
|
|
60
61
|
* const result = await client.emails.send({
|
|
61
62
|
* to: 'user@example.com',
|
|
62
63
|
* fromName: 'Your Company',
|
|
@@ -64,6 +65,16 @@ var EmailsResource = class {
|
|
|
64
65
|
* subject: 'Welcome!',
|
|
65
66
|
* html: '<h1>Hello!</h1>'
|
|
66
67
|
* });
|
|
68
|
+
*
|
|
69
|
+
* // Agency account (multi-tenant) - identify client by domain
|
|
70
|
+
* const result = await agencyClient.emails.send({
|
|
71
|
+
* to: 'customer@example.com',
|
|
72
|
+
* fromName: 'Pizza Palace',
|
|
73
|
+
* fromEmail: 'hello@pizzapalace.com',
|
|
74
|
+
* subject: 'Your order is ready!',
|
|
75
|
+
* html: '<h1>Order Ready!</h1>',
|
|
76
|
+
* domain: 'pizzapalace.com' // Required for agency accounts
|
|
77
|
+
* });
|
|
67
78
|
* ```
|
|
68
79
|
*/
|
|
69
80
|
async send(params) {
|
|
@@ -77,13 +88,15 @@ var EmailsResource = class {
|
|
|
77
88
|
from_name: params.fromName,
|
|
78
89
|
from_email: params.fromEmail,
|
|
79
90
|
variables: params.variables,
|
|
80
|
-
type: params.type || "transactional"
|
|
91
|
+
type: params.type || "transactional",
|
|
92
|
+
workspace_id: params.workspaceId,
|
|
93
|
+
domain: params.domain
|
|
81
94
|
})
|
|
82
95
|
});
|
|
83
96
|
}
|
|
84
97
|
/**
|
|
85
98
|
* Send email using a template
|
|
86
|
-
*
|
|
99
|
+
*
|
|
87
100
|
* @example
|
|
88
101
|
* ```ts
|
|
89
102
|
* const result = await client.emails.sendTemplate({
|
|
@@ -101,7 +114,9 @@ var EmailsResource = class {
|
|
|
101
114
|
fromName: params.fromName,
|
|
102
115
|
fromEmail: params.fromEmail,
|
|
103
116
|
variables: params.variables,
|
|
104
|
-
type: "transactional"
|
|
117
|
+
type: "transactional",
|
|
118
|
+
workspaceId: params.workspaceId,
|
|
119
|
+
domain: params.domain
|
|
105
120
|
});
|
|
106
121
|
}
|
|
107
122
|
};
|
|
@@ -113,14 +128,23 @@ var SubscribersResource = class {
|
|
|
113
128
|
}
|
|
114
129
|
/**
|
|
115
130
|
* Create or update a subscriber (upsert)
|
|
116
|
-
*
|
|
131
|
+
*
|
|
117
132
|
* @example
|
|
118
133
|
* ```ts
|
|
134
|
+
* // Business account
|
|
119
135
|
* const { subscriber } = await client.subscribers.create({
|
|
120
136
|
* email: 'user@example.com',
|
|
121
137
|
* firstName: 'John',
|
|
122
138
|
* tags: ['newsletter', 'premium']
|
|
123
139
|
* });
|
|
140
|
+
*
|
|
141
|
+
* // Agency account - subscriber tracked to client domain
|
|
142
|
+
* const { subscriber } = await agencyClient.subscribers.create({
|
|
143
|
+
* email: 'customer@example.com',
|
|
144
|
+
* firstName: 'Jane',
|
|
145
|
+
* domain: 'pizzapalace.com', // Required for agency accounts
|
|
146
|
+
* tags: ['loyalty-member']
|
|
147
|
+
* });
|
|
124
148
|
* ```
|
|
125
149
|
*/
|
|
126
150
|
async create(params) {
|
|
@@ -131,7 +155,10 @@ var SubscribersResource = class {
|
|
|
131
155
|
first_name: params.firstName,
|
|
132
156
|
last_name: params.lastName,
|
|
133
157
|
tags: params.tags,
|
|
134
|
-
domain_id: params.domainId
|
|
158
|
+
domain_id: params.domainId,
|
|
159
|
+
workspace_id: params.workspaceId,
|
|
160
|
+
domain: params.domain
|
|
161
|
+
// Alternative to workspace_id
|
|
135
162
|
})
|
|
136
163
|
});
|
|
137
164
|
}
|
|
@@ -150,6 +177,8 @@ var SubscribersResource = class {
|
|
|
150
177
|
const searchParams = new URLSearchParams();
|
|
151
178
|
if (params.limit) searchParams.set("limit", String(params.limit));
|
|
152
179
|
if (params.offset) searchParams.set("offset", String(params.offset));
|
|
180
|
+
if (params.workspaceId) searchParams.set("workspace_id", params.workspaceId);
|
|
181
|
+
if (params.domain) searchParams.set("domain", params.domain);
|
|
153
182
|
const query = searchParams.toString();
|
|
154
183
|
const endpoint = query ? `/subscribers?${query}` : "/subscribers";
|
|
155
184
|
return this.request(endpoint, {
|
|
@@ -221,9 +250,10 @@ var CampaignsResource = class {
|
|
|
221
250
|
}
|
|
222
251
|
/**
|
|
223
252
|
* Send a campaign to subscribers
|
|
224
|
-
*
|
|
253
|
+
*
|
|
225
254
|
* @example
|
|
226
255
|
* ```ts
|
|
256
|
+
* // Business account
|
|
227
257
|
* const result = await client.campaigns.send({
|
|
228
258
|
* name: 'January Newsletter',
|
|
229
259
|
* subject: 'What\'s new this month',
|
|
@@ -232,6 +262,17 @@ var CampaignsResource = class {
|
|
|
232
262
|
* html: '<h1>Hello {{first_name}}!</h1>',
|
|
233
263
|
* tags: ['newsletter', 'active']
|
|
234
264
|
* });
|
|
265
|
+
*
|
|
266
|
+
* // Agency account - send to specific client's subscribers
|
|
267
|
+
* const result = await agencyClient.campaigns.send({
|
|
268
|
+
* name: 'Pizza Promo',
|
|
269
|
+
* subject: 'New menu items!',
|
|
270
|
+
* fromName: 'Pizza Palace',
|
|
271
|
+
* fromEmail: 'promo@pizzapalace.com',
|
|
272
|
+
* html: '<h1>Check out our new menu!</h1>',
|
|
273
|
+
* domain: 'pizzapalace.com', // Filter to this client's subscribers
|
|
274
|
+
* sourceDomains: ['pizzapalace.com'] // Only subscribers who signed up on this domain
|
|
275
|
+
* });
|
|
235
276
|
* ```
|
|
236
277
|
*/
|
|
237
278
|
async send(params) {
|
|
@@ -245,7 +286,10 @@ var CampaignsResource = class {
|
|
|
245
286
|
html: params.html,
|
|
246
287
|
templateId: params.templateId,
|
|
247
288
|
tags: params.tags,
|
|
248
|
-
variables: params.variables
|
|
289
|
+
variables: params.variables,
|
|
290
|
+
workspace_id: params.workspaceId,
|
|
291
|
+
domain: params.domain,
|
|
292
|
+
sourceDomains: params.sourceDomains
|
|
249
293
|
})
|
|
250
294
|
});
|
|
251
295
|
}
|
|
@@ -260,7 +304,10 @@ var CampaignsResource = class {
|
|
|
260
304
|
fromEmail: params.fromEmail,
|
|
261
305
|
templateId: params.templateId,
|
|
262
306
|
tags: params.tags,
|
|
263
|
-
variables: params.variables
|
|
307
|
+
variables: params.variables,
|
|
308
|
+
workspaceId: params.workspaceId,
|
|
309
|
+
domain: params.domain,
|
|
310
|
+
sourceDomains: params.sourceDomains
|
|
264
311
|
});
|
|
265
312
|
}
|
|
266
313
|
};
|
|
@@ -325,10 +372,633 @@ var DomainsResource = class {
|
|
|
325
372
|
}
|
|
326
373
|
};
|
|
327
374
|
|
|
375
|
+
// src/resources/organization.ts
|
|
376
|
+
var OrganizationResource = class {
|
|
377
|
+
constructor(request) {
|
|
378
|
+
this.request = request;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Get current organization details
|
|
382
|
+
*/
|
|
383
|
+
async get() {
|
|
384
|
+
const response = await this.request("/organization", {
|
|
385
|
+
method: "GET"
|
|
386
|
+
});
|
|
387
|
+
return response.organization;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Update organization settings
|
|
391
|
+
*/
|
|
392
|
+
async update(updates) {
|
|
393
|
+
const response = await this.request("/organization", {
|
|
394
|
+
method: "PATCH",
|
|
395
|
+
body: JSON.stringify(updates)
|
|
396
|
+
});
|
|
397
|
+
return response.organization;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Set organization industries (during onboarding)
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```ts
|
|
404
|
+
* await client.organization.setIndustries(['ecommerce', 'saas']);
|
|
405
|
+
* ```
|
|
406
|
+
*/
|
|
407
|
+
async setIndustries(industries) {
|
|
408
|
+
return this.update({ industries });
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Convert to agency account (enables workspaces)
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```ts
|
|
415
|
+
* await client.organization.convertToAgency();
|
|
416
|
+
* // Now you can create client workspaces
|
|
417
|
+
* await client.workspaces.create({ name: 'Client A', industry: 'ecommerce' });
|
|
418
|
+
* ```
|
|
419
|
+
*/
|
|
420
|
+
async convertToAgency() {
|
|
421
|
+
return this.update({ org_type: "agency" });
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Complete onboarding
|
|
425
|
+
*/
|
|
426
|
+
async completeOnboarding() {
|
|
427
|
+
return this.update({ onboarding_completed: true });
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
var INDUSTRIES = {
|
|
431
|
+
hotels: "Hotels & Hospitality",
|
|
432
|
+
restaurants: "Restaurants & Food Service",
|
|
433
|
+
gyms: "Gyms & Fitness",
|
|
434
|
+
travel_agencies: "Travel Agencies",
|
|
435
|
+
real_estate: "Real Estate",
|
|
436
|
+
schools: "Schools & Education",
|
|
437
|
+
ecommerce: "E-commerce",
|
|
438
|
+
dentists: "Dentists",
|
|
439
|
+
car_dealerships: "Car Dealerships",
|
|
440
|
+
events: "Events & Entertainment",
|
|
441
|
+
beauty_salons: "Beauty Salons",
|
|
442
|
+
law_firms: "Law Firms",
|
|
443
|
+
nonprofits: "Non-Profits",
|
|
444
|
+
saas: "SaaS & Software",
|
|
445
|
+
recruitment: "Recruitment & HR",
|
|
446
|
+
insurance: "Insurance",
|
|
447
|
+
online_courses: "Online Courses",
|
|
448
|
+
municipalities: "Government & Municipalities",
|
|
449
|
+
personal_trainers: "Personal Trainers",
|
|
450
|
+
influencers: "Influencers & Creators",
|
|
451
|
+
doctors_clinics: "Doctors & Clinics",
|
|
452
|
+
nightclubs: "Nightclubs & Bars",
|
|
453
|
+
coworking: "Coworking Spaces",
|
|
454
|
+
wedding_planners: "Wedding Planners",
|
|
455
|
+
art_galleries: "Art Galleries",
|
|
456
|
+
car_rentals: "Car Rentals",
|
|
457
|
+
podcasters: "Podcasters",
|
|
458
|
+
consultants: "Consultants",
|
|
459
|
+
bakeries: "Bakeries",
|
|
460
|
+
veterinarians: "Veterinarians",
|
|
461
|
+
airbnb_hosts: "Airbnb Hosts",
|
|
462
|
+
accountants: "Accountants",
|
|
463
|
+
developers: "Developers",
|
|
464
|
+
musicians: "Musicians & Bands",
|
|
465
|
+
spas: "Spas & Wellness",
|
|
466
|
+
bookstores: "Bookstores",
|
|
467
|
+
cleaning_services: "Cleaning Services",
|
|
468
|
+
churches: "Churches & Religious",
|
|
469
|
+
graphic_designers: "Graphic Designers",
|
|
470
|
+
coffee_shops: "Coffee Shops",
|
|
471
|
+
florists: "Florists",
|
|
472
|
+
political: "Political Campaigns",
|
|
473
|
+
libraries: "Libraries",
|
|
474
|
+
taxis_limos: "Taxis & Limos",
|
|
475
|
+
home_inspectors: "Home Inspectors",
|
|
476
|
+
photographers: "Photographers",
|
|
477
|
+
universities: "Universities",
|
|
478
|
+
fashion: "Fashion Brands",
|
|
479
|
+
nutritionists: "Nutritionists",
|
|
480
|
+
startups: "Startups",
|
|
481
|
+
other: "Other"
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
// src/resources/workspaces.ts
|
|
485
|
+
var WorkspacesResource = class {
|
|
486
|
+
constructor(request) {
|
|
487
|
+
this.request = request;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* List all workspaces (clients)
|
|
491
|
+
* @note Only available for agency accounts
|
|
492
|
+
*
|
|
493
|
+
* @example
|
|
494
|
+
* ```ts
|
|
495
|
+
* const { workspaces } = await client.workspaces.list();
|
|
496
|
+
* for (const ws of workspaces) {
|
|
497
|
+
* console.log(`${ws.name}: ${ws.stats?.subscribers} subscribers`);
|
|
498
|
+
* }
|
|
499
|
+
* ```
|
|
500
|
+
*/
|
|
501
|
+
async list() {
|
|
502
|
+
const response = await this.request("/workspaces", {
|
|
503
|
+
method: "GET"
|
|
504
|
+
});
|
|
505
|
+
return { workspaces: response.workspaces, total: response.total };
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Create a new workspace (client)
|
|
509
|
+
* @note Only available for agency accounts
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```ts
|
|
513
|
+
* const workspace = await client.workspaces.create({
|
|
514
|
+
* name: 'Pizza Palace',
|
|
515
|
+
* industry: 'restaurants',
|
|
516
|
+
* import_templates: true // Auto-import restaurant templates
|
|
517
|
+
* });
|
|
518
|
+
* ```
|
|
519
|
+
*/
|
|
520
|
+
async create(workspace) {
|
|
521
|
+
const response = await this.request("/workspaces", {
|
|
522
|
+
method: "POST",
|
|
523
|
+
body: JSON.stringify(workspace)
|
|
524
|
+
});
|
|
525
|
+
return response.workspace;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Get a workspace by ID with detailed stats
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```ts
|
|
532
|
+
* const workspace = await client.workspaces.get('ws_123');
|
|
533
|
+
* console.log('Active subscribers:', workspace.stats.active_subscribers);
|
|
534
|
+
* ```
|
|
535
|
+
*/
|
|
536
|
+
async get(workspaceId) {
|
|
537
|
+
const response = await this.request(`/workspaces/${workspaceId}`, {
|
|
538
|
+
method: "GET"
|
|
539
|
+
});
|
|
540
|
+
return response.workspace;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Update a workspace
|
|
544
|
+
*
|
|
545
|
+
* @example
|
|
546
|
+
* ```ts
|
|
547
|
+
* await client.workspaces.update('ws_123', {
|
|
548
|
+
* name: 'Pizza Palace - Main Location',
|
|
549
|
+
* client_can_view_reports: true
|
|
550
|
+
* });
|
|
551
|
+
* ```
|
|
552
|
+
*/
|
|
553
|
+
async update(workspaceId, updates) {
|
|
554
|
+
const response = await this.request(`/workspaces/${workspaceId}`, {
|
|
555
|
+
method: "PATCH",
|
|
556
|
+
body: JSON.stringify(updates)
|
|
557
|
+
});
|
|
558
|
+
return response.workspace;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Delete a workspace
|
|
562
|
+
* @warning This will delete all associated data (subscribers, campaigns, etc.)
|
|
563
|
+
*
|
|
564
|
+
* @example
|
|
565
|
+
* ```ts
|
|
566
|
+
* await client.workspaces.delete('ws_123');
|
|
567
|
+
* ```
|
|
568
|
+
*/
|
|
569
|
+
async delete(workspaceId) {
|
|
570
|
+
const response = await this.request(`/workspaces/${workspaceId}`, {
|
|
571
|
+
method: "DELETE"
|
|
572
|
+
});
|
|
573
|
+
return { message: response.message };
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Activate a workspace
|
|
577
|
+
*/
|
|
578
|
+
async activate(workspaceId) {
|
|
579
|
+
return this.update(workspaceId, { is_active: true });
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Deactivate a workspace
|
|
583
|
+
*/
|
|
584
|
+
async deactivate(workspaceId) {
|
|
585
|
+
return this.update(workspaceId, { is_active: false });
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Invite client to view reports
|
|
589
|
+
*
|
|
590
|
+
* @example
|
|
591
|
+
* ```ts
|
|
592
|
+
* await client.workspaces.inviteClient('ws_123', 'owner@pizzapalace.com');
|
|
593
|
+
* // Client receives email with portal access
|
|
594
|
+
* ```
|
|
595
|
+
*/
|
|
596
|
+
async inviteClient(workspaceId, email) {
|
|
597
|
+
return this.update(workspaceId, {
|
|
598
|
+
client_email: email,
|
|
599
|
+
client_can_view_reports: true
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Smart workspace provisioning - finds existing or creates new
|
|
604
|
+
*
|
|
605
|
+
* This is the recommended method for agency client onboarding.
|
|
606
|
+
* It will:
|
|
607
|
+
* 1. Search for existing workspace by website URL or client_email
|
|
608
|
+
* 2. Return existing workspace if found
|
|
609
|
+
* 3. Create new workspace with industry templates if not found
|
|
610
|
+
* 4. Optionally generate a workspace-scoped API key
|
|
611
|
+
*
|
|
612
|
+
* @note Only available for agency accounts
|
|
613
|
+
*
|
|
614
|
+
* @example
|
|
615
|
+
* ```ts
|
|
616
|
+
* // Auto-provision workspace for a new client
|
|
617
|
+
* const result = await client.workspaces.provision({
|
|
618
|
+
* name: 'Pizza Palace',
|
|
619
|
+
* website: 'https://pizzapalace.com',
|
|
620
|
+
* client_email: 'owner@pizzapalace.com',
|
|
621
|
+
* industry: 'restaurants',
|
|
622
|
+
* generate_api_key: true
|
|
623
|
+
* });
|
|
624
|
+
*
|
|
625
|
+
* if (result.is_new) {
|
|
626
|
+
* console.log('Created new workspace:', result.workspace.id);
|
|
627
|
+
* console.log('API Key:', result.api_key);
|
|
628
|
+
* } else {
|
|
629
|
+
* console.log('Found existing workspace:', result.workspace.id);
|
|
630
|
+
* }
|
|
631
|
+
* ```
|
|
632
|
+
*
|
|
633
|
+
* @example
|
|
634
|
+
* ```ts
|
|
635
|
+
* // Idempotent client setup - safe to call multiple times
|
|
636
|
+
* const { workspace, is_new } = await client.workspaces.provision({
|
|
637
|
+
* name: 'Client Name',
|
|
638
|
+
* website: 'https://client.com',
|
|
639
|
+
* industry: 'ecommerce'
|
|
640
|
+
* });
|
|
641
|
+
* // Always returns the same workspace for the same website
|
|
642
|
+
* ```
|
|
643
|
+
*/
|
|
644
|
+
async provision(request) {
|
|
645
|
+
const response = await this.request("/workspaces/provision", {
|
|
646
|
+
method: "POST",
|
|
647
|
+
body: JSON.stringify(request)
|
|
648
|
+
});
|
|
649
|
+
return {
|
|
650
|
+
workspace: response.workspace,
|
|
651
|
+
is_new: response.is_new,
|
|
652
|
+
api_key: response.api_key,
|
|
653
|
+
message: response.message
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Alias for provision() - find or create workspace
|
|
658
|
+
* @see provision
|
|
659
|
+
*/
|
|
660
|
+
async findOrCreate(request) {
|
|
661
|
+
return this.provision(request);
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Complete client onboarding in ONE call (Agency only)
|
|
665
|
+
*
|
|
666
|
+
* This is the simplest way to onboard a new client:
|
|
667
|
+
* 1. Creates or finds workspace by domain
|
|
668
|
+
* 2. Registers domain for email verification
|
|
669
|
+
* 3. Generates workspace token
|
|
670
|
+
* 4. Returns DNS records + token
|
|
671
|
+
*
|
|
672
|
+
* After this, use the returned `token` for all API calls.
|
|
673
|
+
*
|
|
674
|
+
* @example
|
|
675
|
+
* ```ts
|
|
676
|
+
* // Your SaaS onboards a new restaurant
|
|
677
|
+
* const result = await agency.workspaces.onboard({
|
|
678
|
+
* domain: 'pizzapalace.com',
|
|
679
|
+
* industry: 'restaurants'
|
|
680
|
+
* });
|
|
681
|
+
*
|
|
682
|
+
* // Save this token - it's all you need
|
|
683
|
+
* saveToDatabase(restaurantId, result.token);
|
|
684
|
+
*
|
|
685
|
+
* // Show DNS records to restaurant owner
|
|
686
|
+
* console.log('Add these DNS records:', result.dns_records);
|
|
687
|
+
*
|
|
688
|
+
* // Later, use the token directly
|
|
689
|
+
* const restaurant = new SendMailOS(result.token);
|
|
690
|
+
* await restaurant.emails.send({ ... });
|
|
691
|
+
* ```
|
|
692
|
+
*/
|
|
693
|
+
async onboard(request) {
|
|
694
|
+
const response = await this.request("/workspaces/onboard", {
|
|
695
|
+
method: "POST",
|
|
696
|
+
body: JSON.stringify(request)
|
|
697
|
+
});
|
|
698
|
+
return {
|
|
699
|
+
token: response.token,
|
|
700
|
+
workspace_id: response.workspace_id,
|
|
701
|
+
workspace_name: response.workspace_name,
|
|
702
|
+
domain: response.domain,
|
|
703
|
+
domain_status: response.domain_status,
|
|
704
|
+
dns_records: response.dns_records,
|
|
705
|
+
is_new: response.is_new,
|
|
706
|
+
message: response.message
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
// src/resources/workflows.ts
|
|
712
|
+
var WorkflowsResource = class {
|
|
713
|
+
constructor(request) {
|
|
714
|
+
this.request = request;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Create a new workflow
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* ```ts
|
|
721
|
+
* // Create workflow for a specific client (multi-brand)
|
|
722
|
+
* const result = await platform.workflows.create({
|
|
723
|
+
* name: 'Welcome Sequence',
|
|
724
|
+
* domain: 'pizzapalace.com',
|
|
725
|
+
* trigger: { type: 'subscriber_created' }
|
|
726
|
+
* });
|
|
727
|
+
*
|
|
728
|
+
* // Create workflow (single brand)
|
|
729
|
+
* const result = await client.workflows.create({
|
|
730
|
+
* name: 'Onboarding Flow',
|
|
731
|
+
* trigger: { type: 'api' }
|
|
732
|
+
* });
|
|
733
|
+
* ```
|
|
734
|
+
*/
|
|
735
|
+
async create(params) {
|
|
736
|
+
return this.request("/workflows", {
|
|
737
|
+
method: "POST",
|
|
738
|
+
body: JSON.stringify(params)
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* List all workflows
|
|
743
|
+
*
|
|
744
|
+
* @example
|
|
745
|
+
* ```ts
|
|
746
|
+
* // List all workflows
|
|
747
|
+
* const { workflows } = await client.workflows.list();
|
|
748
|
+
*
|
|
749
|
+
* // List workflows for a specific client (multi-brand)
|
|
750
|
+
* const { workflows } = await platform.workflows.list({ domain: 'pizzapalace.com' });
|
|
751
|
+
* ```
|
|
752
|
+
*/
|
|
753
|
+
async list(params = {}) {
|
|
754
|
+
const searchParams = new URLSearchParams();
|
|
755
|
+
if (params.domain) searchParams.set("domain", params.domain);
|
|
756
|
+
if (params.workspace_id) searchParams.set("workspace_id", params.workspace_id);
|
|
757
|
+
const query = searchParams.toString();
|
|
758
|
+
const endpoint = query ? `/workflows?${query}` : "/workflows";
|
|
759
|
+
return this.request(endpoint, {
|
|
760
|
+
method: "GET"
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Get a workflow by ID (includes nodes and edges)
|
|
765
|
+
*
|
|
766
|
+
* @example
|
|
767
|
+
* ```ts
|
|
768
|
+
* const { workflow } = await client.workflows.get('workflow-uuid');
|
|
769
|
+
* console.log(workflow.nodes); // The workflow steps
|
|
770
|
+
* console.log(workflow.edges); // Connections between steps
|
|
771
|
+
* ```
|
|
772
|
+
*/
|
|
773
|
+
async get(workflowId) {
|
|
774
|
+
return this.request(`/workflows/${workflowId}`, {
|
|
775
|
+
method: "GET"
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Update a workflow (name, nodes, edges, trigger)
|
|
780
|
+
*
|
|
781
|
+
* @example
|
|
782
|
+
* ```ts
|
|
783
|
+
* // Update workflow name
|
|
784
|
+
* await client.workflows.update('workflow-uuid', { name: 'New Name' });
|
|
785
|
+
*
|
|
786
|
+
* // Update workflow steps
|
|
787
|
+
* await client.workflows.update('workflow-uuid', {
|
|
788
|
+
* nodes: [
|
|
789
|
+
* { id: '1', type: 'trigger', data: { triggerType: 'api' } },
|
|
790
|
+
* { id: '2', type: 'email', data: { templateId: 'tmpl_xxx', subject: 'Welcome!' } },
|
|
791
|
+
* { id: '3', type: 'delay', data: { duration: 3, unit: 'days' } }
|
|
792
|
+
* ],
|
|
793
|
+
* edges: [
|
|
794
|
+
* { id: 'e1', source: '1', target: '2' },
|
|
795
|
+
* { id: 'e2', source: '2', target: '3' }
|
|
796
|
+
* ]
|
|
797
|
+
* });
|
|
798
|
+
* ```
|
|
799
|
+
*/
|
|
800
|
+
async update(workflowId, params) {
|
|
801
|
+
return this.request(`/workflows/${workflowId}`, {
|
|
802
|
+
method: "PUT",
|
|
803
|
+
body: JSON.stringify(params)
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* Delete a workflow
|
|
808
|
+
*/
|
|
809
|
+
async delete(workflowId) {
|
|
810
|
+
return this.request(`/workflows/${workflowId}`, {
|
|
811
|
+
method: "DELETE"
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Activate a workflow (start accepting triggers)
|
|
816
|
+
*
|
|
817
|
+
* @example
|
|
818
|
+
* ```ts
|
|
819
|
+
* await client.workflows.activate('workflow-uuid');
|
|
820
|
+
* // Workflow is now active and will process triggers
|
|
821
|
+
* ```
|
|
822
|
+
*/
|
|
823
|
+
async activate(workflowId) {
|
|
824
|
+
return this.request(`/workflows/${workflowId}/activate`, {
|
|
825
|
+
method: "POST"
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Pause a workflow (stop accepting new triggers)
|
|
830
|
+
*
|
|
831
|
+
* @example
|
|
832
|
+
* ```ts
|
|
833
|
+
* await client.workflows.pause('workflow-uuid');
|
|
834
|
+
* // Workflow is paused - existing executions continue, but no new ones start
|
|
835
|
+
* ```
|
|
836
|
+
*/
|
|
837
|
+
async pause(workflowId) {
|
|
838
|
+
return this.request(`/workflows/${workflowId}/pause`, {
|
|
839
|
+
method: "POST"
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Trigger a workflow for a subscriber
|
|
844
|
+
*
|
|
845
|
+
* @example
|
|
846
|
+
* ```ts
|
|
847
|
+
* // Trigger when a customer signs up
|
|
848
|
+
* const result = await platform.workflows.trigger('workflow-uuid', {
|
|
849
|
+
* email: 'customer@example.com',
|
|
850
|
+
* data: {
|
|
851
|
+
* firstName: 'John',
|
|
852
|
+
* restaurantName: 'Pizza Palace',
|
|
853
|
+
* signupSource: 'website'
|
|
854
|
+
* }
|
|
855
|
+
* });
|
|
856
|
+
*
|
|
857
|
+
* console.log(result.execution_id); // Track this execution
|
|
858
|
+
* ```
|
|
859
|
+
*/
|
|
860
|
+
async trigger(workflowId, params) {
|
|
861
|
+
return this.request(`/webhooks/${workflowId}`, {
|
|
862
|
+
method: "POST",
|
|
863
|
+
body: JSON.stringify(params)
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Send a custom event to resume waiting workflows
|
|
868
|
+
*
|
|
869
|
+
* Use this when you have workflows waiting for specific events (e.g., "purchase_completed").
|
|
870
|
+
* All workflows waiting for this event for the given subscriber will resume.
|
|
871
|
+
*
|
|
872
|
+
* @example
|
|
873
|
+
* ```ts
|
|
874
|
+
* // When a customer completes a purchase
|
|
875
|
+
* await platform.workflows.sendEvent({
|
|
876
|
+
* event: 'purchase_completed',
|
|
877
|
+
* email: 'customer@example.com',
|
|
878
|
+
* data: { orderTotal: 45.99, orderId: 'ORD-123' }
|
|
879
|
+
* });
|
|
880
|
+
*
|
|
881
|
+
* // Any workflow with a "wait_for_event: purchase_completed" node will resume
|
|
882
|
+
* ```
|
|
883
|
+
*/
|
|
884
|
+
async sendEvent(params) {
|
|
885
|
+
return this.request("/events", {
|
|
886
|
+
method: "POST",
|
|
887
|
+
body: JSON.stringify(params)
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
// src/resources/webhooks.ts
|
|
893
|
+
var WebhooksResource = class {
|
|
894
|
+
constructor(request) {
|
|
895
|
+
this.request = request;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Create a new webhook endpoint
|
|
899
|
+
*
|
|
900
|
+
* @example
|
|
901
|
+
* ```ts
|
|
902
|
+
* const webhook = await client.webhooks.create({
|
|
903
|
+
* url: 'https://yourserver.com/webhooks',
|
|
904
|
+
* events: ['email.sent', 'email.delivered', 'email.opened'],
|
|
905
|
+
* secret: 'your-secret-key' // Optional, auto-generated if not provided
|
|
906
|
+
* });
|
|
907
|
+
*
|
|
908
|
+
* console.log('Webhook secret:', webhook.secret);
|
|
909
|
+
* ```
|
|
910
|
+
*/
|
|
911
|
+
async create(params) {
|
|
912
|
+
return this.request("/webhooks", {
|
|
913
|
+
method: "POST",
|
|
914
|
+
body: JSON.stringify(params)
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* List all webhooks
|
|
919
|
+
*/
|
|
920
|
+
async list() {
|
|
921
|
+
return this.request("/webhooks", {
|
|
922
|
+
method: "GET"
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Get a webhook by ID with recent delivery history
|
|
927
|
+
*/
|
|
928
|
+
async get(webhookId) {
|
|
929
|
+
return this.request(`/webhooks/${webhookId}`, {
|
|
930
|
+
method: "GET"
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Update a webhook
|
|
935
|
+
*
|
|
936
|
+
* @example
|
|
937
|
+
* ```ts
|
|
938
|
+
* // Update webhook URL
|
|
939
|
+
* await client.webhooks.update('webhook-id', {
|
|
940
|
+
* url: 'https://newserver.com/webhooks'
|
|
941
|
+
* });
|
|
942
|
+
*
|
|
943
|
+
* // Add new events
|
|
944
|
+
* await client.webhooks.update('webhook-id', {
|
|
945
|
+
* events: ['email.sent', 'email.delivered', 'email.bounced']
|
|
946
|
+
* });
|
|
947
|
+
*
|
|
948
|
+
* // Disable webhook
|
|
949
|
+
* await client.webhooks.update('webhook-id', { active: false });
|
|
950
|
+
* ```
|
|
951
|
+
*/
|
|
952
|
+
async update(webhookId, params) {
|
|
953
|
+
return this.request(`/webhooks/${webhookId}`, {
|
|
954
|
+
method: "PATCH",
|
|
955
|
+
body: JSON.stringify(params)
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Delete a webhook
|
|
960
|
+
*/
|
|
961
|
+
async delete(webhookId) {
|
|
962
|
+
return this.request(`/webhooks/${webhookId}`, {
|
|
963
|
+
method: "DELETE"
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Test a webhook by sending a test event
|
|
968
|
+
*
|
|
969
|
+
* @example
|
|
970
|
+
* ```ts
|
|
971
|
+
* const result = await client.webhooks.test('webhook-id');
|
|
972
|
+
* if (result.test.sent) {
|
|
973
|
+
* console.log(`Test delivered in ${result.test.responseTimeMs}ms`);
|
|
974
|
+
* } else {
|
|
975
|
+
* console.log('Test failed:', result.test.error);
|
|
976
|
+
* }
|
|
977
|
+
* ```
|
|
978
|
+
*/
|
|
979
|
+
async test(webhookId) {
|
|
980
|
+
return this.request(`/webhooks/${webhookId}/test`, {
|
|
981
|
+
method: "POST"
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
/**
|
|
985
|
+
* Enable a webhook
|
|
986
|
+
*/
|
|
987
|
+
async enable(webhookId) {
|
|
988
|
+
return this.update(webhookId, { active: true });
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* Disable a webhook
|
|
992
|
+
*/
|
|
993
|
+
async disable(webhookId) {
|
|
994
|
+
return this.update(webhookId, { active: false });
|
|
995
|
+
}
|
|
996
|
+
};
|
|
997
|
+
|
|
328
998
|
// src/client.ts
|
|
329
999
|
var DEFAULT_BASE_URL = "https://api.sendmailos.com/api/v1";
|
|
330
1000
|
var DEFAULT_TIMEOUT = 3e4;
|
|
331
|
-
var SDK_VERSION = "1.
|
|
1001
|
+
var SDK_VERSION = "1.2.0";
|
|
332
1002
|
var SendMailOS = class {
|
|
333
1003
|
constructor(apiKey, options = {}) {
|
|
334
1004
|
if (!apiKey) {
|
|
@@ -353,6 +1023,10 @@ var SendMailOS = class {
|
|
|
353
1023
|
this.subscribers = new SubscribersResource(boundRequest);
|
|
354
1024
|
this.campaigns = new CampaignsResource(boundRequest);
|
|
355
1025
|
this.domains = new DomainsResource(boundRequest);
|
|
1026
|
+
this.organization = new OrganizationResource(boundRequest);
|
|
1027
|
+
this.workspaces = new WorkspacesResource(boundRequest);
|
|
1028
|
+
this.workflows = new WorkflowsResource(boundRequest);
|
|
1029
|
+
this.webhooks = new WebhooksResource(boundRequest);
|
|
356
1030
|
}
|
|
357
1031
|
/**
|
|
358
1032
|
* Make an authenticated request to the API
|
|
@@ -896,6 +1570,6 @@ function constructWebhookEvent(payload, headers, secret) {
|
|
|
896
1570
|
return JSON.parse(payload);
|
|
897
1571
|
}
|
|
898
1572
|
|
|
899
|
-
export { AuthenticationError, NotFoundError, Pixel, RateLimitError, SendMailOS, SendMailOSError, SendmailPixel, ValidationError, constructWebhookEvent, createGlobalPixel, SendMailOS as default, verifyWebhookSignature, verifyWebhookSignatureAsync };
|
|
1573
|
+
export { AuthenticationError, INDUSTRIES, NotFoundError, Pixel, RateLimitError, SendMailOS, SendMailOSError, SendmailPixel, ValidationError, constructWebhookEvent, createGlobalPixel, SendMailOS as default, verifyWebhookSignature, verifyWebhookSignatureAsync };
|
|
900
1574
|
//# sourceMappingURL=index.mjs.map
|
|
901
1575
|
//# sourceMappingURL=index.mjs.map
|