@cosmoops/connect-sdk 0.41.0 → 0.43.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 (48) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/dist/cjs/client/components/access-gate.js +18 -40
  3. package/dist/cjs/client/components/apps-grid.js +11 -3
  4. package/dist/cjs/client/components/ask-ai-errors.js +109 -0
  5. package/dist/cjs/client/components/ask-ai-turns.js +12 -0
  6. package/dist/cjs/client/components/ask-ai.js +75 -8
  7. package/dist/cjs/client/components/plans.js +8 -2
  8. package/dist/cjs/client/components/readiness.js +2 -1
  9. package/dist/cjs/client/components/subscription.js +4 -4
  10. package/dist/cjs/client/components/user-menu.js +16 -11
  11. package/dist/cjs/client/handoff.js +78 -0
  12. package/dist/cjs/client/index.js +9 -6
  13. package/dist/cjs/client/provider.js +75 -4
  14. package/dist/cjs/client/use-checkout.js +23 -16
  15. package/dist/cjs/server/client.js +5 -1
  16. package/dist/cjs/server/handler.js +4 -1
  17. package/dist/cjs/server/resources/calls.js +5 -2
  18. package/dist/cjs/server/resources/identity.js +12 -0
  19. package/dist/cjs/server/resources/whatsapp.js +58 -0
  20. package/dist/esm/client/components/access-gate.js +18 -40
  21. package/dist/esm/client/components/apps-grid.js +11 -3
  22. package/dist/esm/client/components/ask-ai-errors.js +102 -0
  23. package/dist/esm/client/components/ask-ai-turns.js +12 -0
  24. package/dist/esm/client/components/ask-ai.js +76 -9
  25. package/dist/esm/client/components/plans.js +8 -2
  26. package/dist/esm/client/components/readiness.js +2 -1
  27. package/dist/esm/client/components/subscription.js +4 -4
  28. package/dist/esm/client/components/user-menu.js +16 -11
  29. package/dist/esm/client/handoff.js +72 -0
  30. package/dist/esm/client/index.js +4 -3
  31. package/dist/esm/client/provider.js +75 -4
  32. package/dist/esm/client/use-checkout.js +23 -16
  33. package/dist/esm/server/client.js +5 -1
  34. package/dist/esm/server/handler.js +4 -1
  35. package/dist/esm/server/resources/calls.js +5 -2
  36. package/dist/esm/server/resources/identity.js +12 -0
  37. package/dist/esm/server/resources/whatsapp.js +54 -0
  38. package/dist/types/client/components/ask-ai-errors.d.ts +41 -0
  39. package/dist/types/client/components/ask-ai-turns.d.ts +5 -0
  40. package/dist/types/client/handoff.d.ts +62 -0
  41. package/dist/types/client/index.d.ts +3 -1
  42. package/dist/types/client/provider.d.ts +72 -5
  43. package/dist/types/client/use-checkout.d.ts +4 -1
  44. package/dist/types/server/client.d.ts +4 -1
  45. package/dist/types/server/resources/identity.d.ts +10 -0
  46. package/dist/types/server/resources/whatsapp.d.ts +44 -0
  47. package/dist/types/types.d.ts +102 -2
  48. package/package.json +1 -1
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The hand-off contract with Connect's portal - the pure half, so the rules
3
+ * can be tested without a browser. `openConnect` (on `useConnect()`) is the
4
+ * half that touches `window`.
5
+ *
6
+ * Every time this SDK sends somebody to Connect for a task - a plan, a
7
+ * payment method, their profile - it appends three params, and Connect's
8
+ * portal brings them back when the task is done:
9
+ *
10
+ * | Param | |
11
+ * |---|---|
12
+ * | `client_id` | Names this application. Connect only honours a `return_to` whose origin is registered for that client. |
13
+ * | `return_to` | The page they left. |
14
+ * | `mode` | `popup` - Connect closes its window when done and posts the outcome to this page first. `redirect` - Connect navigates back here with `?connect_result=`. |
15
+ */
16
+ /** How this application sends people to Connect - see `ConnectProviderProps.handoff`. */
17
+ export type ConnectHandoffMode = "popup" | "redirect";
18
+ /**
19
+ * How a trip to Connect ended, as Connect reports it.
20
+ *
21
+ * Advisory. A payment confirmed by webhook can settle a moment after the
22
+ * window has closed, so `"completed"` means "they finished there", not "it is
23
+ * live" - re-read entitlements for that. The provider already does, for every
24
+ * hand-off.
25
+ */
26
+ export type ConnectHandoffResult = "completed" | "cancelled" | "closed";
27
+ /** `MessageEvent.data.type` of the message Connect posts before closing a popup. */
28
+ export declare const CONNECT_HANDOFF_MESSAGE_TYPE = "connect:handoff";
29
+ /** The query param Connect adds when it redirects back. */
30
+ export declare const CONNECT_HANDOFF_RESULT_PARAM = "connect_result";
31
+ export interface HandoffUrlOptions {
32
+ appUrl: string;
33
+ /** Empty when neither the provider nor the bridge knows it - the URL still works, Connect just cannot offer the way back. */
34
+ clientId: string;
35
+ mode: ConnectHandoffMode;
36
+ /** The page to come back to - `window.location.href` at the moment of the press. */
37
+ returnTo: string;
38
+ }
39
+ /**
40
+ * `target` - a path (`"/billing"`) or an absolute Connect URL (a readiness
41
+ * blocker's `resolveUrl`) - with the hand-off params set.
42
+ *
43
+ * Throws for a URL on any other origin: these params tell Connect where to
44
+ * send somebody back, and stamping them onto a third party's URL would hand
45
+ * that party the page this visitor was on.
46
+ */
47
+ export declare function buildHandoffUrl(target: string, { appUrl, clientId, mode, returnTo }: HandoffUrlOptions): string;
48
+ /**
49
+ * The result a `message` event carries, or `null` when it is not Connect's
50
+ * hand-off message. The origin check is the whole security story: any page
51
+ * can `postMessage` this window, and only Connect's verdict may trigger work.
52
+ */
53
+ export declare function readHandoffMessage(event: Pick<MessageEvent, "origin" | "data">, appUrl: string): ConnectHandoffResult | null;
54
+ /**
55
+ * The result a redirect-mode return carries in `href`, and `href` with it
56
+ * removed - so a reload does not report the same trip twice and the param
57
+ * does not end up in a link somebody shares.
58
+ */
59
+ export declare function takeHandoffResult(href: string): {
60
+ result: ConnectHandoffResult;
61
+ cleaned: string;
62
+ } | null;
@@ -11,7 +11,9 @@
11
11
  * change lands identically in all of them.
12
12
  */
13
13
  export { ConnectProvider, useConnect, useConnectOptional, useConnectUser, useConnectWorkspaceType, useConnectAudience, useConnectPlatformAccess, useConnectEntitlements, useConnectPlans, useConnectApps, useConnectCompanyProfile, useConnectAddonUsage, useConnectSessions, useConnectIntegrations, useConnectResource, CONNECT_APP_URL, } from "./provider.js";
14
- export type { ConnectProviderProps, ConnectContextValue, ConnectSession, ConnectOneTapHint, ConnectOneTapFailure, UseConnectResourceOptions, } from "./provider.js";
14
+ export type { ConnectProviderProps, ConnectContextValue, ConnectSession, ConnectOneTapHint, ConnectOneTapFailure, UseConnectResourceOptions, OpenConnectOptions, } from "./provider.js";
15
+ export type { ConnectHandoffMode, ConnectHandoffResult } from "./handoff.js";
16
+ export { CONNECT_HANDOFF_MESSAGE_TYPE, CONNECT_HANDOFF_RESULT_PARAM } from "./handoff.js";
15
17
  export { blockingBlockers, normalizePlanFeatures } from "../helpers.js";
16
18
  export type { WirePlanFeature } from "../helpers.js";
17
19
  export { ConnectError, isConnectError } from "../errors.js";
@@ -1,4 +1,5 @@
1
1
  import type { ReactNode } from "react";
2
+ import { type ConnectHandoffMode, type ConnectHandoffResult } from "./handoff.js";
2
3
  import type { AddonUsageResponse, CompanyProfileResponse, ConnectUser, IntegrationsListResponse, WorkspaceApp, UserWorkspace, ConnectWorkspaceMember, PlansResponse, ReadinessResponse, SessionsListResponse, SessionSubscription, SessionAudience, SubscriptionResponse, WorkspaceType } from "../types.js";
3
4
  export declare const CONNECT_APP_URL = "https://connect.cosmoops.com";
4
5
  export interface ConnectSession {
@@ -32,6 +33,13 @@ export interface ConnectSession {
32
33
  hintUrl: string;
33
34
  authorizeUrl: string;
34
35
  } | null;
36
+ /**
37
+ * This application's public `client_id`, from the bridge - so `openConnect`
38
+ * can name the application on a hand-off without `clientId` being passed to
39
+ * `<ConnectProvider>` as well. Optional because an older bridge will not
40
+ * send it; the provider's own `clientId` prop wins when both exist.
41
+ */
42
+ clientId?: string | null;
35
43
  }
36
44
  /**
37
45
  * What Connect says about the visitor, before anything has been signed.
@@ -68,14 +76,39 @@ export interface ConnectOneTapHint {
68
76
  export type ConnectOneTapFailure = "unavailable" | "login_required" | "consent_required" | "interaction_required" | "rate_limited" | "failed";
69
77
  export interface ConnectContextValue {
70
78
  /**
71
- * Public OAuth client id, if `clientId` was passed to `<ConnectProvider>` -
72
- * empty string otherwise. Safe in a browser regardless: it only ever goes
73
- * into the authorize URL. Most integrations never read this - it exists for
74
- * the explicit-`redirectUri` flow, see `ConnectProviderProps.clientId`.
79
+ * Public OAuth client id - the `clientId` passed to `<ConnectProvider>`,
80
+ * else the one your bridge reports on `/session`, else an empty string
81
+ * (an older bridge, before the session read settles). Safe in a browser
82
+ * regardless: it only ever goes into Connect URLs. Most integrations never
83
+ * read this - it exists for the explicit-`redirectUri` flow and for
84
+ * `connectPortalUrl`'s way back.
75
85
  */
76
86
  clientId: string;
77
87
  /** Connect's own origin, for deep links out to Profile, Billing and the catalog. */
78
88
  appUrl: string;
89
+ /** How `openConnect` sends people to Connect - `ConnectProviderProps.handoff`, after defaulting. */
90
+ handoffMode: ConnectHandoffMode;
91
+ /**
92
+ * Sends the visitor to a Connect page for a task, and brings them back when
93
+ * it is done. **Call it from a press handler** - a popup opened after an
94
+ * `await` is what pop-up blockers exist to stop.
95
+ *
96
+ * `target` is a path (`"/billing"`) or an absolute Connect URL, such as a
97
+ * readiness blocker's `resolveUrl`. Anything on another origin throws.
98
+ *
99
+ * - `"popup"` mode opens Connect in a new tab (or a sized window, with
100
+ * `features`), which closes itself when the task is done and tells this
101
+ * page first - every Connect component on it then re-reads. Returns the
102
+ * window, for a caller that wants to watch it.
103
+ * - `"redirect"` mode, or a popup the browser blocked, navigates this tab
104
+ * to Connect, which navigates back with `?connect_result=`. Returns
105
+ * `null`; the page is going away.
106
+ *
107
+ * Either way the way back carries this page's URL and this application's
108
+ * `client_id`, and Connect only honours an origin registered for that
109
+ * client - register your app's origin among its redirect URIs.
110
+ */
111
+ openConnect(target: string, options?: OpenConnectOptions): Window | null;
79
112
  session: ConnectSession | null;
80
113
  /** `true` until the first `/session` read settles. Render skeletons, not a Login button. */
81
114
  isLoading: boolean;
@@ -178,6 +211,16 @@ export interface ConnectContextValue {
178
211
  reason: ConnectOneTapFailure;
179
212
  }>;
180
213
  }
214
+ export interface OpenConnectOptions {
215
+ /**
216
+ * `window.open` features for a sized pop-up window instead of a tab -
217
+ * checkout uses `"popup,width=520,height=780"`. Must not include
218
+ * `noopener`: the window handle is how Connect reports back and closes.
219
+ */
220
+ features?: string;
221
+ /** `window.open` target name. A second `openConnect` with the same name reuses that window. */
222
+ name?: string;
223
+ }
181
224
  export interface ConnectProviderProps {
182
225
  /**
183
226
  * This application's public `client_id`, from its Connect client section in Connect.
@@ -241,6 +284,30 @@ export interface ConnectProviderProps {
241
284
  * to your own `/signin`, which mints the `state` server-side.
242
285
  */
243
286
  silentSignIn?: boolean;
287
+ /**
288
+ * How every Connect button in this package - Billing, Profile, Manage,
289
+ * checkout, a readiness blocker's fix - takes the visitor to Connect.
290
+ *
291
+ * - `"popup"` (the default): Connect opens in a new tab and **closes itself**
292
+ * when the task is done, telling this page first, so the visitor is back
293
+ * where they were with everything repainted. A blocked popup falls back
294
+ * to `"redirect"` rather than leaving them with nothing.
295
+ * - `"redirect"`: this tab goes to Connect and comes back. Prefer it for an
296
+ * installed PWA or an app inside an iframe, where a second tab is a
297
+ * different window the visitor may never find.
298
+ *
299
+ * Both need this app's origin registered among the client's redirect URIs
300
+ * in Connect - an unregistered origin still reaches Connect, it just gets no
301
+ * way back.
302
+ */
303
+ handoff?: ConnectHandoffMode;
304
+ /**
305
+ * Told how each trip to Connect ended - from the popup's message, or from
306
+ * `?connect_result=` on the way back from a redirect (which the provider
307
+ * then strips from the address bar). The provider already re-reads the
308
+ * session and every Connect resource; this is for your own state.
309
+ */
310
+ onHandoffResult?: (result: ConnectHandoffResult) => void;
244
311
  children: ReactNode;
245
312
  }
246
313
  /**
@@ -257,7 +324,7 @@ export interface ConnectProviderProps {
257
324
  * </ConnectProvider>
258
325
  * ```
259
326
  */
260
- export declare function ConnectProvider({ clientId, basePath, redirectUri, appUrl, fetch: fetchImpl, silentSignIn, children, }: ConnectProviderProps): import("react").JSX.Element;
327
+ export declare function ConnectProvider({ clientId, basePath, redirectUri, appUrl, fetch: fetchImpl, silentSignIn, handoff, onHandoffResult, children, }: ConnectProviderProps): import("react").JSX.Element;
261
328
  export declare function useConnect(): ConnectContextValue;
262
329
  /**
263
330
  * The context when there is one, `null` when there is not.
@@ -9,7 +9,10 @@ import type { ReadinessResponse, SubscriptionResponse } from "../types.js";
9
9
  * closing is not one.
10
10
  * - `abandoned` - the window closed (or the deadline passed) with the
11
11
  * entitlement unchanged.
12
- * - `blocked` - the browser refused to open the window at all.
12
+ * - `blocked` - **no longer produced.** A blocked window now falls back to a
13
+ * same-tab trip to Connect and back (see `openConnect`), which reaches the
14
+ * same place without asking the customer to click a fallback link. Kept in
15
+ * the union so code that handles it still compiles.
13
16
  */
14
17
  export type ConnectCheckoutStatus = "idle" | "waiting" | "completed" | "abandoned" | "blocked";
15
18
  export interface ConnectCheckoutState {
@@ -23,6 +23,7 @@ import { SessionsResource } from "./resources/sessions.js";
23
23
  import { PlatformResource } from "./resources/platform.js";
24
24
  import { VisitorResource } from "./resources/visitor.js";
25
25
  import { PushResource } from "./resources/push.js";
26
+ import { WhatsAppResource } from "./resources/whatsapp.js";
26
27
  export declare const DEFAULT_BASE_URL = "https://connect.cosmoops.com";
27
28
  export interface ConnectClientOptions {
28
29
  /**
@@ -124,6 +125,8 @@ export declare class ConnectClient {
124
125
  * preferences; you supply a title, a body and a URL. See `PushResource`.
125
126
  */
126
127
  readonly push: PushResource;
128
+ /** Your application's own approved WhatsApp templates, to a workspace's customers. */
129
+ readonly whatsapp: WhatsAppResource;
127
130
  /**
128
131
  * Relays one `/data/*` or `/kv/*` request verbatim - `createConnectHandler`'s
129
132
  * store route and nothing else. See `storePassthrough`.
@@ -138,4 +141,4 @@ export declare class ConnectClient {
138
141
  constructor(options: ConnectClientOptions);
139
142
  }
140
143
  /** Kept in step with `package.json` by `sdk.test.ts`. */
141
- export declare const SDK_VERSION = "0.41.0";
144
+ export declare const SDK_VERSION = "0.43.0";
@@ -77,6 +77,16 @@ export declare class IdentityResource {
77
77
  hintUrl: string;
78
78
  authorizeUrl: string;
79
79
  } | null;
80
+ /**
81
+ * This client's public `client_id`, or `null` when none is configured.
82
+ *
83
+ * The bridge hands it to the browser on `/session` so `openConnect` can name
84
+ * the application on every hand-off without the host passing `clientId` to
85
+ * `<ConnectProvider>` too - Connect only honours a `return_to` it can match
86
+ * against *a client's* registered redirect origins. Public by definition:
87
+ * it already rides on every authorize URL.
88
+ */
89
+ publicClientId(): string | null;
80
90
  /** Step 2 - trade the one-time `code` for a session. Server-side only. */
81
91
  exchangeCode(input: ExchangeCodeInput): Promise<TokenResponse>;
82
92
  /**
@@ -0,0 +1,44 @@
1
+ import { type TransportOptions } from "../http.js";
2
+ import type { SendWhatsAppInput, SendWhatsAppResponse, WhatsAppTemplateState } from "../../types.js";
3
+ /**
4
+ * Your application's own WhatsApp templates, sent to a workspace's customers
5
+ * through Connect's WhatsApp sender - no WhatsApp Business account of your
6
+ * own.
7
+ *
8
+ * Templates are written and submitted to Meta in Console under your
9
+ * application; you name them here by slug and Connect resolves
10
+ * `app_<yourApplicationKey>_<slug>` from your key, so a key can never send
11
+ * another application's message or one of Connect's own. There is no free
12
+ * text: outside a customer's 24-hour window WhatsApp permits nothing else.
13
+ *
14
+ * Server-to-server only - there is no browser path, by design.
15
+ */
16
+ export declare class WhatsAppResource {
17
+ private readonly transport;
18
+ constructor(transport: TransportOptions);
19
+ /**
20
+ * Send one template to one customer.
21
+ *
22
+ * Refusals arrive as a `ConnectError` whose `code` says what to tell the
23
+ * person who pressed Send - `template_not_approved`, `consent_required`,
24
+ * `opted_out`, `not_found`. None of them is a fault worth retrying.
25
+ *
26
+ * An `Idempotency-Key` is always sent, as on `otp.send`: a retried send
27
+ * without one is a second message on somebody's phone. Pass your own -
28
+ * derived from what is being sent, e.g. the quote number - to make a
29
+ * retry from a *later* request safe too.
30
+ */
31
+ send(input: SendWhatsAppInput, options?: {
32
+ idempotencyKey?: string;
33
+ }): Promise<SendWhatsAppResponse>;
34
+ /**
35
+ * Whether a template would send right now, and the values it needs.
36
+ *
37
+ * Ask before offering WhatsApp on a screen: Meta's approval takes minutes
38
+ * to days, and an approved template can be paused later. A `ConnectError`
39
+ * with `status: 404` means your application has no such template.
40
+ */
41
+ template(slug: string, options?: {
42
+ language?: string;
43
+ }): Promise<WhatsAppTemplateState>;
44
+ }
@@ -1114,7 +1114,7 @@ export interface EmitEventsResponse {
1114
1114
  * `createConnectWebhookHandler` simply ignores anything you have not
1115
1115
  * registered a handler for.
1116
1116
  */
1117
- export type ConnectWebhookEventType = "workspace.deletion_scheduled" | "workspace.deletion_cancelled" | "workspace.deleted" | "subscription.cancelled" | "call.completed" | "call.missed" | "booking.confirmed" | "booking.cancelled" | "booking.rescheduled" | "contact.created" | "contact.updated";
1117
+ export type ConnectWebhookEventType = "workspace.deletion_scheduled" | "workspace.deletion_cancelled" | "workspace.deleted" | "subscription.cancelled" | "call.completed" | "call.missed" | "call.analyzed" | "booking.confirmed" | "booking.cancelled" | "booking.rescheduled" | "contact.created" | "contact.updated";
1118
1118
  /** What becomes of one class of data when the workspace is purged. */
1119
1119
  export type ConnectDataDisposition = "erase" | "anonymize" | "retain";
1120
1120
  /** Who answers for your copy of the customer's data. See the deletion-policy guide. */
@@ -1321,6 +1321,48 @@ export interface CallMissedEvent {
1321
1321
  /** ISO-8601. */
1322
1322
  occurredAt: string;
1323
1323
  }
1324
+ /** How the person called came across, by the end of the call. */
1325
+ export type CallSentiment = "positive" | "neutral" | "negative";
1326
+ /**
1327
+ * Something somebody committed to on a recorded call. `owner` is who said
1328
+ * they would do it - `rep` for your user's side, `customer` for the person
1329
+ * called. Both are worth a follow-up: one to do, one to chase.
1330
+ */
1331
+ export interface CallActionItem {
1332
+ title: string;
1333
+ /** `YYYY-MM-DD` when a day was named or clearly implied, else `null`. */
1334
+ dueDate: string | null;
1335
+ owner: "rep" | "customer";
1336
+ }
1337
+ /**
1338
+ * A recorded call, transcribed and read. Sent minutes after `call.completed`,
1339
+ * and only for calls placed while the workspace records them - file the call
1340
+ * on `call.completed` and enrich that row here. The transcript itself is the
1341
+ * call's turns on `calls.get`.
1342
+ */
1343
+ export interface CallAnalyzedEvent {
1344
+ workspaceId: string;
1345
+ callId: string;
1346
+ channelId: string | null;
1347
+ /** E.164 - the person called on an outbound call, the caller on an inbound one. */
1348
+ contactPhone: string | null;
1349
+ direction: ConnectCallDirection;
1350
+ handler: CallHandler;
1351
+ placedByUserId: string | null;
1352
+ placedByName: string | null;
1353
+ /** Two or three sentences, in English whatever language was spoken. */
1354
+ summary: string | null;
1355
+ /** Why they were on the call, in a few lowercase words - "pricing enquiry". */
1356
+ intent: string | null;
1357
+ sentiment: CallSentiment | null;
1358
+ /** The main language spoken, BCP-47 - `hi-IN`, `en-IN`. */
1359
+ language: string | null;
1360
+ actionItems: CallActionItem[];
1361
+ /** The audio in the workspace's Drive - read it with a `drive:read` key. */
1362
+ recordingFileId: string | null;
1363
+ /** ISO-8601 - when the call started. */
1364
+ occurredAt: string;
1365
+ }
1324
1366
  /**
1325
1367
  * An appointment was booked and is holding its slot.
1326
1368
  *
@@ -1446,6 +1488,7 @@ export interface ConnectWebhookEventMap {
1446
1488
  "subscription.cancelled": SubscriptionCancelledEvent;
1447
1489
  "call.completed": CallCompletedEvent;
1448
1490
  "call.missed": CallMissedEvent;
1491
+ "call.analyzed": CallAnalyzedEvent;
1449
1492
  "booking.confirmed": BookingConfirmedEvent;
1450
1493
  "booking.cancelled": BookingCancelledEvent;
1451
1494
  "booking.rescheduled": BookingRescheduledEvent;
@@ -2804,7 +2847,7 @@ export interface ConnectCall {
2804
2847
  extraction: Record<string, unknown> | null;
2805
2848
  agentId: string | null;
2806
2849
  agentVersion: number | null;
2807
- /** `member` for a call a person placed with `<ConnectCallButton>`; such a call has no agent, transcript or recording. */
2850
+ /** `member` for a call a person placed with `<ConnectCallButton>`. Such a call has no agent; it has a recording, a transcript and an `analysis` only when the workspace records calls. */
2808
2851
  handler: CallHandler;
2809
2852
  /** The member who placed a `member` call - their Connect user id. */
2810
2853
  placedByUserId: string | null;
@@ -2817,6 +2860,21 @@ export interface ConnectCall {
2817
2860
  talkSeconds: number | null;
2818
2861
  /** Why nobody answered - set only when `status` is `unanswered`. */
2819
2862
  unansweredReason: CallUnansweredReason | (string & {}) | null;
2863
+ /**
2864
+ * The reading of a recorded member call - summary, intent, action items.
2865
+ * `null` for a call that was not recorded; `status: "pending"` while it is
2866
+ * being read. The transcript is `CallDetail.turns`, the member as `agent`
2867
+ * and the person called as `user`.
2868
+ */
2869
+ analysis: ConnectCallAnalysis | null;
2870
+ }
2871
+ export interface ConnectCallAnalysis {
2872
+ status: "pending" | "done" | "failed";
2873
+ summary: string | null;
2874
+ intent: string | null;
2875
+ sentiment: CallSentiment | null;
2876
+ actionItems: CallActionItem[];
2877
+ language: string | null;
2820
2878
  }
2821
2879
  /**
2822
2880
  * What the browser needs to place one approved call - see
@@ -2982,6 +3040,48 @@ export interface ConversationsPage {
2982
3040
  nextCursor: string | null;
2983
3041
  hasMore: boolean;
2984
3042
  }
3043
+ /**
3044
+ * One of your application's own Meta-approved templates, to one customer.
3045
+ *
3046
+ * Hand-written here like every wire type in this file - see `SendPushInput`.
3047
+ */
3048
+ export interface SendWhatsAppInput {
3049
+ /** The subscribing workspace this is sent on behalf of. */
3050
+ workspaceId: string;
3051
+ /** The template's slug within your application, e.g. `quote-issued` - never its Meta name. */
3052
+ template: string;
3053
+ /** Meta language code the template was approved in. Defaults to `en`. */
3054
+ language?: string;
3055
+ /** E.164, e.g. `+919876543210`. */
3056
+ to: string;
3057
+ /** One value per template variable, by name. A missing one refuses the send. */
3058
+ values?: Record<string, string>;
3059
+ /**
3060
+ * The opt-in your application collected, recorded only when Connect has
3061
+ * none on file for the number. A number that withdrew stays withdrawn.
3062
+ */
3063
+ consent?: {
3064
+ collectedVia: string;
3065
+ };
3066
+ }
3067
+ export interface SendWhatsAppResponse {
3068
+ status: "sent";
3069
+ messageId: string;
3070
+ }
3071
+ /** Meta's review state for a template. Only `APPROVED` sends. */
3072
+ export type WhatsAppTemplateReviewStatus = "DRAFT" | "PENDING" | "APPROVED" | "REJECTED" | "PAUSED" | "DISABLED";
3073
+ /** Whether one of your templates would send right now. Branch on `live`. */
3074
+ export interface WhatsAppTemplateState {
3075
+ slug: string;
3076
+ language: string;
3077
+ /** Meta's name for it: `app_<applicationKey>_<slug>`. */
3078
+ name: string;
3079
+ status: WhatsAppTemplateReviewStatus;
3080
+ /** Approved by Meta *and* currently served. */
3081
+ live: boolean;
3082
+ /** The values a send must carry, from the approved content. */
3083
+ variables: string[];
3084
+ }
2985
3085
  /**
2986
3086
  * One notification, to members of one workspace.
2987
3087
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmoops/connect-sdk",
3
- "version": "0.41.0",
3
+ "version": "0.43.0",
4
4
  "description": "Official server-side SDK for the CosmoOps Connect platform API - Login with Connect, entitlements, billing and metering.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "commonjs",