Skip to content

Commit 8c113cf

Browse files
committed
fix(confluence): use event field for exact matching with entity-category fallback
Admin REST API webhooks (Settings > Webhooks) include an event field for action-level filtering (page_created vs page_updated). Connect app webhooks omit it, so we fall back to entity-category matching.
1 parent f9d5f2c commit 8c113cf

File tree

1 file changed

+57
-25
lines changed

1 file changed

+57
-25
lines changed

apps/sim/triggers/confluence/utils.ts

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,51 @@ export function extractLabelData(body: any) {
309309
}
310310

311311
/**
312-
* Infers the entity category from a Confluence webhook payload.
313-
* Unlike Jira, Confluence payloads have no `event`/`webhookEvent` field
314-
* we detect the category by which entity key is present in the body.
312+
* Maps trigger IDs to the exact Confluence event strings they accept.
313+
* Admin REST API webhooks include an `event` field (e.g. `"event": "page_created"`).
314+
* Connect app webhooks do NOT — for those we fall back to entity-category matching.
315315
*/
316-
export function inferConfluenceEntityCategory(body: Record<string, unknown>): string | null {
316+
const TRIGGER_EVENT_MAP: Record<string, string[]> = {
317+
confluence_page_created: ['page_created'],
318+
confluence_page_updated: ['page_updated'],
319+
confluence_page_removed: ['page_removed', 'page_trashed'],
320+
confluence_page_moved: ['page_moved'],
321+
confluence_comment_created: ['comment_created'],
322+
confluence_comment_removed: ['comment_removed'],
323+
confluence_blog_created: ['blog_created'],
324+
confluence_blog_updated: ['blog_updated'],
325+
confluence_blog_removed: ['blog_removed', 'blog_trashed'],
326+
confluence_attachment_created: ['attachment_created'],
327+
confluence_attachment_removed: ['attachment_removed', 'attachment_trashed'],
328+
confluence_space_created: ['space_created'],
329+
confluence_space_updated: ['space_updated'],
330+
confluence_label_added: ['label_added', 'label_created'],
331+
confluence_label_removed: ['label_removed', 'label_deleted'],
332+
}
333+
334+
const TRIGGER_CATEGORY_MAP: Record<string, string> = {
335+
confluence_page_created: 'page',
336+
confluence_page_updated: 'page',
337+
confluence_page_removed: 'page',
338+
confluence_page_moved: 'page',
339+
confluence_comment_created: 'comment',
340+
confluence_comment_removed: 'comment',
341+
confluence_blog_created: 'blog',
342+
confluence_blog_updated: 'blog',
343+
confluence_blog_removed: 'blog',
344+
confluence_attachment_created: 'attachment',
345+
confluence_attachment_removed: 'attachment',
346+
confluence_space_created: 'space',
347+
confluence_space_updated: 'space',
348+
confluence_label_added: 'label',
349+
confluence_label_removed: 'label',
350+
}
351+
352+
/**
353+
* Infers the entity category from a Confluence webhook payload by checking
354+
* which entity key is present in the body.
355+
*/
356+
function inferEntityCategory(body: Record<string, unknown>): string | null {
317357
if (body.comment) return 'comment'
318358
if (body.attachment) return 'attachment'
319359
if (body.blog || body.blogpost) return 'blog'
@@ -323,7 +363,13 @@ export function inferConfluenceEntityCategory(body: Record<string, unknown>): st
323363
return null
324364
}
325365

326-
/** Checks if a Confluence webhook payload matches a trigger's expected entity category. */
366+
/**
367+
* Checks if a Confluence webhook payload matches a trigger.
368+
*
369+
* Admin REST API webhooks (Settings > Webhooks) include an `event` field
370+
* for exact action-level matching. Connect app webhooks omit it, so we
371+
* fall back to entity-category matching (page vs comment vs blog, etc.).
372+
*/
327373
export function isConfluencePayloadMatch(
328374
triggerId: string,
329375
body: Record<string, unknown>
@@ -332,29 +378,15 @@ export function isConfluencePayloadMatch(
332378
return true
333379
}
334380

335-
const triggerCategoryMap: Record<string, string> = {
336-
confluence_page_created: 'page',
337-
confluence_page_updated: 'page',
338-
confluence_page_removed: 'page',
339-
confluence_page_moved: 'page',
340-
confluence_comment_created: 'comment',
341-
confluence_comment_removed: 'comment',
342-
confluence_blog_created: 'blog',
343-
confluence_blog_updated: 'blog',
344-
confluence_blog_removed: 'blog',
345-
confluence_attachment_created: 'attachment',
346-
confluence_attachment_removed: 'attachment',
347-
confluence_space_created: 'space',
348-
confluence_space_updated: 'space',
349-
confluence_label_added: 'label',
350-
confluence_label_removed: 'label',
381+
const event = body.event as string | undefined
382+
if (event) {
383+
const acceptedEvents = TRIGGER_EVENT_MAP[triggerId]
384+
return acceptedEvents ? acceptedEvents.includes(event) : false
351385
}
352386

353-
const expectedCategory = triggerCategoryMap[triggerId]
387+
const expectedCategory = TRIGGER_CATEGORY_MAP[triggerId]
354388
if (!expectedCategory) {
355389
return false
356390
}
357-
358-
const actualCategory = inferConfluenceEntityCategory(body)
359-
return actualCategory === expectedCategory
391+
return inferEntityCategory(body) === expectedCategory
360392
}

0 commit comments

Comments
 (0)