@signalhousellc/sdk 1.0.68 → 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/README.md +0 -10
- package/package.json +3 -2
- package/skills/VENDORED.json +8 -8
- package/skills/signalhouse-10dlc/SKILL.md +5 -9
- package/skills/signalhouse-10dlc/references/tcr-rejection-causes.md +5 -12
- package/skills/signalhouse-advisor/SKILL.md +3 -3
- package/skills/signalhouse-numbers/SKILL.md +1 -2
- package/skills/signalhouse-setup/SKILL.md +41 -11
- package/skills/signalhouse-sms/SKILL.md +4 -4
- package/skills/signalhouse-webhooks/SKILL.md +76 -56
- package/src/SignalHouseSDK.js +4 -0
- package/src/domains/Agents.js +131 -0
- package/src/domains/Brands.js +56 -3
- package/src/domains/Dnc.js +168 -0
- package/src/domains/Messages.js +75 -33
- package/src/domains/Numbers.js +6 -5
- package/src/domains/Registrations.js +240 -0
- package/src/domains/Users.js +6 -2
- package/src/domains/Webhooks.js +31 -5
- package/src/webhooks/verifySignature.js +66 -0
package/src/domains/Brands.js
CHANGED
|
@@ -140,11 +140,64 @@ export class Brands {
|
|
|
140
140
|
* @param {number} [params.limit] - The number of items per page
|
|
141
141
|
* @param {string} [params.status] - The status of the brand to filter by (PENDING_CREATION, PENDING_APPROVAL, UNVERIFIED, VERIFIED, VETTED_VERIFIED, PENDING_DELETE, DELETED)
|
|
142
142
|
* @param {string} [params.registrationType] - Filter by registration type ("TEN_DLC", "TOLL_FREE", or "SHORT_CODE")
|
|
143
|
+
* @param {string} [params.search] - Staff-only (no id/subgroupId/groupId): case-insensitive substring over brandId, names, EIN, email, group, subgroup and reference ID
|
|
144
|
+
* @param {string} [params.sortBy] - Staff-only: createdAt, brandId, displayName, groupId, subgroupId, status, entityType or country
|
|
145
|
+
* @param {"asc"|"desc"} [params.sortOrder] - Staff-only: sort direction (default asc)
|
|
146
|
+
* @param {string} [params.entityType] - Staff-only: exact entity type filter
|
|
147
|
+
* @param {string} [params.ein] - Staff-only: EIN substring filter
|
|
148
|
+
* @param {string} [params.email] - Staff-only: support email substring filter
|
|
149
|
+
* @param {string} [params.referenceId] - Staff-only: reference ID substring filter
|
|
150
|
+
* @param {string|Array<string>} [params.groupIds] - Staff-only: restrict to these group IDs (sent comma-separated)
|
|
151
|
+
* @param {string} [params.createdFrom] - Staff-only: inclusive createdAt lower bound (ISO date)
|
|
152
|
+
* @param {string} [params.createdTo] - Staff-only: inclusive createdAt upper bound (ISO date)
|
|
153
|
+
* @param {boolean} [params.excludeDeleted] - Staff-only: hide DELETED brands when no status is given
|
|
154
|
+
* @param {boolean} [params.includeTotal] - Staff-only: with page and limit, return `{ data, total, page, limit, totalPages }` instead of the array
|
|
143
155
|
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
144
|
-
* @returns {Promise<SdkResponse<Array<{ _id: string, brandId: string|null, status: string, registrationType: string, [key: string]: any }
|
|
156
|
+
* @returns {Promise<SdkResponse<Array<{ _id: string, brandId: string|null, status: string, registrationType: string, [key: string]: any }>|{ data: Array<Object>, total: number, page: number, limit: number, totalPages: number }>>} Brand records. For 10DLC brands in PENDING_CREATION (or rejected before carrier assignment), brandId is null — poll by _id until status advances and brandId is assigned. The staff-only list (no id/subgroupId/groupId) returns the `{ data, total, page, limit, totalPages }` envelope only when includeTotal is sent with page and limit.
|
|
145
157
|
*/
|
|
146
|
-
async getBrands({
|
|
147
|
-
|
|
158
|
+
async getBrands({
|
|
159
|
+
id,
|
|
160
|
+
subgroupId,
|
|
161
|
+
groupId,
|
|
162
|
+
page,
|
|
163
|
+
limit,
|
|
164
|
+
status,
|
|
165
|
+
registrationType,
|
|
166
|
+
search,
|
|
167
|
+
sortBy,
|
|
168
|
+
sortOrder,
|
|
169
|
+
entityType,
|
|
170
|
+
ein,
|
|
171
|
+
email,
|
|
172
|
+
referenceId,
|
|
173
|
+
groupIds,
|
|
174
|
+
createdFrom,
|
|
175
|
+
createdTo,
|
|
176
|
+
excludeDeleted,
|
|
177
|
+
includeTotal,
|
|
178
|
+
options = {},
|
|
179
|
+
}) {
|
|
180
|
+
const filters = {
|
|
181
|
+
id,
|
|
182
|
+
subgroupId,
|
|
183
|
+
groupId,
|
|
184
|
+
page,
|
|
185
|
+
limit,
|
|
186
|
+
status,
|
|
187
|
+
registrationType,
|
|
188
|
+
search,
|
|
189
|
+
sortBy,
|
|
190
|
+
sortOrder,
|
|
191
|
+
entityType,
|
|
192
|
+
ein,
|
|
193
|
+
email,
|
|
194
|
+
referenceId,
|
|
195
|
+
groupIds: Array.isArray(groupIds) ? (groupIds.length ? groupIds.join(',') : undefined) : groupIds,
|
|
196
|
+
createdFrom,
|
|
197
|
+
createdTo,
|
|
198
|
+
excludeDeleted,
|
|
199
|
+
includeTotal,
|
|
200
|
+
};
|
|
148
201
|
const queryString = this.client._getQueryString(filters);
|
|
149
202
|
return this.client(`/brand${queryString}`, { method: 'GET', ...options });
|
|
150
203
|
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/** @typedef {import('../SignalHouseSDK.js').RequestOptions} RequestOptions */
|
|
2
|
+
/**
|
|
3
|
+
* @template T
|
|
4
|
+
* @typedef {import('../SignalHouseSDK.js').SdkResponse<T>} SdkResponse
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Do Not Contact domain: the attested "Disable Automated Opt-Out" account setting. Signal House
|
|
9
|
+
* suppresses sends to recipients who opted out of the sending campaign by default; an account may
|
|
10
|
+
* disable that only by having an officer read and e-sign the Opt-Out Handling Attestation inside a
|
|
11
|
+
* Signal House app: the portal (a customer login signs for its own account) or one of our apps running
|
|
12
|
+
* as signalhouse_api (GHL, Shopify), which signs for the account it names on behalf of the customer user
|
|
13
|
+
* it authenticated. Every method therefore lives under the admin namespace (present only when the SDK is
|
|
14
|
+
* created with `enableAdmin: true`), and the API refuses the customer "api" (API key) role on the signing
|
|
15
|
+
* routes, so attestation can never be performed by a third-party integration.
|
|
16
|
+
*/
|
|
17
|
+
export class Dnc {
|
|
18
|
+
constructor(client, enableAdmin) {
|
|
19
|
+
this.client = client;
|
|
20
|
+
this.enableAdmin = enableAdmin;
|
|
21
|
+
|
|
22
|
+
// Hidden Admin namespace INSIDE the domain
|
|
23
|
+
if (enableAdmin) {
|
|
24
|
+
this.admin = {
|
|
25
|
+
/**
|
|
26
|
+
* Get the current Opt-Out Handling Attestation text for the session's account with every placeholder
|
|
27
|
+
* filled (account values, the session's email and role, blanks in the signature block for what only
|
|
28
|
+
* signing supplies), plus the version and template hash a signature must echo back. The app must
|
|
29
|
+
* render this text; it never ships its own copy.
|
|
30
|
+
* @async
|
|
31
|
+
* @roles admin, developer, billing (portal logins); signalhouse_* with groupId
|
|
32
|
+
* @param {Object} [params] - Optional parameters
|
|
33
|
+
* @param {string} [params.groupId] - Group to render for (apps and staff; customers always get their active group)
|
|
34
|
+
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
35
|
+
* @returns {Promise<SdkResponse<any>>} - `{ version, templateSha256, text, checkboxText, groupId, accountName, customerLegalName }`
|
|
36
|
+
*/
|
|
37
|
+
getCurrentAttestation: async ({ groupId, options = {} } = {}) => {
|
|
38
|
+
const queryString = this.client._getQueryString({ groupId });
|
|
39
|
+
return this.client(`/dnc/attestation/current${queryString}`, { method: "GET", ...options });
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Sign the attestation and disable automated opt-out suppression for the account and every subgroup,
|
|
44
|
+
* effective within about a minute on every API instance. Two callers: a portal login signs for its own
|
|
45
|
+
* account and the signer identity is taken from the session; a Signal House app running as
|
|
46
|
+
* signalhouse_api (GHL, Shopify) signs for the `groupId` it names and supplies the identity of the
|
|
47
|
+
* customer user it authenticated (`signerEmail`, optional `signerUserId`, `signedVia`, and the end
|
|
48
|
+
* user's `signerIpAddress` / `signerUserAgent`, which otherwise default to the app server's). Resolves
|
|
49
|
+
* 201 when this call created the record and 200 with the existing record on a repeat or concurrent
|
|
50
|
+
* call. A stale version or hash is refused with 409 and `details.code === "ATTESTATION_VERSION_MISMATCH"`;
|
|
51
|
+
* an unchecked box or blank field with 400. Human staff roles and customer API-key sessions are refused.
|
|
52
|
+
* @async
|
|
53
|
+
* @roles admin, developer, billing (portal logins); signalhouse_api (apps, with groupId)
|
|
54
|
+
* @param {Object} params
|
|
55
|
+
* @param {string} params.version - The version returned by getCurrentAttestation
|
|
56
|
+
* @param {string} params.templateSha256 - The template hash returned by getCurrentAttestation
|
|
57
|
+
* @param {boolean} params.checkboxAcknowledged - Must be true
|
|
58
|
+
* @param {boolean} params.scrolledToEnd - Must be true
|
|
59
|
+
* @param {string} params.customerLegalName - Company legal name
|
|
60
|
+
* @param {string} params.signerName - Signer's typed full legal name (the electronic signature)
|
|
61
|
+
* @param {string} params.signerTitle - Signer's title
|
|
62
|
+
* @param {string} [params.groupId] - App callers: the account being attested
|
|
63
|
+
* @param {string} [params.signerEmail] - App callers (required): the signer's email as authenticated by the app
|
|
64
|
+
* @param {string} [params.signerUserId] - App callers: the app's id for the signer
|
|
65
|
+
* @param {string} [params.signedVia] - App callers: the app name, e.g. "ghl" or "shopify"
|
|
66
|
+
* @param {string} [params.signerIpAddress] - App callers: the end user's IP address
|
|
67
|
+
* @param {string} [params.signerUserAgent] - App callers: the end user's user agent
|
|
68
|
+
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
69
|
+
* @throws {Error} Throws an error if a required parameter is missing
|
|
70
|
+
* @returns {Promise<SdkResponse<any>>} - `{ attestation, created }`
|
|
71
|
+
*/
|
|
72
|
+
signAttestation: async ({ version, templateSha256, checkboxAcknowledged, scrolledToEnd, customerLegalName, signerName, signerTitle, groupId, signerEmail, signerUserId, signedVia, signerIpAddress, signerUserAgent, options = {} }) => {
|
|
73
|
+
this.client._require({ version, templateSha256, customerLegalName, signerName, signerTitle });
|
|
74
|
+
const appFields = Object.fromEntries(Object.entries({ groupId, signerEmail, signerUserId, signedVia, signerIpAddress, signerUserAgent }).filter(([, value]) => value !== undefined));
|
|
75
|
+
return this.client(`/dnc/attestation`, {
|
|
76
|
+
method: "POST",
|
|
77
|
+
body: { version, templateSha256, checkboxAcknowledged, scrolledToEnd, customerLegalName, signerName, signerTitle, ...appFields },
|
|
78
|
+
...options,
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Revoke the active attestation and re-enable automated opt-out suppression, effective within about a
|
|
84
|
+
* minute: a portal login for its own account, or an app (signalhouse_api) for the `groupId` it names.
|
|
85
|
+
* The record is retained as "revoked". 404 when nothing is active.
|
|
86
|
+
* @async
|
|
87
|
+
* @roles admin, developer, billing (portal logins); signalhouse_api (apps, with groupId)
|
|
88
|
+
* @param {Object} [params] - Optional parameters
|
|
89
|
+
* @param {string} [params.groupId] - App callers: the account
|
|
90
|
+
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
91
|
+
* @returns {Promise<SdkResponse<any>>} - `{ attestation }`
|
|
92
|
+
*/
|
|
93
|
+
revokeAttestation: async ({ groupId, options = {} } = {}) => {
|
|
94
|
+
return this.client(`/dnc/attestation/revoke`, { method: "POST", ...(groupId ? { body: { groupId } } : {}), ...options });
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Read an account's attestation state: whether automated opt-out is disabled, the active record
|
|
99
|
+
* (full stored text included), the full history, and whether the active record predates the
|
|
100
|
+
* current template and must be re-signed by `resignDeadline`.
|
|
101
|
+
* @async
|
|
102
|
+
* @roles admin, developer, billing (portal logins); signalhouse_* with groupId
|
|
103
|
+
* @param {Object} [params] - Optional parameters
|
|
104
|
+
* @param {string} [params.groupId] - Group to read (apps and staff; customers always get their active group)
|
|
105
|
+
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
106
|
+
* @returns {Promise<SdkResponse<any>>} - `{ groupId, automatedOptOutDisabled, currentVersion, currentTemplateSha256, requiresResign, resignDeadline, active, history }`
|
|
107
|
+
*/
|
|
108
|
+
getAttestation: async ({ groupId, options = {} } = {}) => {
|
|
109
|
+
const queryString = this.client._getQueryString({ groupId });
|
|
110
|
+
return this.client(`/dnc/attestation${queryString}`, { method: "GET", ...options });
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* List opt-out attestations across every account, newest first, with each group's trailing
|
|
115
|
+
* would-have-suppressed counts (7 and 30 days, recorded while attested) and 7-day opt-out count.
|
|
116
|
+
* The full attestation text is omitted from list rows. Staff-only.
|
|
117
|
+
* @async
|
|
118
|
+
* @roles signalhouse
|
|
119
|
+
* @param {Object} [params] - Optional parameters
|
|
120
|
+
* @param {("active"|"revoked"|"superseded")} [params.status] - Filter by status
|
|
121
|
+
* @param {string} [params.groupId] - Filter by group
|
|
122
|
+
* @param {number} [params.page] - Page number (default 1)
|
|
123
|
+
* @param {number} [params.limit] - Rows per page (default 50, max 500)
|
|
124
|
+
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
125
|
+
* @returns {Promise<SdkResponse<any>>} - `{ rows, totalCount, page, limit }`
|
|
126
|
+
*/
|
|
127
|
+
listAttestations: async ({ status, groupId, page, limit, options = {} } = {}) => {
|
|
128
|
+
const queryString = this.client._getQueryString({ status, groupId, page, limit });
|
|
129
|
+
return this.client(`/dnc/attestations${queryString}`, { method: "GET", ...options });
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Read one attestation with its stored text, hashes, signer identity, IP and user agent, plus
|
|
134
|
+
* the group's full attestation history. Staff-only.
|
|
135
|
+
* @async
|
|
136
|
+
* @roles signalhouse
|
|
137
|
+
* @param {Object} params
|
|
138
|
+
* @param {string} params.id - The attestation id
|
|
139
|
+
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
140
|
+
* @throws {Error} Throws an error if the id parameter is missing
|
|
141
|
+
* @returns {Promise<SdkResponse<any>>} - `{ attestation, history }`
|
|
142
|
+
*/
|
|
143
|
+
getAttestationById: async ({ id, options = {} }) => {
|
|
144
|
+
this.client._require({ id });
|
|
145
|
+
return this.client(`/dnc/attestations/${encodeURIComponent(id)}`, { method: "GET", ...options });
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Revoke an active attestation with a reason and re-enable automated opt-out for the account.
|
|
150
|
+
* Emails the signer and account owner. There is no staff path that creates an attestation. Staff-only.
|
|
151
|
+
* @async
|
|
152
|
+
* @roles signalhouse
|
|
153
|
+
* @param {Object} params
|
|
154
|
+
* @param {string} params.id - The attestation id
|
|
155
|
+
* @param {("carrier_complaint"|"regulator_inquiry"|"legal_request"|"excessive_opt_out_rate"|"customer_request"|"other")} params.reasonCode - Why it is being revoked
|
|
156
|
+
* @param {string} params.reason - Free-text reason shown to the customer
|
|
157
|
+
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
158
|
+
* @throws {Error} Throws an error if a required parameter is missing
|
|
159
|
+
* @returns {Promise<SdkResponse<any>>} - `{ attestation }` (status "revoked", revokedByType "signalhouse_admin")
|
|
160
|
+
*/
|
|
161
|
+
revokeAttestationById: async ({ id, reasonCode, reason, options = {} }) => {
|
|
162
|
+
this.client._require({ id, reasonCode, reason });
|
|
163
|
+
return this.client(`/dnc/attestations/${encodeURIComponent(id)}/revoke`, { method: "POST", body: { reasonCode, reason }, ...options });
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
package/src/domains/Messages.js
CHANGED
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
* @typedef {import('../SignalHouseSDK.js').SdkResponse<T>} SdkResponse
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Serialise regionScopes for the query string: an array of branches becomes JSON, a string is passed through.
|
|
9
|
+
* @param {Object} filters - Query filters that may carry regionScopes
|
|
10
|
+
* @returns {Object} - The filters with regionScopes JSON-encoded when present
|
|
11
|
+
*/
|
|
12
|
+
function withRegionScopes(filters) {
|
|
13
|
+
if (filters.regionScopes === undefined) return filters;
|
|
14
|
+
const regionScopes = typeof filters.regionScopes === "string" ? filters.regionScopes : JSON.stringify(filters.regionScopes);
|
|
15
|
+
return { ...filters, regionScopes };
|
|
16
|
+
}
|
|
17
|
+
|
|
7
18
|
export class Messages {
|
|
8
19
|
constructor(client, multipartClient, enableAdmin) {
|
|
9
20
|
this.client = client;
|
|
@@ -12,9 +23,12 @@ export class Messages {
|
|
|
12
23
|
}
|
|
13
24
|
|
|
14
25
|
/**
|
|
15
|
-
* Estimate
|
|
26
|
+
* Estimate regional SMS/MMS retail cost; no charge or send. A Canadian sender requires a Ready Canadian sender and
|
|
27
|
+
* Canadian or US recipients, and is unavailable unless Canada is enabled for the environment. A +44 (UK) sender
|
|
28
|
+
* estimates SMS to GB mobiles only and returns region "GB"; while UK sending is disabled for the environment a UK
|
|
29
|
+
* sender is refused with a 400.
|
|
16
30
|
* @async
|
|
17
|
-
* @param {Object} params - Sender, up to 100 recipients, messageBody and request options.
|
|
31
|
+
* @param {Object} params - Sender, up to 100 recipients (10-15 digits each), messageBody and request options.
|
|
18
32
|
* @returns {Promise<SdkResponse<any>>} - Per-recipient rates and total in microdollars; unknown carriers use the upper fallback.
|
|
19
33
|
*/
|
|
20
34
|
async estimateMessage({ senderPhoneNumber, recipientPhoneNumbers, messageBody, messageType = "SMS", options = {} }) {
|
|
@@ -31,13 +45,17 @@ export class Messages {
|
|
|
31
45
|
* @param {string} [params.brandId] - Filter messages by the ID of the associated brand
|
|
32
46
|
* @param {string} [params.subgroupId] - Filter messages by the ID of the associated subgroup
|
|
33
47
|
* @param {string} [params.groupId] - Filter messages by the ID of the associated group
|
|
48
|
+
* @param {string|string[]} [params.registrationId] - Filter to messages attributed to these registrations. Cannot be combined with campaignId; each id must belong to the group. Accepts a single value or an array.
|
|
34
49
|
* @param {string} [params.status] - Filter messages by their status (ENQUEUED, DEQUEUED, SENT, FAILED, DELIVERED)
|
|
35
50
|
* @param {string} [params.direction] - Filter messages by their direction (INBOUND, OUTBOUND)
|
|
36
51
|
* @param {string|string[]} [params.messageType] - Filter messages by their type. Accepts a single value or an array (e.g. ["SMS", "MMS"]). Allowed values: SMS, MMS, RCS, WHATSAPP, VIBER, P2P. When omitted, defaults to all non-P2P types.
|
|
37
52
|
* @param {string|string[]} [params.channel] - Filter messages by channel. Accepts a single value or an array. Allowed values: tenDLC, virtualLongCode, tollFree, shortCode, p2p. Each message records its channel when it is saved, and this filters on that stored value; older messages from before this feature have no channel and count as tenDLC. Ignored when matchAny is true (matchAny takes precedence).
|
|
53
|
+
* @param {string|string[]} [params.region] - ISO-2 country filter: US, GB or CA (UK is accepted for GB); one value, an array, or a comma-separated string; omitted = every region. Accepted whether or not the environment serves hourly analytics.
|
|
54
|
+
* @param {Object[]|string} [params.regionScopes] - Array of OR-ed branches `{ region, channels, brandId?, campaignId?, phoneNumber? }` (channels among tenDLC, virtualLongCode, tollFree, shortCode, p2p); `[]` matches nothing. Sent as JSON unless already a string. Accepted whether or not the environment serves hourly analytics.
|
|
38
55
|
* @param {boolean} [params.matchAny] - When true, the provided campaignId/brandId/phoneNumber filters are OR'd (a message matches ANY of them) instead of the default most-specific-single behavior. subgroupId stays an AND scope. Opt-in/additive.
|
|
39
56
|
* @param {string} [params.carrier] - Filter messages by the carrier used for sending
|
|
40
57
|
* @param {string|string[]} [params.sentimentLabel] - Filter messages by sentiment bucket. Accepts a single value or an array (e.g. ["positive", "negative"]). Allowed values: positive, neutral, negative. Applied as the sentimentScore range the ±25 label threshold produces, so unscored messages match no bucket and outbound messages (never scored) are excluded.
|
|
58
|
+
* @param {string|string[]} [params.errorCode] - Filter FAILED messages by Signal House error code (single value or array). "OUT" is the campaign opt-out, displayed as RECIPIENT_OPTED_OUT. Carrier codes are not filterable here; they live inside successOrFailureReason.
|
|
41
59
|
* @param {string|string[]} [params.phoneNumber] - Filter messages by a business number on either side of the message. Accepts a single value or an array; OR'd with campaignId/brandId when matchAny is true
|
|
42
60
|
* @param {string} [params.senderPhoneNumber] - Filter messages by the sender's 5-6 digit Short Code or 10+ digit phone number
|
|
43
61
|
* @param {string} [params.recipientPhoneNumber] - Filter messages by the recipient's phone number
|
|
@@ -59,6 +77,7 @@ export class Messages {
|
|
|
59
77
|
brandId,
|
|
60
78
|
subgroupId,
|
|
61
79
|
groupId,
|
|
80
|
+
registrationId,
|
|
62
81
|
phoneNumber,
|
|
63
82
|
senderPhoneNumber,
|
|
64
83
|
recipientPhoneNumber,
|
|
@@ -66,9 +85,12 @@ export class Messages {
|
|
|
66
85
|
direction,
|
|
67
86
|
messageType,
|
|
68
87
|
channel,
|
|
88
|
+
region,
|
|
89
|
+
regionScopes,
|
|
69
90
|
matchAny,
|
|
70
91
|
carrier,
|
|
71
92
|
sentimentLabel,
|
|
93
|
+
errorCode,
|
|
72
94
|
startDate,
|
|
73
95
|
endDate,
|
|
74
96
|
sortField,
|
|
@@ -78,8 +100,8 @@ export class Messages {
|
|
|
78
100
|
dateBounds,
|
|
79
101
|
options = {},
|
|
80
102
|
}) {
|
|
81
|
-
const filters = { id, campaignId, brandId, subgroupId, groupId, phoneNumber, senderPhoneNumber, recipientPhoneNumber, status, direction, messageType, channel, matchAny, carrier, sentimentLabel, startDate, endDate, sortField, sortOrder, page, limit, dateBounds };
|
|
82
|
-
const queryString = this.client._getQueryString(filters);
|
|
103
|
+
const filters = { id, campaignId, brandId, subgroupId, groupId, registrationId, phoneNumber, senderPhoneNumber, recipientPhoneNumber, status, direction, messageType, channel, region, regionScopes, matchAny, carrier, sentimentLabel, errorCode, startDate, endDate, sortField, sortOrder, page, limit, dateBounds };
|
|
104
|
+
const queryString = this.client._getQueryString(withRegionScopes(filters));
|
|
83
105
|
return this.client(`/message${queryString}`, { method: "GET", ...options });
|
|
84
106
|
}
|
|
85
107
|
|
|
@@ -112,14 +134,17 @@ export class Messages {
|
|
|
112
134
|
* @param {string|string[]} [params.subgroupId] - Filter analytics by the ID of the associated subgroup. Accepts a single value, an array, or a comma-separated string.
|
|
113
135
|
* @param {string|string[]} [params.brandId] - Filter analytics by the ID of the associated brand. Accepts a single value, an array, or a comma-separated string.
|
|
114
136
|
* @param {string|string[]} [params.campaignId] - Filter analytics by the ID of the associated campaign. Accepts a single value, an array, or a comma-separated string.
|
|
137
|
+
* @param {string|string[]} [params.registrationId] - Filter to traffic attributed to these registrations (hourly analytics only; a 400 while hourly reads are off). A phoneNumber filter takes precedence. Accepts a single value or an array.
|
|
115
138
|
* @param {string|string[]} [params.phoneNumber] - Filter analytics by the phone number involved in the messages. Accepts a single value, an array, or a comma-separated string.
|
|
116
139
|
* @param {string|string[]} [params.carrier] - Filter analytics by the carrier used for sending. Accepts a single value, an array, or a comma-separated string.
|
|
117
|
-
* @param {string|string[]} [params.carrierFamily] - Filter analytics by the recipient's resolved carrier family (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P). Accepts a single value, an array, or a comma-separated string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
|
|
140
|
+
* @param {string|string[]} [params.carrierFamily] - Filter analytics by the recipient's resolved carrier family (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P, Standard, IceWireless). Accepts a single value, an array, or a comma-separated string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
|
|
118
141
|
* @param {string} [params.startDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode
|
|
119
142
|
* @param {string} [params.endDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back
|
|
120
143
|
* @param {boolean} [params.matchAny] - When true, the provided campaignId/brandId/phoneNumber filters are OR'd (match ANY) instead of the default most-specific-single behavior. subgroupId stays an AND scope. Opt-in/additive.
|
|
121
144
|
* @param {(string|string[])} [params.messageType] - Message type(s) the SENTIMENT figures are scoped to: SMS, MMS or P2P (single value, array, or comma-separated string). Omit for all scored types. Does NOT narrow the message counts, which are always returned split per type (smsInbound/mmsInbound/p2pInbound) and have no filterable type dimension.
|
|
122
145
|
* @param {string|string[]} [params.channel] - Filter analytics by channel (tenDLC, virtualLongCode, tollFree, shortCode, p2p). Filters on the stored channel column; a tenDLC selection also includes older messages that have no channel, and p2p is a real channel here (matched by carrier). Accepts a single value or an array. Ignored when matchAny is true (matchAny takes precedence).
|
|
146
|
+
* @param {string|string[]} [params.region] - ISO-2 country filter: US, GB or CA (UK is accepted for GB); one value, an array, or a comma-separated string; omitted = every region. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
147
|
+
* @param {Object[]|string} [params.regionScopes] - Array of OR-ed branches `{ region, channels, brandId?, campaignId?, phoneNumber? }` (channels among tenDLC, virtualLongCode, tollFree, shortCode, p2p); `[]` matches nothing. Sent as JSON unless already a string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
123
148
|
* @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
|
|
124
149
|
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
125
150
|
* @returns {Promise<SdkResponse<any>>} - A promise that resolves to the analytics data. Also includes inbound-message
|
|
@@ -131,9 +156,9 @@ export class Messages {
|
|
|
131
156
|
* summed or re-averaged across types, rows or responses. To weight a subset of message types, pass
|
|
132
157
|
* messageType and read sentimentScore.
|
|
133
158
|
*/
|
|
134
|
-
async getAnalytics({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, messageType, matchAny, dateBounds, options = {} }) {
|
|
135
|
-
const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, messageType, matchAny, dateBounds };
|
|
136
|
-
const queryString = this.client._getQueryString(filters);
|
|
159
|
+
async getAnalytics({ groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, region, regionScopes, messageType, matchAny, dateBounds, options = {} }) {
|
|
160
|
+
const filters = { groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, region, regionScopes, messageType, matchAny, dateBounds };
|
|
161
|
+
const queryString = this.client._getQueryString(withRegionScopes(filters));
|
|
137
162
|
return this.client(`/message/analytics${queryString}`, { method: "GET", ...options });
|
|
138
163
|
}
|
|
139
164
|
|
|
@@ -146,13 +171,16 @@ export class Messages {
|
|
|
146
171
|
* @param {string|string[]} [params.subgroupId] - Filter analytics by the ID of the associated subgroup. Accepts a single value, an array, or a comma-separated string.
|
|
147
172
|
* @param {string|string[]} [params.brandId] - Filter analytics by the ID of the associated brand. Accepts a single value, an array, or a comma-separated string.
|
|
148
173
|
* @param {string|string[]} [params.campaignId] - Filter analytics by the ID of the associated campaign. Accepts a single value, an array, or a comma-separated string.
|
|
174
|
+
* @param {string|string[]} [params.registrationId] - Filter to traffic attributed to these registrations (hourly analytics only; a 400 while hourly reads are off). A phoneNumber filter takes precedence. Accepts a single value or an array.
|
|
149
175
|
* @param {string|string[]} [params.phoneNumber] - Filter analytics by the phone number involved in the messages. Accepts a single value, an array, or a comma-separated string.
|
|
150
176
|
* @param {string|string[]} [params.carrier] - Filter analytics by the carrier used for sending. Accepts a single value, an array, or a comma-separated string.
|
|
151
|
-
* @param {string|string[]} [params.carrierFamily] - Filter analytics by the recipient's resolved carrier family (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P). Accepts a single value, an array, or a comma-separated string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
|
|
177
|
+
* @param {string|string[]} [params.carrierFamily] - Filter analytics by the recipient's resolved carrier family (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P, Standard, IceWireless). Accepts a single value, an array, or a comma-separated string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
|
|
152
178
|
* @param {string} [params.startDate] - ISO-8601 date or timestamp. It is bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode, then floored to the start of its hour at either granularity, because the hourly cube is keyed by hour and a mid-hour start would drop that hour's bucket.
|
|
153
179
|
* @param {string} [params.endDate] - ISO-8601 date or timestamp. At day granularity it is bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back; at hour granularity it is honoured as given.
|
|
154
180
|
* @param {(string|string[])} [params.messageType] - Message type(s) the SENTIMENT figures are scoped to: SMS, MMS or P2P (single value, array, or comma-separated string). Omit for all scored types. Does NOT narrow the message counts, which are always returned split per type (smsInbound/mmsInbound/p2pInbound) and have no filterable type dimension.
|
|
155
181
|
* @param {string|string[]} [params.channel] - Filter analytics by channel (tenDLC, virtualLongCode, tollFree, shortCode, p2p). Filters on the stored channel column; a tenDLC selection also includes older messages that have no channel, and p2p is a real channel here. Accepts a single value or an array.
|
|
182
|
+
* @param {string|string[]} [params.region] - ISO-2 country filter: US, GB or CA (UK is accepted for GB); one value, an array, or a comma-separated string; omitted = every region. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
183
|
+
* @param {Object[]|string} [params.regionScopes] - Array of OR-ed branches `{ region, channels, brandId?, campaignId?, phoneNumber? }` (channels among tenDLC, virtualLongCode, tollFree, shortCode, p2p); `[]` matches nothing. Sent as JSON unless already a string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
156
184
|
* @param {("day"|"hour")} [params.granularity] - Time-bucket grain of the byDate rows. Omit for day (each row's _id is a "YYYY-MM-DD" date). "hour" buckets by hour (each row's _id is a "YYYY-MM-DD HH:MM:SS" UTC hour) and is capped to a 7-day span. Only accepted where the environment serves hourly analytics; elsewhere any value, including "day", is rejected with a 400 -- omit the parameter unless hour grain is wanted.
|
|
157
185
|
* @param {("carrier"|"carrierFamily")} [params.breakdown] - Adds a byBreakdown time × dimension series to the response ({ dimension, rows }: each row is one byDate bucket (_id) for one carrier or carrier family (key), over the top 50 keys by volume, 10DLC only) and caps the span at 31 days. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
|
|
158
186
|
* @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
|
|
@@ -165,9 +193,9 @@ export class Messages {
|
|
|
165
193
|
* score is divided server-side and the raw sums are never returned: a score is an average and must never be
|
|
166
194
|
* summed or re-averaged across types, rows or responses.
|
|
167
195
|
*/
|
|
168
|
-
async getAnalyticsDetail({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, messageType, granularity, breakdown, dateBounds, options = {} }) {
|
|
169
|
-
const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, messageType, granularity, breakdown, dateBounds };
|
|
170
|
-
const queryString = this.client._getQueryString(filters);
|
|
196
|
+
async getAnalyticsDetail({ groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, region, regionScopes, messageType, granularity, breakdown, dateBounds, options = {} }) {
|
|
197
|
+
const filters = { groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, region, regionScopes, messageType, granularity, breakdown, dateBounds };
|
|
198
|
+
const queryString = this.client._getQueryString(withRegionScopes(filters));
|
|
171
199
|
return this.client(`/message/analytics/detail${queryString}`, { method: "GET", ...options });
|
|
172
200
|
}
|
|
173
201
|
|
|
@@ -183,6 +211,7 @@ export class Messages {
|
|
|
183
211
|
* @param {string} params.groupId - The group to scope the read to (required)
|
|
184
212
|
* @param {string|string[]} [params.brandId] - Brand scope. Accepts a single value, an array, or a comma-separated string.
|
|
185
213
|
* @param {string|string[]} [params.campaignId] - Campaign scope; wins over brandId. Accepts a single value, an array, or a comma-separated string.
|
|
214
|
+
* @param {string|string[]} [params.registrationId] - Filter to traffic attributed to these registrations (hourly analytics only; a 400 while hourly reads are off). Accepts a single value or an array.
|
|
186
215
|
* @param {string|string[]} [params.carrierFamily] - Carrier-family filter (ATT, TMobile, Verizon, USCellular, ...). Accepts a single value, an array, or a comma-separated string.
|
|
187
216
|
* @param {string} params.startDate - ISO-8601 date or timestamp. It is bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode, then floored to the start of its hour at hour granularity and of its minute at day granularity (the cube is keyed by minute).
|
|
188
217
|
* @param {string} params.endDate - ISO-8601 date or timestamp. At hour granularity it is honoured as given; at day granularity it is bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back. The span is capped at 35 days (the retention of the per-minute data).
|
|
@@ -192,8 +221,8 @@ export class Messages {
|
|
|
192
221
|
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
193
222
|
* @returns {Promise<SdkResponse<any>>} - `{ totals, byDate, byCarrierFamily, byBreakdown: { dimension: "carrierFamily", rows } }`. Every row carries segments, messages, peakSegmentsPerMinute, peakMessagesPerMinute, peakMinute (UTC "YYYY-MM-DD HH:MM:SS", null when no traffic), sendingMinutes, averageSegmentsPerSendingMinute and minutesAtCeiling.
|
|
194
223
|
*/
|
|
195
|
-
async getAnalyticsThroughput({ groupId, brandId, campaignId, carrierFamily, startDate, endDate, granularity, ceiling, dateBounds, options = {} }) {
|
|
196
|
-
const filters = { groupId, brandId, campaignId, carrierFamily, startDate, endDate, granularity, ceiling, dateBounds };
|
|
224
|
+
async getAnalyticsThroughput({ groupId, brandId, campaignId, registrationId, carrierFamily, startDate, endDate, granularity, ceiling, dateBounds, options = {} }) {
|
|
225
|
+
const filters = { groupId, brandId, campaignId, registrationId, carrierFamily, startDate, endDate, granularity, ceiling, dateBounds };
|
|
197
226
|
const queryString = this.client._getQueryString(filters);
|
|
198
227
|
return this.client(`/message/analytics/throughput${queryString}`, { method: "GET", ...options });
|
|
199
228
|
}
|
|
@@ -205,11 +234,12 @@ export class Messages {
|
|
|
205
234
|
* @roles api, admin, developer, billing, user
|
|
206
235
|
* @param {Object} params - The parameters for getting analytics filter options
|
|
207
236
|
* @param {string} params.groupId - The ID of the group whose filter options to load
|
|
237
|
+
* @param {string|string[]} [params.region] - ISO-2 country filter: US, GB or CA (UK is accepted for GB); one value, an array, or a comma-separated string; omitted = every region. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
208
238
|
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
209
|
-
* @returns {Promise<SdkResponse<any>>} - A promise that resolves to { subgroups, brands, campaigns, phoneNumbers }
|
|
239
|
+
* @returns {Promise<SdkResponse<any>>} - A promise that resolves to { subgroups, brands, campaigns, phoneNumbers }. Each phone number carries type (TOLL_FREE, SHORT_CODE, ALPHANUMERIC, VIRTUAL_LONG_NUMBER, ...) and country (ISO-2), null when unknown: TOLL_FREE, SHORT_CODE and ALPHANUMERIC are channels by type; any other US number is 10DLC and a non-US one is a Virtual Long Code.
|
|
210
240
|
*/
|
|
211
|
-
async getAnalyticsFilterOptions({ groupId, options = {} }) {
|
|
212
|
-
const filters = { groupId };
|
|
241
|
+
async getAnalyticsFilterOptions({ groupId, region, options = {} }) {
|
|
242
|
+
const filters = { groupId, region };
|
|
213
243
|
const queryString = this.client._getQueryString(filters);
|
|
214
244
|
return this.client(`/message/analytics/filter-options${queryString}`, { method: "GET", ...options });
|
|
215
245
|
}
|
|
@@ -224,9 +254,10 @@ export class Messages {
|
|
|
224
254
|
* @param {string|string[]} [params.subgroupId]
|
|
225
255
|
* @param {string|string[]} [params.brandId]
|
|
226
256
|
* @param {string|string[]} [params.campaignId]
|
|
257
|
+
* @param {string|string[]} [params.registrationId] - Filter to traffic attributed to these registrations (hourly analytics only; a 400 while hourly reads are off). A phoneNumber filter takes precedence. Accepts a single value or an array.
|
|
227
258
|
* @param {string|string[]} [params.phoneNumber]
|
|
228
259
|
* @param {string|string[]} [params.carrier]
|
|
229
|
-
* @param {string|string[]} [params.carrierFamily] - Resolved carrier family of the recipient (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P); single value, array, or comma-separated. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
|
|
260
|
+
* @param {string|string[]} [params.carrierFamily] - Resolved carrier family of the recipient (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P, Standard, IceWireless); single value, array, or comma-separated. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
|
|
230
261
|
* @param {string} [params.startDate]
|
|
231
262
|
* @param {string} [params.endDate]
|
|
232
263
|
* @param {number} [params.page=1]
|
|
@@ -234,13 +265,15 @@ export class Messages {
|
|
|
234
265
|
* @param {("tenDLC"|"virtualLongCode"|"tollFree"|"shortCode"|"p2p"|"both")|Array<"tenDLC"|"virtualLongCode"|"tollFree"|"shortCode"|"p2p">} [params.channel="both"] - Filter and rank rows by the stored channel column. "both" (default) means all activity. tenDLC/virtualLongCode/tollFree/shortCode/p2p (single value or array) limit to the selected channel(s).
|
|
235
266
|
* @param {(string|string[])} [params.messageType] - Message type(s) the SENTIMENT figures are scoped to: SMS, MMS or P2P (single value, array, or comma-separated string). Omit for all scored types. Does NOT narrow the message counts, which are always returned split per type (smsInbound/mmsInbound/p2pInbound) and have no filterable type dimension.
|
|
236
267
|
* @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
|
|
268
|
+
* @param {string|string[]} [params.region] - ISO-2 country filter: US, GB or CA (UK is accepted for GB); one value, an array, or a comma-separated string; omitted = every region. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
269
|
+
* @param {Object[]|string} [params.regionScopes] - Array of OR-ed branches `{ region, channels, brandId?, campaignId?, phoneNumber? }` (channels among tenDLC, virtualLongCode, tollFree, shortCode, p2p); `[]` matches nothing. Sent as JSON unless already a string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
237
270
|
* @param {RequestOptions} [params.options]
|
|
238
271
|
* @returns {Promise<SdkResponse<any>>} - { rows, totalCount, page, limit }. Each row carries sms/mms/p2p metric columns plus `smsOptOuts` and `mmsOptOuts` from the DNC analytics MV (P2P has no opt-outs).
|
|
239
272
|
* Each row also carries that subgroup's inbound-message sentiment: `sentimentScore` (volume-weighted average of every scored inbound message in that subgroup, -100..100, null when nothing was scored), `sentimentLabel`, `sentimentScoredCount`, `sentimentPositive`, `sentimentNeutral`, `sentimentNegative`, plus the same six per message type under `smsSentiment*`, `mmsSentiment*` and `p2pSentiment*` prefixes. The score is derived server-side and must never be re-averaged across rows — combine the counts, not the scores.
|
|
240
273
|
*/
|
|
241
|
-
async getAnalyticsBySubgroup({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, messageType, dateBounds, options = {} }) {
|
|
242
|
-
const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, messageType, dateBounds };
|
|
243
|
-
const queryString = this.client._getQueryString(filters);
|
|
274
|
+
async getAnalyticsBySubgroup({ groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, region, regionScopes, messageType, dateBounds, options = {} }) {
|
|
275
|
+
const filters = { groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, region, regionScopes, messageType, dateBounds };
|
|
276
|
+
const queryString = this.client._getQueryString(withRegionScopes(filters));
|
|
244
277
|
return this.client(`/message/analytics/by-subgroup${queryString}`, { method: "GET", ...options });
|
|
245
278
|
}
|
|
246
279
|
|
|
@@ -254,21 +287,24 @@ export class Messages {
|
|
|
254
287
|
* @param {string|string[]} [params.subgroupId]
|
|
255
288
|
* @param {string|string[]} [params.brandId]
|
|
256
289
|
* @param {string|string[]} [params.campaignId]
|
|
290
|
+
* @param {string|string[]} [params.registrationId] - Filter to traffic attributed to these registrations (hourly analytics only; a 400 while hourly reads are off). A phoneNumber filter takes precedence. Accepts a single value or an array.
|
|
257
291
|
* @param {string|string[]} [params.phoneNumber]
|
|
258
292
|
* @param {string|string[]} [params.carrier]
|
|
259
|
-
* @param {string|string[]} [params.carrierFamily] - Resolved carrier family of the recipient (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P); single value, array, or comma-separated. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
|
|
293
|
+
* @param {string|string[]} [params.carrierFamily] - Resolved carrier family of the recipient (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P, Standard, IceWireless); single value, array, or comma-separated. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
|
|
260
294
|
* @param {string} [params.startDate]
|
|
261
295
|
* @param {string} [params.endDate]
|
|
262
296
|
* @param {number} [params.page=1]
|
|
263
297
|
* @param {number} [params.limit=50] - max 50 per page
|
|
264
298
|
* @param {("tenDLC"|"virtualLongCode"|"tollFree"|"shortCode"|"p2p"|"both")|Array<"tenDLC"|"virtualLongCode"|"tollFree"|"shortCode"|"p2p">} [params.channel="both"] - Filter and rank rows by the stored channel column. "both" (default) means every code. tenDLC/virtualLongCode/tollFree/shortCode/p2p (single value or array) limit to the selected channel(s); when one channel is selected, totalErrors reflects only that channel.
|
|
265
299
|
* @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
|
|
300
|
+
* @param {string|string[]} [params.region] - ISO-2 country filter: US, GB or CA (UK is accepted for GB); one value, an array, or a comma-separated string; omitted = every region. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
301
|
+
* @param {Object[]|string} [params.regionScopes] - Array of OR-ed branches `{ region, channels, brandId?, campaignId?, phoneNumber? }` (channels among tenDLC, virtualLongCode, tollFree, shortCode, p2p); `[]` matches nothing. Sent as JSON unless already a string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
266
302
|
* @param {RequestOptions} [params.options]
|
|
267
303
|
* @returns {Promise<SdkResponse<any>>} - { rows, totalCount, totalErrors: { sms, mms, p2p, all }, page, limit }
|
|
268
304
|
*/
|
|
269
|
-
async getAnalyticsByErrorCode({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, dateBounds, options = {} }) {
|
|
270
|
-
const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, dateBounds };
|
|
271
|
-
const queryString = this.client._getQueryString(filters);
|
|
305
|
+
async getAnalyticsByErrorCode({ groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, region, regionScopes, dateBounds, options = {} }) {
|
|
306
|
+
const filters = { groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, region, regionScopes, dateBounds };
|
|
307
|
+
const queryString = this.client._getQueryString(withRegionScopes(filters));
|
|
272
308
|
return this.client(`/message/analytics/by-error-code${queryString}`, { method: "GET", ...options });
|
|
273
309
|
}
|
|
274
310
|
|
|
@@ -281,18 +317,21 @@ export class Messages {
|
|
|
281
317
|
* @param {string} [params.subgroupId] - Filter by the ID of the associated subgroup
|
|
282
318
|
* @param {string} [params.brandId] - Filter by the ID of the associated brand
|
|
283
319
|
* @param {string} [params.campaignId] - Filter by the ID of the associated campaign
|
|
320
|
+
* @param {string|string[]} [params.registrationId] - Filter to traffic attributed to these registrations (hourly analytics only; a 400 while hourly reads are off). A phoneNumber filter takes precedence. Accepts a single value or an array.
|
|
284
321
|
* @param {string} [params.phoneNumber] - Filter by the phone number
|
|
285
322
|
* @param {string} [params.carrier] - Filter by the carrier
|
|
286
323
|
* @param {string} [params.startDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode
|
|
287
324
|
* @param {string} [params.endDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back
|
|
288
325
|
* @param {string|string[]} [params.channel] - Filter by channel (tenDLC, virtualLongCode, tollFree, shortCode). Opt-outs are A2P-only, so p2p applies no filter. Filters on the stored channel column; a tenDLC selection also includes older opt-outs that have no channel.
|
|
289
326
|
* @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
|
|
327
|
+
* @param {string|string[]} [params.region] - ISO-2 country filter: US, GB or CA (UK is accepted for GB); one value, an array, or a comma-separated string; omitted = every region. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
328
|
+
* @param {Object[]|string} [params.regionScopes] - Array of OR-ed branches `{ region, channels, brandId?, campaignId?, phoneNumber? }` (channels among tenDLC, virtualLongCode, tollFree, shortCode, p2p); `[]` matches nothing. Sent as JSON unless already a string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
290
329
|
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
291
|
-
* @returns {Promise<SdkResponse<any>>} - A promise that resolves to the DNC analytics data (totals, byDate, byPhoneNumber, byCarrier, byKeyword). byKeyword breaks opt-outs down by the normalized keyword that revoked consent ({ optOutKeyword, total, sms, mms }); opt-outs recorded before keyword capture shipped appear as a single optOutKeyword: null bucket ("not recorded"). The distinct keyword set is open-ended (campaigns register their own keywords beyond the mandatory floor) — render top-N plus Other, never a fixed list.
|
|
330
|
+
* @returns {Promise<SdkResponse<any>>} - A promise that resolves to the DNC analytics data (totals, byDate, byPhoneNumber, bySenderNumber, byCampaign, bySubgroup, byType, byCarrier, byKeyword). bySenderNumber ({ senderPhoneNumber, total, sms, mms }) attributes each opt-out to the first business number that received it, so it is unchanged by later campaign moves and START replies. byCampaign ({ campaignId, ... }) counts campaign-scoped opt-outs only, by the campaign at the time of the STOP; subgroup-scoped opt-outs (non-US recipients) are never attributed to a campaign and appear under bySubgroup ({ subgroupId, ... }) instead. byType ({ messageType, total }) splits SMS/MMS. byKeyword breaks opt-outs down by the normalized keyword that revoked consent ({ optOutKeyword, total, sms, mms }); opt-outs recorded before keyword capture shipped appear as a single optOutKeyword: null bucket ("not recorded"). The distinct keyword set is open-ended (campaigns register their own keywords beyond the mandatory floor) — render top-N plus Other, never a fixed list.
|
|
292
331
|
*/
|
|
293
|
-
async getDncAnalytics({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel, dateBounds, options = {} }) {
|
|
294
|
-
const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel, dateBounds };
|
|
295
|
-
const queryString = this.client._getQueryString(filters);
|
|
332
|
+
async getDncAnalytics({ groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, startDate, endDate, channel, region, regionScopes, dateBounds, options = {} }) {
|
|
333
|
+
const filters = { groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, startDate, endDate, channel, region, regionScopes, dateBounds };
|
|
334
|
+
const queryString = this.client._getQueryString(withRegionScopes(filters));
|
|
296
335
|
return this.client(`/message/dnc/analytics${queryString}`, { method: "GET", ...options });
|
|
297
336
|
}
|
|
298
337
|
|
|
@@ -305,6 +344,7 @@ export class Messages {
|
|
|
305
344
|
* @param {string} [params.subgroupId] - Filter by the ID of the associated subgroup
|
|
306
345
|
* @param {string} [params.brandId] - Filter by the ID of the associated brand
|
|
307
346
|
* @param {string} [params.campaignId] - Filter by the ID of the associated campaign
|
|
347
|
+
* @param {string|string[]} [params.registrationId] - Filter to traffic attributed to these registrations (hourly analytics only; a 400 while hourly reads are off). A phoneNumber filter takes precedence. Accepts a single value or an array.
|
|
308
348
|
* @param {string} [params.phoneNumber] - Filter by the phone number
|
|
309
349
|
* @param {string} [params.carrier] - Filter by the carrier
|
|
310
350
|
* @param {string} [params.startDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode
|
|
@@ -315,12 +355,14 @@ export class Messages {
|
|
|
315
355
|
* @param {string} [params.sortOrder] - Sort direction (asc, desc)
|
|
316
356
|
* @param {string|string[]} [params.channel] - Filter by channel (tenDLC, virtualLongCode, tollFree, shortCode). Opt-outs are A2P-only, so p2p applies no filter. Filters on the stored channel column; a tenDLC selection also includes older opt-outs that have no channel.
|
|
317
357
|
* @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
|
|
358
|
+
* @param {string|string[]} [params.region] - ISO-2 country filter: US, GB or CA (UK is accepted for GB); one value, an array, or a comma-separated string; omitted = every region. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
359
|
+
* @param {Object[]|string} [params.regionScopes] - Array of OR-ed branches `{ region, channels, brandId?, campaignId?, phoneNumber? }` (channels among tenDLC, virtualLongCode, tollFree, shortCode, p2p); `[]` matches nothing. Sent as JSON unless already a string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400.
|
|
318
360
|
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
319
|
-
* @returns {Promise<SdkResponse<any>>} - A promise that resolves to the paginated DNC records. Each record carries optOutKeyword — the normalized keyword that revoked consent (e.g. "stop", "opt out"; a repeat opt-out records the most recent word), null for opt-outs recorded before keyword capture shipped — and carrierFamily, the resolved carrier family of the recipient number (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile), copied from the inbound message that triggered the opt-out.
|
|
361
|
+
* @returns {Promise<SdkResponse<any>>} - A promise that resolves to the paginated DNC records. Each record carries senderPhoneNumber — the first business number that received the opt-out (set once, never changed by a later STOP or a campaign move; the same value as phoneNumber) — optOutKeyword — the normalized keyword that revoked consent (e.g. "stop", "opt out"; a repeat opt-out records the most recent word), null for opt-outs recorded before keyword capture shipped — and carrierFamily, the resolved carrier family of the recipient number (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, Standard, IceWireless), copied from the inbound message that triggered the opt-out. campaignId is null on subgroup-scoped records (non-US recipients).
|
|
320
362
|
*/
|
|
321
|
-
async getDncRecords({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, sortField, sortOrder, channel, dateBounds, options = {} }) {
|
|
322
|
-
const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, sortField, sortOrder, channel, dateBounds };
|
|
323
|
-
const queryString = this.client._getQueryString(filters);
|
|
363
|
+
async getDncRecords({ groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, startDate, endDate, page, limit, sortField, sortOrder, channel, region, regionScopes, dateBounds, options = {} }) {
|
|
364
|
+
const filters = { groupId, subgroupId, brandId, campaignId, registrationId, phoneNumber, carrier, startDate, endDate, page, limit, sortField, sortOrder, channel, region, regionScopes, dateBounds };
|
|
365
|
+
const queryString = this.client._getQueryString(withRegionScopes(filters));
|
|
324
366
|
return this.client(`/message/dnc${queryString}`, { method: "GET", ...options });
|
|
325
367
|
}
|
|
326
368
|
|
package/src/domains/Numbers.js
CHANGED
|
@@ -77,6 +77,7 @@ export class Numbers {
|
|
|
77
77
|
* @param {Object} params - The parameters for filtering the phone numbers
|
|
78
78
|
* @param {string} [params.phoneNumber] - Filter by phone number (partial match)
|
|
79
79
|
* @param {string} [params.campaignId] - Filter by campaign ID
|
|
80
|
+
* @param {string} [params.registrationId] - Filter to numbers provisioned under this registration.
|
|
80
81
|
* @param {string} [params.brandId] - Filter by brand ID
|
|
81
82
|
* @param {string} [params.subgroupId] - Filter by subgroup ID
|
|
82
83
|
* @param {string} [params.groupId] - Filter by group ID
|
|
@@ -102,8 +103,8 @@ export class Numbers {
|
|
|
102
103
|
* or GET /campaign/health.
|
|
103
104
|
* @returns {Promise<SdkResponse<any>>} A promise that resolves to the list of phone numbers
|
|
104
105
|
*/
|
|
105
|
-
async getPhoneNumbers({ phoneNumber, campaignId, brandId, subgroupId, groupId, page, limit, options = {} }) {
|
|
106
|
-
const filters = { phoneNumber, campaignId, brandId, subgroupId, groupId, page, limit };
|
|
106
|
+
async getPhoneNumbers({ phoneNumber, campaignId, registrationId, brandId, subgroupId, groupId, page, limit, options = {} }) {
|
|
107
|
+
const filters = { phoneNumber, campaignId, registrationId, brandId, subgroupId, groupId, page, limit };
|
|
107
108
|
const queryString = this.client._getQueryString(filters);
|
|
108
109
|
return this.client(`/number${queryString}`, { method: 'GET', ...options });
|
|
109
110
|
}
|
|
@@ -134,7 +135,7 @@ export class Numbers {
|
|
|
134
135
|
* @param {boolean} [params.voiceEnabled] - Filter for phone numbers that are voice enabled
|
|
135
136
|
* @param {string} [params.country] - Filter by country code (e.g., "US")
|
|
136
137
|
* @param {string} [params.state] - Filter by state code (e.g., "CA")
|
|
137
|
-
* @param {string} [params.city] - City prefix; requires country US
|
|
138
|
+
* @param {string} [params.city] - City prefix; requires country US and state.
|
|
138
139
|
* @param {string} [params.npa] - Filter by NPA (area code)
|
|
139
140
|
* @param {string} [params.nxx] - Filter by NXX (central office code) - the first three digits of the local phone number after the area code
|
|
140
141
|
* @param {string} [params.phoneNumber] - Filter by phone number
|
|
@@ -172,7 +173,7 @@ export class Numbers {
|
|
|
172
173
|
* @param {Object} params - The parameters for purchasing phone numbers
|
|
173
174
|
* @param {string[]} params.phoneNumbers - The list of phone numbers to purchase
|
|
174
175
|
* @param {string} params.subgroupId - The ID of the subgroup to assign the purchased phone numbers to
|
|
175
|
-
* @param {
|
|
176
|
+
* @param {string} [params.country='US'] - ISO-2 purchase country; US.
|
|
176
177
|
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
177
178
|
* @throws {Error} Throws an error if the phoneNumbers or subgroupId parameter is missing
|
|
178
179
|
* @returns {Promise<SdkResponse<any>>} A promise that resolves to `{ message }` once the request is queued.
|
|
@@ -193,7 +194,7 @@ export class Numbers {
|
|
|
193
194
|
* @param {Object} params - The parameters for purchasing toll-free numbers
|
|
194
195
|
* @param {number} params.quantity - The number of toll-free numbers to purchase (1-10)
|
|
195
196
|
* @param {string} params.subgroupId - The subgroup the purchased numbers are assigned to
|
|
196
|
-
* @param {
|
|
197
|
+
* @param {string} [params.country='US'] - ISO-2 purchase country; US.
|
|
197
198
|
* @param {RequestOptions} [params.options] - Additional options for the request
|
|
198
199
|
* @throws {Error} Throws an error if the quantity or subgroupId parameter is missing
|
|
199
200
|
* @returns {Promise<SdkResponse<any>>} A promise that resolves to `{ message, orderId }` once the request is queued.
|