Files
sim/apps/sim/lib/webhooks/provider-utils.ts
Waleed 142c9a0428 fix(grain): add grain key to idempotency service (#2712)
* fix(grain): add grain key to idempotency service

* fixed dropdown issue for grain, webhook registration
2026-01-07 12:00:32 -08:00

94 lines
2.5 KiB
TypeScript

/**
* Provider-specific unique identifier extractors for webhook idempotency
*/
function extractSlackIdentifier(body: any): string | null {
if (body.event_id) {
return body.event_id
}
if (body.event?.ts && body.team_id) {
return `${body.team_id}:${body.event.ts}`
}
return null
}
function extractTwilioIdentifier(body: any): string | null {
return body.MessageSid || body.CallSid || null
}
function extractStripeIdentifier(body: any): string | null {
if (body.id && body.object === 'event') {
return body.id
}
return null
}
function extractHubSpotIdentifier(body: any): string | null {
if (Array.isArray(body) && body.length > 0 && body[0]?.eventId) {
return String(body[0].eventId)
}
return null
}
function extractLinearIdentifier(body: any): string | null {
if (body.action && body.data?.id) {
return `${body.action}:${body.data.id}`
}
return null
}
function extractJiraIdentifier(body: any): string | null {
if (body.webhookEvent && (body.issue?.id || body.project?.id)) {
return `${body.webhookEvent}:${body.issue?.id || body.project?.id}`
}
return null
}
function extractMicrosoftTeamsIdentifier(body: any): string | null {
if (body.value && Array.isArray(body.value) && body.value.length > 0) {
const notification = body.value[0]
if (notification.subscriptionId && notification.resourceData?.id) {
return `${notification.subscriptionId}:${notification.resourceData.id}`
}
}
return null
}
function extractAirtableIdentifier(body: any): string | null {
if (body.cursor && typeof body.cursor === 'string') {
return body.cursor
}
return null
}
function extractGrainIdentifier(body: any): string | null {
if (body.type && body.data?.id) {
return `${body.type}:${body.data.id}`
}
return null
}
const PROVIDER_EXTRACTORS: Record<string, (body: any) => string | null> = {
slack: extractSlackIdentifier,
twilio: extractTwilioIdentifier,
twilio_voice: extractTwilioIdentifier,
stripe: extractStripeIdentifier,
hubspot: extractHubSpotIdentifier,
linear: extractLinearIdentifier,
jira: extractJiraIdentifier,
'microsoft-teams': extractMicrosoftTeamsIdentifier,
airtable: extractAirtableIdentifier,
grain: extractGrainIdentifier,
}
export function extractProviderIdentifierFromBody(provider: string, body: any): string | null {
if (!body || typeof body !== 'object') {
return null
}
const extractor = PROVIDER_EXTRACTORS[provider]
return extractor ? extractor(body) : null
}