@@ -290,6 +290,15 @@ export const TRIGGER_EVENT_MAP: Record<string, string[]> = {
290290 attio_list_entry_deleted : [ 'list-entry.deleted' ] ,
291291}
292292
293+ /**
294+ * Extracts the first event from an Attio webhook payload.
295+ * Attio wraps events in an `events` array: `{ webhook_id, events: [{ event_type, id, ... }] }`.
296+ */
297+ export function getAttioEvent ( body : Record < string , unknown > ) : Record < string , unknown > | undefined {
298+ const events = body . events as Array < Record < string , unknown > > | undefined
299+ return events ?. [ 0 ]
300+ }
301+
293302/**
294303 * Checks if an Attio webhook payload matches a trigger.
295304 */
@@ -298,11 +307,155 @@ export function isAttioPayloadMatch(triggerId: string, body: Record<string, unkn
298307 return true
299308 }
300309
301- const eventType = body . event_type as string | undefined
310+ const event = getAttioEvent ( body )
311+ const eventType = event ?. event_type as string | undefined
302312 if ( ! eventType ) {
303313 return false
304314 }
305315
306316 const acceptedEvents = TRIGGER_EVENT_MAP [ triggerId ]
307317 return acceptedEvents ? acceptedEvents . includes ( eventType ) : false
308318}
319+
320+ /**
321+ * Extracts formatted data from an Attio record event payload.
322+ * Used for record.created, record.deleted triggers.
323+ */
324+ export function extractAttioRecordData ( body : Record < string , unknown > ) : Record < string , unknown > {
325+ const event = getAttioEvent ( body ) ?? { }
326+ const id = ( event . id as Record < string , unknown > ) ?? { }
327+ return {
328+ eventType : event . event_type ?? null ,
329+ workspaceId : id . workspace_id ?? null ,
330+ objectId : id . object_id ?? null ,
331+ recordId : id . record_id ?? null ,
332+ }
333+ }
334+
335+ /**
336+ * Extracts formatted data from an Attio record.updated event payload.
337+ */
338+ export function extractAttioRecordUpdatedData (
339+ body : Record < string , unknown >
340+ ) : Record < string , unknown > {
341+ const event = getAttioEvent ( body ) ?? { }
342+ const id = ( event . id as Record < string , unknown > ) ?? { }
343+ return {
344+ eventType : event . event_type ?? null ,
345+ workspaceId : id . workspace_id ?? null ,
346+ objectId : id . object_id ?? null ,
347+ recordId : id . record_id ?? null ,
348+ attributeId : id . attribute_id ?? null ,
349+ }
350+ }
351+
352+ /**
353+ * Extracts formatted data from an Attio record.merged event payload.
354+ */
355+ export function extractAttioRecordMergedData (
356+ body : Record < string , unknown >
357+ ) : Record < string , unknown > {
358+ const event = getAttioEvent ( body ) ?? { }
359+ const id = ( event . id as Record < string , unknown > ) ?? { }
360+ return {
361+ eventType : event . event_type ?? null ,
362+ workspaceId : id . workspace_id ?? null ,
363+ objectId : id . object_id ?? null ,
364+ recordId : id . record_id ?? null ,
365+ duplicateObjectId : ( event . duplicate_object_id as string ) ?? null ,
366+ duplicateRecordId : ( event . duplicate_record_id as string ) ?? null ,
367+ }
368+ }
369+
370+ /**
371+ * Extracts formatted data from an Attio note event payload.
372+ */
373+ export function extractAttioNoteData ( body : Record < string , unknown > ) : Record < string , unknown > {
374+ const event = getAttioEvent ( body ) ?? { }
375+ const id = ( event . id as Record < string , unknown > ) ?? { }
376+ return {
377+ eventType : event . event_type ?? null ,
378+ workspaceId : id . workspace_id ?? null ,
379+ noteId : id . note_id ?? null ,
380+ parentObjectId : ( event . parent_object_id as string ) ?? null ,
381+ parentRecordId : ( event . parent_record_id as string ) ?? null ,
382+ }
383+ }
384+
385+ /**
386+ * Extracts formatted data from an Attio task event payload.
387+ */
388+ export function extractAttioTaskData ( body : Record < string , unknown > ) : Record < string , unknown > {
389+ const event = getAttioEvent ( body ) ?? { }
390+ const id = ( event . id as Record < string , unknown > ) ?? { }
391+ return {
392+ eventType : event . event_type ?? null ,
393+ workspaceId : id . workspace_id ?? null ,
394+ taskId : id . task_id ?? null ,
395+ }
396+ }
397+
398+ /**
399+ * Extracts formatted data from an Attio comment event payload.
400+ */
401+ export function extractAttioCommentData ( body : Record < string , unknown > ) : Record < string , unknown > {
402+ const event = getAttioEvent ( body ) ?? { }
403+ const id = ( event . id as Record < string , unknown > ) ?? { }
404+ return {
405+ eventType : event . event_type ?? null ,
406+ workspaceId : id . workspace_id ?? null ,
407+ threadId : ( event . thread_id as string ) ?? null ,
408+ commentId : id . comment_id ?? null ,
409+ objectId : ( event . object_id as string ) ?? null ,
410+ recordId : ( event . record_id as string ) ?? null ,
411+ listId : ( event . list_id as string ) ?? null ,
412+ entryId : ( event . entry_id as string ) ?? null ,
413+ }
414+ }
415+
416+ /**
417+ * Extracts formatted data from an Attio list-entry event payload.
418+ * Used for list-entry.created, list-entry.deleted triggers.
419+ */
420+ export function extractAttioListEntryData ( body : Record < string , unknown > ) : Record < string , unknown > {
421+ const event = getAttioEvent ( body ) ?? { }
422+ const id = ( event . id as Record < string , unknown > ) ?? { }
423+ return {
424+ eventType : event . event_type ?? null ,
425+ workspaceId : id . workspace_id ?? null ,
426+ listId : id . list_id ?? null ,
427+ entryId : id . entry_id ?? null ,
428+ }
429+ }
430+
431+ /**
432+ * Extracts formatted data from an Attio list-entry.updated event payload.
433+ */
434+ export function extractAttioListEntryUpdatedData (
435+ body : Record < string , unknown >
436+ ) : Record < string , unknown > {
437+ const event = getAttioEvent ( body ) ?? { }
438+ const id = ( event . id as Record < string , unknown > ) ?? { }
439+ return {
440+ eventType : event . event_type ?? null ,
441+ workspaceId : id . workspace_id ?? null ,
442+ listId : id . list_id ?? null ,
443+ entryId : id . entry_id ?? null ,
444+ attributeId : id . attribute_id ?? null ,
445+ }
446+ }
447+
448+ /**
449+ * Extracts formatted data from a generic Attio webhook payload.
450+ * Passes through the first event with camelCase field mapping.
451+ */
452+ export function extractAttioGenericData ( body : Record < string , unknown > ) : Record < string , unknown > {
453+ const event = getAttioEvent ( body ) ?? { }
454+ const id = ( event . id as Record < string , unknown > ) ?? { }
455+ return {
456+ eventType : event . event_type ?? null ,
457+ id,
458+ parentObjectId : ( event . parent_object_id as string ) ?? null ,
459+ parentRecordId : ( event . parent_record_id as string ) ?? null ,
460+ }
461+ }
0 commit comments