@mailiy/sdk 0.2.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mailiy.d.ts CHANGED
@@ -70,10 +70,140 @@ export interface MailiyForm {
70
70
  max_submissions: number;
71
71
  /** Field names, one per line; a submission missing one gets missing_fields. */
72
72
  required_fields: string;
73
+ /** A submission whose field has the value goes to these addresses instead of recipients. */
74
+ recipient_rules: MailiyRecipientRule[];
75
+ /** Fields of the hosted page; empty until set. */
76
+ fields: MailiyFormField[];
77
+ /** 1: the form has a public page at hosted_url. */
78
+ hosted: number;
79
+ hosted_url: string;
80
+ hosted_intro: string;
81
+ /** 1: the page keeps unsent answers in the visitor's browser. */
82
+ hosted_save: number;
83
+ /** Shown after sending on the hosted page; empty: a default text. */
84
+ success_message: string;
85
+ /**
86
+ * Field whose amount the visitor pays through Stripe after sending; empty: no payment.
87
+ * The owner gets the mail once paid, or after 24 hours marked as payment open.
88
+ */
89
+ payment_field: string;
90
+ currency: MailiyCurrency;
91
+ /** Statuses, roles and actions; forms without their own get open, in_progress and done. */
92
+ workflow: MailiyWorkflow;
73
93
  created_at: number;
74
94
  submissions?: number;
75
95
  delivered?: number;
76
96
  }
97
+ /** Compared without case; the address must be a verified email of the account. */
98
+ export interface MailiyRecipientRule {
99
+ field: string;
100
+ value: string;
101
+ to: string;
102
+ }
103
+ export type MailiyFieldType = "text" | "email" | "tel" | "url" | "number" | "currency" | "date" | "time" | "textarea" | "select" | "radio" | "checkbox" | "checkboxes" | "file" | "name" | "address" | "rating" | "signature" | "lookup" | "person" | "price" | "calculation" | "content" | "section" | "pagebreak" | "repeating" | "table";
104
+ export type MailiyCurrency = "EUR" | "CHF" | "GBP" | "USD";
105
+ /** Rules compare the answer of another field of the same form. */
106
+ export interface MailiyCondition {
107
+ match: "all" | "any";
108
+ rules: {
109
+ field: string;
110
+ op: "equals" | "not_equals" | "contains" | "empty" | "not_empty" | "greater" | "less";
111
+ value?: string;
112
+ }[];
113
+ }
114
+ /**
115
+ * `name` is the key in the submission. `options` holds the choices of select, radio and
116
+ * checkboxes, the questions of a rating and the people of a person field as "Name <email>"
117
+ * lines (the page shows only the names).
118
+ */
119
+ export interface MailiyFormField {
120
+ name: string;
121
+ label: string;
122
+ type: MailiyFieldType;
123
+ required?: boolean;
124
+ options?: string[];
125
+ placeholder?: string;
126
+ help?: string;
127
+ default?: string;
128
+ /** Length for text, value for number and currency, rows for repeating and table. */
129
+ min?: number;
130
+ max?: number;
131
+ width?: 25 | 33 | 50 | 67 | 75 | 100;
132
+ /** Highest score of a rating, 3 to 10. */
133
+ scale?: number;
134
+ /** Price per option of select, radio and checkboxes. */
135
+ prices?: number[];
136
+ /** Fixed amount of a price field or a checkbox. */
137
+ price?: number;
138
+ /** Calculation, e.g. "{rooms} * 80 + {fee}". */
139
+ formula?: string;
140
+ /** Choices taken from the answers to a field of another form of the same account. */
141
+ lookup?: {
142
+ form: string;
143
+ field: string;
144
+ };
145
+ show_when?: MailiyCondition;
146
+ require_when?: MailiyCondition;
147
+ /** Columns of repeating and table, up to 10 simple fields. */
148
+ fields?: MailiyFormField[];
149
+ }
150
+ /** A status id from the form's workflow; the default workflow has open, in_progress and done. */
151
+ export type MailiySubmissionStatus = string;
152
+ export type MailiyWorkflowColor = "gray" | "blue" | "green" | "yellow" | "orange" | "red" | "purple";
153
+ /**
154
+ * Ids match ^[a-z][a-z0-9_]{0,31}$ and may not be all, delivered, spam or unread.
155
+ * x and y place the node on the dashboard canvas.
156
+ */
157
+ export interface MailiyWorkflowStatus {
158
+ id: string;
159
+ /** 1 to 365: the owner gets one mail when a submission sits this many days in the status. */
160
+ remind_days?: number;
161
+ name: string;
162
+ color: MailiyWorkflowColor;
163
+ x: number;
164
+ y: number;
165
+ }
166
+ /** Someone outside the team who runs actions through an emailed link (valid 30 days). */
167
+ export interface MailiyWorkflowRole {
168
+ id: string;
169
+ name: string;
170
+ /** A fixed address or `field:<name>` of an email or person field. */
171
+ email: string;
172
+ }
173
+ export interface MailiyWorkflowEmail {
174
+ /** A fixed address or `field:<name>`. */
175
+ to: string;
176
+ /** Subject and body take {field:name} placeholders. */
177
+ subject: string;
178
+ body: string;
179
+ /** Role whose action link goes into the mail; "" for none. */
180
+ link_role: string;
181
+ }
182
+ export interface MailiyWorkflowAction {
183
+ id: string;
184
+ /** Button text. */
185
+ name: string;
186
+ /** Statuses in which the action is offered; empty: every status. */
187
+ from: string[];
188
+ /** Roles that may run it by link; the team may run every action. */
189
+ roles: string[];
190
+ /** New status; "" keeps the current one. */
191
+ to: string;
192
+ /** Up to 5. */
193
+ emails: MailiyWorkflowEmail[];
194
+ /** Sends the run to the website's integrations. */
195
+ integrations: boolean;
196
+ /** Answers deleted for good when the action runs. */
197
+ clear_fields: string[];
198
+ x: number;
199
+ y: number;
200
+ }
201
+ /** Up to 12 statuses (new submissions get the first), 10 roles and 20 actions. */
202
+ export interface MailiyWorkflow {
203
+ statuses: MailiyWorkflowStatus[];
204
+ roles: MailiyWorkflowRole[];
205
+ actions: MailiyWorkflowAction[];
206
+ }
77
207
  export interface MailiySubmission {
78
208
  id: string;
79
209
  form_id: string;
@@ -89,15 +219,47 @@ export interface MailiySubmission {
89
219
  type: string;
90
220
  url: string;
91
221
  }[];
222
+ read: boolean;
92
223
  spam: boolean;
224
+ status: MailiySubmissionStatus;
225
+ /** User id of the person who takes care of it (see listAssignees); null: nobody. */
226
+ assignee_id: string | null;
227
+ /** Set when the hosted form asked for a payment; paid once Stripe confirms it, refunded once paid back in full. */
228
+ payment_status: "" | "pending" | "paid" | "refunded";
229
+ /** In cents of the form's currency. */
230
+ payment_amount: number;
231
+ /** Cents paid back so far through Mailiy. */
232
+ payment_refunded: number;
233
+ }
234
+ /** One line of a submission's history; the fields after kind depend on it. */
235
+ export interface MailiyHistoryEntry {
236
+ /** Email of the person; null for the arrival, a workflow link (see role) or a deleted account. */
237
+ actor: string | null;
238
+ created_at: number;
239
+ kind: "action" | "assign" | "created" | "forward" | "refund" | "status";
240
+ /** action: name of the workflow action. */
241
+ action?: string;
242
+ /** refund: in cents. */
243
+ amount?: number;
244
+ /** assign: user id, null for nobody. */
245
+ assignee?: string | null;
246
+ /** action through a workflow link: name of the role. */
247
+ role?: string;
248
+ /** action and status: the new status id. */
249
+ status?: string;
250
+ /** forward: recipient address. */
251
+ to?: string;
93
252
  }
94
253
  export interface MailiySubmissionFilter {
254
+ /** A user id from listAssignees, or "me" for the signed-in person (with an API key: the account owner). */
255
+ assignee?: string;
95
256
  /** next_cursor of the previous result: opens the next block of 1000 older submissions. */
96
257
  cursor?: string;
97
258
  form?: string;
98
259
  page?: number;
99
260
  q?: string;
100
- status?: "delivered" | "spam";
261
+ /** A workflow status id or unread only lists delivered submissions. */
262
+ status?: "delivered" | "spam" | "unread" | MailiySubmissionStatus;
101
263
  }
102
264
  export interface MailiySubmissionPage {
103
265
  keys: string[];
@@ -200,12 +362,26 @@ export type MailiyFormPatch = Partial<{
200
362
  /** Placeholders: {fields}, {intro}, {form}, {field:name}. */
201
363
  email_html: string;
202
364
  email_template: EmailTemplate;
365
+ /** Up to 50 fields with unique names. */
366
+ fields: MailiyFormField[];
203
367
  from_name: string;
204
368
  group_emails: boolean;
369
+ hosted: boolean;
370
+ hosted_intro: string;
371
+ /** Keep unsent answers in the visitor's browser (localStorage) until they send. */
372
+ hosted_save: boolean;
205
373
  intro_text: string;
206
374
  max_submissions: number;
207
375
  name: string;
208
376
  opens_at: number | null;
377
+ /**
378
+ * Name of a price, calculation or currency field, else invalid_payment_field.
379
+ * Amounts under 0.50 (GBP 0.30) fail on submit with 422 amount_too_low.
380
+ */
381
+ payment_field: string;
382
+ currency: MailiyCurrency;
383
+ /** Up to 20 rules. */
384
+ recipient_rules: MailiyRecipientRule[];
209
385
  recipients: string[];
210
386
  redirect_url: string;
211
387
  require_consent: boolean;
@@ -217,7 +393,13 @@ export type MailiyFormPatch = Partial<{
217
393
  server_requires_key: boolean;
218
394
  spam_filter: SpamFilter;
219
395
  subject: string;
396
+ success_message: string;
220
397
  website: string;
398
+ /**
399
+ * Replaces the workflow, else invalid_workflow (unknown or duplicate ids, missing references,
400
+ * limits). Submissions in a removed status move to the first status.
401
+ */
402
+ workflow: MailiyWorkflow;
221
403
  }>;
222
404
  export interface MailiyOptions {
223
405
  /** Personal API key from Dashboard → Account → API keys (starts with mk_). */
@@ -237,7 +419,9 @@ export declare class MailiyError extends Error {
237
419
  name: string;
238
420
  readonly code: string;
239
421
  readonly status: number;
240
- constructor(code: string, status: number);
422
+ /** With missing_fields: the required fields that were missing or empty. */
423
+ readonly fields: string[] | undefined;
424
+ constructor(code: string, status: number, fields?: string[]);
241
425
  }
242
426
  export declare const DEFAULT_BASE_URL = "https://mailiy.com";
243
427
  export declare const createMailiy: (options?: MailiyOptions) => {
@@ -271,6 +455,10 @@ export declare const createMailiy: (options?: MailiyOptions) => {
271
455
  deleteSubmission: (formId: string, submissionId: string) => Promise<{
272
456
  ok: true;
273
457
  }>;
458
+ /** Deletes up to 500 submissions of any forms in the account; ids from elsewhere are skipped. */
459
+ deleteSubmissions: (ids: string[]) => Promise<{
460
+ deleted: number;
461
+ }>;
274
462
  /** Deletes the website with all its forms and stored submissions. */
275
463
  deleteWebsite: (id: string) => Promise<{
276
464
  ok: true;
@@ -280,10 +468,25 @@ export declare const createMailiy: (options?: MailiyOptions) => {
280
468
  id: string;
281
469
  name: string;
282
470
  }>;
471
+ /** Mails the answers and file links to any address; the reply-to is your own. Up to 20 per hour. */
472
+ forwardSubmission: (submissionId: string, to: string, note?: string) => Promise<{
473
+ ok: true;
474
+ }>;
283
475
  getForm: (id: string) => Promise<MailiyForm>;
284
476
  /** Public service health, cached for 30 seconds. */
285
477
  getStatus: () => Promise<MailiyStatus>;
478
+ /** Who changed the status, assigned, ran actions, forwarded or refunded, newest first; the last entry is the arrival. */
479
+ getSubmissionHistory: (submissionId: string) => Promise<MailiyHistoryEntry[]>;
286
480
  getWebsite: (id: string) => Promise<MailiyWebsite>;
481
+ /** Adds old submissions from CSV text (first line the field names, up to 5000 rows and 1 MB); they arrive read and send no mails. */
482
+ importSubmissions: (formId: string, csv: string) => Promise<{
483
+ imported: number;
484
+ }>;
485
+ /** The owner and the members (not clients) a submission can be assigned to. */
486
+ listAssignees: () => Promise<{
487
+ email: string;
488
+ id: string;
489
+ }[]>;
287
490
  /** The newest 50 deliveries of an integration. */
288
491
  listDeliveries: (id: string) => Promise<MailiyDelivery[]>;
289
492
  listForms: (websiteId?: string) => Promise<MailiyForm[]>;
@@ -305,12 +508,30 @@ export declare const createMailiy: (options?: MailiyOptions) => {
305
508
  previewEmail: (id: string, patch?: MailiyFormPatch) => Promise<MailiyRenderedEmail & {
306
509
  autoresponder: MailiyRenderedEmail | null;
307
510
  }>;
511
+ /**
512
+ * Pays back a paid form payment through the connected Stripe account, in cents; without an amount the
513
+ * whole open rest. not_refundable (409) when nothing is left or the payment predates refunds in Mailiy.
514
+ */
515
+ refundSubmission: (submissionId: string, amount?: number) => Promise<{
516
+ id: string;
517
+ payment_refunded: number;
518
+ payment_status: "paid" | "refunded";
519
+ }>;
308
520
  /** Sends a failed delivery once more, as long as its payload is still stored. */
309
521
  retryDelivery: (id: string) => Promise<MailiyDelivery>;
310
522
  /** Replaces the access key; the old one stops working at once. Submissions move to the new id. */
311
523
  rotateAccessKey: (id: string) => Promise<{
312
524
  id: string;
313
525
  }>;
526
+ /**
527
+ * Runs a workflow action on a submission: clears fields, sets the status, sends the emails and
528
+ * notifies integrations. not_found for an unknown submission or action, action_not_allowed (409)
529
+ * when the action does not start from the current status.
530
+ */
531
+ runAction: (submissionId: string, actionId: string) => Promise<{
532
+ id: string;
533
+ status: MailiySubmissionStatus;
534
+ }>;
314
535
  /** Submissions of all forms in the account (or one website), 25 per page, newest first, in blocks of 1000 (see cursor). */
315
536
  searchSubmissions: (filter?: MailiySubmissionFilter & {
316
537
  website?: string;
@@ -320,6 +541,14 @@ export declare const createMailiy: (options?: MailiyOptions) => {
320
541
  sendTest: (id: string) => Promise<{
321
542
  ok: true;
322
543
  }>;
544
+ /** Sets the status, the read mark or the assignee (null: nobody) of up to 500 submissions; ids from elsewhere are skipped. */
545
+ setSubmissions: (ids: string[], patch: {
546
+ assignee?: string | null;
547
+ read?: boolean;
548
+ status?: MailiySubmissionStatus;
549
+ }) => Promise<{
550
+ updated: number;
551
+ }>;
323
552
  /** Delivered and spam counts per day (7d, 30d) or month (12m), for the account or one website. */
324
553
  stats: (range?: "7d" | "30d" | "12m", website?: string) => Promise<MailiyStats>;
325
554
  /**
package/dist/mailiy.js CHANGED
@@ -10,10 +10,15 @@ export class MailiyError extends Error {
10
10
  name = "MailiyError";
11
11
  code;
12
12
  status;
13
- constructor(code, status) {
14
- super(`Mailiy API error ${status}: ${code}`);
13
+ /** With missing_fields: the required fields that were missing or empty. */
14
+ fields;
15
+ constructor(code, status, fields) {
16
+ super(fields
17
+ ? `Mailiy API error ${status}: ${code} (${fields.join(", ")})`
18
+ : `Mailiy API error ${status}: ${code}`);
15
19
  this.code = code;
16
20
  this.status = status;
21
+ this.fields = fields;
17
22
  }
18
23
  }
19
24
  const form = (id) => `/forms/${encodeURIComponent(id)}`;
@@ -41,7 +46,7 @@ export const createMailiy = (options = {}) => {
41
46
  });
42
47
  const json = (await res.json().catch(() => ({})));
43
48
  if (!res.ok) {
44
- throw new MailiyError(json.error ?? json.code ?? res.statusText, res.status);
49
+ throw new MailiyError(json.error ?? json.code ?? res.statusText, res.status, json.fields);
45
50
  }
46
51
  return { headers: res.headers, json };
47
52
  };
@@ -70,14 +75,24 @@ export const createMailiy = (options = {}) => {
70
75
  deleteForm: (id) => call(form(id), "DELETE"),
71
76
  deleteIntegration: (id) => call(integration(id), "DELETE"),
72
77
  deleteSubmission: (formId, submissionId) => call(`${form(formId)}/submissions/${encodeURIComponent(submissionId)}`, "DELETE"),
78
+ /** Deletes up to 500 submissions of any forms in the account; ids from elsewhere are skipped. */
79
+ deleteSubmissions: (ids) => call("/submissions/delete", "POST", { ids }),
73
80
  /** Deletes the website with all its forms and stored submissions. */
74
81
  deleteWebsite: (id) => call(site(id), "DELETE"),
75
82
  /** Copies a form with all settings under a new access key. */
76
83
  duplicateForm: (id, name) => call(`${form(id)}/duplicate`, "POST", name === undefined ? {} : { name }),
84
+ /** Mails the answers and file links to any address; the reply-to is your own. Up to 20 per hour. */
85
+ forwardSubmission: (submissionId, to, note = "") => call(`/submissions/${encodeURIComponent(submissionId)}/forward`, "POST", { note, to }),
77
86
  getForm: (id) => call(form(id)),
78
87
  /** Public service health, cached for 30 seconds. */
79
88
  getStatus: () => call("/status"),
89
+ /** Who changed the status, assigned, ran actions, forwarded or refunded, newest first; the last entry is the arrival. */
90
+ getSubmissionHistory: (submissionId) => call(`/submissions/${encodeURIComponent(submissionId)}/history`),
80
91
  getWebsite: (id) => call(site(id)),
92
+ /** Adds old submissions from CSV text (first line the field names, up to 5000 rows and 1 MB); they arrive read and send no mails. */
93
+ importSubmissions: (formId, csv) => call(`${form(formId)}/import`, "POST", { csv }),
94
+ /** The owner and the members (not clients) a submission can be assigned to. */
95
+ listAssignees: () => call("/assignees"),
81
96
  /** The newest 50 deliveries of an integration. */
82
97
  listDeliveries: (id) => call(`${integration(id)}/deliveries`),
83
98
  listForms: (websiteId) => call(websiteId ? `/forms?website=${encodeURIComponent(websiteId)}` : "/forms"),
@@ -95,15 +110,28 @@ export const createMailiy = (options = {}) => {
95
110
  pageSubmissions,
96
111
  /** Renders the notification and auto-reply with sample data; patch fields override the saved ones. */
97
112
  previewEmail: (id, patch = {}) => call(`${form(id)}/preview`, "POST", patch),
113
+ /**
114
+ * Pays back a paid form payment through the connected Stripe account, in cents; without an amount the
115
+ * whole open rest. not_refundable (409) when nothing is left or the payment predates refunds in Mailiy.
116
+ */
117
+ refundSubmission: (submissionId, amount) => call(`/submissions/${encodeURIComponent(submissionId)}/refund`, "POST", amount === undefined ? {} : { amount }),
98
118
  /** Sends a failed delivery once more, as long as its payload is still stored. */
99
119
  retryDelivery: (id) => call(`/deliveries/${encodeURIComponent(id)}/retry`, "POST"),
100
120
  /** Replaces the access key; the old one stops working at once. Submissions move to the new id. */
101
121
  rotateAccessKey: (id) => call(`${form(id)}/rotate-key`, "POST"),
122
+ /**
123
+ * Runs a workflow action on a submission: clears fields, sets the status, sends the emails and
124
+ * notifies integrations. not_found for an unknown submission or action, action_not_allowed (409)
125
+ * when the action does not start from the current status.
126
+ */
127
+ runAction: (submissionId, actionId) => call(`/submissions/${encodeURIComponent(submissionId)}/actions/${encodeURIComponent(actionId)}`, "POST"),
102
128
  /** Submissions of all forms in the account (or one website), 25 per page, newest first, in blocks of 1000 (see cursor). */
103
129
  searchSubmissions: (filter = {}) => call(`/submissions?${query(filter)}`),
104
130
  /** Submissions of all forms in a website, 25 per page, newest first, in blocks of 1000 (see cursor). */
105
131
  searchWebsiteSubmissions: (id, filter = {}) => call(`${site(id)}/submissions?${query(filter)}`),
106
132
  sendTest: (id) => call(`${form(id)}/test`, "POST"),
133
+ /** Sets the status, the read mark or the assignee (null: nobody) of up to 500 submissions; ids from elsewhere are skipped. */
134
+ setSubmissions: (ids, patch) => call("/submissions", "PATCH", { ids, ...patch }),
107
135
  /** Delivered and spam counts per day (7d, 30d) or month (12m), for the account or one website. */
108
136
  stats: (range = "30d", website) => call(`/stats?${query({ range, website })}`),
109
137
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mailiy/sdk",
3
- "version": "0.2.0",
3
+ "version": "0.5.0",
4
4
  "description": "Typed, dependency-free client for the Mailiy REST API.",
5
5
  "keywords": [
6
6
  "api-client",