@whooshbang/sdk 4.0.1 → 4.2.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.
Files changed (47) hide show
  1. package/README.md +43 -2
  2. package/dist/client.d.ts +18 -5
  3. package/dist/client.js +111 -1
  4. package/dist/client.js.map +1 -1
  5. package/dist/recipient/element.js +160 -7
  6. package/dist/recipient/element.js.map +1 -1
  7. package/dist/recipient/hosted-entry.d.ts +5 -0
  8. package/dist/recipient/hosted-entry.js +89 -0
  9. package/dist/recipient/hosted-entry.js.map +1 -0
  10. package/dist/recipient/i18n/ar.js +6 -0
  11. package/dist/recipient/i18n/ar.js.map +1 -1
  12. package/dist/recipient/i18n/catalog.d.ts +6 -0
  13. package/dist/recipient/i18n/catalog.js.map +1 -1
  14. package/dist/recipient/i18n/de.js +6 -0
  15. package/dist/recipient/i18n/de.js.map +1 -1
  16. package/dist/recipient/i18n/en.js +6 -0
  17. package/dist/recipient/i18n/en.js.map +1 -1
  18. package/dist/recipient/i18n/es.js +6 -0
  19. package/dist/recipient/i18n/es.js.map +1 -1
  20. package/dist/recipient/i18n/fa.js +6 -0
  21. package/dist/recipient/i18n/fa.js.map +1 -1
  22. package/dist/recipient/i18n/fr.js +6 -0
  23. package/dist/recipient/i18n/fr.js.map +1 -1
  24. package/dist/recipient/i18n/hi.js +6 -0
  25. package/dist/recipient/i18n/hi.js.map +1 -1
  26. package/dist/recipient/i18n/id.js +6 -0
  27. package/dist/recipient/i18n/id.js.map +1 -1
  28. package/dist/recipient/i18n/it.js +6 -0
  29. package/dist/recipient/i18n/it.js.map +1 -1
  30. package/dist/recipient/i18n/nl.js +6 -0
  31. package/dist/recipient/i18n/nl.js.map +1 -1
  32. package/dist/recipient/i18n/pl.js +6 -0
  33. package/dist/recipient/i18n/pl.js.map +1 -1
  34. package/dist/recipient/i18n/pt-BR.js +6 -0
  35. package/dist/recipient/i18n/pt-BR.js.map +1 -1
  36. package/dist/recipient/i18n/ru.js +6 -0
  37. package/dist/recipient/i18n/ru.js.map +1 -1
  38. package/dist/recipient/i18n/tr.js +6 -0
  39. package/dist/recipient/i18n/tr.js.map +1 -1
  40. package/dist/recipient/i18n/uk.js +6 -0
  41. package/dist/recipient/i18n/uk.js.map +1 -1
  42. package/dist/recipient/i18n/zh-Hans.js +6 -0
  43. package/dist/recipient/i18n/zh-Hans.js.map +1 -1
  44. package/dist/recipient/view.d.ts +9 -0
  45. package/dist/recipient/view.js +2 -0
  46. package/dist/recipient/view.js.map +1 -1
  47. package/package.json +2 -2
package/README.md CHANGED
@@ -144,8 +144,11 @@ state, or the link's Problem Details, and never claims provider-side deletion.
144
144
 
145
145
  ## Awaiting an answer
146
146
 
147
- `awaitInteraction` repeats the polling until the person answers or the
148
- question ends. Set `patienceMs` to stop waiting sooner:
147
+ Use your configured customer-events webhook to receive answers without keeping
148
+ your app waiting. For a short interactive wait, testing, or a client without a
149
+ webhook receiver, `awaitInteraction` repeats polls until the person answers or
150
+ the question ends. Each poll waits up to 30 seconds, which is also the default.
151
+ Set `patienceMs` to stop the overall wait sooner:
149
152
 
150
153
  ```ts
151
154
  const read = await whooshBang.awaitInteraction(interactionId, {
@@ -202,6 +205,12 @@ same outcomes `createMessage` returns, carrying `problem` and nothing else,
202
205
  because no message exists. A request without an interaction is refused locally
203
206
  before anything is sent.
204
207
 
208
+ While a request waits, it holds one of 1,000 slots shared by all customers.
209
+ If none is available, the API returns `429` with the detail "No long-poll slot
210
+ is available for this request." `awaitInteraction` waits until `retry_at`, then
211
+ retries. For an immediate read, use `getInteraction(id, { wait: 0 })`. It doesn't
212
+ hold a slot.
213
+
205
214
  **The wait retries its reads; the send is never retried.** A read has no side
206
215
  effect, so a failed read is re-issued: a transport failure, a `5xx` or `429`
207
216
  that arrived without a Problem body (the edge in front of the service during a
@@ -362,6 +371,34 @@ authorize now. Read and write project recipient configuration using
362
371
  `projects:read` and `projects:write`; a project credential can configure only
363
372
  its own project.
364
373
 
374
+ To open the same settings on WhooshBang's hosted page, first create a recipient
375
+ session on your backend and return its `CreateRecipientSessionResponse` to your
376
+ app. The hosted page asks the opener for that response. Send it only after
377
+ checking the ready message's window and origin:
378
+
379
+ ```js
380
+ const hostedOrigin = new URL(session.hosted_url).origin;
381
+ let popup = null;
382
+ function onReady(event) {
383
+ if (
384
+ event.source !== popup ||
385
+ event.origin !== hostedOrigin ||
386
+ event.data?.type !== "whooshbang.recipient-settings.ready"
387
+ ) return;
388
+ window.removeEventListener("message", onReady);
389
+ popup.postMessage(
390
+ { type: "whooshbang.recipient-settings.session", session },
391
+ hostedOrigin,
392
+ );
393
+ }
394
+ window.addEventListener("message", onReady);
395
+ popup = window.open(session.hosted_url, "_blank");
396
+ if (!popup) window.removeEventListener("message", onReady);
397
+ ```
398
+
399
+ The capability stays in the message, not the address or page markup. The hosted
400
+ page uses the same category switches and channel controls as the embedded panel.
401
+
365
402
  ## Machine clients
366
403
 
367
404
  `createMachineCredential` generates the C0-03 secret with Web Crypto and
@@ -456,6 +493,10 @@ credit. These ceilings do not schedule an automatic SDK retry.
456
493
  | `subscriber_unbound` | Outcome | On a send, the person's channel state: they revoked their channel or never finished subscribing, so the branch is to invite them again. It is also the answer when a send names a `connection_id` and the subscriber has no connected channel at all. `createMessage` and `createMessageInEnvironment` return it. `createMachineClient` still throws it: a machine client for an unbound subscriber is setup that is wrong. |
457
494
  | `subscriber_not_connected` | Exception | A send or a connection test named a connection the subscriber has not connected through, while they are connected through another. `problem.subscriber_id` and `problem.channel` say who and where; nothing was sent. Naming the connection was the caller's choice: omit `connection_id` to let the service choose one of their channels, pick a connection they connected through, or invite them through this one. |
458
495
  | `not_consented_for_marketing` | Exception | A `marketing` send or broadcast reached an email recipient enrolled only on a service basis. Nothing was sent to that recipient and nothing was charged. Send it as `service`, or obtain marketing consent first. |
496
+ | `category_not_found` | Exception | The named category is not active in this project. Check its key before sending. |
497
+ | `category_purpose_mismatch` | Exception | The stated purpose disagrees with the category's purpose. Nothing was sent or charged. |
498
+ | `category_turned_off` | Exception | The subscriber switched this category off. Nothing was sent or charged. |
499
+ | `category_conflict` | Exception | A category key is taken, the category is in use, or its settings prevent the requested change. |
459
500
  | `recipient_configuration_invalid` | Exception | The owner's recipient-experience configuration is not usable as submitted or as stored. |
460
501
  | `recipient_origin_forbidden` | Exception | The presenting browser origin is not registered for the session. |
461
502
  | `return_destination_not_found` | Exception | The return-destination key is not configured. |
package/dist/client.d.ts CHANGED
@@ -2,7 +2,7 @@ import { type WhoAmI, type OperatorCollection, type OperatorResolution, type Cre
2
2
  import type { BillingProjectSlots, BillingPromotions, BillingPromotion, RedeemBillingPromotionRequest, AssignBillingProjectSlotsRequest, SubscriptionChange, ConfirmSubscriptionChangeRequest, BillingEntitlements, SubscriptionSelection, ProjectAttribution, UpdateProjectAttributionRequest, AutoTopUpSettings, UpdateAutoTopUpSettingsRequest, BillingAccount, CardSetup, CreateCreditPurchaseRequest, CreditPurchase, BillingInvoiceCollection, UpdateBillingReceiptEmailRequest } from "@whooshbang/contracts";
3
3
  import { type AssertEmailConsentRequest, type BindingSummary } from "@whooshbang/contracts";
4
4
  import type { InteractionOutcome } from "./interactions.js";
5
- import type { OrganizationProjection, ApiCredential, OrganizationCredential, OrganizationCredentialCollection, OrganizationCredentialRotation, OrganizationCredentialSecretReveal, ApiCredentialCollection, ApiCredentialRotation, ApiCredentialSecretReveal, AttachNotifierConnectionRequest, ChannelConnection, ChannelConnectionCollection, ConnectionProviderCollection, UsageGrouping, UsageReport, MessageState, MessageListPage, MessageDeliveryHistory, MessageNotificationImage, InteractionTimeline, UpdateEmailSenderRequest, CustomerEventDeliveryHistory, CustomerEventDeliveryAttempt, DeliveryHolds, MachineClientOperationsList, RecipientCopyCatalogue, NotifierConnectionCollection, ProjectRecipientExperience, RecipientBrandLogoUpload, NotificationImageAsset, UpdateProjectRecipientExperienceRequest, EnvironmentRecipientExperience, UpdateEnvironmentRecipientExperienceRequest, SubscriberChannelSettings, AcknowledgeEmailRemediationRequest, CreateRecipientSessionRequest, CreateRecipientSessionResponse, RecipientSession, RecipientSessionCapability, CreateProviderHandoffRequest, ProviderHandoff, SetPreferredBindingRequest, PreferredBinding, CreateSubscriberRequest, Subscriber, SubscriberDataExport, UpdateSubscriberRequest, SubscriberCollection, CloseOrganizationRequest, InviteTeammateRequest, Teammate, TeammateAccessRequest, TeammateCollection, OrganizationClosureResult, CreateSubscriberGroupRequest, UpdateSubscriberGroupRequest, SubscriberGroup, SubscriberGroupCollection, SubscriberGroupMembership, SubscriberGroupMembershipCollection, CreateGroupBroadcastRequest, GroupBroadcast, CreateOrganizationCredentialRequest, CreateApiCredentialRequest, CreateChannelConnectionRequest, CreateCustomerEndpointRequest, CreateMachineClientRequest, CreateMessageRequest, CreateProjectRequest, UpdateProjectRequest, CreateSubscriptionLinkRequest, CustomerEndpoint, CustomerEndpointAttemptCollection, CustomerEndpointCollection, CustomerEndpointMutationResult, InteractionSummary, MachineClient, MachineCredential, MachineEventAckRequest, MachineEventAckResponse, MachineEventPollResponse, Message, Problem, Project, ProjectCollection, RecipientCopyKey, RecipientCopyOverride, RecipientCopyOverrideCollection, RecipientLanguage, ProviderCapabilitiesCollection, ProviderInstallation, ProviderInstallationCollection, EmailDomain, EmailDomainCollection, CreateEmailDomainRequest, RegisterMachineCredentialRequest, RotateOrganizationCredentialRequest, RotateApiCredentialRequest, ConnectionTest, ConnectionTestCollection, CreateConnectionTestRequest, CustomerApplicationManifest, RotateChannelConnectionCredentialRequest, RotateCustomerEndpointRequest, SubscriptionLink, UpdateChannelConnectionRequest, UpdateRecipientCopyOverrideRequest } from "@whooshbang/contracts";
5
+ import type { OrganizationProjection, ApiCredential, OrganizationCredential, OrganizationCredentialCollection, OrganizationCredentialRotation, OrganizationCredentialSecretReveal, ApiCredentialCollection, ApiCredentialRotation, ApiCredentialSecretReveal, AttachNotifierConnectionRequest, ChannelConnection, ChannelConnectionCollection, ConnectionProviderCollection, UsageGrouping, UsageReport, MessageState, MessageListPage, MessageDeliveryHistory, MessageNotificationImage, InteractionTimeline, UpdateEmailSenderRequest, CustomerEventDeliveryHistory, CustomerEventDeliveryAttempt, DeliveryHolds, MachineClientOperationsList, RecipientCopyCatalogue, NotifierConnectionCollection, ProjectRecipientExperience, RecipientBrandLogoUpload, NotificationImageAsset, UpdateProjectRecipientExperienceRequest, EnvironmentRecipientExperience, UpdateEnvironmentRecipientExperienceRequest, SubscriberChannelSettings, AcknowledgeEmailRemediationRequest, CreateRecipientSessionRequest, CreateRecipientSessionResponse, RecipientSession, RecipientSessionCapability, CreateProviderHandoffRequest, ProviderHandoff, SetPreferredBindingRequest, PreferredBinding, CreateSubscriberRequest, Subscriber, SubscriberDataExport, UpdateSubscriberRequest, SubscriberCollection, CloseOrganizationRequest, InviteTeammateRequest, Teammate, TeammateAccessRequest, TeammateCollection, OrganizationClosureResult, CreateSubscriberGroupRequest, UpdateSubscriberGroupRequest, SubscriberGroup, SubscriberGroupCollection, SubscriberGroupMembership, SubscriberGroupMembershipCollection, CreateGroupBroadcastRequest, GroupBroadcast, CreateOrganizationCredentialRequest, CreateApiCredentialRequest, CreateChannelConnectionRequest, CreateCustomerEndpointRequest, CreateMachineClientRequest, CreateMessageRequest, MessageCategory, MessageCategoryCollection, CreateMessageCategoryRequest, UpdateMessageCategoryRequest, SubscriberCategoryPreference, SubscriberCategoryPreferenceCollection, CreateProjectRequest, UpdateProjectRequest, CreateSubscriptionLinkRequest, CustomerEndpoint, CustomerEndpointAttemptCollection, CustomerEndpointCollection, CustomerEndpointMutationResult, InteractionSummary, MachineClient, MachineCredential, MachineEventAckRequest, MachineEventAckResponse, MachineEventPollResponse, Message, Problem, Project, ProjectCollection, RecipientCopyKey, RecipientCopyOverride, RecipientCopyOverrideCollection, RecipientLanguage, ProviderCapabilitiesCollection, ProviderInstallation, ProviderInstallationCollection, EmailDomain, EmailDomainCollection, CreateEmailDomainRequest, RegisterMachineCredentialRequest, RotateOrganizationCredentialRequest, RotateApiCredentialRequest, ConnectionTest, ConnectionTestCollection, CreateConnectionTestRequest, CustomerApplicationManifest, RotateChannelConnectionCredentialRequest, RotateCustomerEndpointRequest, SubscriptionLink, UpdateChannelConnectionRequest, UpdateRecipientCopyOverrideRequest } from "@whooshbang/contracts";
6
6
  export type WhooshBangFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
7
7
  /**
8
8
  * The outcome of one SDK invocation, as reported to an optional logging hook.
@@ -48,7 +48,8 @@ export interface SideEffectRequestOptions extends RequestOptions {
48
48
  readonly idempotencyKey?: string | undefined;
49
49
  }
50
50
  /**
51
- * Options for the bounded response-inspection reads.
51
+ * Options for reading a message or interaction, with an optional short wait.
52
+ * Use your configured customer-events webhook to receive answers without polling.
52
53
  *
53
54
  * `wait` is the server-held long poll in whole seconds, 0 through 30. Omitting
54
55
  * it uses the documented server default of 30. A wait that expires is a
@@ -186,7 +187,9 @@ export type MessageCreation = {
186
187
  readonly problem: Problem;
187
188
  };
188
189
  /**
189
- * Options for the composed wait, `awaitInteraction`.
190
+ * Options for `awaitInteraction`, for interactive waits, testing, or clients
191
+ * without a webhook receiver. Use your configured customer-events webhook
192
+ * for answers that can take longer.
190
193
  *
191
194
  * `wait` is one server hold in whole seconds, 0 through 30, defaulting to the
192
195
  * documented 30. `patienceMs` bounds the whole wait, 0 through 86400000: when
@@ -194,8 +197,8 @@ export type MessageCreation = {
194
197
  * interaction can be awaited again. It is deliberately not `timeoutMs`, which
195
198
  * bounds one HTTP call and cannot express a fifteen-minute wait; each read
196
199
  * here derives its own `timeoutMs` from `wait`. Without a patience bound the
197
- * wait ends when the interaction does — one expires server-side within 24
198
- * hours, and `expired` is terminal.
200
+ * wait ends when the interaction does. The answer deadline defaults to 24
201
+ * hours and can be longer.
199
202
  */
200
203
  export interface AwaitInteractionOptions {
201
204
  readonly patienceMs?: number;
@@ -244,6 +247,8 @@ export declare class WhooshBangClient {
244
247
  getOperatorBroadcast(projectId: string, environmentId: string, broadcastId: string, options?: RequestOptions): Promise<OperatorBroadcast>;
245
248
  getOperatorPreferences(projectId: string, environmentId: string, options?: RequestOptions): Promise<OperatorPreferences>;
246
249
  setOperatorPreferredBinding(projectId: string, environmentId: string, request: SetPreferredBindingRequest, options?: RequestOptions): Promise<OperatorPreferences>;
250
+ /** Resumes one of the signed-in person's own paused channels. */
251
+ resumeOperatorBinding(projectId: string, environmentId: string, bindingId: string, options?: RequestOptions): Promise<OperatorPreferences>;
247
252
  connectOperatorChannel(projectId: string, environmentId: string, request: OperatorConnectRequest, options?: SideEffectRequestOptions): Promise<SubscriptionLink>;
248
253
  constructor(options: WhooshBangClientOptions);
249
254
  getOrganization(options?: RequestOptions): Promise<OrganizationProjection>;
@@ -307,6 +312,12 @@ export declare class WhooshBangClient {
307
312
  uploadRecipientBrandLogo(projectId: string, logo: Blob | Uint8Array, rowVersion: number, options?: RequestOptions): Promise<RecipientBrandLogoUpload>;
308
313
  uploadNotificationImageAsset(projectId: string, environmentId: string, image: Blob | Uint8Array, options?: SideEffectRequestOptions): Promise<NotificationImageAsset>;
309
314
  deleteNotificationImageAsset(projectId: string, environmentId: string, assetId: string, options?: RequestOptions): Promise<void>;
315
+ listMessageCategories(projectId: string, options?: RequestOptions): Promise<MessageCategoryCollection>;
316
+ createMessageCategory(projectId: string, request: CreateMessageCategoryRequest, options?: RequestOptions): Promise<MessageCategory>;
317
+ updateMessageCategory(projectId: string, key: string, request: UpdateMessageCategoryRequest, options?: RequestOptions): Promise<MessageCategory>;
318
+ deleteMessageCategory(projectId: string, key: string, options?: RequestOptions): Promise<void>;
319
+ getOwnCategoryPreferences(projectId: string, environmentId: string, options?: RequestOptions): Promise<SubscriberCategoryPreferenceCollection>;
320
+ setOwnCategoryPreference(projectId: string, environmentId: string, key: string, enabled: boolean, options?: RequestOptions): Promise<SubscriberCategoryPreference>;
310
321
  getEnvironmentRecipientExperience(projectId: string, environmentId: string, options?: RequestOptions): Promise<EnvironmentRecipientExperience>;
311
322
  updateEnvironmentRecipientExperience(projectId: string, environmentId: string, request: UpdateEnvironmentRecipientExperienceRequest, options?: RequestOptions): Promise<EnvironmentRecipientExperience>;
312
323
  getSubscriberChannelSettings(projectId: string, environmentId: string, subscriberId: string, options?: RequestOptions): Promise<SubscriberChannelSettings>;
@@ -710,6 +721,8 @@ export declare class WhooshBangRecipientSessionClient {
710
721
  #private;
711
722
  constructor(options: WhooshBangRecipientSessionClientOptions);
712
723
  getSession(options?: RequestOptions): Promise<RecipientSession>;
724
+ getCategoryPreferences(options?: RequestOptions): Promise<SubscriberCategoryPreferenceCollection>;
725
+ setCategoryPreference(key: string, enabled: boolean, options?: RequestOptions): Promise<SubscriberCategoryPreference>;
713
726
  getRecipientBrandLogo(assetId: string, options?: RequestOptions): Promise<Blob>;
714
727
  createProviderHandoff(request: CreateProviderHandoffRequest, options?: RequestOptions): Promise<ProviderHandoff>;
715
728
  setPreferredBinding(request: SetPreferredBindingRequest, options?: RequestOptions): Promise<PreferredBinding>;
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { validateWhoAmI, validateOperatorCollection, validateOperatorResolution, validateCreateOperatorMessageRequest, validateOperatorMessageResult, validateOperatorBroadcast, validateOperatorPreferences, validateOperatorConnectRequest, } from "@whooshbang/contracts";
2
2
  import { validateAssertEmailConsentRequest, validateBindingSummary, } from "@whooshbang/contracts";
3
- import { contractValidationErrors, validateOrganizationCredential, validateOrganizationCredentialCollection, validateOrganizationCredentialRotation, validateOrganizationCredentialSecretReveal, validateBillingProjectSlots, validateBillingPromotions, validateBillingPromotion, validateRedeemBillingPromotionRequest, validateAssignBillingProjectSlotsRequest, validateSubscriptionChange, validateConfirmSubscriptionChangeRequest, validateBillingEntitlements, validateSubscriptionSelection, validateProjectAttribution, validateUpdateProjectAttributionRequest, validateAutoTopUpSettings, validateUpdateAutoTopUpSettingsRequest, validateBillingAccount, validateCardSetup, validateCreateCreditPurchaseRequest, validateCreditPurchase, validateBillingInvoiceCollection, validateUpdateBillingReceiptEmailRequest, validateOrganizationProjection, validateApiCredential, validateApiCredentialCollection, validateApiCredentialRotation, validateApiCredentialSecretReveal, validateAttachNotifierConnectionRequest, validateChannelConnection, validateChannelConnectionCollection, validateConnectionProviderCollection, validateUsageReport, validateMessageListPage, validateMessageDeliveryHistory, validateMessageNotificationImage, validateInteractionTimeline, validateUpdateEmailSenderRequest, validateCustomerEventDeliveryHistory, validateCustomerEventDeliveryAttempt, validateDeliveryHolds, validateMachineClientOperationsList, validateRecipientCopyCatalogue, validateNotifierConnectionCollection, validateProjectRecipientExperience, validateRecipientBrandLogoUpload, validateNotificationImageAsset, validateUpdateProjectRecipientExperienceRequest, validateEnvironmentRecipientExperience, validateUpdateEnvironmentRecipientExperienceRequest, validateSubscriberChannelSettings, validateAcknowledgeEmailRemediationRequest, validateCreateRecipientSessionRequest, validateCreateRecipientSessionResponse, validateRecipientSession, validateCreateProviderHandoffRequest, validateProviderHandoff, validateSetPreferredBindingRequest, validatePreferredBinding, validateCreateSubscriberRequest, validateSubscriber, validateSubscriberDataExport, validateUpdateSubscriberRequest, validateSubscriberCollection, validateCloseOrganizationRequest, validateInviteTeammateRequest, validateTeammate, validateTeammateAccessRequest, validateTeammateCollection, validateOrganizationClosureResult, validateCreateSubscriberGroupRequest, validateUpdateSubscriberGroupRequest, validateSubscriberGroup, validateSubscriberGroupCollection, validateSubscriberGroupMembership, validateSubscriberGroupMembershipCollection, validateCreateGroupBroadcastRequest, validateGroupBroadcast, validateCreateOrganizationCredentialRequest, validateCreateApiCredentialRequest, validateCreateChannelConnectionRequest, validateCreateCustomerEndpointRequest, validateCreateMachineClientRequest, validateCreateMessageRequest, validateCreateProjectRequest, validateUpdateProjectRequest, validateCreateSubscriptionLinkRequest, validateCustomerEndpoint, validateCustomerEndpointAttemptCollection, validateCustomerEndpointCollection, validateCustomerEndpointMutationResult, validateInteractionSummary, validateMachineClient, validateMachineCredential, validateMachineEventAckRequest, validateMachineEventAckResponse, validateMachineEventPollResponse, validateMessage, validateProblem, validateProject, validateProjectCollection, validateRecipientCopyOverride, validateRecipientCopyOverrideCollection, validateProviderCapabilitiesCollection, validateProviderInstallationCollection, validateEmailDomainCollection, validateCreateEmailDomainRequest, validateRegisterMachineCredentialRequest, validateRotateOrganizationCredentialRequest, validateRotateApiCredentialRequest, validateConnectionTest, validateConnectionTestCollection, validateCreateConnectionTestRequest, validateCustomerApplicationManifest, validateRotateChannelConnectionCredentialRequest, validateRotateCustomerEndpointRequest, validateSubscriptionLink, validateUpdateChannelConnectionRequest, validateUpdateRecipientCopyOverrideRequest, } from "@whooshbang/contracts";
3
+ import { contractValidationErrors, validateOrganizationCredential, validateOrganizationCredentialCollection, validateOrganizationCredentialRotation, validateOrganizationCredentialSecretReveal, validateBillingProjectSlots, validateBillingPromotions, validateBillingPromotion, validateRedeemBillingPromotionRequest, validateAssignBillingProjectSlotsRequest, validateSubscriptionChange, validateConfirmSubscriptionChangeRequest, validateBillingEntitlements, validateSubscriptionSelection, validateProjectAttribution, validateUpdateProjectAttributionRequest, validateAutoTopUpSettings, validateUpdateAutoTopUpSettingsRequest, validateBillingAccount, validateCardSetup, validateCreateCreditPurchaseRequest, validateCreditPurchase, validateBillingInvoiceCollection, validateUpdateBillingReceiptEmailRequest, validateOrganizationProjection, validateApiCredential, validateApiCredentialCollection, validateApiCredentialRotation, validateApiCredentialSecretReveal, validateAttachNotifierConnectionRequest, validateChannelConnection, validateChannelConnectionCollection, validateConnectionProviderCollection, validateUsageReport, validateMessageListPage, validateMessageDeliveryHistory, validateMessageNotificationImage, validateInteractionTimeline, validateUpdateEmailSenderRequest, validateCustomerEventDeliveryHistory, validateCustomerEventDeliveryAttempt, validateDeliveryHolds, validateMachineClientOperationsList, validateRecipientCopyCatalogue, validateNotifierConnectionCollection, validateProjectRecipientExperience, validateRecipientBrandLogoUpload, validateNotificationImageAsset, validateUpdateProjectRecipientExperienceRequest, validateEnvironmentRecipientExperience, validateUpdateEnvironmentRecipientExperienceRequest, validateSubscriberChannelSettings, validateAcknowledgeEmailRemediationRequest, validateCreateRecipientSessionRequest, validateCreateRecipientSessionResponse, validateRecipientSession, validateCreateProviderHandoffRequest, validateProviderHandoff, validateSetPreferredBindingRequest, validatePreferredBinding, validateCreateSubscriberRequest, validateSubscriber, validateSubscriberDataExport, validateUpdateSubscriberRequest, validateSubscriberCollection, validateCloseOrganizationRequest, validateInviteTeammateRequest, validateTeammate, validateTeammateAccessRequest, validateTeammateCollection, validateOrganizationClosureResult, validateCreateSubscriberGroupRequest, validateUpdateSubscriberGroupRequest, validateSubscriberGroup, validateSubscriberGroupCollection, validateSubscriberGroupMembership, validateSubscriberGroupMembershipCollection, validateCreateGroupBroadcastRequest, validateGroupBroadcast, validateCreateOrganizationCredentialRequest, validateCreateApiCredentialRequest, validateCreateChannelConnectionRequest, validateCreateCustomerEndpointRequest, validateCreateMachineClientRequest, validateCreateMessageRequest, validateMessageCategory, validateMessageCategoryCollection, validateCreateMessageCategoryRequest, validateUpdateMessageCategoryRequest, validateSubscriberCategoryPreference, validateSubscriberCategoryPreferenceCollection, validateSetSubscriberCategoryPreferenceRequest, validateCreateProjectRequest, validateUpdateProjectRequest, validateCreateSubscriptionLinkRequest, validateCustomerEndpoint, validateCustomerEndpointAttemptCollection, validateCustomerEndpointCollection, validateCustomerEndpointMutationResult, validateInteractionSummary, validateMachineClient, validateMachineCredential, validateMachineEventAckRequest, validateMachineEventAckResponse, validateMachineEventPollResponse, validateMessage, validateProblem, validateProject, validateProjectCollection, validateRecipientCopyOverride, validateRecipientCopyOverrideCollection, validateProviderCapabilitiesCollection, validateProviderInstallationCollection, validateEmailDomainCollection, validateCreateEmailDomainRequest, validateRegisterMachineCredentialRequest, validateRotateOrganizationCredentialRequest, validateRotateApiCredentialRequest, validateConnectionTest, validateConnectionTestCollection, validateCreateConnectionTestRequest, validateCustomerApplicationManifest, validateRotateChannelConnectionCredentialRequest, validateRotateCustomerEndpointRequest, validateSubscriptionLink, validateUpdateChannelConnectionRequest, validateUpdateRecipientCopyOverrideRequest, } from "@whooshbang/contracts";
4
4
  import { validateAdditiveCompatible } from "./additive-compatibility.js";
5
5
  import { WhooshBangContractError, WhooshBangOutcomeUnknownError, WhooshBangProblemError, WhooshBangProtocolError, WhooshBangTransportError, validationError, } from "./errors.js";
6
6
  import { interactionAnswer } from "./interactions.js";
@@ -640,6 +640,19 @@ export class WhooshBangClient {
640
640
  body: request,
641
641
  });
642
642
  }
643
+ /** Resumes one of the signed-in person's own paused channels. */
644
+ async resumeOperatorBinding(projectId, environmentId, bindingId, options = {}) {
645
+ const operation = "resumeOperatorBinding";
646
+ return this.#request({
647
+ method: "POST",
648
+ operation,
649
+ options,
650
+ sideEffect: true,
651
+ path: `${environmentRoot(operation, projectId, environmentId)}/notification-preferences/bindings/${pathSegment(operation, bindingId, "bindingId")}/resume`,
652
+ validator: validateOperatorPreferences,
653
+ strictResponse: true,
654
+ });
655
+ }
643
656
  async connectOperatorChannel(projectId, environmentId, request, options = {}) {
644
657
  const operation = "connectOperatorChannel";
645
658
  assertInput(operation, request, validateOperatorConnectRequest);
@@ -1346,6 +1359,79 @@ export class WhooshBangClient {
1346
1359
  sideEffect: true,
1347
1360
  });
1348
1361
  }
1362
+ async listMessageCategories(projectId, options = {}) {
1363
+ const operation = "listMessageCategories";
1364
+ return this.#request({
1365
+ method: "GET",
1366
+ operation,
1367
+ options,
1368
+ path: `v1/projects/${pathSegment(operation, projectId, "projectId")}/message-categories`,
1369
+ sideEffect: false,
1370
+ validator: validateMessageCategoryCollection,
1371
+ });
1372
+ }
1373
+ async createMessageCategory(projectId, request, options = {}) {
1374
+ const operation = "createMessageCategory";
1375
+ assertInput(operation, request, validateCreateMessageCategoryRequest);
1376
+ return this.#request({
1377
+ body: request,
1378
+ method: "POST",
1379
+ operation,
1380
+ options,
1381
+ path: `v1/projects/${pathSegment(operation, projectId, "projectId")}/message-categories`,
1382
+ sideEffect: true,
1383
+ validator: validateMessageCategory,
1384
+ });
1385
+ }
1386
+ async updateMessageCategory(projectId, key, request, options = {}) {
1387
+ const operation = "updateMessageCategory";
1388
+ assertInput(operation, request, validateUpdateMessageCategoryRequest);
1389
+ return this.#request({
1390
+ body: request,
1391
+ method: "PUT",
1392
+ operation,
1393
+ options,
1394
+ path: `v1/projects/${pathSegment(operation, projectId, "projectId")}/message-categories/${pathSegment(operation, key, "key")}`,
1395
+ sideEffect: true,
1396
+ validator: validateMessageCategory,
1397
+ });
1398
+ }
1399
+ async deleteMessageCategory(projectId, key, options = {}) {
1400
+ const operation = "deleteMessageCategory";
1401
+ return this.#request({
1402
+ method: "DELETE",
1403
+ operation,
1404
+ options,
1405
+ path: `v1/projects/${pathSegment(operation, projectId, "projectId")}/message-categories/${pathSegment(operation, key, "key")}`,
1406
+ sideEffect: true,
1407
+ noContent: true,
1408
+ });
1409
+ }
1410
+ async getOwnCategoryPreferences(projectId, environmentId, options = {}) {
1411
+ const operation = "getOwnCategoryPreferences";
1412
+ return this.#request({
1413
+ method: "GET",
1414
+ operation,
1415
+ options,
1416
+ path: `${environmentRoot(operation, projectId, environmentId)}/notification-preferences/categories`,
1417
+ sideEffect: false,
1418
+ validator: validateSubscriberCategoryPreferenceCollection,
1419
+ });
1420
+ }
1421
+ async setOwnCategoryPreference(projectId, environmentId, key, enabled, options = {}) {
1422
+ const operation = "setOwnCategoryPreference";
1423
+ const request = { enabled };
1424
+ assertInput(operation, request, validateSetSubscriberCategoryPreferenceRequest);
1425
+ return this.#request({
1426
+ body: request,
1427
+ method: "PUT",
1428
+ operation,
1429
+ options,
1430
+ path: `${environmentRoot(operation, projectId, environmentId)}/notification-preferences/categories/${pathSegment(operation, key, "key")}`,
1431
+ sideEffect: true,
1432
+ validator: validateSubscriberCategoryPreference,
1433
+ });
1434
+ }
1349
1435
  async getEnvironmentRecipientExperience(projectId, environmentId, options = {}) {
1350
1436
  const operation = "getEnvironmentRecipientExperience";
1351
1437
  return this.#request({
@@ -3392,6 +3478,30 @@ export class WhooshBangRecipientSessionClient {
3392
3478
  validator: validateRecipientSession,
3393
3479
  });
3394
3480
  }
3481
+ async getCategoryPreferences(options = {}) {
3482
+ return this.#request({
3483
+ method: "GET",
3484
+ operation: "getCategoryPreferences",
3485
+ options,
3486
+ path: "v1/recipient-session/category-preferences",
3487
+ sideEffect: false,
3488
+ validator: validateSubscriberCategoryPreferenceCollection,
3489
+ });
3490
+ }
3491
+ async setCategoryPreference(key, enabled, options = {}) {
3492
+ const operation = "setCategoryPreference";
3493
+ const request = { enabled };
3494
+ assertInput(operation, request, validateSetSubscriberCategoryPreferenceRequest);
3495
+ return this.#request({
3496
+ body: request,
3497
+ method: "PUT",
3498
+ operation,
3499
+ options,
3500
+ path: `v1/recipient-session/category-preferences/${pathSegment(operation, key, "key")}`,
3501
+ sideEffect: true,
3502
+ validator: validateSubscriberCategoryPreference,
3503
+ });
3504
+ }
3395
3505
  async getRecipientBrandLogo(assetId, options = {}) {
3396
3506
  const operation = "getRecipientBrandLogo";
3397
3507
  if (!/^asset_[0-9a-f]{32}$/u.test(assetId)) {