@mrrocket/sdk 0.14.0 → 0.15.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.
@@ -78,6 +78,28 @@ interface SurveyDefinition {
78
78
  questions: SurveyQuestion[];
79
79
  }
80
80
  type SurveyAnswer = number | string | string[];
81
+ /** A file in the messenger's chat: a screenshot, a photo or a PDF the visitor sent (servers from SDK 0.15 on). */
82
+ interface ChatFile {
83
+ /** From an upload: the signed id a message sends. In a message: the file's own id (`attachmentUrl` reads it). */
84
+ id: string;
85
+ name: string;
86
+ type: "image/png" | "image/jpeg" | "image/webp" | "image/gif" | "application/pdf";
87
+ /** Bytes. */
88
+ size: number;
89
+ }
90
+ /** A file to upload: a Blob or File on the web, the image picker's `{ uri, name, type }` in React Native. */
91
+ type ChatUpload = Blob | {
92
+ uri: string;
93
+ name: string;
94
+ type: string;
95
+ };
96
+ /** The bug context a visitor message carries; the server fills browser and system from the user agent when left out. */
97
+ interface ChatContext {
98
+ browser?: string;
99
+ os?: string;
100
+ /** "1440×900". */
101
+ viewport?: string;
102
+ }
81
103
  /** One message of the messenger's chat. "visitor" is the person on the site; the rest come from the product's team. */
82
104
  interface ChatMessage {
83
105
  id: string;
@@ -89,6 +111,8 @@ interface ChatMessage {
89
111
  id: string;
90
112
  title: string;
91
113
  }[];
114
+ /** Files sent with it (servers from SDK 0.15 on). */
115
+ attachments?: ChatFile[];
92
116
  }
93
117
  /** A published help article in a list (the messenger's Help tab). */
94
118
  interface ArticleSummary {
@@ -126,11 +150,17 @@ interface Article {
126
150
  updatedAt: string;
127
151
  blocks: ArticleBlock[];
128
152
  }
153
+ /** Where the chat button sits: a corner, the middle of the top or bottom edge, or the middle of a side. */
154
+ type MessengerPosition = "top-left" | "top-center" | "top-right" | "middle-left" | "middle-right" | "bottom-left" | "bottom-center" | "bottom-right";
155
+ /** How round the messenger is. */
156
+ type MessengerCorners = "round" | "soft" | "square";
129
157
  /** The messenger's look and texts as set in MRRocket › Support › Messenger (servers from SDK 0.9 on). */
130
158
  interface MessengerLook {
131
159
  accent: string;
160
+ /** Up to two more colors blended into Home's background glow (MRRocket from 0.16; older servers leave it out). */
161
+ glow?: string[];
132
162
  theme: "light" | "dark" | "auto";
133
- position: "bottom-right" | "bottom-left";
163
+ position: MessengerPosition;
134
164
  title: string;
135
165
  greeting: string;
136
166
  label: string;
@@ -142,6 +172,16 @@ interface MessengerLook {
142
172
  sound: boolean;
143
173
  preview: boolean;
144
174
  askEmail: boolean;
175
+ /** How round panel, bubbles, cards and fields are (MRRocket from 0.15; older servers leave it out: round). */
176
+ corners?: MessengerCorners;
177
+ /** The site's own font (the default) or the system's (web only; from 0.15). */
178
+ font?: "site" | "system";
179
+ /** Home's top: plain like the rest, or in the accent color (from 0.15; older servers leave it out: plain). */
180
+ header?: "plain" | "color";
181
+ /** "Powered by MRRocket" at the bottom; the server sends false only on plans that may hide it (from 0.15). */
182
+ branding?: boolean;
183
+ /** The product's icon (its favicon) at the top left of Home; without it the title's first letter. */
184
+ logo?: string;
145
185
  }
146
186
  /** The visitor's newest chat (open or closed) and its messages. */
147
187
  interface ChatThread {
@@ -197,11 +237,18 @@ declare const createApi: (c: Conn) => {
197
237
  seconds: number;
198
238
  }) => Promise<unknown>;
199
239
  chat: (signal?: AbortSignal) => Promise<ChatThread>;
240
+ /** A message; `attachments` are upload ids from `uploadChatFile` (then the body may be empty). */
200
241
  sendChat: (m: {
201
242
  body: string;
202
243
  email?: string;
203
244
  url?: string;
245
+ attachments?: string[];
246
+ context?: ChatContext;
204
247
  }) => Promise<ChatThread>;
248
+ /** Uploads one picked file for the next message (pictures and PDFs, at most 10 MB); answers its upload id. */
249
+ uploadChatFile: (file: ChatUpload, signal?: AbortSignal) => Promise<ChatFile>;
250
+ /** Where a sent file of this visitor's chat is read (an image's src, a PDF's link). */
251
+ attachmentUrl: (id: string) => string;
205
252
  articles: (q?: string, signal?: AbortSignal) => Promise<{
206
253
  articles: ArticleSummary[];
207
254
  }>;
@@ -243,6 +290,29 @@ interface CancelOffer {
243
290
  plan?: string;
244
291
  planName?: string;
245
292
  }
293
+ /** 0.15.0: a second question after an answer ("What would be a fair price?"); no answers means a free text. */
294
+ interface CancelFollowUp {
295
+ question: string;
296
+ /** The choices, in order; empty for a free text. */
297
+ answers: string[];
298
+ }
299
+ /**
300
+ * 0.15.0: a different offer for some customers of one answer. Every condition that is set must hold; the first rule
301
+ * that matches wins, else the answer's own offer. `offer: null` means no offer (straight to the confirmation).
302
+ */
303
+ interface CancelRule {
304
+ when: {
305
+ /** The follow-up's answer, as written. */
306
+ answer?: string;
307
+ /** The customer's plan: its id or name as MRRocket knows it from the payment provider (any of a list). */
308
+ plan?: string | string[];
309
+ /** A customer for fewer than this many months. */
310
+ tenureUnder?: number;
311
+ /** A customer for at least this many months. */
312
+ tenureOver?: number;
313
+ };
314
+ offer: CancelOffer | null;
315
+ }
246
316
  /** The product's live cancel flow (MRRocket › Churn › Cancel flow). */
247
317
  interface CancelFlowConfig {
248
318
  /** Grows with every publish. */
@@ -255,6 +325,12 @@ interface CancelFlowConfig {
255
325
  }[];
256
326
  /** The offer per answer id. */
257
327
  offers: Record<string, CancelOffer>;
328
+ /** 0.15.0: the follow-up question per answer id. */
329
+ followUps?: Record<string, CancelFollowUp>;
330
+ /** 0.15.0: the rules per answer id, checked in order before its offer. */
331
+ rules?: Record<string, CancelRule[]>;
332
+ /** 0.15.0: what one answer offers after its first offer was declined. */
333
+ second?: Record<string, CancelOffer>;
258
334
  confirm: {
259
335
  title: string;
260
336
  body: string;
@@ -326,6 +402,8 @@ interface CancelFlowResult {
326
402
  outcome: "cancelled" | "saved" | "kept";
327
403
  reason?: string;
328
404
  reasonLabel?: string;
405
+ /** 0.15.0: the answer to the follow-up question. */
406
+ answer?: string;
329
407
  offer?: CancelOffer;
330
408
  /** What the customer wrote on the confirmation, if anything. */
331
409
  comment?: string;
@@ -344,6 +422,10 @@ interface CancelFlowOptions {
344
422
  currency: string;
345
423
  interval?: "month" | "year";
346
424
  };
425
+ /** 0.15.0: the customer's plan (its id or name in your billing), for offers that depend on it. */
426
+ plan?: string;
427
+ /** 0.15.0: since when they pay (a date, ISO string or ms), for offers that depend on how long. */
428
+ customerSince?: Date | string | number;
347
429
  /** The customer confirmed: cancel the subscription in your code. Throwing keeps the dialog open with an error. */
348
430
  onCancel?: (result: CancelFlowResult) => unknown;
349
431
  /** The customer took an offer: apply it in your code (coupon, pause, plan change). Throwing keeps the dialog open. */
@@ -354,11 +436,16 @@ interface CancelFlowOptions {
354
436
  /** What a renderer draws. */
355
437
  type FlowView = {
356
438
  type: "cancel";
357
- screen: "survey" | "offer" | "confirm";
439
+ screen: "survey" | "followup" | "offer" | "confirm";
358
440
  flow: CancelFlowConfig;
359
441
  /** The answer picked on the survey. */
360
442
  reason?: string;
443
+ /** 0.15.0: the follow-up question on its screen, and its answer so far. */
444
+ followUp?: CancelFollowUp;
445
+ answer?: string;
361
446
  offer?: CancelOffer;
447
+ /** 0.15.0: 2 for the offer after a declined one. */
448
+ round?: 1 | 2;
362
449
  price?: CancelFlowOptions["price"];
363
450
  busy: boolean;
364
451
  error?: string;
@@ -395,8 +482,10 @@ interface FlowsController {
395
482
  view(): FlowView | null;
396
483
  subscribe(listener: () => void): () => void;
397
484
  /** `accept(comment)`: a "Talk to us" offer sends what the customer wrote with it. */
485
+ /** `answer(text)`: the follow-up's choice or free text (0.15.0); `next()` moves on from the survey and the follow-up. */
398
486
  cancel: {
399
487
  pick(reason: string): void;
488
+ answer(text: string): void;
400
489
  next(): void;
401
490
  accept(comment?: string): void;
402
491
  decline(): void;
@@ -531,7 +620,7 @@ interface PaywallHost {
531
620
 
532
621
  type VariantId = string;
533
622
  /** This build of the SDK. Sent with the config request so MRRocket knows what the site runs (error tracking, flags). */
534
- declare const SDK_VERSION = "0.14.0";
623
+ declare const SDK_VERSION = "0.15.0";
535
624
  /** One variant of an experiment. `changes` replaces texts that the page marks with `<Text id>`. */
536
625
  interface VariantConfig {
537
626
  id: VariantId;
@@ -895,15 +984,22 @@ declare const useMessenger: () => {
895
984
  interface NativeMessengerOptions {
896
985
  /** A round chat button (default false: open it with `useMessenger().open()` from your own button). */
897
986
  launcher?: boolean;
898
- /** Where the chat button sits (default bottom right). */
899
- position?: "bottom-right" | "bottom-left";
987
+ /** Where the chat button sits: a corner, the middle of the top or bottom edge, or the middle of a side (default bottom right). */
988
+ position?: MessengerPosition;
900
989
  /** Text beside the chat button's icon; empty: the round button. */
901
990
  label?: string;
991
+ /** The name beside the team's mark at the top of Home (MRRocket fills in the product's name). */
902
992
  title?: string;
903
993
  /** The big line on Home and the first line of an empty chat. */
904
994
  greeting?: string;
905
- /** How soon the team usually answers, said under "Send us a message" and in the chat's head. */
995
+ /** How soon the team usually answers, said on Home. */
906
996
  replyTime?: "minutes" | "hours" | "day";
997
+ /** How round bubbles, cards and fields are (default round; the sheet itself keeps the system's corners). */
998
+ corners?: MessengerCorners;
999
+ /** Home's top: plain like the rest (default), or in the accent color with raised cards. */
1000
+ header?: "plain" | "color";
1001
+ /** The product's icon at the top left of Home (MRRocket sends the product's favicon). */
1002
+ logo?: string;
907
1003
  /** Ask people the app did not identify with an email for an email (optional for them). Default true. */
908
1004
  askEmail?: boolean;
909
1005
  /** The Help tab with your published help articles (default true; hidden while there are none). */
@@ -78,6 +78,28 @@ interface SurveyDefinition {
78
78
  questions: SurveyQuestion[];
79
79
  }
80
80
  type SurveyAnswer = number | string | string[];
81
+ /** A file in the messenger's chat: a screenshot, a photo or a PDF the visitor sent (servers from SDK 0.15 on). */
82
+ interface ChatFile {
83
+ /** From an upload: the signed id a message sends. In a message: the file's own id (`attachmentUrl` reads it). */
84
+ id: string;
85
+ name: string;
86
+ type: "image/png" | "image/jpeg" | "image/webp" | "image/gif" | "application/pdf";
87
+ /** Bytes. */
88
+ size: number;
89
+ }
90
+ /** A file to upload: a Blob or File on the web, the image picker's `{ uri, name, type }` in React Native. */
91
+ type ChatUpload = Blob | {
92
+ uri: string;
93
+ name: string;
94
+ type: string;
95
+ };
96
+ /** The bug context a visitor message carries; the server fills browser and system from the user agent when left out. */
97
+ interface ChatContext {
98
+ browser?: string;
99
+ os?: string;
100
+ /** "1440×900". */
101
+ viewport?: string;
102
+ }
81
103
  /** One message of the messenger's chat. "visitor" is the person on the site; the rest come from the product's team. */
82
104
  interface ChatMessage {
83
105
  id: string;
@@ -89,6 +111,8 @@ interface ChatMessage {
89
111
  id: string;
90
112
  title: string;
91
113
  }[];
114
+ /** Files sent with it (servers from SDK 0.15 on). */
115
+ attachments?: ChatFile[];
92
116
  }
93
117
  /** A published help article in a list (the messenger's Help tab). */
94
118
  interface ArticleSummary {
@@ -126,11 +150,17 @@ interface Article {
126
150
  updatedAt: string;
127
151
  blocks: ArticleBlock[];
128
152
  }
153
+ /** Where the chat button sits: a corner, the middle of the top or bottom edge, or the middle of a side. */
154
+ type MessengerPosition = "top-left" | "top-center" | "top-right" | "middle-left" | "middle-right" | "bottom-left" | "bottom-center" | "bottom-right";
155
+ /** How round the messenger is. */
156
+ type MessengerCorners = "round" | "soft" | "square";
129
157
  /** The messenger's look and texts as set in MRRocket › Support › Messenger (servers from SDK 0.9 on). */
130
158
  interface MessengerLook {
131
159
  accent: string;
160
+ /** Up to two more colors blended into Home's background glow (MRRocket from 0.16; older servers leave it out). */
161
+ glow?: string[];
132
162
  theme: "light" | "dark" | "auto";
133
- position: "bottom-right" | "bottom-left";
163
+ position: MessengerPosition;
134
164
  title: string;
135
165
  greeting: string;
136
166
  label: string;
@@ -142,6 +172,16 @@ interface MessengerLook {
142
172
  sound: boolean;
143
173
  preview: boolean;
144
174
  askEmail: boolean;
175
+ /** How round panel, bubbles, cards and fields are (MRRocket from 0.15; older servers leave it out: round). */
176
+ corners?: MessengerCorners;
177
+ /** The site's own font (the default) or the system's (web only; from 0.15). */
178
+ font?: "site" | "system";
179
+ /** Home's top: plain like the rest, or in the accent color (from 0.15; older servers leave it out: plain). */
180
+ header?: "plain" | "color";
181
+ /** "Powered by MRRocket" at the bottom; the server sends false only on plans that may hide it (from 0.15). */
182
+ branding?: boolean;
183
+ /** The product's icon (its favicon) at the top left of Home; without it the title's first letter. */
184
+ logo?: string;
145
185
  }
146
186
  /** The visitor's newest chat (open or closed) and its messages. */
147
187
  interface ChatThread {
@@ -197,11 +237,18 @@ declare const createApi: (c: Conn) => {
197
237
  seconds: number;
198
238
  }) => Promise<unknown>;
199
239
  chat: (signal?: AbortSignal) => Promise<ChatThread>;
240
+ /** A message; `attachments` are upload ids from `uploadChatFile` (then the body may be empty). */
200
241
  sendChat: (m: {
201
242
  body: string;
202
243
  email?: string;
203
244
  url?: string;
245
+ attachments?: string[];
246
+ context?: ChatContext;
204
247
  }) => Promise<ChatThread>;
248
+ /** Uploads one picked file for the next message (pictures and PDFs, at most 10 MB); answers its upload id. */
249
+ uploadChatFile: (file: ChatUpload, signal?: AbortSignal) => Promise<ChatFile>;
250
+ /** Where a sent file of this visitor's chat is read (an image's src, a PDF's link). */
251
+ attachmentUrl: (id: string) => string;
205
252
  articles: (q?: string, signal?: AbortSignal) => Promise<{
206
253
  articles: ArticleSummary[];
207
254
  }>;
@@ -243,6 +290,29 @@ interface CancelOffer {
243
290
  plan?: string;
244
291
  planName?: string;
245
292
  }
293
+ /** 0.15.0: a second question after an answer ("What would be a fair price?"); no answers means a free text. */
294
+ interface CancelFollowUp {
295
+ question: string;
296
+ /** The choices, in order; empty for a free text. */
297
+ answers: string[];
298
+ }
299
+ /**
300
+ * 0.15.0: a different offer for some customers of one answer. Every condition that is set must hold; the first rule
301
+ * that matches wins, else the answer's own offer. `offer: null` means no offer (straight to the confirmation).
302
+ */
303
+ interface CancelRule {
304
+ when: {
305
+ /** The follow-up's answer, as written. */
306
+ answer?: string;
307
+ /** The customer's plan: its id or name as MRRocket knows it from the payment provider (any of a list). */
308
+ plan?: string | string[];
309
+ /** A customer for fewer than this many months. */
310
+ tenureUnder?: number;
311
+ /** A customer for at least this many months. */
312
+ tenureOver?: number;
313
+ };
314
+ offer: CancelOffer | null;
315
+ }
246
316
  /** The product's live cancel flow (MRRocket › Churn › Cancel flow). */
247
317
  interface CancelFlowConfig {
248
318
  /** Grows with every publish. */
@@ -255,6 +325,12 @@ interface CancelFlowConfig {
255
325
  }[];
256
326
  /** The offer per answer id. */
257
327
  offers: Record<string, CancelOffer>;
328
+ /** 0.15.0: the follow-up question per answer id. */
329
+ followUps?: Record<string, CancelFollowUp>;
330
+ /** 0.15.0: the rules per answer id, checked in order before its offer. */
331
+ rules?: Record<string, CancelRule[]>;
332
+ /** 0.15.0: what one answer offers after its first offer was declined. */
333
+ second?: Record<string, CancelOffer>;
258
334
  confirm: {
259
335
  title: string;
260
336
  body: string;
@@ -326,6 +402,8 @@ interface CancelFlowResult {
326
402
  outcome: "cancelled" | "saved" | "kept";
327
403
  reason?: string;
328
404
  reasonLabel?: string;
405
+ /** 0.15.0: the answer to the follow-up question. */
406
+ answer?: string;
329
407
  offer?: CancelOffer;
330
408
  /** What the customer wrote on the confirmation, if anything. */
331
409
  comment?: string;
@@ -344,6 +422,10 @@ interface CancelFlowOptions {
344
422
  currency: string;
345
423
  interval?: "month" | "year";
346
424
  };
425
+ /** 0.15.0: the customer's plan (its id or name in your billing), for offers that depend on it. */
426
+ plan?: string;
427
+ /** 0.15.0: since when they pay (a date, ISO string or ms), for offers that depend on how long. */
428
+ customerSince?: Date | string | number;
347
429
  /** The customer confirmed: cancel the subscription in your code. Throwing keeps the dialog open with an error. */
348
430
  onCancel?: (result: CancelFlowResult) => unknown;
349
431
  /** The customer took an offer: apply it in your code (coupon, pause, plan change). Throwing keeps the dialog open. */
@@ -354,11 +436,16 @@ interface CancelFlowOptions {
354
436
  /** What a renderer draws. */
355
437
  type FlowView = {
356
438
  type: "cancel";
357
- screen: "survey" | "offer" | "confirm";
439
+ screen: "survey" | "followup" | "offer" | "confirm";
358
440
  flow: CancelFlowConfig;
359
441
  /** The answer picked on the survey. */
360
442
  reason?: string;
443
+ /** 0.15.0: the follow-up question on its screen, and its answer so far. */
444
+ followUp?: CancelFollowUp;
445
+ answer?: string;
361
446
  offer?: CancelOffer;
447
+ /** 0.15.0: 2 for the offer after a declined one. */
448
+ round?: 1 | 2;
362
449
  price?: CancelFlowOptions["price"];
363
450
  busy: boolean;
364
451
  error?: string;
@@ -395,8 +482,10 @@ interface FlowsController {
395
482
  view(): FlowView | null;
396
483
  subscribe(listener: () => void): () => void;
397
484
  /** `accept(comment)`: a "Talk to us" offer sends what the customer wrote with it. */
485
+ /** `answer(text)`: the follow-up's choice or free text (0.15.0); `next()` moves on from the survey and the follow-up. */
398
486
  cancel: {
399
487
  pick(reason: string): void;
488
+ answer(text: string): void;
400
489
  next(): void;
401
490
  accept(comment?: string): void;
402
491
  decline(): void;
@@ -531,7 +620,7 @@ interface PaywallHost {
531
620
 
532
621
  type VariantId = string;
533
622
  /** This build of the SDK. Sent with the config request so MRRocket knows what the site runs (error tracking, flags). */
534
- declare const SDK_VERSION = "0.14.0";
623
+ declare const SDK_VERSION = "0.15.0";
535
624
  /** One variant of an experiment. `changes` replaces texts that the page marks with `<Text id>`. */
536
625
  interface VariantConfig {
537
626
  id: VariantId;
@@ -895,15 +984,22 @@ declare const useMessenger: () => {
895
984
  interface NativeMessengerOptions {
896
985
  /** A round chat button (default false: open it with `useMessenger().open()` from your own button). */
897
986
  launcher?: boolean;
898
- /** Where the chat button sits (default bottom right). */
899
- position?: "bottom-right" | "bottom-left";
987
+ /** Where the chat button sits: a corner, the middle of the top or bottom edge, or the middle of a side (default bottom right). */
988
+ position?: MessengerPosition;
900
989
  /** Text beside the chat button's icon; empty: the round button. */
901
990
  label?: string;
991
+ /** The name beside the team's mark at the top of Home (MRRocket fills in the product's name). */
902
992
  title?: string;
903
993
  /** The big line on Home and the first line of an empty chat. */
904
994
  greeting?: string;
905
- /** How soon the team usually answers, said under "Send us a message" and in the chat's head. */
995
+ /** How soon the team usually answers, said on Home. */
906
996
  replyTime?: "minutes" | "hours" | "day";
997
+ /** How round bubbles, cards and fields are (default round; the sheet itself keeps the system's corners). */
998
+ corners?: MessengerCorners;
999
+ /** Home's top: plain like the rest (default), or in the accent color with raised cards. */
1000
+ header?: "plain" | "color";
1001
+ /** The product's icon at the top left of Home (MRRocket sends the product's favicon). */
1002
+ logo?: string;
907
1003
  /** Ask people the app did not identify with an email for an email (optional for them). Default true. */
908
1004
  askEmail?: boolean;
909
1005
  /** The Help tab with your published help articles (default true; hidden while there are none). */