mailchannels-sdk 1.0.0 → 1.1.0
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/.agents/skills/mailchannels-js/SKILL.md +91 -0
- package/.agents/skills/mailchannels-js/resources/attachments.md +113 -0
- package/.agents/skills/mailchannels-js/resources/clients-and-transport.md +98 -0
- package/.agents/skills/mailchannels-js/resources/custom-headers.md +64 -0
- package/.agents/skills/mailchannels-js/resources/dkim.md +148 -0
- package/.agents/skills/mailchannels-js/resources/domain-checks.md +100 -0
- package/.agents/skills/mailchannels-js/resources/error-handling.md +142 -0
- package/.agents/skills/mailchannels-js/resources/metrics-and-usage.md +113 -0
- package/.agents/skills/mailchannels-js/resources/overview.md +91 -0
- package/.agents/skills/mailchannels-js/resources/sending.md +195 -0
- package/.agents/skills/mailchannels-js/resources/sub-accounts.md +129 -0
- package/.agents/skills/mailchannels-js/resources/suppressions.md +91 -0
- package/.agents/skills/mailchannels-js/resources/templates.md +97 -0
- package/.agents/skills/mailchannels-js/resources/testing.md +95 -0
- package/.agents/skills/mailchannels-js/resources/unsubscribe.md +73 -0
- package/.agents/skills/mailchannels-js/resources/webhooks.md +174 -0
- package/README.md +64 -0
- package/dist/_chunks/simulator.mjs +1 -1
- package/dist/mailchannels.d.mts +428 -379
- package/dist/mailchannels.mjs +401 -270
- package/package.json +7 -6
package/dist/mailchannels.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { $fetch } from "ofetch";
|
|
|
2
2
|
import { subtle } from "node:crypto";
|
|
3
3
|
import { Buffer } from "node:buffer";
|
|
4
4
|
import mime from "mime";
|
|
5
|
-
var version = "1.
|
|
5
|
+
var version = "1.1.0";
|
|
6
6
|
var MailChannelsClient = class MailChannelsClient {
|
|
7
7
|
static DEFAULT_BASE_URL = "https://api.mailchannels.net";
|
|
8
8
|
static DEFAULT_TIMEOUT = 12e4;
|
|
@@ -160,7 +160,7 @@ const parseArrayRecipients = (recipients) => {
|
|
|
160
160
|
return filtered.length > 0 ? filtered : void 0;
|
|
161
161
|
};
|
|
162
162
|
const stripPemHeaders = (pem) => pem.replace(/-----[^-]+-----|\s|#.*$/gm, "");
|
|
163
|
-
const RESERVED_HEADER_NAMES = new Set([
|
|
163
|
+
const RESERVED_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
164
164
|
"authentication-results",
|
|
165
165
|
"bcc",
|
|
166
166
|
"cc",
|
|
@@ -424,80 +424,6 @@ const mapDkimKey = (key) => ({
|
|
|
424
424
|
status: key.status,
|
|
425
425
|
statusModifiedAt: key.status_modified_at
|
|
426
426
|
});
|
|
427
|
-
var Domains = class {
|
|
428
|
-
mailchannels;
|
|
429
|
-
dkim;
|
|
430
|
-
constructor(mailchannels) {
|
|
431
|
-
this.mailchannels = mailchannels;
|
|
432
|
-
this.dkim = new DomainsDkim(mailchannels);
|
|
433
|
-
}
|
|
434
|
-
async check(domain, options) {
|
|
435
|
-
let error = null;
|
|
436
|
-
if (!domain) {
|
|
437
|
-
error = createValidationError("No domain provided.");
|
|
438
|
-
return {
|
|
439
|
-
data: null,
|
|
440
|
-
error
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
const dkimOptions = options?.dkim ? Array.isArray(options.dkim) ? options.dkim : [options.dkim] : void 0;
|
|
444
|
-
if (dkimOptions && dkimOptions.length > 10) {
|
|
445
|
-
error = createValidationError("A maximum of 10 DKIM settings can be provided.");
|
|
446
|
-
return {
|
|
447
|
-
data: null,
|
|
448
|
-
error
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
if (dkimOptions?.find(({ privateKey, selector }) => privateKey && !selector)) {
|
|
452
|
-
error = createValidationError("DKIM settings with a privateKey must also include a selector.");
|
|
453
|
-
return {
|
|
454
|
-
data: null,
|
|
455
|
-
error
|
|
456
|
-
};
|
|
457
|
-
}
|
|
458
|
-
const payload = {
|
|
459
|
-
dkim_settings: dkimOptions?.map((dkim) => ({
|
|
460
|
-
dkim_domain: dkim.domain,
|
|
461
|
-
dkim_private_key: dkim.privateKey ? stripPemHeaders(dkim.privateKey) : void 0,
|
|
462
|
-
dkim_selector: dkim.selector
|
|
463
|
-
})),
|
|
464
|
-
domain,
|
|
465
|
-
sender_id: options?.senderId
|
|
466
|
-
};
|
|
467
|
-
const response = await this.mailchannels.post("/tx/v1/check-domain", {
|
|
468
|
-
body: payload,
|
|
469
|
-
onResponseError: async ({ response }) => {
|
|
470
|
-
error = getStatusError(response, {
|
|
471
|
-
[400]: "Bad Request.",
|
|
472
|
-
[403]: "User does not have access to this feature."
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
}).catch((e) => {
|
|
476
|
-
error ||= getResultError(e, "Failed to check domain.");
|
|
477
|
-
return null;
|
|
478
|
-
});
|
|
479
|
-
if (!response) return {
|
|
480
|
-
data: null,
|
|
481
|
-
error
|
|
482
|
-
};
|
|
483
|
-
return {
|
|
484
|
-
data: clean({
|
|
485
|
-
dkim: response.check_results.dkim.map((dkimResults) => ({
|
|
486
|
-
domain: dkimResults.dkim_domain,
|
|
487
|
-
keyStatus: dkimResults.dkim_key_status,
|
|
488
|
-
selector: dkimResults.dkim_selector,
|
|
489
|
-
reason: dkimResults.reason,
|
|
490
|
-
verdict: dkimResults.verdict
|
|
491
|
-
})),
|
|
492
|
-
domainLockdown: response.check_results.domain_lockdown,
|
|
493
|
-
senderDomain: response.check_results.sender_domain,
|
|
494
|
-
spf: response.check_results.spf,
|
|
495
|
-
references: response.references
|
|
496
|
-
}),
|
|
497
|
-
error: null
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
};
|
|
501
427
|
var DomainsDkim = class {
|
|
502
428
|
mailchannels;
|
|
503
429
|
constructor(mailchannels) {
|
|
@@ -524,7 +450,7 @@ var DomainsDkim = class {
|
|
|
524
450
|
key_length: options.length,
|
|
525
451
|
selector: options.selector
|
|
526
452
|
};
|
|
527
|
-
const response = await this.mailchannels.post(`/tx/v1/domains/${domain}/dkim-keys`, {
|
|
453
|
+
const response = await this.mailchannels.post(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys`, {
|
|
528
454
|
body: payload,
|
|
529
455
|
onResponseError: async ({ response }) => {
|
|
530
456
|
error = getStatusError(response, {
|
|
@@ -576,7 +502,7 @@ var DomainsDkim = class {
|
|
|
576
502
|
limit: options?.limit,
|
|
577
503
|
include_dns_record: options?.includeDnsRecord
|
|
578
504
|
};
|
|
579
|
-
const response = await this.mailchannels.get(`/tx/v1/domains/${domain}/dkim-keys`, {
|
|
505
|
+
const response = await this.mailchannels.get(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys`, {
|
|
580
506
|
query: payload,
|
|
581
507
|
onResponseError: async ({ response }) => {
|
|
582
508
|
error = getStatusError(response, { [400]: "Bad Request." });
|
|
@@ -611,7 +537,7 @@ var DomainsDkim = class {
|
|
|
611
537
|
};
|
|
612
538
|
}
|
|
613
539
|
const payload = { status: options.status };
|
|
614
|
-
await this.mailchannels.patch(`/tx/v1/domains/${domain}/dkim-keys/${options.selector}`, {
|
|
540
|
+
await this.mailchannels.patch(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys/${encodeURIComponent(options.selector)}`, {
|
|
615
541
|
body: payload,
|
|
616
542
|
onResponseError: async ({ response }) => {
|
|
617
543
|
error = getStatusError(response, {
|
|
@@ -651,7 +577,7 @@ var DomainsDkim = class {
|
|
|
651
577
|
};
|
|
652
578
|
}
|
|
653
579
|
const payload = { new_key: { selector: options.newKey.selector } };
|
|
654
|
-
const response = await this.mailchannels.post(`/tx/v1/domains/${domain}/dkim-keys/${selector}/rotate`, {
|
|
580
|
+
const response = await this.mailchannels.post(`/tx/v1/domains/${encodeURIComponent(domain)}/dkim-keys/${encodeURIComponent(selector)}/rotate`, {
|
|
655
581
|
body: payload,
|
|
656
582
|
onResponseError: async ({ response }) => {
|
|
657
583
|
error = getStatusError(response, {
|
|
@@ -677,6 +603,80 @@ var DomainsDkim = class {
|
|
|
677
603
|
};
|
|
678
604
|
}
|
|
679
605
|
};
|
|
606
|
+
var Domains = class {
|
|
607
|
+
mailchannels;
|
|
608
|
+
dkim;
|
|
609
|
+
constructor(mailchannels) {
|
|
610
|
+
this.mailchannels = mailchannels;
|
|
611
|
+
this.dkim = new DomainsDkim(mailchannels);
|
|
612
|
+
}
|
|
613
|
+
async check(domain, options) {
|
|
614
|
+
let error = null;
|
|
615
|
+
if (!domain) {
|
|
616
|
+
error = createValidationError("No domain provided.");
|
|
617
|
+
return {
|
|
618
|
+
data: null,
|
|
619
|
+
error
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
const dkimOptions = options?.dkim ? Array.isArray(options.dkim) ? options.dkim : [options.dkim] : void 0;
|
|
623
|
+
if (dkimOptions && dkimOptions.length > 10) {
|
|
624
|
+
error = createValidationError("A maximum of 10 DKIM settings can be provided.");
|
|
625
|
+
return {
|
|
626
|
+
data: null,
|
|
627
|
+
error
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
if (dkimOptions?.find(({ privateKey, selector }) => privateKey && !selector)) {
|
|
631
|
+
error = createValidationError("DKIM settings with a privateKey must also include a selector.");
|
|
632
|
+
return {
|
|
633
|
+
data: null,
|
|
634
|
+
error
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
const payload = {
|
|
638
|
+
dkim_settings: dkimOptions?.map((dkim) => ({
|
|
639
|
+
dkim_domain: dkim.domain,
|
|
640
|
+
dkim_private_key: dkim.privateKey ? stripPemHeaders(dkim.privateKey) : void 0,
|
|
641
|
+
dkim_selector: dkim.selector
|
|
642
|
+
})),
|
|
643
|
+
domain,
|
|
644
|
+
sender_id: options?.senderId
|
|
645
|
+
};
|
|
646
|
+
const response = await this.mailchannels.post("/tx/v1/check-domain", {
|
|
647
|
+
body: payload,
|
|
648
|
+
onResponseError: async ({ response }) => {
|
|
649
|
+
error = getStatusError(response, {
|
|
650
|
+
[400]: "Bad Request.",
|
|
651
|
+
[403]: "User does not have access to this feature."
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
}).catch((e) => {
|
|
655
|
+
error ||= getResultError(e, "Failed to check domain.");
|
|
656
|
+
return null;
|
|
657
|
+
});
|
|
658
|
+
if (!response) return {
|
|
659
|
+
data: null,
|
|
660
|
+
error
|
|
661
|
+
};
|
|
662
|
+
return {
|
|
663
|
+
data: clean({
|
|
664
|
+
dkim: response.check_results.dkim.map((dkimResults) => ({
|
|
665
|
+
domain: dkimResults.dkim_domain,
|
|
666
|
+
keyStatus: dkimResults.dkim_key_status,
|
|
667
|
+
selector: dkimResults.dkim_selector,
|
|
668
|
+
reason: dkimResults.reason,
|
|
669
|
+
verdict: dkimResults.verdict
|
|
670
|
+
})),
|
|
671
|
+
domainLockdown: response.check_results.domain_lockdown,
|
|
672
|
+
senderDomain: response.check_results.sender_domain,
|
|
673
|
+
spf: response.check_results.spf,
|
|
674
|
+
references: response.references
|
|
675
|
+
}),
|
|
676
|
+
error: null
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
680
|
const HMAC_SHA256 = {
|
|
681
681
|
name: "HMAC",
|
|
682
682
|
hash: "SHA-256"
|
|
@@ -749,6 +749,35 @@ async function isValidWebhook(options) {
|
|
|
749
749
|
const key = await subtle.importKey(format, publicKeyBuffer, ED25519, false, ["verify"]);
|
|
750
750
|
return subtle.verify(ED25519.name, key, webhookSignatureBuffer, encoder.encode(signingString));
|
|
751
751
|
}
|
|
752
|
+
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
|
|
753
|
+
const ISO_DATE_ONLY_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
754
|
+
const formatDateInput = (value) => {
|
|
755
|
+
if (value instanceof Date) {
|
|
756
|
+
if (Number.isNaN(value.getTime())) return null;
|
|
757
|
+
return value.toISOString();
|
|
758
|
+
}
|
|
759
|
+
if (typeof value === "string") {
|
|
760
|
+
if (!ISO_DATE_REGEX.test(value) && !ISO_DATE_ONLY_REGEX.test(value) || Number.isNaN(Date.parse(value))) return null;
|
|
761
|
+
if (ISO_DATE_REGEX.test(value)) return new Date(value).toISOString();
|
|
762
|
+
}
|
|
763
|
+
return value;
|
|
764
|
+
};
|
|
765
|
+
const parseDateInputs = (options) => {
|
|
766
|
+
const dates = {};
|
|
767
|
+
const keys = Object.keys(options);
|
|
768
|
+
for (const key of keys) {
|
|
769
|
+
const formatted = formatDateInput(options?.[key]);
|
|
770
|
+
if (formatted === null) return {
|
|
771
|
+
dates: null,
|
|
772
|
+
error: createValidationError(`The '${key}' value is not a valid date.`)
|
|
773
|
+
};
|
|
774
|
+
dates[key] = formatted;
|
|
775
|
+
}
|
|
776
|
+
return {
|
|
777
|
+
dates,
|
|
778
|
+
error: null
|
|
779
|
+
};
|
|
780
|
+
};
|
|
752
781
|
var Webhooks = class Webhooks {
|
|
753
782
|
mailchannels;
|
|
754
783
|
constructor(mailchannels) {
|
|
@@ -936,17 +965,17 @@ var Webhooks = class Webhooks {
|
|
|
936
965
|
data: null,
|
|
937
966
|
error: createValidationError("Status filters must be unique.")
|
|
938
967
|
};
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
};
|
|
943
|
-
if (
|
|
968
|
+
const { dates, error: dateError } = parseDateInputs({
|
|
969
|
+
createdAfter: options?.createdAfter,
|
|
970
|
+
createdBefore: options?.createdBefore
|
|
971
|
+
});
|
|
972
|
+
if (!dates || dateError) return {
|
|
944
973
|
data: null,
|
|
945
|
-
error:
|
|
974
|
+
error: dateError
|
|
946
975
|
};
|
|
947
|
-
if (
|
|
948
|
-
const createdAfter = Date.parse(
|
|
949
|
-
const createdBefore = Date.parse(
|
|
976
|
+
if (dates.createdAfter && dates.createdBefore) {
|
|
977
|
+
const createdAfter = Date.parse(dates.createdAfter);
|
|
978
|
+
const createdBefore = Date.parse(dates.createdBefore);
|
|
950
979
|
const maxRangeMs = 744 * 60 * 60 * 1e3;
|
|
951
980
|
if (createdBefore <= createdAfter) return {
|
|
952
981
|
data: null,
|
|
@@ -959,8 +988,8 @@ var Webhooks = class Webhooks {
|
|
|
959
988
|
}
|
|
960
989
|
const response = await this.mailchannels.get("/tx/v1/webhook-batch", {
|
|
961
990
|
query: {
|
|
962
|
-
created_after:
|
|
963
|
-
created_before:
|
|
991
|
+
created_after: dates.createdAfter,
|
|
992
|
+
created_before: dates.createdBefore,
|
|
964
993
|
statuses: options?.statuses,
|
|
965
994
|
webhook: options?.webhook,
|
|
966
995
|
limit: options?.limit,
|
|
@@ -993,7 +1022,7 @@ var Webhooks = class Webhooks {
|
|
|
993
1022
|
}
|
|
994
1023
|
async resendBatch(batchId) {
|
|
995
1024
|
let error = null;
|
|
996
|
-
const response = await this.mailchannels.post(`/tx/v1/webhook-batch/${batchId}/resend`, { onResponseError: async ({ response }) => {
|
|
1025
|
+
const response = await this.mailchannels.post(`/tx/v1/webhook-batch/${encodeURIComponent(batchId)}/resend`, { onResponseError: async ({ response }) => {
|
|
997
1026
|
error = getStatusError(response, {
|
|
998
1027
|
[400]: "Bad Request. The batch ID is invalid.",
|
|
999
1028
|
[404]: `The batch '${batchId}' is not found for the customer.`
|
|
@@ -1020,152 +1049,12 @@ var Webhooks = class Webhooks {
|
|
|
1020
1049
|
};
|
|
1021
1050
|
}
|
|
1022
1051
|
};
|
|
1023
|
-
var
|
|
1052
|
+
var SubAccountsApiKeys = class {
|
|
1024
1053
|
mailchannels;
|
|
1025
|
-
static COMPANY_PATTERN = /^.{3,128}$/;
|
|
1026
|
-
static HANDLE_PATTERN = /^[a-z0-9]{3,128}$/;
|
|
1027
1054
|
constructor(mailchannels) {
|
|
1028
1055
|
this.mailchannels = mailchannels;
|
|
1029
1056
|
}
|
|
1030
|
-
async create(
|
|
1031
|
-
let error = null;
|
|
1032
|
-
if (!SubAccounts.COMPANY_PATTERN.test(companyName)) {
|
|
1033
|
-
error = createValidationError("Invalid company name. Company name must be between 3 and 128 characters.");
|
|
1034
|
-
return {
|
|
1035
|
-
data: null,
|
|
1036
|
-
error
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
if (handle) {
|
|
1040
|
-
if (!SubAccounts.HANDLE_PATTERN.test(handle)) {
|
|
1041
|
-
error = createValidationError("Invalid handle. Sub-account handle must be between 3 and 128 characters and contain only lowercase letters and numbers.");
|
|
1042
|
-
return {
|
|
1043
|
-
data: null,
|
|
1044
|
-
error
|
|
1045
|
-
};
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
const response = await this.mailchannels.post("/tx/v1/sub-account", {
|
|
1049
|
-
body: {
|
|
1050
|
-
company_name: companyName,
|
|
1051
|
-
handle
|
|
1052
|
-
},
|
|
1053
|
-
onResponseError: async ({ response }) => {
|
|
1054
|
-
error = getStatusError(response, {
|
|
1055
|
-
[403]: "The parent account does not have permission to create sub-accounts.",
|
|
1056
|
-
[409]: `Sub-account with handle '${handle}' already exists.`
|
|
1057
|
-
});
|
|
1058
|
-
}
|
|
1059
|
-
}).catch((e) => {
|
|
1060
|
-
error ||= getResultError(e, "Failed to create sub-account.");
|
|
1061
|
-
return null;
|
|
1062
|
-
});
|
|
1063
|
-
if (!response) return {
|
|
1064
|
-
data: null,
|
|
1065
|
-
error
|
|
1066
|
-
};
|
|
1067
|
-
return {
|
|
1068
|
-
data: clean({
|
|
1069
|
-
companyName: response.company_name,
|
|
1070
|
-
enabled: response.enabled,
|
|
1071
|
-
handle: response.handle
|
|
1072
|
-
}),
|
|
1073
|
-
error: null
|
|
1074
|
-
};
|
|
1075
|
-
}
|
|
1076
|
-
async list(options) {
|
|
1077
|
-
let error = null;
|
|
1078
|
-
error = validatePagination({
|
|
1079
|
-
...options,
|
|
1080
|
-
max: 1e3
|
|
1081
|
-
});
|
|
1082
|
-
if (error) return {
|
|
1083
|
-
data: null,
|
|
1084
|
-
error
|
|
1085
|
-
};
|
|
1086
|
-
const response = await this.mailchannels.get("/tx/v1/sub-account", {
|
|
1087
|
-
query: options,
|
|
1088
|
-
onResponseError: async ({ response }) => {
|
|
1089
|
-
error = getStatusError(response);
|
|
1090
|
-
}
|
|
1091
|
-
}).catch((e) => {
|
|
1092
|
-
error ||= getResultError(e, "Failed to fetch sub-accounts.");
|
|
1093
|
-
return null;
|
|
1094
|
-
});
|
|
1095
|
-
if (!response) return {
|
|
1096
|
-
data: null,
|
|
1097
|
-
error
|
|
1098
|
-
};
|
|
1099
|
-
return {
|
|
1100
|
-
data: clean(response.map((account) => ({
|
|
1101
|
-
companyName: account.company_name,
|
|
1102
|
-
enabled: account.enabled,
|
|
1103
|
-
handle: account.handle
|
|
1104
|
-
}))),
|
|
1105
|
-
error: null
|
|
1106
|
-
};
|
|
1107
|
-
}
|
|
1108
|
-
async delete(handle) {
|
|
1109
|
-
let error = null;
|
|
1110
|
-
if (!handle) {
|
|
1111
|
-
error = createValidationError("No handle provided.");
|
|
1112
|
-
return {
|
|
1113
|
-
success: false,
|
|
1114
|
-
error
|
|
1115
|
-
};
|
|
1116
|
-
}
|
|
1117
|
-
await this.mailchannels.delete(`/tx/v1/sub-account/${handle}`, { onResponseError: async ({ response }) => {
|
|
1118
|
-
error = getStatusError(response);
|
|
1119
|
-
} }).catch((e) => {
|
|
1120
|
-
error ||= getResultError(e, "Failed to delete sub-account.");
|
|
1121
|
-
});
|
|
1122
|
-
return {
|
|
1123
|
-
success: !error,
|
|
1124
|
-
error
|
|
1125
|
-
};
|
|
1126
|
-
}
|
|
1127
|
-
async suspend(handle) {
|
|
1128
|
-
let error = null;
|
|
1129
|
-
if (!handle) {
|
|
1130
|
-
error = createValidationError("No handle provided.");
|
|
1131
|
-
return {
|
|
1132
|
-
success: false,
|
|
1133
|
-
error
|
|
1134
|
-
};
|
|
1135
|
-
}
|
|
1136
|
-
await this.mailchannels.post(`/tx/v1/sub-account/${handle}/suspend`, { onResponseError: async ({ response }) => {
|
|
1137
|
-
error = getStatusError(response, { [404]: `The specified sub-account '${handle}' does not exist.` });
|
|
1138
|
-
} }).catch((e) => {
|
|
1139
|
-
error ||= getResultError(e, "Failed to suspend sub-account.");
|
|
1140
|
-
});
|
|
1141
|
-
return {
|
|
1142
|
-
success: !error,
|
|
1143
|
-
error
|
|
1144
|
-
};
|
|
1145
|
-
}
|
|
1146
|
-
async activate(handle) {
|
|
1147
|
-
let error = null;
|
|
1148
|
-
if (!handle) {
|
|
1149
|
-
error = createValidationError("No handle provided.");
|
|
1150
|
-
return {
|
|
1151
|
-
success: false,
|
|
1152
|
-
error
|
|
1153
|
-
};
|
|
1154
|
-
}
|
|
1155
|
-
await this.mailchannels.post(`/tx/v1/sub-account/${handle}/activate`, { onResponseError: async ({ response }) => {
|
|
1156
|
-
error = getStatusError(response, {
|
|
1157
|
-
[403]: "The parent account does not have permission to activate the sub-account.",
|
|
1158
|
-
[404]: `The specified sub-account '${handle}' does not exist.`
|
|
1159
|
-
});
|
|
1160
|
-
} }).catch((e) => {
|
|
1161
|
-
error ||= getResultError(e, "Failed to activate sub-account.");
|
|
1162
|
-
});
|
|
1163
|
-
return {
|
|
1164
|
-
success: !error,
|
|
1165
|
-
error
|
|
1166
|
-
};
|
|
1167
|
-
}
|
|
1168
|
-
async createApiKey(handle) {
|
|
1057
|
+
async create(handle) {
|
|
1169
1058
|
let error = null;
|
|
1170
1059
|
if (!handle) {
|
|
1171
1060
|
error = createValidationError("No handle provided.");
|
|
@@ -1174,7 +1063,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1174
1063
|
error
|
|
1175
1064
|
};
|
|
1176
1065
|
}
|
|
1177
|
-
const response = await this.mailchannels.post(`/tx/v1/sub-account/${handle}/api-key`, { onResponseError: async ({ response }) => {
|
|
1066
|
+
const response = await this.mailchannels.post(`/tx/v1/sub-account/${encodeURIComponent(handle)}/api-key`, { onResponseError: async ({ response }) => {
|
|
1178
1067
|
error = getStatusError(response, {
|
|
1179
1068
|
[403]: "You can't create API keys for this sub-account.",
|
|
1180
1069
|
[404]: `Sub-account with handle '${handle}' not found.`,
|
|
@@ -1193,7 +1082,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1193
1082
|
error: null
|
|
1194
1083
|
};
|
|
1195
1084
|
}
|
|
1196
|
-
async
|
|
1085
|
+
async list(handle, options) {
|
|
1197
1086
|
let error = null;
|
|
1198
1087
|
if (!handle) {
|
|
1199
1088
|
error = createValidationError("No handle provided.");
|
|
@@ -1210,9 +1099,12 @@ var SubAccounts = class SubAccounts {
|
|
|
1210
1099
|
data: null,
|
|
1211
1100
|
error
|
|
1212
1101
|
};
|
|
1213
|
-
const response = await this.mailchannels.get(`/tx/v1/sub-account/${handle}/api-key`, {
|
|
1214
|
-
|
|
1215
|
-
|
|
1102
|
+
const response = await this.mailchannels.get(`/tx/v1/sub-account/${encodeURIComponent(handle)}/api-key`, {
|
|
1103
|
+
query: options,
|
|
1104
|
+
onResponseError: async ({ response }) => {
|
|
1105
|
+
error = getStatusError(response, { [404]: `Sub-account with handle '${handle}' not found.` });
|
|
1106
|
+
}
|
|
1107
|
+
}).catch((e) => {
|
|
1216
1108
|
error ||= getResultError(e, "Failed to fetch sub-account API keys.");
|
|
1217
1109
|
return null;
|
|
1218
1110
|
});
|
|
@@ -1228,7 +1120,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1228
1120
|
error: null
|
|
1229
1121
|
};
|
|
1230
1122
|
}
|
|
1231
|
-
async
|
|
1123
|
+
async delete(handle, id) {
|
|
1232
1124
|
let error = null;
|
|
1233
1125
|
if (!handle) {
|
|
1234
1126
|
error = createValidationError("No handle provided.");
|
|
@@ -1237,7 +1129,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1237
1129
|
error
|
|
1238
1130
|
};
|
|
1239
1131
|
}
|
|
1240
|
-
await this.mailchannels.delete(`/tx/v1/sub-account/${handle}/api-key/${id}`, { onResponseError: async ({ response }) => {
|
|
1132
|
+
await this.mailchannels.delete(`/tx/v1/sub-account/${encodeURIComponent(handle)}/api-key/${encodeURIComponent(id)}`, { onResponseError: async ({ response }) => {
|
|
1241
1133
|
error = getStatusError(response, { [400]: "Missing or invalid API key ID." });
|
|
1242
1134
|
} }).catch((e) => {
|
|
1243
1135
|
error ||= getResultError(e, "Failed to delete sub-account API key.");
|
|
@@ -1247,7 +1139,13 @@ var SubAccounts = class SubAccounts {
|
|
|
1247
1139
|
error
|
|
1248
1140
|
};
|
|
1249
1141
|
}
|
|
1250
|
-
|
|
1142
|
+
};
|
|
1143
|
+
var SubAccountsSmtpPasswords = class {
|
|
1144
|
+
mailchannels;
|
|
1145
|
+
constructor(mailchannels) {
|
|
1146
|
+
this.mailchannels = mailchannels;
|
|
1147
|
+
}
|
|
1148
|
+
async create(handle) {
|
|
1251
1149
|
let error = null;
|
|
1252
1150
|
if (!handle) {
|
|
1253
1151
|
error = createValidationError("No handle provided.");
|
|
@@ -1256,7 +1154,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1256
1154
|
error
|
|
1257
1155
|
};
|
|
1258
1156
|
}
|
|
1259
|
-
const response = await this.mailchannels.post(`/tx/v1/sub-account/${handle}/smtp-password`, { onResponseError: async ({ response }) => {
|
|
1157
|
+
const response = await this.mailchannels.post(`/tx/v1/sub-account/${encodeURIComponent(handle)}/smtp-password`, { onResponseError: async ({ response }) => {
|
|
1260
1158
|
error = getStatusError(response, {
|
|
1261
1159
|
[403]: "You can't create SMTP passwords for this sub-account.",
|
|
1262
1160
|
[404]: `Sub-account with handle '${handle}' not found.`,
|
|
@@ -1279,7 +1177,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1279
1177
|
error: null
|
|
1280
1178
|
};
|
|
1281
1179
|
}
|
|
1282
|
-
async
|
|
1180
|
+
async list(handle) {
|
|
1283
1181
|
let error = null;
|
|
1284
1182
|
if (!handle) {
|
|
1285
1183
|
error = createValidationError("No handle provided.");
|
|
@@ -1288,7 +1186,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1288
1186
|
error
|
|
1289
1187
|
};
|
|
1290
1188
|
}
|
|
1291
|
-
const response = await this.mailchannels.get(`/tx/v1/sub-account/${handle}/smtp-password`, { onResponseError: async ({ response }) => {
|
|
1189
|
+
const response = await this.mailchannels.get(`/tx/v1/sub-account/${encodeURIComponent(handle)}/smtp-password`, { onResponseError: async ({ response }) => {
|
|
1292
1190
|
error = getStatusError(response, { [404]: `Sub-account with handle '${handle}' not found.` });
|
|
1293
1191
|
} }).catch((e) => {
|
|
1294
1192
|
error ||= getResultError(e, "Failed to fetch sub-account SMTP passwords.");
|
|
@@ -1307,7 +1205,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1307
1205
|
error: null
|
|
1308
1206
|
};
|
|
1309
1207
|
}
|
|
1310
|
-
async
|
|
1208
|
+
async delete(handle, id) {
|
|
1311
1209
|
let error = null;
|
|
1312
1210
|
if (!handle) {
|
|
1313
1211
|
error = createValidationError("No handle provided.");
|
|
@@ -1316,7 +1214,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1316
1214
|
error
|
|
1317
1215
|
};
|
|
1318
1216
|
}
|
|
1319
|
-
await this.mailchannels.delete(`/tx/v1/sub-account/${handle}/smtp-password/${id}`, { onResponseError: async ({ response }) => {
|
|
1217
|
+
await this.mailchannels.delete(`/tx/v1/sub-account/${encodeURIComponent(handle)}/smtp-password/${encodeURIComponent(id)}`, { onResponseError: async ({ response }) => {
|
|
1320
1218
|
error = getStatusError(response, { [400]: "Missing or invalid SMTP password ID." });
|
|
1321
1219
|
} }).catch((e) => {
|
|
1322
1220
|
error ||= getResultError(e, "Failed to delete sub-account SMTP password.");
|
|
@@ -1326,7 +1224,13 @@ var SubAccounts = class SubAccounts {
|
|
|
1326
1224
|
error
|
|
1327
1225
|
};
|
|
1328
1226
|
}
|
|
1329
|
-
|
|
1227
|
+
};
|
|
1228
|
+
var SubAccountsLimits = class {
|
|
1229
|
+
mailchannels;
|
|
1230
|
+
constructor(mailchannels) {
|
|
1231
|
+
this.mailchannels = mailchannels;
|
|
1232
|
+
}
|
|
1233
|
+
async get(handle) {
|
|
1330
1234
|
let error = null;
|
|
1331
1235
|
if (!handle) {
|
|
1332
1236
|
error = createValidationError("No handle provided.");
|
|
@@ -1335,7 +1239,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1335
1239
|
error
|
|
1336
1240
|
};
|
|
1337
1241
|
}
|
|
1338
|
-
const response = await this.mailchannels.get(`/tx/v1/sub-account/${handle}/limit`, { onResponseError: async ({ response }) => {
|
|
1242
|
+
const response = await this.mailchannels.get(`/tx/v1/sub-account/${encodeURIComponent(handle)}/limit`, { onResponseError: async ({ response }) => {
|
|
1339
1243
|
error = getStatusError(response, { [404]: `Sub-account with handle '${handle}' not found.` });
|
|
1340
1244
|
} }).catch((e) => {
|
|
1341
1245
|
error ||= getResultError(e, "Failed to fetch sub-account limit.");
|
|
@@ -1350,7 +1254,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1350
1254
|
error: null
|
|
1351
1255
|
};
|
|
1352
1256
|
}
|
|
1353
|
-
async
|
|
1257
|
+
async set(handle, options) {
|
|
1354
1258
|
let error = null;
|
|
1355
1259
|
if (!handle) {
|
|
1356
1260
|
error = createValidationError("No handle provided.");
|
|
@@ -1359,15 +1263,15 @@ var SubAccounts = class SubAccounts {
|
|
|
1359
1263
|
error
|
|
1360
1264
|
};
|
|
1361
1265
|
}
|
|
1362
|
-
if (
|
|
1266
|
+
if (options.sends < 0) {
|
|
1363
1267
|
error = createValidationError("The sends value must be at least 0.");
|
|
1364
1268
|
return {
|
|
1365
1269
|
success: false,
|
|
1366
1270
|
error
|
|
1367
1271
|
};
|
|
1368
1272
|
}
|
|
1369
|
-
await this.mailchannels.put(`/tx/v1/sub-account/${handle}/limit`, {
|
|
1370
|
-
body:
|
|
1273
|
+
await this.mailchannels.put(`/tx/v1/sub-account/${encodeURIComponent(handle)}/limit`, {
|
|
1274
|
+
body: options,
|
|
1371
1275
|
onResponseError: async ({ response }) => {
|
|
1372
1276
|
error = getStatusError(response, {
|
|
1373
1277
|
[400]: "Bad Request.",
|
|
@@ -1382,7 +1286,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1382
1286
|
error
|
|
1383
1287
|
};
|
|
1384
1288
|
}
|
|
1385
|
-
async
|
|
1289
|
+
async delete(handle) {
|
|
1386
1290
|
let error = null;
|
|
1387
1291
|
if (!handle) {
|
|
1388
1292
|
error = createValidationError("No handle provided.");
|
|
@@ -1391,7 +1295,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1391
1295
|
error
|
|
1392
1296
|
};
|
|
1393
1297
|
}
|
|
1394
|
-
await this.mailchannels.delete(`/tx/v1/sub-account/${handle}/limit`, { onResponseError: async ({ response }) => {
|
|
1298
|
+
await this.mailchannels.delete(`/tx/v1/sub-account/${encodeURIComponent(handle)}/limit`, { onResponseError: async ({ response }) => {
|
|
1395
1299
|
error = getStatusError(response, { [404]: `Sub-account with handle '${handle}' not found.` });
|
|
1396
1300
|
} }).catch((e) => {
|
|
1397
1301
|
error ||= getResultError(e, "Failed to delete sub-account limit.");
|
|
@@ -1401,6 +1305,158 @@ var SubAccounts = class SubAccounts {
|
|
|
1401
1305
|
error
|
|
1402
1306
|
};
|
|
1403
1307
|
}
|
|
1308
|
+
};
|
|
1309
|
+
var SubAccounts = class SubAccounts {
|
|
1310
|
+
mailchannels;
|
|
1311
|
+
static COMPANY_PATTERN = /^.{3,128}$/;
|
|
1312
|
+
static HANDLE_PATTERN = /^[a-z0-9]{3,128}$/;
|
|
1313
|
+
apiKeys;
|
|
1314
|
+
smtpPasswords;
|
|
1315
|
+
limits;
|
|
1316
|
+
constructor(mailchannels) {
|
|
1317
|
+
this.mailchannels = mailchannels;
|
|
1318
|
+
this.apiKeys = new SubAccountsApiKeys(mailchannels);
|
|
1319
|
+
this.smtpPasswords = new SubAccountsSmtpPasswords(mailchannels);
|
|
1320
|
+
this.limits = new SubAccountsLimits(mailchannels);
|
|
1321
|
+
}
|
|
1322
|
+
async create(companyName, handle) {
|
|
1323
|
+
let error = null;
|
|
1324
|
+
if (!SubAccounts.COMPANY_PATTERN.test(companyName)) {
|
|
1325
|
+
error = createValidationError("Invalid company name. Company name must be between 3 and 128 characters.");
|
|
1326
|
+
return {
|
|
1327
|
+
data: null,
|
|
1328
|
+
error
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
if (handle) {
|
|
1332
|
+
if (!SubAccounts.HANDLE_PATTERN.test(handle)) {
|
|
1333
|
+
error = createValidationError("Invalid handle. Sub-account handle must be between 3 and 128 characters and contain only lowercase letters and numbers.");
|
|
1334
|
+
return {
|
|
1335
|
+
data: null,
|
|
1336
|
+
error
|
|
1337
|
+
};
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
const response = await this.mailchannels.post("/tx/v1/sub-account", {
|
|
1341
|
+
body: {
|
|
1342
|
+
company_name: companyName,
|
|
1343
|
+
handle
|
|
1344
|
+
},
|
|
1345
|
+
onResponseError: async ({ response }) => {
|
|
1346
|
+
error = getStatusError(response, {
|
|
1347
|
+
[403]: "The parent account does not have permission to create sub-accounts.",
|
|
1348
|
+
[409]: `Sub-account with handle '${handle}' already exists.`
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
}).catch((e) => {
|
|
1352
|
+
error ||= getResultError(e, "Failed to create sub-account.");
|
|
1353
|
+
return null;
|
|
1354
|
+
});
|
|
1355
|
+
if (!response) return {
|
|
1356
|
+
data: null,
|
|
1357
|
+
error
|
|
1358
|
+
};
|
|
1359
|
+
return {
|
|
1360
|
+
data: clean({
|
|
1361
|
+
companyName: response.company_name,
|
|
1362
|
+
enabled: response.enabled,
|
|
1363
|
+
handle: response.handle
|
|
1364
|
+
}),
|
|
1365
|
+
error: null
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
async list(options) {
|
|
1369
|
+
let error = null;
|
|
1370
|
+
error = validatePagination({
|
|
1371
|
+
...options,
|
|
1372
|
+
max: 1e3
|
|
1373
|
+
});
|
|
1374
|
+
if (error) return {
|
|
1375
|
+
data: null,
|
|
1376
|
+
error
|
|
1377
|
+
};
|
|
1378
|
+
const response = await this.mailchannels.get("/tx/v1/sub-account", {
|
|
1379
|
+
query: options,
|
|
1380
|
+
onResponseError: async ({ response }) => {
|
|
1381
|
+
error = getStatusError(response);
|
|
1382
|
+
}
|
|
1383
|
+
}).catch((e) => {
|
|
1384
|
+
error ||= getResultError(e, "Failed to fetch sub-accounts.");
|
|
1385
|
+
return null;
|
|
1386
|
+
});
|
|
1387
|
+
if (!response) return {
|
|
1388
|
+
data: null,
|
|
1389
|
+
error
|
|
1390
|
+
};
|
|
1391
|
+
return {
|
|
1392
|
+
data: clean(response.map((account) => ({
|
|
1393
|
+
companyName: account.company_name,
|
|
1394
|
+
enabled: account.enabled,
|
|
1395
|
+
handle: account.handle
|
|
1396
|
+
}))),
|
|
1397
|
+
error: null
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
async delete(handle) {
|
|
1401
|
+
let error = null;
|
|
1402
|
+
if (!handle) {
|
|
1403
|
+
error = createValidationError("No handle provided.");
|
|
1404
|
+
return {
|
|
1405
|
+
success: false,
|
|
1406
|
+
error
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
await this.mailchannels.delete(`/tx/v1/sub-account/${encodeURIComponent(handle)}`, { onResponseError: async ({ response }) => {
|
|
1410
|
+
error = getStatusError(response);
|
|
1411
|
+
} }).catch((e) => {
|
|
1412
|
+
error ||= getResultError(e, "Failed to delete sub-account.");
|
|
1413
|
+
});
|
|
1414
|
+
return {
|
|
1415
|
+
success: !error,
|
|
1416
|
+
error
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
async suspend(handle) {
|
|
1420
|
+
let error = null;
|
|
1421
|
+
if (!handle) {
|
|
1422
|
+
error = createValidationError("No handle provided.");
|
|
1423
|
+
return {
|
|
1424
|
+
success: false,
|
|
1425
|
+
error
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
await this.mailchannels.post(`/tx/v1/sub-account/${encodeURIComponent(handle)}/suspend`, { onResponseError: async ({ response }) => {
|
|
1429
|
+
error = getStatusError(response, { [404]: `The specified sub-account '${handle}' does not exist.` });
|
|
1430
|
+
} }).catch((e) => {
|
|
1431
|
+
error ||= getResultError(e, "Failed to suspend sub-account.");
|
|
1432
|
+
});
|
|
1433
|
+
return {
|
|
1434
|
+
success: !error,
|
|
1435
|
+
error
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
async activate(handle) {
|
|
1439
|
+
let error = null;
|
|
1440
|
+
if (!handle) {
|
|
1441
|
+
error = createValidationError("No handle provided.");
|
|
1442
|
+
return {
|
|
1443
|
+
success: false,
|
|
1444
|
+
error
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
await this.mailchannels.post(`/tx/v1/sub-account/${encodeURIComponent(handle)}/activate`, { onResponseError: async ({ response }) => {
|
|
1448
|
+
error = getStatusError(response, {
|
|
1449
|
+
[403]: "The parent account does not have permission to activate the sub-account.",
|
|
1450
|
+
[404]: `The specified sub-account '${handle}' does not exist.`
|
|
1451
|
+
});
|
|
1452
|
+
} }).catch((e) => {
|
|
1453
|
+
error ||= getResultError(e, "Failed to activate sub-account.");
|
|
1454
|
+
});
|
|
1455
|
+
return {
|
|
1456
|
+
success: !error,
|
|
1457
|
+
error
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1404
1460
|
async getUsage(handle) {
|
|
1405
1461
|
let error = null;
|
|
1406
1462
|
if (!handle) {
|
|
@@ -1410,7 +1466,7 @@ var SubAccounts = class SubAccounts {
|
|
|
1410
1466
|
error
|
|
1411
1467
|
};
|
|
1412
1468
|
}
|
|
1413
|
-
const response = await this.mailchannels.get(`/tx/v1/sub-account/${handle}/usage`, { onResponseError: async ({ response }) => {
|
|
1469
|
+
const response = await this.mailchannels.get(`/tx/v1/sub-account/${encodeURIComponent(handle)}/usage`, { onResponseError: async ({ response }) => {
|
|
1414
1470
|
error = getStatusError(response, { [404]: `Sub-account with handle '${handle}' not found.` });
|
|
1415
1471
|
} }).catch((e) => {
|
|
1416
1472
|
error ||= getResultError(e, "Failed to fetch sub-account usage.");
|
|
@@ -1429,6 +1485,33 @@ var SubAccounts = class SubAccounts {
|
|
|
1429
1485
|
error: null
|
|
1430
1486
|
};
|
|
1431
1487
|
}
|
|
1488
|
+
createApiKey(...args) {
|
|
1489
|
+
return this.apiKeys.create(...args);
|
|
1490
|
+
}
|
|
1491
|
+
listApiKeys(...args) {
|
|
1492
|
+
return this.apiKeys.list(...args);
|
|
1493
|
+
}
|
|
1494
|
+
deleteApiKey(...args) {
|
|
1495
|
+
return this.apiKeys.delete(...args);
|
|
1496
|
+
}
|
|
1497
|
+
createSmtpPassword(...args) {
|
|
1498
|
+
return this.smtpPasswords.create(...args);
|
|
1499
|
+
}
|
|
1500
|
+
listSmtpPasswords(...args) {
|
|
1501
|
+
return this.smtpPasswords.list(...args);
|
|
1502
|
+
}
|
|
1503
|
+
deleteSmtpPassword(...args) {
|
|
1504
|
+
return this.smtpPasswords.delete(...args);
|
|
1505
|
+
}
|
|
1506
|
+
setLimit(...args) {
|
|
1507
|
+
return this.limits.set(...args);
|
|
1508
|
+
}
|
|
1509
|
+
getLimit(...args) {
|
|
1510
|
+
return this.limits.get(...args);
|
|
1511
|
+
}
|
|
1512
|
+
deleteLimit(...args) {
|
|
1513
|
+
return this.limits.delete(...args);
|
|
1514
|
+
}
|
|
1432
1515
|
};
|
|
1433
1516
|
const mapBucket = (bucket) => {
|
|
1434
1517
|
return {
|
|
@@ -1443,10 +1526,18 @@ var Metrics = class {
|
|
|
1443
1526
|
}
|
|
1444
1527
|
async engagement(options) {
|
|
1445
1528
|
let error = null;
|
|
1529
|
+
const { dates, error: dateError } = parseDateInputs({
|
|
1530
|
+
startTime: options?.startTime,
|
|
1531
|
+
endTime: options?.endTime
|
|
1532
|
+
});
|
|
1533
|
+
if (!dates || dateError) return {
|
|
1534
|
+
data: null,
|
|
1535
|
+
error: dateError
|
|
1536
|
+
};
|
|
1446
1537
|
const response = await this.mailchannels.get("/tx/v1/metrics/engagement", {
|
|
1447
1538
|
query: {
|
|
1448
|
-
start_time:
|
|
1449
|
-
end_time:
|
|
1539
|
+
start_time: dates.startTime,
|
|
1540
|
+
end_time: dates.endTime,
|
|
1450
1541
|
campaign_id: options?.campaignId,
|
|
1451
1542
|
interval: options?.interval
|
|
1452
1543
|
},
|
|
@@ -1481,10 +1572,18 @@ var Metrics = class {
|
|
|
1481
1572
|
}
|
|
1482
1573
|
async performance(options) {
|
|
1483
1574
|
let error = null;
|
|
1575
|
+
const { dates, error: dateError } = parseDateInputs({
|
|
1576
|
+
startTime: options?.startTime,
|
|
1577
|
+
endTime: options?.endTime
|
|
1578
|
+
});
|
|
1579
|
+
if (!dates || dateError) return {
|
|
1580
|
+
data: null,
|
|
1581
|
+
error: dateError
|
|
1582
|
+
};
|
|
1484
1583
|
const response = await this.mailchannels.get("/tx/v1/metrics/performance", {
|
|
1485
1584
|
query: {
|
|
1486
|
-
start_time:
|
|
1487
|
-
end_time:
|
|
1585
|
+
start_time: dates.startTime,
|
|
1586
|
+
end_time: dates.endTime,
|
|
1488
1587
|
campaign_id: options?.campaignId,
|
|
1489
1588
|
interval: options?.interval
|
|
1490
1589
|
},
|
|
@@ -1517,10 +1616,18 @@ var Metrics = class {
|
|
|
1517
1616
|
}
|
|
1518
1617
|
async recipientBehaviour(options) {
|
|
1519
1618
|
let error = null;
|
|
1619
|
+
const { dates, error: dateError } = parseDateInputs({
|
|
1620
|
+
startTime: options?.startTime,
|
|
1621
|
+
endTime: options?.endTime
|
|
1622
|
+
});
|
|
1623
|
+
if (!dates || dateError) return {
|
|
1624
|
+
data: null,
|
|
1625
|
+
error: dateError
|
|
1626
|
+
};
|
|
1520
1627
|
const response = await this.mailchannels.get("/tx/v1/metrics/recipient-behaviour", {
|
|
1521
1628
|
query: {
|
|
1522
|
-
start_time:
|
|
1523
|
-
end_time:
|
|
1629
|
+
start_time: dates.startTime,
|
|
1630
|
+
end_time: dates.endTime,
|
|
1524
1631
|
campaign_id: options?.campaignId,
|
|
1525
1632
|
interval: options?.interval
|
|
1526
1633
|
},
|
|
@@ -1551,10 +1658,18 @@ var Metrics = class {
|
|
|
1551
1658
|
}
|
|
1552
1659
|
async volume(options) {
|
|
1553
1660
|
let error = null;
|
|
1661
|
+
const { dates, error: dateError } = parseDateInputs({
|
|
1662
|
+
startTime: options?.startTime,
|
|
1663
|
+
endTime: options?.endTime
|
|
1664
|
+
});
|
|
1665
|
+
if (!dates || dateError) return {
|
|
1666
|
+
data: null,
|
|
1667
|
+
error: dateError
|
|
1668
|
+
};
|
|
1554
1669
|
const response = await this.mailchannels.get("/tx/v1/metrics/volume", {
|
|
1555
1670
|
query: {
|
|
1556
|
-
start_time:
|
|
1557
|
-
end_time:
|
|
1671
|
+
start_time: dates.startTime,
|
|
1672
|
+
end_time: dates.endTime,
|
|
1558
1673
|
campaign_id: options?.campaignId,
|
|
1559
1674
|
interval: options?.interval
|
|
1560
1675
|
},
|
|
@@ -1608,6 +1723,14 @@ var Metrics = class {
|
|
|
1608
1723
|
}
|
|
1609
1724
|
async senders(type, options) {
|
|
1610
1725
|
let error = null;
|
|
1726
|
+
const { dates, error: dateError } = parseDateInputs({
|
|
1727
|
+
startTime: options?.startTime,
|
|
1728
|
+
endTime: options?.endTime
|
|
1729
|
+
});
|
|
1730
|
+
if (!dates || dateError) return {
|
|
1731
|
+
data: null,
|
|
1732
|
+
error: dateError
|
|
1733
|
+
};
|
|
1611
1734
|
error = validatePagination({
|
|
1612
1735
|
...options,
|
|
1613
1736
|
max: 1e3
|
|
@@ -1616,10 +1739,10 @@ var Metrics = class {
|
|
|
1616
1739
|
data: null,
|
|
1617
1740
|
error
|
|
1618
1741
|
};
|
|
1619
|
-
const response = await this.mailchannels.get(`/tx/v1/metrics/senders/${type}`, {
|
|
1742
|
+
const response = await this.mailchannels.get(`/tx/v1/metrics/senders/${encodeURIComponent(type)}`, {
|
|
1620
1743
|
query: {
|
|
1621
|
-
start_time:
|
|
1622
|
-
end_time:
|
|
1744
|
+
start_time: dates.startTime,
|
|
1745
|
+
end_time: dates.endTime,
|
|
1623
1746
|
limit: options?.limit,
|
|
1624
1747
|
offset: options?.offset,
|
|
1625
1748
|
sort_order: options?.sortOrder
|
|
@@ -1690,7 +1813,7 @@ var Suppressions = class {
|
|
|
1690
1813
|
}
|
|
1691
1814
|
async delete(recipient, source) {
|
|
1692
1815
|
let error = null;
|
|
1693
|
-
await this.mailchannels.delete(`/tx/v1/suppression-list/recipients/${recipient}`, {
|
|
1816
|
+
await this.mailchannels.delete(`/tx/v1/suppression-list/recipients/${encodeURIComponent(recipient)}`, {
|
|
1694
1817
|
query: { source },
|
|
1695
1818
|
onResponseError: async ({ response }) => {
|
|
1696
1819
|
error = getStatusError(response, { [400]: "Bad Request." });
|
|
@@ -1712,6 +1835,14 @@ var Suppressions = class {
|
|
|
1712
1835
|
error
|
|
1713
1836
|
};
|
|
1714
1837
|
}
|
|
1838
|
+
const { dates, error: dateError } = parseDateInputs({
|
|
1839
|
+
createdBefore: options?.createdBefore,
|
|
1840
|
+
createdAfter: options?.createdAfter
|
|
1841
|
+
});
|
|
1842
|
+
if (!dates || dateError) return {
|
|
1843
|
+
data: null,
|
|
1844
|
+
error: dateError
|
|
1845
|
+
};
|
|
1715
1846
|
error = validatePagination({
|
|
1716
1847
|
...options,
|
|
1717
1848
|
max: 1e3
|
|
@@ -1723,8 +1854,8 @@ var Suppressions = class {
|
|
|
1723
1854
|
const payload = {
|
|
1724
1855
|
recipient: options?.recipient,
|
|
1725
1856
|
source: options?.source,
|
|
1726
|
-
created_before:
|
|
1727
|
-
created_after:
|
|
1857
|
+
created_before: dates.createdBefore,
|
|
1858
|
+
created_after: dates.createdAfter,
|
|
1728
1859
|
limit: options?.limit,
|
|
1729
1860
|
offset: options?.offset
|
|
1730
1861
|
};
|