@automate.ax/integration-contracts 0.114.4 → 0.115.2

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.
@@ -1,332 +1,268 @@
1
1
  import * as z from "zod";
2
- export const BREVO_TRANSACTIONAL_EVENT_TYPES = [
2
+ export const BREVO_EVENT_FAMILIES = [
3
+ "transactionalEmail",
4
+ "transactionalSms",
5
+ "marketingEmail",
6
+ "marketingSms",
7
+ "contact",
8
+ ];
9
+ export const BREVO_TRANSACTIONAL_EMAIL_EVENT_TYPES = [
10
+ "sent",
11
+ "delivered",
12
+ "hardBounced",
13
+ "softBounced",
3
14
  "blocked",
4
- "click",
15
+ "markedAsSpam",
16
+ "invalid",
5
17
  "deferred",
18
+ "clicked",
19
+ "opened",
20
+ "firstOpened",
21
+ "unsubscribed",
22
+ ];
23
+ export const BREVO_TRANSACTIONAL_SMS_EVENT_TYPES = [
24
+ "sent",
6
25
  "delivered",
7
- "error",
8
- "hard_bounce",
9
- "invalid_email",
26
+ "hardBounced",
27
+ "softBounced",
28
+ "replied",
29
+ "unsubscribed",
30
+ ];
31
+ export const BREVO_MARKETING_EMAIL_EVENT_TYPES = [
32
+ "delivered",
33
+ "hardBounced",
34
+ "softBounced",
35
+ "markedAsSpam",
10
36
  "opened",
11
- "request",
12
- "soft_bounce",
13
- "spam",
14
- "unique_opened",
37
+ "clicked",
15
38
  "unsubscribed",
16
39
  ];
17
- const BREVO_PROVIDER_EVENT_BASE_SCHEMA = z
18
- .looseObject({
19
- /** Custom header supplied with the original email. */
20
- "X-Mailin-custom": z.string().optional(),
21
- /** Provider-local formatted date for the event. */
22
- date: z.string().optional(),
23
- /** Recipient email address. */
24
- email: z.string().optional(),
25
- /** Brevo webhook ID that delivered the event. */
26
- id: z.number().int().nonnegative(),
27
- /** Provider message identity. */
28
- "message-id": z.string().optional(),
29
- /** Email subject. */
30
- subject: z.string().optional(),
31
- /** Tags supplied with the original email. */
32
- tags: z.string().array().optional(),
33
- /** Internal template ID used to send the email. */
34
- template_id: z.number().int().nonnegative().optional(),
35
- /** Unix timestamp in seconds for the underlying email event. */
36
- ts: z.number().int().nonnegative().optional(),
37
- /** Unix timestamp in seconds when Brevo emitted the webhook event. */
38
- ts_event: z.number().int().nonnegative(),
39
- })
40
- .catchall(z.json());
41
- const BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA = z.object({
42
- /** Sending IP used for the message. */
43
- sending_ip: z.string().optional(),
44
- /** Provider timestamp in milliseconds. */
45
- ts_epoch: z.number().int().nonnegative().optional(),
46
- });
47
- const BREVO_PROVIDER_ENGAGEMENT_METADATA_SCHEMA = z.object({
48
- /** Brevo contact ID, or zero when the recipient is not a contact. */
49
- contact_id: z.number().int().nonnegative().optional(),
50
- /** Device category reported for the interaction. */
51
- device_used: z.string().optional(),
52
- /** Brevo log preview URL. */
53
- mirror_link: z.string().optional(),
54
- /** Browser or email-client user agent. */
55
- user_agent: z.string().optional(),
56
- });
57
- const BREVO_PROVIDER_SENT_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
58
- ...BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA.shape,
59
- ...BREVO_PROVIDER_ENGAGEMENT_METADATA_SCHEMA.pick({
60
- contact_id: true,
61
- mirror_link: true,
62
- }).shape,
63
- event: z.literal("request"),
64
- });
65
- const BREVO_PROVIDER_DELIVERED_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
66
- ...BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA.shape,
67
- event: z.literal("delivered"),
68
- });
69
- const BREVO_PROVIDER_HARD_BOUNCED_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
70
- ...BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA.shape,
71
- event: z.literal("hard_bounce"),
72
- reason: z.string().optional(),
73
- });
74
- const BREVO_PROVIDER_SOFT_BOUNCED_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
75
- ...BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA.shape,
76
- event: z.literal("soft_bounce"),
77
- reason: z.string().optional(),
78
- });
79
- const BREVO_PROVIDER_BLOCKED_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
80
- event: z.literal("blocked"),
81
- ts_epoch: z.number().int().nonnegative().optional(),
82
- });
83
- const BREVO_PROVIDER_DEFERRED_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
84
- ...BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA.shape,
85
- event: z.literal("deferred"),
86
- reason: z.string().optional(),
87
- });
88
- const BREVO_PROVIDER_OPENED_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
89
- ...BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA.shape,
90
- ...BREVO_PROVIDER_ENGAGEMENT_METADATA_SCHEMA.shape,
91
- event: z.literal("opened"),
92
- });
93
- const BREVO_PROVIDER_UNIQUE_OPENED_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
94
- ...BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA.shape,
95
- ...BREVO_PROVIDER_ENGAGEMENT_METADATA_SCHEMA.shape,
96
- event: z.literal("unique_opened"),
97
- });
98
- const BREVO_PROVIDER_CLICKED_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
99
- ...BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA.shape,
100
- ...BREVO_PROVIDER_ENGAGEMENT_METADATA_SCHEMA.shape,
101
- event: z.literal("click"),
102
- link: z.string().optional(),
103
- });
104
- const BREVO_PROVIDER_SPAM_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({ event: z.literal("spam") });
105
- const BREVO_PROVIDER_UNSUBSCRIBED_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
106
- ...BREVO_PROVIDER_DELIVERY_METADATA_SCHEMA.shape,
107
- ...BREVO_PROVIDER_ENGAGEMENT_METADATA_SCHEMA.shape,
108
- event: z.literal("unsubscribed"),
109
- tag: z.string().optional(),
110
- });
111
- const BREVO_PROVIDER_INVALID_EMAIL_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
112
- event: z.literal("invalid_email"),
113
- ts_epoch: z.number().int().nonnegative().optional(),
114
- });
115
- const BREVO_PROVIDER_ERROR_EVENT_SCHEMA = BREVO_PROVIDER_EVENT_BASE_SCHEMA.extend({
116
- event: z.literal("error"),
117
- ts_epoch: z.number().int().nonnegative().optional(),
118
- });
119
- const BREVO_PROVIDER_TRANSACTIONAL_EVENT_SCHEMA = z.discriminatedUnion("event", [
120
- BREVO_PROVIDER_BLOCKED_EVENT_SCHEMA,
121
- BREVO_PROVIDER_CLICKED_EVENT_SCHEMA,
122
- BREVO_PROVIDER_DEFERRED_EVENT_SCHEMA,
123
- BREVO_PROVIDER_DELIVERED_EVENT_SCHEMA,
124
- BREVO_PROVIDER_ERROR_EVENT_SCHEMA,
125
- BREVO_PROVIDER_HARD_BOUNCED_EVENT_SCHEMA,
126
- BREVO_PROVIDER_INVALID_EMAIL_EVENT_SCHEMA,
127
- BREVO_PROVIDER_OPENED_EVENT_SCHEMA,
128
- BREVO_PROVIDER_SENT_EVENT_SCHEMA,
129
- BREVO_PROVIDER_SOFT_BOUNCED_EVENT_SCHEMA,
130
- BREVO_PROVIDER_SPAM_EVENT_SCHEMA,
131
- BREVO_PROVIDER_UNIQUE_OPENED_EVENT_SCHEMA,
132
- BREVO_PROVIDER_UNSUBSCRIBED_EVENT_SCHEMA,
133
- ]);
134
- const BREVO_EVENT_BASE_SCHEMA = z.object({
135
- /** Custom header supplied with the original email. */
40
+ export const BREVO_CONTACT_EVENT_TYPES = [
41
+ "addedToList",
42
+ "updated",
43
+ "deleted",
44
+ ];
45
+ export const BREVO_MARKETING_SMS_EVENT_TYPES = [
46
+ "sent",
47
+ "delivered",
48
+ "hardBounced",
49
+ "softBounced",
50
+ "replied",
51
+ "unsubscribed",
52
+ ];
53
+ const BREVO_NORMALIZED_EVENT_FIELDS = {
54
+ bounceType: z.string().optional(),
55
+ campaignId: z.number().int().nonnegative().optional(),
56
+ campaignName: z.string().optional(),
57
+ contactId: z.number().int().nonnegative().optional(),
58
+ content: z.json().optional(),
59
+ creditsUsed: z.number().nonnegative().optional(),
136
60
  customHeader: z.string().optional(),
137
- /** Provider-local formatted date for the event. */
138
61
  date: z.string().optional(),
139
- /** Recipient email address. */
62
+ dateEvent: z.string().optional(),
63
+ dateSent: z.string().optional(),
64
+ description: z.string().optional(),
65
+ deviceUsed: z.string().optional(),
140
66
  email: z.string().optional(),
141
- /** Provider message identity. */
142
- messageId: z.string().optional(),
143
- /** Unix timestamp in seconds when Brevo emitted the webhook event. */
144
- occurredAt: z.number().int().nonnegative(),
145
- /** Email subject. */
67
+ errorCode: z.number().int().optional(),
68
+ event: z.record(z.string(), z.json()),
69
+ key: z.string().optional(),
70
+ link: z.string().optional(),
71
+ listIds: z.number().int().nonnegative().array().optional(),
72
+ messageId: z.union([z.string(), z.number().int()]).optional(),
73
+ mirrorLink: z.string().optional(),
74
+ occurredAt: z.number().int().nonnegative().optional(),
75
+ phone: z.string().optional(),
76
+ reason: z.string().optional(),
77
+ reference: z.union([z.string(), z.record(z.string(), z.string())]).optional(),
78
+ remainingCredit: z.number().nonnegative().optional(),
79
+ reply: z.string().optional(),
80
+ segmentIds: z.number().int().nonnegative().array().optional(),
81
+ senderEmail: z.string().optional(),
82
+ sendingIp: z.string().optional(),
83
+ smsCount: z.number().int().nonnegative().optional(),
84
+ status: z.string().optional(),
146
85
  subject: z.string().optional(),
147
- /** Tags supplied with the original email. */
86
+ tag: z.union([z.string(), z.string().array()]).optional(),
148
87
  tags: z.string().array().optional(),
149
- /** Internal template ID used to send the email. */
150
88
  templateId: z.number().int().nonnegative().optional(),
151
- /** Unix timestamp in seconds for the underlying email event. */
152
89
  timestamp: z.number().int().nonnegative().optional(),
153
- /** Brevo webhook ID that delivered the event. */
154
- webhookId: z.number().int().nonnegative(),
155
- });
156
- const BREVO_DELIVERY_METADATA_SCHEMA = z.object({
157
- /** Sending IP used for the message. */
158
- sendingIp: z.string().optional(),
159
- /** Provider timestamp in milliseconds. */
160
90
  timestampMilliseconds: z.number().int().nonnegative().optional(),
161
- });
162
- const BREVO_ENGAGEMENT_METADATA_SCHEMA = z.object({
163
- /** Brevo contact ID, or zero when the recipient is not a contact. */
164
- contactId: z.number().int().nonnegative().optional(),
165
- /** Device category reported for the interaction. */
166
- deviceUsed: z.string().optional(),
167
- /** Brevo log preview URL. */
168
- mirrorLink: z.string().optional(),
169
- /** Browser or email-client user agent. */
91
+ timestampSent: z.number().int().nonnegative().optional(),
170
92
  userAgent: z.string().optional(),
93
+ webhookId: z.number().int().nonnegative(),
94
+ };
95
+ const createBrevoFamilyEventSchema = (family, types) => z.object({
96
+ ...BREVO_NORMALIZED_EVENT_FIELDS,
97
+ family: z.literal(family),
98
+ type: z.enum(types),
171
99
  });
172
- export const BREVO_EMAIL_SENT_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
173
- ...BREVO_DELIVERY_METADATA_SCHEMA.shape,
174
- ...BREVO_ENGAGEMENT_METADATA_SCHEMA.pick({
175
- contactId: true,
176
- mirrorLink: true,
177
- }).shape,
178
- /** Original provider webhook payload. */
179
- event: BREVO_PROVIDER_SENT_EVENT_SCHEMA,
180
- /** Brevo transactional event category. */
181
- type: z.literal("request"),
182
- });
183
- export const BREVO_EMAIL_DELIVERED_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
184
- ...BREVO_DELIVERY_METADATA_SCHEMA.shape,
185
- /** Original provider webhook payload. */
186
- event: BREVO_PROVIDER_DELIVERED_EVENT_SCHEMA,
187
- /** Brevo transactional event category. */
188
- type: z.literal("delivered"),
189
- });
190
- export const BREVO_EMAIL_HARD_BOUNCED_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
191
- ...BREVO_DELIVERY_METADATA_SCHEMA.shape,
192
- /** Original provider webhook payload. */
193
- event: BREVO_PROVIDER_HARD_BOUNCED_EVENT_SCHEMA,
194
- /** Provider explanation for the permanent delivery failure. */
195
- reason: z.string().optional(),
196
- /** Brevo transactional event category. */
197
- type: z.literal("hard_bounce"),
198
- });
199
- export const BREVO_EMAIL_SOFT_BOUNCED_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
200
- ...BREVO_DELIVERY_METADATA_SCHEMA.shape,
201
- /** Original provider webhook payload. */
202
- event: BREVO_PROVIDER_SOFT_BOUNCED_EVENT_SCHEMA,
203
- /** Provider explanation for the temporary delivery failure. */
204
- reason: z.string().optional(),
205
- /** Brevo transactional event category. */
206
- type: z.literal("soft_bounce"),
207
- });
208
- export const BREVO_EMAIL_BLOCKED_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
209
- /** Original provider webhook payload. */
210
- event: BREVO_PROVIDER_BLOCKED_EVENT_SCHEMA,
211
- /** Provider timestamp in milliseconds. */
212
- timestampMilliseconds: z.number().int().nonnegative().optional(),
213
- /** Brevo transactional event category. */
214
- type: z.literal("blocked"),
215
- });
216
- export const BREVO_EMAIL_DEFERRED_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
217
- ...BREVO_DELIVERY_METADATA_SCHEMA.shape,
218
- /** Original provider webhook payload. */
219
- event: BREVO_PROVIDER_DEFERRED_EVENT_SCHEMA,
220
- /** Provider explanation for the delayed delivery attempt. */
221
- reason: z.string().optional(),
222
- /** Brevo transactional event category. */
223
- type: z.literal("deferred"),
224
- });
225
- const BREVO_EMAIL_OPENED_EVENT_MEMBER_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
226
- ...BREVO_DELIVERY_METADATA_SCHEMA.shape,
227
- ...BREVO_ENGAGEMENT_METADATA_SCHEMA.shape,
228
- /** Original provider webhook payload. */
229
- event: BREVO_PROVIDER_OPENED_EVENT_SCHEMA,
230
- /** Brevo transactional event category. */
231
- type: z.literal("opened"),
232
- });
233
- const BREVO_EMAIL_UNIQUE_OPENED_EVENT_MEMBER_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
234
- ...BREVO_DELIVERY_METADATA_SCHEMA.shape,
235
- ...BREVO_ENGAGEMENT_METADATA_SCHEMA.shape,
236
- /** Original provider webhook payload. */
237
- event: BREVO_PROVIDER_UNIQUE_OPENED_EVENT_SCHEMA,
238
- /** Brevo transactional event category. */
239
- type: z.literal("unique_opened"),
240
- });
241
- export const BREVO_EMAIL_OPENED_EVENT_SCHEMA = z.discriminatedUnion("type", [
242
- BREVO_EMAIL_OPENED_EVENT_MEMBER_SCHEMA,
243
- BREVO_EMAIL_UNIQUE_OPENED_EVENT_MEMBER_SCHEMA,
100
+ export const BREVO_TRANSACTIONAL_EMAIL_EVENT_SCHEMA = createBrevoFamilyEventSchema("transactionalEmail", BREVO_TRANSACTIONAL_EMAIL_EVENT_TYPES);
101
+ export const BREVO_TRANSACTIONAL_SMS_EVENT_SCHEMA = createBrevoFamilyEventSchema("transactionalSms", BREVO_TRANSACTIONAL_SMS_EVENT_TYPES);
102
+ export const BREVO_MARKETING_EMAIL_EVENT_SCHEMA = createBrevoFamilyEventSchema("marketingEmail", BREVO_MARKETING_EMAIL_EVENT_TYPES);
103
+ export const BREVO_MARKETING_SMS_EVENT_SCHEMA = createBrevoFamilyEventSchema("marketingSms", BREVO_MARKETING_SMS_EVENT_TYPES);
104
+ export const BREVO_CONTACT_EVENT_SCHEMA = createBrevoFamilyEventSchema("contact", BREVO_CONTACT_EVENT_TYPES);
105
+ export const BREVO_EVENT_SCHEMA = z.discriminatedUnion("family", [
106
+ BREVO_TRANSACTIONAL_EMAIL_EVENT_SCHEMA,
107
+ BREVO_TRANSACTIONAL_SMS_EVENT_SCHEMA,
108
+ BREVO_MARKETING_EMAIL_EVENT_SCHEMA,
109
+ BREVO_MARKETING_SMS_EVENT_SCHEMA,
110
+ BREVO_CONTACT_EVENT_SCHEMA,
244
111
  ]);
245
- export const BREVO_EMAIL_CLICKED_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
246
- ...BREVO_DELIVERY_METADATA_SCHEMA.shape,
247
- ...BREVO_ENGAGEMENT_METADATA_SCHEMA.shape,
248
- /** Original provider webhook payload. */
249
- event: BREVO_PROVIDER_CLICKED_EVENT_SCHEMA,
250
- /** URL followed by the recipient. */
251
- link: z.string().optional(),
252
- /** Brevo transactional event category. */
253
- type: z.literal("click"),
254
- });
255
- export const BREVO_EMAIL_MARKED_AS_SPAM_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
256
- /** Original provider webhook payload. */
257
- event: BREVO_PROVIDER_SPAM_EVENT_SCHEMA,
258
- /** Brevo transactional event category. */
259
- type: z.literal("spam"),
260
- });
261
- export const BREVO_EMAIL_UNSUBSCRIBED_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
262
- ...BREVO_DELIVERY_METADATA_SCHEMA.shape,
263
- ...BREVO_ENGAGEMENT_METADATA_SCHEMA.shape,
264
- /** Original provider webhook payload. */
265
- event: BREVO_PROVIDER_UNSUBSCRIBED_EVENT_SCHEMA,
266
- /** Provider-native serialized tag value for the unsubscribe. */
267
- tag: z.string().optional(),
268
- /** Brevo transactional event category. */
269
- type: z.literal("unsubscribed"),
270
- });
271
- const BREVO_INVALID_EMAIL_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
272
- /** Original provider webhook payload. */
273
- event: BREVO_PROVIDER_INVALID_EMAIL_EVENT_SCHEMA,
274
- /** Provider timestamp in milliseconds. */
275
- timestampMilliseconds: z.number().int().nonnegative().optional(),
276
- /** Brevo transactional event category. */
277
- type: z.literal("invalid_email"),
112
+ export const createBrevoSemanticEventSchema = (family, type) => z.object({
113
+ ...BREVO_NORMALIZED_EVENT_FIELDS,
114
+ family: z.literal(family),
115
+ type: z.literal(type),
278
116
  });
279
- const BREVO_ERROR_EVENT_SCHEMA = BREVO_EVENT_BASE_SCHEMA.extend({
280
- /** Original provider webhook payload. */
281
- event: BREVO_PROVIDER_ERROR_EVENT_SCHEMA,
282
- /** Provider timestamp in milliseconds. */
283
- timestampMilliseconds: z.number().int().nonnegative().optional(),
284
- /** Brevo transactional event category. */
285
- type: z.literal("error"),
286
- });
287
- export const BREVO_TRANSACTIONAL_EVENT_SCHEMA = z.discriminatedUnion("type", [
288
- BREVO_EMAIL_BLOCKED_EVENT_SCHEMA,
289
- BREVO_EMAIL_CLICKED_EVENT_SCHEMA,
290
- BREVO_EMAIL_DEFERRED_EVENT_SCHEMA,
291
- BREVO_EMAIL_DELIVERED_EVENT_SCHEMA,
292
- BREVO_ERROR_EVENT_SCHEMA,
293
- BREVO_EMAIL_HARD_BOUNCED_EVENT_SCHEMA,
294
- BREVO_INVALID_EMAIL_EVENT_SCHEMA,
295
- BREVO_EMAIL_OPENED_EVENT_MEMBER_SCHEMA,
296
- BREVO_EMAIL_SENT_EVENT_SCHEMA,
297
- BREVO_EMAIL_SOFT_BOUNCED_EVENT_SCHEMA,
298
- BREVO_EMAIL_MARKED_AS_SPAM_EVENT_SCHEMA,
299
- BREVO_EMAIL_UNIQUE_OPENED_EVENT_MEMBER_SCHEMA,
300
- BREVO_EMAIL_UNSUBSCRIBED_EVENT_SCHEMA,
301
- ]);
117
+ const TRANSACTIONAL_EMAIL_PROVIDER_TYPES = {
118
+ blocked: "blocked",
119
+ click: "clicked",
120
+ deferred: "deferred",
121
+ delivered: "delivered",
122
+ hard_bounce: "hardBounced",
123
+ invalid_email: "invalid",
124
+ opened: "opened",
125
+ proxy_open: "opened",
126
+ request: "sent",
127
+ soft_bounce: "softBounced",
128
+ spam: "markedAsSpam",
129
+ unique_opened: "firstOpened",
130
+ unique_proxy_open: "firstOpened",
131
+ unsubscribed: "unsubscribed",
132
+ };
133
+ const SMS_PROVIDER_TYPES = {
134
+ delivered: "delivered",
135
+ hard_bounce: "hardBounced",
136
+ replied: "replied",
137
+ sent: "sent",
138
+ soft_bounce: "softBounced",
139
+ unsubscribed: "unsubscribed",
140
+ };
141
+ const MARKETING_EMAIL_PROVIDER_TYPES = {
142
+ click: "clicked",
143
+ delivered: "delivered",
144
+ hard_bounce: "hardBounced",
145
+ opened: "opened",
146
+ proxy_open: "opened",
147
+ soft_bounce: "softBounced",
148
+ spam: "markedAsSpam",
149
+ unsubscribe: "unsubscribed",
150
+ unsubscribed: "unsubscribed",
151
+ };
152
+ const CONTACT_PROVIDER_TYPES = {
153
+ contact_deleted: "deleted",
154
+ contact_updated: "updated",
155
+ list_addition: "addedToList",
156
+ };
157
+ const BREVO_PROVIDER_EVENT_SCHEMA = z
158
+ .looseObject({
159
+ camp_id: z.number().int().nonnegative().optional(),
160
+ campaign_id: z.number().int().nonnegative().optional(),
161
+ event: z.string().optional(),
162
+ id: z.number().int().nonnegative(),
163
+ msg_status: z.string().optional(),
164
+ type: z.string().optional(),
165
+ })
166
+ .catchall(z.json());
302
167
  /**
303
- * Normalizes one provider-native Brevo transactional webhook.
168
+ * Normalizes every supported Brevo managed-webhook delivery.
304
169
  *
305
- * @param value - Untrusted provider webhook payload.
170
+ * @param value - Untrusted provider callback payload.
171
+ * @param webhookId - Authenticated provider webhook registration identity.
172
+ * @throws When the payload or event discriminator is unsupported.
306
173
  */
307
- export function normalizeBrevoTransactionalEvent(value) {
308
- const event = BREVO_PROVIDER_TRANSACTIONAL_EVENT_SCHEMA.parse(value);
309
- return BREVO_TRANSACTIONAL_EVENT_SCHEMA.parse({
174
+ export function normalizeBrevoEvent(value, webhookId) {
175
+ const event = BREVO_PROVIDER_EVENT_SCHEMA.parse(value);
176
+ const family = classifyBrevoEventFamily(event);
177
+ const providerType = event.msg_status ?? event.event;
178
+ if (!providerType)
179
+ throw new Error("Brevo webhook event type is missing.");
180
+ // Resolve the semantic discriminator before assembling the normalized payload.
181
+ const type = normalizeBrevoProviderType(family, providerType);
182
+ // Keep provider-to-public field mapping readable and validate it as one unit.
183
+ const payload = {
184
+ bounceType: event.bounce_type,
185
+ campaignId: event.camp_id ?? event.campaign_id,
186
+ campaignName: event["campaign name"] ?? event.campaign_name,
310
187
  contactId: event.contact_id,
188
+ content: event.content,
189
+ creditsUsed: event.credits_used,
311
190
  customHeader: event["X-Mailin-custom"],
312
191
  date: event.date,
192
+ dateEvent: event.date_event,
193
+ dateSent: event.date_sent,
194
+ description: event.description,
313
195
  deviceUsed: event.device_used,
314
196
  email: event.email,
197
+ errorCode: event.error_code,
315
198
  event,
199
+ family,
200
+ key: event.key,
316
201
  link: event.link,
317
- messageId: event["message-id"],
202
+ listIds: event.list_id,
203
+ messageId: event["message-id"] ?? event.messageId,
318
204
  mirrorLink: event.mirror_link,
319
205
  occurredAt: event.ts_event,
206
+ phone: event.to,
320
207
  reason: event.reason,
208
+ reference: event.reference,
209
+ remainingCredit: event.remaining_credit,
210
+ reply: event.reply,
211
+ segmentIds: event.segment_ids,
212
+ senderEmail: event.sender_email,
321
213
  sendingIp: event.sending_ip,
214
+ smsCount: event.sms_count,
215
+ status: event.status,
322
216
  subject: event.subject,
323
217
  tag: event.tag,
324
218
  tags: event.tags,
325
219
  templateId: event.template_id,
326
220
  timestamp: event.ts,
327
221
  timestampMilliseconds: event.ts_epoch,
328
- type: event.event,
222
+ timestampSent: event.ts_sent,
329
223
  userAgent: event.user_agent,
330
- webhookId: event.id,
331
- });
224
+ type,
225
+ webhookId: webhookId ?? event.id,
226
+ };
227
+ return BREVO_EVENT_SCHEMA.parse(payload);
228
+ }
229
+ /**
230
+ * Classifies a provider callback into its managed webhook family.
231
+ *
232
+ * @param event - Parsed provider callback.
233
+ */
234
+ function classifyBrevoEventFamily(event) {
235
+ if (event.msg_status) {
236
+ return event.type?.toLowerCase() === "marketing"
237
+ ? "marketingSms"
238
+ : "transactionalSms";
239
+ }
240
+ if (event.event && Object.hasOwn(CONTACT_PROVIDER_TYPES, event.event)) {
241
+ return "contact";
242
+ }
243
+ return event.camp_id !== undefined
244
+ ? "marketingEmail"
245
+ : "transactionalEmail";
246
+ }
247
+ /**
248
+ * Maps a provider event discriminator to the public semantic type.
249
+ *
250
+ * @param family - Managed webhook family.
251
+ * @param providerType - Provider event discriminator.
252
+ * @throws When the provider event is unsupported for the family.
253
+ */
254
+ function normalizeBrevoProviderType(family, providerType) {
255
+ // Select one family mapping before performing the shared lookup and failure path.
256
+ const mapping = family === "transactionalEmail"
257
+ ? TRANSACTIONAL_EMAIL_PROVIDER_TYPES
258
+ : family === "marketingEmail"
259
+ ? MARKETING_EMAIL_PROVIDER_TYPES
260
+ : family === "contact"
261
+ ? CONTACT_PROVIDER_TYPES
262
+ : SMS_PROVIDER_TYPES;
263
+ const type = mapping[providerType];
264
+ if (!type) {
265
+ throw new Error(`Unsupported Brevo ${family} event: ${providerType}`);
266
+ }
267
+ return type;
332
268
  }
@@ -2021,8 +2021,8 @@ export declare const closeTriggerContracts: {
2021
2021
  sQuery: z.ZodOptional<z.ZodNullable<z.ZodCustom<Record<string, import("@automate.ax/codec").Encodable>, Record<string, import("@automate.ax/codec").Encodable>>>>;
2022
2022
  type: z.ZodOptional<z.ZodEnum<{
2023
2023
  email: "email";
2024
- lead: "lead";
2025
2024
  contact: "contact";
2025
+ lead: "lead";
2026
2026
  opportunity: "opportunity";
2027
2027
  call: "call";
2028
2028
  sms: "sms";
@@ -2078,8 +2078,8 @@ export declare const closeTriggerContracts: {
2078
2078
  sQuery: z.ZodOptional<z.ZodNullable<z.ZodCustom<Record<string, import("@automate.ax/codec").Encodable>, Record<string, import("@automate.ax/codec").Encodable>>>>;
2079
2079
  type: z.ZodOptional<z.ZodEnum<{
2080
2080
  email: "email";
2081
- lead: "lead";
2082
2081
  contact: "contact";
2082
+ lead: "lead";
2083
2083
  opportunity: "opportunity";
2084
2084
  call: "call";
2085
2085
  sms: "sms";
@@ -87,8 +87,8 @@ export declare const CLOSE_CONTACT_SCHEMA: z.ZodObject<{
87
87
  }, z.core.$strip>;
88
88
  export declare const CLOSE_SMART_VIEW_TYPE_SCHEMA: z.ZodEnum<{
89
89
  email: "email";
90
- lead: "lead";
91
90
  contact: "contact";
91
+ lead: "lead";
92
92
  opportunity: "opportunity";
93
93
  call: "call";
94
94
  sms: "sms";
@@ -130,8 +130,8 @@ export declare const CLOSE_SMART_VIEW_SCHEMA: z.ZodObject<{
130
130
  sQuery: z.ZodNullable<z.ZodCustom<Record<string, import("@automate.ax/codec").Encodable>, Record<string, import("@automate.ax/codec").Encodable>>>;
131
131
  type: z.ZodEnum<{
132
132
  email: "email";
133
- lead: "lead";
134
133
  contact: "contact";
134
+ lead: "lead";
135
135
  opportunity: "opportunity";
136
136
  call: "call";
137
137
  sms: "sms";
@@ -19,8 +19,8 @@ export declare const convexTriggerContracts: {
19
19
  readonly eventSchema: z.ZodObject<{
20
20
  action: z.ZodEnum<{
21
21
  deleted: "deleted";
22
- created: "created";
23
22
  updated: "updated";
23
+ created: "created";
24
24
  }>;
25
25
  component: z.ZodString;
26
26
  document: z.ZodNullable<z.ZodObject<{
@@ -41,8 +41,8 @@ export declare const convexTriggerContracts: {
41
41
  readonly eventSchema: z.ZodObject<{
42
42
  action: z.ZodEnum<{
43
43
  deleted: "deleted";
44
- created: "created";
45
44
  updated: "updated";
45
+ created: "created";
46
46
  }>;
47
47
  component: z.ZodString;
48
48
  document: z.ZodNullable<z.ZodObject<{
@@ -63,8 +63,8 @@ export declare const convexTriggerContracts: {
63
63
  readonly eventSchema: z.ZodObject<{
64
64
  action: z.ZodEnum<{
65
65
  deleted: "deleted";
66
- created: "created";
67
66
  updated: "updated";
67
+ created: "created";
68
68
  }>;
69
69
  component: z.ZodString;
70
70
  document: z.ZodNullable<z.ZodObject<{
@@ -85,8 +85,8 @@ export declare const convexTriggerContracts: {
85
85
  readonly eventSchema: z.ZodObject<{
86
86
  action: z.ZodEnum<{
87
87
  deleted: "deleted";
88
- created: "created";
89
88
  updated: "updated";
89
+ created: "created";
90
90
  }>;
91
91
  component: z.ZodString;
92
92
  document: z.ZodNullable<z.ZodObject<{
@@ -11,14 +11,14 @@ export declare const CONVEX_DOCUMENT_SCHEMA: z.ZodObject<{
11
11
  export declare const CONVEX_DOCUMENT_EVENT_TYPES: readonly ["convex.document.event", "convex.document.created", "convex.document.updated", "convex.document.deleted"];
12
12
  export declare const CONVEX_DOCUMENT_ACTION_SCHEMA: z.ZodEnum<{
13
13
  deleted: "deleted";
14
- created: "created";
15
14
  updated: "updated";
15
+ created: "created";
16
16
  }>;
17
17
  export declare const CONVEX_DOCUMENT_EVENT_SCHEMA: z.ZodObject<{
18
18
  action: z.ZodEnum<{
19
19
  deleted: "deleted";
20
- created: "created";
21
20
  updated: "updated";
21
+ created: "created";
22
22
  }>;
23
23
  component: z.ZodString;
24
24
  document: z.ZodNullable<z.ZodObject<{
@@ -4500,9 +4500,9 @@ export declare const LINEAR_PROVIDER_ISSUE_SCHEMA: z.ZodObject<{
4500
4500
  id: z.ZodString;
4501
4501
  name: z.ZodString;
4502
4502
  }, z.core.$strip>>;
4503
+ title: z.ZodString;
4503
4504
  priority: z.ZodNumber;
4504
4505
  url: z.ZodString;
4505
- title: z.ZodString;
4506
4506
  updatedAt: z.ZodUnion<readonly [z.ZodDate, z.ZodPipe<z.ZodISODateTime, z.ZodTransform<Date, string>>]>;
4507
4507
  state: z.ZodObject<{
4508
4508
  color: z.ZodString;