@messagebird/sdk 0.37.3 → 0.38.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1654,6 +1654,112 @@ const updateContact = (options) => (options.client ?? client).patch({
1654
1654
  }
1655
1655
  });
1656
1656
  /**
1657
+ * List a contact's preferences
1658
+ *
1659
+ * Returns the preferences on record for the contact's current handles: rows keyed to their email address on the email channel, and to their phone number on SMS and WhatsApp. A contact with no handles, or with no statements on record, returns an empty page.
1660
+ *
1661
+ * Rows are keyed by handle, not by contact: changing a contact's email address or phone number changes which rows this returns, and the old handle's rows remain in force for anything still sent to it.
1662
+ *
1663
+ */
1664
+ const listContactPreferences = (options) => (options.client ?? client).get({
1665
+ security: [{
1666
+ scheme: "bearer",
1667
+ type: "http"
1668
+ }, {
1669
+ in: "cookie",
1670
+ name: "bird_session",
1671
+ type: "apiKey"
1672
+ }],
1673
+ url: "/v1/contacts/{contact_id}/preferences",
1674
+ ...options
1675
+ });
1676
+ /**
1677
+ * List preferences
1678
+ *
1679
+ * Returns the workspace's recorded preferences, most recently created first. Pass `channel` to narrow to one channel, and `handle` with it to look up everything on record for one address or number.
1680
+ *
1681
+ * Each row is a key's current statement. A person can hold several rows on one channel (a channel-wide opt-out next to sender-scoped ones), and the most restrictive statement is what decides whether a message goes out.
1682
+ *
1683
+ */
1684
+ const listPreferences = (options) => (options?.client ?? client).get({
1685
+ security: [{
1686
+ scheme: "bearer",
1687
+ type: "http"
1688
+ }, {
1689
+ in: "cookie",
1690
+ name: "bird_session",
1691
+ type: "apiKey"
1692
+ }],
1693
+ url: "/v1/preferences",
1694
+ ...options
1695
+ });
1696
+ /**
1697
+ * Record a preference
1698
+ *
1699
+ * Records one statement, a grant or an opt-out, for a handle on one channel. Writing is an upsert: the key is the channel, handle, and optional sender scope, and a new statement replaces the key's current one.
1700
+ *
1701
+ * Statements are ordered by when they were made, not when they arrive. A statement older than the key's current one is refused and returned with `applied: false` alongside the statement that survived; refusals are recorded on the key's history. Granting over a stored opt-out needs `consented_at` later than the opt-out, and a person's own opt-out (an unsubscribe, a stop keyword) cannot be overridden by a grant asserted on their behalf.
1702
+ *
1703
+ * A `201` means this key had no record and one was created; a `200` returns the key's surviving record, whether this statement replaced it, repeated it, or was refused.
1704
+ *
1705
+ */
1706
+ const createPreference = (options) => (options.client ?? client).post({
1707
+ security: [{
1708
+ scheme: "bearer",
1709
+ type: "http"
1710
+ }, {
1711
+ in: "cookie",
1712
+ name: "bird_session",
1713
+ type: "apiKey"
1714
+ }],
1715
+ url: "/v1/preferences",
1716
+ ...options,
1717
+ headers: {
1718
+ "Content-Type": "application/json",
1719
+ ...options.headers
1720
+ }
1721
+ });
1722
+ /**
1723
+ * Delete a preference
1724
+ *
1725
+ * Deletes a preference, returning its key to having no record, as if nothing had ever been stated. The deletion itself is kept on the key's history, so a later statement is still ordered against what was deleted.
1726
+ *
1727
+ * **A statement the person made themselves cannot be deleted.** An unsubscribe or a stop keyword is their statement to reverse: it ends when they opt back in, and attempts to delete it return `422`. To restore messaging with the person's consent, record a `granted` statement with `consented_at` evidence instead; that records the change of mind rather than erasing the opt-out.
1728
+ *
1729
+ * A delete is ordered like any statement, using the time it is received: if the record carries a statement made after that moment, the delete is refused and returned with `applied: false` alongside the surviving record. An ID that does not exist in the workspace returns `404`.
1730
+ *
1731
+ */
1732
+ const deletePreference = (options) => (options.client ?? client).delete({
1733
+ security: [{
1734
+ scheme: "bearer",
1735
+ type: "http"
1736
+ }, {
1737
+ in: "cookie",
1738
+ name: "bird_session",
1739
+ type: "apiKey"
1740
+ }],
1741
+ url: "/v1/preferences/{preference_id}",
1742
+ ...options
1743
+ });
1744
+ /**
1745
+ * Get a preference
1746
+ *
1747
+ * Returns one preference: the key it is about, the current statement on it, and the statement's provenance. An ID that does not exist in the workspace returns `404`, including after a delete, which removes the record its ID pointed at.
1748
+ *
1749
+ */
1750
+ const getPreference = (options) => (options.client ?? client).get({
1751
+ security: [{
1752
+ scheme: "bearer",
1753
+ type: "http"
1754
+ }, {
1755
+ in: "cookie",
1756
+ name: "bird_session",
1757
+ type: "apiKey"
1758
+ }],
1759
+ url: "/v1/preferences/{preference_id}",
1760
+ ...options
1761
+ });
1762
+ /**
1657
1763
  * List contact properties
1658
1764
  *
1659
1765
  * Returns a paginated list of the workspace's contact properties, newest first. Archived properties are included; check each entry's `archived` flag.
@@ -2845,9 +2951,13 @@ const listWhatsAppMessages = (options) => (options?.client ?? client).get({
2845
2951
  *
2846
2952
  * **Free-form content** is deliverable only inside an open 24-hour customer
2847
2953
  * service window, which the contact opens by messaging or calling you and
2848
- * resets each time they do it again. We do not track the window, so a send
2849
- * outside one is accepted and then fails, carrying `service_window_expired` on
2850
- * the message's `last_error`. Every free-form send requires `from`.
2954
+ * resets each time they do it again. Bird tracks that window, so a send into a
2955
+ * closed one is refused with a `422` `WhatsAppServiceWindowClosed` before
2956
+ * anything is created or charged;
2957
+ * send a template instead, which reopens the window once the contact replies.
2958
+ * A window that closes between accept and dispatch still fails
2959
+ * asynchronously, carrying `service_window_expired` on the message's
2960
+ * `last_error`. Every free-form send requires `from`.
2851
2961
  *
2852
2962
  * The `202` response is the accepted message, echoing the resolved content; it
2853
2963
  * is not a delivery confirmation. Follow delivery with
@@ -2862,6 +2972,8 @@ const listWhatsAppMessages = (options) => (options?.client ?? client).get({
2862
2972
  * - Parameter values that do not match the template's declared placeholders.
2863
2973
  * - A `from` this workspace cannot send from.
2864
2974
  * - A recipient that is neither a valid phone number nor a business-scoped user ID.
2975
+ * - Free-form content sent into a closed customer service window
2976
+ * (`WhatsAppServiceWindowClosed`).
2865
2977
  *
2866
2978
  * A send from a workspace with no wallet balance fails with a `402`.
2867
2979
  *
@@ -5417,7 +5529,7 @@ var ContactPropertiesResource = class extends Resource {
5417
5529
  };
5418
5530
  //#endregion
5419
5531
  //#region src/resources/contacts.gen.ts
5420
- var ContactsResource = class extends Resource {
5532
+ var ContactsResourceBase = class extends Resource {
5421
5533
  /**
5422
5534
  * List the workspace's contacts as a cursor page, newest first. Look one up by exact email, phone_number, or external_id, repeating phone_number to resolve up to 50 numbers in one call (raise limit to match), or search by email, name, or phone substring. Pass include_total for a total count.
5423
5535
  *
@@ -5524,6 +5636,138 @@ var ContactsResource = class extends Resource {
5524
5636
  }
5525
5637
  };
5526
5638
  //#endregion
5639
+ //#region src/resources/contactsPreferences.gen.ts
5640
+ var ContactsPreferencesResource = class extends Resource {
5641
+ /**
5642
+ * List the recorded messaging preferences for a contact's own handles (their email address and phone number) across every channel, as a cursor page.
5643
+ *
5644
+ * @example List a contact's own preferences
5645
+ * for await (const preference of bird.contacts.preferences.list(
5646
+ * "con_01krdgeqcxet5s7t44vh8rt9mg",
5647
+ * )) {
5648
+ * console.log(preference.channel, preference.status);
5649
+ * }
5650
+ */
5651
+ list(contactId, query, options) {
5652
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listContactPreferences({
5653
+ client: this.client,
5654
+ path: { contact_id: contactId },
5655
+ query: {
5656
+ ...query,
5657
+ starting_after: cursor ?? query?.starting_after
5658
+ },
5659
+ headers,
5660
+ signal
5661
+ }));
5662
+ }
5663
+ };
5664
+ //#endregion
5665
+ //#region src/resources/contacts.ts
5666
+ var ContactsResource = class extends ContactsResourceBase {
5667
+ /** A contact's own preferences across every channel — `bird.contacts.preferences.list(contactId)`. */
5668
+ preferences;
5669
+ constructor(core, client) {
5670
+ super(core, client);
5671
+ this.preferences = new ContactsPreferencesResource(core, client);
5672
+ }
5673
+ };
5674
+ //#endregion
5675
+ //#region src/resources/preferences.gen.ts
5676
+ var PreferencesResourceBase = class extends Resource {
5677
+ /**
5678
+ * List the workspace's stated messaging preferences (consent grants and opt-outs) as a cursor page. Filter by channel, and by handle within a channel, to look up one person before messaging them.
5679
+ *
5680
+ * @example List stated preferences for a channel
5681
+ * for await (const preference of bird.preferences.list({ channel: "sms" })) {
5682
+ * console.log(preference.handle, preference.status);
5683
+ * }
5684
+ */
5685
+ list(query, options) {
5686
+ return this.paginated("GET", options, ({ signal, headers }, cursor) => listPreferences({
5687
+ client: this.client,
5688
+ query: {
5689
+ ...query,
5690
+ starting_after: cursor ?? query?.starting_after
5691
+ },
5692
+ headers,
5693
+ signal
5694
+ }));
5695
+ }
5696
+ /**
5697
+ * Read one recorded preference by ID: the channel and handle it is about, whether it grants or revokes, how much traffic it covers, and where the statement came from.
5698
+ *
5699
+ * @example Read one preference
5700
+ * const preference = await bird.preferences.get(
5701
+ * "prf_01krdgeqcxet5s7t44vh8rt9mg",
5702
+ * );
5703
+ * console.log(preference.status, preference.coverage);
5704
+ */
5705
+ get(preferenceId, options) {
5706
+ return this.call("GET", options, ({ signal, headers }) => getPreference({
5707
+ client: this.client,
5708
+ path: { preference_id: preferenceId },
5709
+ headers,
5710
+ signal
5711
+ }));
5712
+ }
5713
+ };
5714
+ //#endregion
5715
+ //#region src/resources/preferences.ts
5716
+ var PreferencesResource = class extends PreferencesResourceBase {
5717
+ /**
5718
+ * Record one preference statement — a grant or an opt-out — for a handle on
5719
+ * one channel. Writing is an upsert by key (channel, handle, and optional
5720
+ * sender scope): statements are causally ordered, so one dated older than
5721
+ * the key's current statement is refused and returned with `applied:
5722
+ * false` rather than applied out of order. A `201` (the key had no record)
5723
+ * and a `200` (the key already had one) return the same shape either way.
5724
+ *
5725
+ * @example Record a stated opt-out
5726
+ * const result = await bird.preferences.create({
5727
+ * channel: "sms",
5728
+ * handle: "+15550001234",
5729
+ * status: "revoked",
5730
+ * });
5731
+ * console.log(result.applied, result.preference?.id);
5732
+ */
5733
+ create(params, options) {
5734
+ const { consented_at, ...rest } = params;
5735
+ const body = consented_at === void 0 ? rest : {
5736
+ ...rest,
5737
+ consented_at: consented_at instanceof Date ? consented_at.toISOString() : consented_at
5738
+ };
5739
+ return this.call("POST", options, ({ signal, headers }) => createPreference({
5740
+ client: this.client,
5741
+ body,
5742
+ headers,
5743
+ signal
5744
+ }));
5745
+ }
5746
+ /**
5747
+ * Delete a preference, returning its key to having no record. Never void:
5748
+ * the delete is ordered like any statement, so a `200` with `applied:
5749
+ * false` means a newer statement survived and is returned in `preference`
5750
+ * rather than deleted. A statement the person made themselves — an
5751
+ * unsubscribe link, a stop keyword — cannot be deleted this way; record a
5752
+ * `granted` statement with `consented_at` evidence to restore messaging
5753
+ * instead.
5754
+ *
5755
+ * @example Delete a preference
5756
+ * const result = await bird.preferences.delete("prf_01krdgeqcxet5s7t44vh8rt9mg");
5757
+ * if (!result.applied) {
5758
+ * console.log("refused — a newer statement survived:", result.preference?.status);
5759
+ * }
5760
+ */
5761
+ delete(preferenceId, options) {
5762
+ return this.call("DELETE", options, ({ signal, headers }) => deletePreference({
5763
+ client: this.client,
5764
+ path: { preference_id: preferenceId },
5765
+ headers,
5766
+ signal
5767
+ }));
5768
+ }
5769
+ };
5770
+ //#endregion
5527
5771
  //#region src/resources/sms.gen.ts
5528
5772
  var SmsResourceBase = class extends Resource {
5529
5773
  /**
@@ -7111,6 +7355,8 @@ var BirdClient = class {
7111
7355
  verify;
7112
7356
  /** Contacts: `bird.contacts.create(...)`, `.list(...)`, `.get(...)`, `.batch(...)`, … */
7113
7357
  contacts;
7358
+ /** Preferences: `bird.preferences.list(...)`, `.get(...)`, `.create(...)`, `.delete(...)`. */
7359
+ preferences;
7114
7360
  /** Audiences: `bird.audiences.create(...)`, `.list(...)`, `.addContacts(...)`, … */
7115
7361
  audiences;
7116
7362
  /** Contact properties: `bird.contactProperties.create(...)`, `.list(...)`, `.archive(...)`, … */
@@ -7132,9 +7378,9 @@ var BirdClient = class {
7132
7378
  this.#headers = {
7133
7379
  ...opts.defaultHeaders,
7134
7380
  Authorization: `Bearer ${opts.apiKey}`,
7135
- "User-Agent": `bird-sdk-js/0.37.3`,
7381
+ "User-Agent": `bird-sdk-js/0.38.1`,
7136
7382
  "Bird-Surface": "sdk-js",
7137
- "Bird-Version": "0.37.3"
7383
+ "Bird-Version": "0.38.1"
7138
7384
  };
7139
7385
  const caller = detectCaller();
7140
7386
  if (caller) this.#headers["Bird-Caller"] = caller;
@@ -7168,6 +7414,7 @@ var BirdClient = class {
7168
7414
  this.voice = new VoiceResource(this.core, this.#client);
7169
7415
  this.verify = new VerifyResource(this.core, this.#client);
7170
7416
  this.contacts = new ContactsResource(this.core, this.#client);
7417
+ this.preferences = new PreferencesResource(this.core, this.#client);
7171
7418
  this.audiences = new AudiencesResource(this.core, this.#client);
7172
7419
  this.contactProperties = new ContactPropertiesResource(this.core, this.#client);
7173
7420
  this.domains = new DomainsResource(this.core, this.#client);
@@ -7258,6 +7505,9 @@ const WebhookEventType = {
7258
7505
  EmailScheduled: "email.scheduled",
7259
7506
  EmailSuppressionCreated: "email_suppression.created",
7260
7507
  EmailUnsubscribed: "email.unsubscribed",
7508
+ PreferenceDeleted: "preference.deleted",
7509
+ PreferenceGranted: "preference.granted",
7510
+ PreferenceRevoked: "preference.revoked",
7261
7511
  SmsAccepted: "sms.accepted",
7262
7512
  SmsDelivered: "sms.delivered",
7263
7513
  SmsExpired: "sms.expired",
@@ -7282,7 +7532,8 @@ const WebhookEventType = {
7282
7532
  WhatsappRead: "whatsapp.read",
7283
7533
  WhatsappReceived: "whatsapp.received",
7284
7534
  WhatsappRejected: "whatsapp.rejected",
7285
- WhatsappSent: "whatsapp.sent"
7535
+ WhatsappSent: "whatsapp.sent",
7536
+ WhatsappSuppressionCreated: "whatsapp_suppression.created"
7286
7537
  };
7287
7538
  //#endregion
7288
7539
  //#region src/open-enums.gen.ts
@@ -7391,6 +7642,30 @@ const NumbersOrderStatus = {
7391
7642
  Pending: "pending"
7392
7643
  };
7393
7644
  /**
7645
+ * Values of PreferenceChannel known at this SDK version. The wire value is an open
7646
+ * string: a value added by a newer server deserializes unchanged, so switch on
7647
+ * these with a `default` branch rather than treating the set as closed.
7648
+ */
7649
+ const PreferenceChannel = {
7650
+ Email: "email",
7651
+ Sms: "sms",
7652
+ Whatsapp: "whatsapp"
7653
+ };
7654
+ /**
7655
+ * Values of PreferenceOrigin known at this SDK version. The wire value is an open
7656
+ * string: a value added by a newer server deserializes unchanged, so switch on
7657
+ * these with a `default` branch rather than treating the set as closed.
7658
+ */
7659
+ const PreferenceOrigin = {
7660
+ ApiKey: "api_key",
7661
+ Import: "import",
7662
+ Keyword: "keyword",
7663
+ PreferencePage: "preference_page",
7664
+ UnsubscribeEvent: "unsubscribe_event",
7665
+ UnsubscribeLink: "unsubscribe_link",
7666
+ User: "user"
7667
+ };
7668
+ /**
7394
7669
  * Values of SMSErrorCode known at this SDK version. The wire value is an open
7395
7670
  * string: a value added by a newer server deserializes unchanged, so switch on
7396
7671
  * these with a `default` branch rather than treating the set as closed.
@@ -7573,6 +7848,6 @@ const WhatsAppTemplateParameterType = {
7573
7848
  Video: "video"
7574
7849
  };
7575
7850
  //#endregion
7576
- export { BirdAPIError, BirdAuthError, BirdBadRequestError, BirdBillingError, BirdClient, BirdConflictError, BirdConnectionError, BirdError, BirdInternalError, BirdMisdirectedError, BirdNotFoundError, BirdNotImplementedError, BirdPayloadTooLargeError, BirdPermissionError, BirdPreconditionError, BirdRateLimitError, BirdServiceUnavailableError, BirdTimeoutError, BirdValidationError, BirdWebhookVerificationError, EmailEventType, EmailLookupFlag, EmailLookupReason, EmailLookupResult, LookupFlag, LookupPropertyStatus, NumberCapability, NumberType, NumbersOrderStatus, SMSErrorCode, SMSKeywordOperation, SMSSuppressionCoverage, SMSSuppressionEndReason, SMSSuppressionOrigin, SMSSuppressionReason, TemplateLanguageStatus, TemplateStatus, VerificationAttemptFailureReason, VerificationChannel, VerificationTerminalReason, WebhookEventType, WhatsAppErrorCode, WhatsAppEventType, WhatsAppTemplateCategory, WhatsAppTemplateParameterType, baseUrlForRegion, regionFromApiKey };
7851
+ export { BirdAPIError, BirdAuthError, BirdBadRequestError, BirdBillingError, BirdClient, BirdConflictError, BirdConnectionError, BirdError, BirdInternalError, BirdMisdirectedError, BirdNotFoundError, BirdNotImplementedError, BirdPayloadTooLargeError, BirdPermissionError, BirdPreconditionError, BirdRateLimitError, BirdServiceUnavailableError, BirdTimeoutError, BirdValidationError, BirdWebhookVerificationError, EmailEventType, EmailLookupFlag, EmailLookupReason, EmailLookupResult, LookupFlag, LookupPropertyStatus, NumberCapability, NumberType, NumbersOrderStatus, PreferenceChannel, PreferenceOrigin, SMSErrorCode, SMSKeywordOperation, SMSSuppressionCoverage, SMSSuppressionEndReason, SMSSuppressionOrigin, SMSSuppressionReason, TemplateLanguageStatus, TemplateStatus, VerificationAttemptFailureReason, VerificationChannel, VerificationTerminalReason, WebhookEventType, WhatsAppErrorCode, WhatsAppEventType, WhatsAppTemplateCategory, WhatsAppTemplateParameterType, baseUrlForRegion, regionFromApiKey };
7577
7852
 
7578
7853
  //# sourceMappingURL=index.mjs.map