chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildCommentOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Comment Created Trigger
*
* Triggers when a comment is created in Attio.
*/
export const attioCommentCreatedTrigger: TriggerConfig = {
id: 'attio_comment_created',
name: 'Attio Comment Created',
provider: 'attio',
description: 'Trigger workflow when a new comment is created in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_comment_created'),
outputs: buildCommentOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildCommentOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Comment Deleted Trigger
*
* Triggers when a comment is deleted in Attio.
*/
export const attioCommentDeletedTrigger: TriggerConfig = {
id: 'attio_comment_deleted',
name: 'Attio Comment Deleted',
provider: 'attio',
description: 'Trigger workflow when a comment is deleted in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_comment_deleted'),
outputs: buildCommentOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildCommentOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Comment Resolved Trigger
*
* Triggers when a comment thread is resolved in Attio.
*/
export const attioCommentResolvedTrigger: TriggerConfig = {
id: 'attio_comment_resolved',
name: 'Attio Comment Resolved',
provider: 'attio',
description: 'Trigger workflow when a comment thread is resolved in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_comment_resolved'),
outputs: buildCommentOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildCommentOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Comment Unresolved Trigger
*
* Triggers when a comment thread is unresolved in Attio.
*/
export const attioCommentUnresolvedTrigger: TriggerConfig = {
id: 'attio_comment_unresolved',
name: 'Attio Comment Unresolved',
provider: 'attio',
description: 'Trigger workflow when a comment thread is unresolved in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_comment_unresolved'),
outputs: buildCommentOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+22
View File
@@ -0,0 +1,22 @@
export { attioCommentCreatedTrigger } from './comment_created'
export { attioCommentDeletedTrigger } from './comment_deleted'
export { attioCommentResolvedTrigger } from './comment_resolved'
export { attioCommentUnresolvedTrigger } from './comment_unresolved'
export { attioListCreatedTrigger } from './list_created'
export { attioListDeletedTrigger } from './list_deleted'
export { attioListEntryCreatedTrigger } from './list_entry_created'
export { attioListEntryDeletedTrigger } from './list_entry_deleted'
export { attioListEntryUpdatedTrigger } from './list_entry_updated'
export { attioListUpdatedTrigger } from './list_updated'
export { attioNoteCreatedTrigger } from './note_created'
export { attioNoteDeletedTrigger } from './note_deleted'
export { attioNoteUpdatedTrigger } from './note_updated'
export { attioRecordCreatedTrigger } from './record_created'
export { attioRecordDeletedTrigger } from './record_deleted'
export { attioRecordMergedTrigger } from './record_merged'
export { attioRecordUpdatedTrigger } from './record_updated'
export { attioTaskCreatedTrigger } from './task_created'
export { attioTaskDeletedTrigger } from './task_deleted'
export { attioTaskUpdatedTrigger } from './task_updated'
export { attioWebhookTrigger } from './webhook'
export { attioWorkspaceMemberCreatedTrigger } from './workspace_member_created'
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildListOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio List Created Trigger
*
* Triggers when a list is created in Attio.
*/
export const attioListCreatedTrigger: TriggerConfig = {
id: 'attio_list_created',
name: 'Attio List Created',
provider: 'attio',
description: 'Trigger workflow when a list is created in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_list_created'),
outputs: buildListOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildListOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio List Deleted Trigger
*
* Triggers when a list is deleted in Attio.
*/
export const attioListDeletedTrigger: TriggerConfig = {
id: 'attio_list_deleted',
name: 'Attio List Deleted',
provider: 'attio',
description: 'Trigger workflow when a list is deleted in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_list_deleted'),
outputs: buildListOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildListEntryOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio List Entry Created Trigger
*
* Triggers when a list entry is created in Attio.
*/
export const attioListEntryCreatedTrigger: TriggerConfig = {
id: 'attio_list_entry_created',
name: 'Attio List Entry Created',
provider: 'attio',
description: 'Trigger workflow when a new list entry is created in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_list_entry_created'),
outputs: buildListEntryOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildListEntryOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio List Entry Deleted Trigger
*
* Triggers when a list entry is deleted in Attio.
*/
export const attioListEntryDeletedTrigger: TriggerConfig = {
id: 'attio_list_entry_deleted',
name: 'Attio List Entry Deleted',
provider: 'attio',
description: 'Trigger workflow when a list entry is deleted in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_list_entry_deleted'),
outputs: buildListEntryOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildListEntryUpdatedOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio List Entry Updated Trigger
*
* Triggers when a list entry is updated in Attio.
*/
export const attioListEntryUpdatedTrigger: TriggerConfig = {
id: 'attio_list_entry_updated',
name: 'Attio List Entry Updated',
provider: 'attio',
description: 'Trigger workflow when a list entry is updated in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_list_entry_updated'),
outputs: buildListEntryUpdatedOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildListOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio List Updated Trigger
*
* Triggers when a list is updated in Attio.
*/
export const attioListUpdatedTrigger: TriggerConfig = {
id: 'attio_list_updated',
name: 'Attio List Updated',
provider: 'attio',
description: 'Trigger workflow when a list is updated in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_list_updated'),
outputs: buildListOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildNoteOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Note Created Trigger
*
* Triggers when a note is created in Attio.
*/
export const attioNoteCreatedTrigger: TriggerConfig = {
id: 'attio_note_created',
name: 'Attio Note Created',
provider: 'attio',
description: 'Trigger workflow when a new note is created in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_note_created'),
outputs: buildNoteOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildNoteOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Note Deleted Trigger
*
* Triggers when a note is deleted in Attio.
*/
export const attioNoteDeletedTrigger: TriggerConfig = {
id: 'attio_note_deleted',
name: 'Attio Note Deleted',
provider: 'attio',
description: 'Trigger workflow when a note is deleted in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_note_deleted'),
outputs: buildNoteOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildNoteOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Note Updated Trigger
*
* Triggers when a note is updated in Attio.
*/
export const attioNoteUpdatedTrigger: TriggerConfig = {
id: 'attio_note_updated',
name: 'Attio Note Updated',
provider: 'attio',
description: 'Trigger workflow when a note is updated in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_note_updated'),
outputs: buildNoteOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+45
View File
@@ -0,0 +1,45 @@
import { AttioIcon } from '@/components/icons'
import {
attioTriggerOptions,
buildAttioTriggerSubBlocks,
buildRecordOutputs,
} from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Record Created Trigger
*
* This is the PRIMARY trigger - it includes the dropdown for selecting trigger type.
* Triggers when a new record is created in Attio.
*/
export const attioRecordCreatedTrigger: TriggerConfig = {
id: 'attio_record_created',
name: 'Attio Record Created',
provider: 'attio',
description: 'Trigger workflow when a new record is created in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: [
{
id: 'selectedTriggerId',
title: 'Trigger Type',
type: 'dropdown',
mode: 'trigger',
options: attioTriggerOptions,
value: () => 'attio_record_created',
required: true,
},
...buildAttioTriggerSubBlocks('attio_record_created'),
],
outputs: buildRecordOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildRecordOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Record Deleted Trigger
*
* Triggers when a record is deleted in Attio.
*/
export const attioRecordDeletedTrigger: TriggerConfig = {
id: 'attio_record_deleted',
name: 'Attio Record Deleted',
provider: 'attio',
description: 'Trigger workflow when a record is deleted in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_record_deleted'),
outputs: buildRecordOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildRecordMergedEventOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Record Merged Trigger
*
* Triggers when two records are merged in Attio.
*/
export const attioRecordMergedTrigger: TriggerConfig = {
id: 'attio_record_merged',
name: 'Attio Record Merged',
provider: 'attio',
description: 'Trigger workflow when two records are merged in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_record_merged'),
outputs: buildRecordMergedEventOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildRecordUpdatedOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Record Updated Trigger
*
* Triggers when a record is updated in Attio.
*/
export const attioRecordUpdatedTrigger: TriggerConfig = {
id: 'attio_record_updated',
name: 'Attio Record Updated',
provider: 'attio',
description: 'Trigger workflow when a record is updated in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_record_updated'),
outputs: buildRecordUpdatedOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildTaskOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Task Created Trigger
*
* Triggers when a task is created in Attio.
*/
export const attioTaskCreatedTrigger: TriggerConfig = {
id: 'attio_task_created',
name: 'Attio Task Created',
provider: 'attio',
description: 'Trigger workflow when a new task is created in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_task_created'),
outputs: buildTaskOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildTaskOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Task Deleted Trigger
*
* Triggers when a task is deleted in Attio.
*/
export const attioTaskDeletedTrigger: TriggerConfig = {
id: 'attio_task_deleted',
name: 'Attio Task Deleted',
provider: 'attio',
description: 'Trigger workflow when a task is deleted in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_task_deleted'),
outputs: buildTaskOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildTaskOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Task Updated Trigger
*
* Triggers when a task is updated in Attio.
*/
export const attioTaskUpdatedTrigger: TriggerConfig = {
id: 'attio_task_updated',
name: 'Attio Task Updated',
provider: 'attio',
description: 'Trigger workflow when a task is updated in Attio',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_task_updated'),
outputs: buildTaskOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
+527
View File
@@ -0,0 +1,527 @@
import type { SubBlockConfig } from '@/blocks/types'
import type { TriggerOutput } from '@/triggers/types'
export const attioTriggerOptions = [
{ label: 'Record Created', id: 'attio_record_created' },
{ label: 'Record Updated', id: 'attio_record_updated' },
{ label: 'Record Deleted', id: 'attio_record_deleted' },
{ label: 'Record Merged', id: 'attio_record_merged' },
{ label: 'Note Created', id: 'attio_note_created' },
{ label: 'Note Updated', id: 'attio_note_updated' },
{ label: 'Note Deleted', id: 'attio_note_deleted' },
{ label: 'Task Created', id: 'attio_task_created' },
{ label: 'Task Updated', id: 'attio_task_updated' },
{ label: 'Task Deleted', id: 'attio_task_deleted' },
{ label: 'Comment Created', id: 'attio_comment_created' },
{ label: 'Comment Resolved', id: 'attio_comment_resolved' },
{ label: 'Comment Unresolved', id: 'attio_comment_unresolved' },
{ label: 'Comment Deleted', id: 'attio_comment_deleted' },
{ label: 'List Entry Created', id: 'attio_list_entry_created' },
{ label: 'List Entry Updated', id: 'attio_list_entry_updated' },
{ label: 'List Entry Deleted', id: 'attio_list_entry_deleted' },
{ label: 'List Created', id: 'attio_list_created' },
{ label: 'List Updated', id: 'attio_list_updated' },
{ label: 'List Deleted', id: 'attio_list_deleted' },
{ label: 'Workspace Member Created', id: 'attio_workspace_member_created' },
{ label: 'Generic Webhook (All Events)', id: 'attio_webhook' },
]
export function attioSetupInstructions(): string {
const instructions = [
'<strong>Note:</strong> Webhooks are automatically created in Attio when you deploy this workflow, and deleted when you undeploy. See the <a href="https://docs.attio.com/rest-api/guides/webhooks" target="_blank" rel="noopener noreferrer">Attio webhook documentation</a> for details.',
'Connect your <strong>Attio account</strong> using the credential selector above.',
'<strong>Deploy</strong> the workflow — a webhook will be created automatically in your Attio workspace.',
]
return instructions
.map(
(instruction, index) =>
`<div class="mb-3">${index === 0 ? instruction : `<strong>${index}.</strong> ${instruction}`}</div>`
)
.join('')
}
/**
* Builds subBlocks for an Attio trigger with OAuth credentials and automatic webhook lifecycle.
* Used by both the primary trigger (with dropdown) and secondary triggers.
*/
export function buildAttioTriggerSubBlocks(triggerId: string): SubBlockConfig[] {
return [
{
id: 'triggerCredentials',
title: 'Attio Account',
type: 'oauth-input',
serviceId: 'attio',
mode: 'trigger',
required: true,
condition: { field: 'selectedTriggerId', value: triggerId },
},
{
id: 'triggerInstructions',
title: 'Setup Instructions',
hideFromPreview: true,
type: 'text',
defaultValue: attioSetupInstructions(),
mode: 'trigger',
condition: { field: 'selectedTriggerId', value: triggerId },
},
]
}
/**
* Base webhook outputs common to all Attio triggers.
*/
function buildBaseWebhookOutputs(): Record<string, TriggerOutput> {
return {
eventType: {
type: 'string',
description: 'The type of event (e.g. record.created, note.created)',
},
}
}
/**
* Record event outputs for record triggers.
*/
function buildRecordIdOutputs(): Record<string, TriggerOutput> {
return {
workspaceId: { type: 'string', description: 'The workspace ID' },
objectId: { type: 'string', description: 'The object type ID (e.g. people, companies)' },
recordId: { type: 'string', description: 'The record ID' },
}
}
/**
* Record updated event outputs (includes attributeId).
*/
function buildRecordUpdatedIdOutputs(): Record<string, TriggerOutput> {
return {
...buildRecordIdOutputs(),
attributeId: {
type: 'string',
description: 'The ID of the attribute that was updated on the record',
},
}
}
/**
* Record merged event outputs.
* Attio payload: id.record_id (winner), duplicate_object_id, duplicate_record_id (loser).
*/
function buildRecordMergedOutputs(): Record<string, TriggerOutput> {
return {
workspaceId: { type: 'string', description: 'The workspace ID' },
objectId: { type: 'string', description: 'The object type ID of the surviving record' },
recordId: { type: 'string', description: 'The surviving record ID after merge' },
duplicateObjectId: {
type: 'string',
description: 'The object type ID of the merged-away record',
},
duplicateRecordId: { type: 'string', description: 'The record ID that was merged away' },
}
}
/**
* Note event outputs.
*/
function buildNoteIdOutputs(): Record<string, TriggerOutput> {
return {
workspaceId: { type: 'string', description: 'The workspace ID' },
noteId: { type: 'string', description: 'The note ID' },
parentObjectId: { type: 'string', description: 'The parent object type ID' },
parentRecordId: { type: 'string', description: 'The parent record ID' },
}
}
/**
* Task event outputs.
* Attio task webhook payloads only contain workspace_id and task_id.
*/
function buildTaskIdOutputs(): Record<string, TriggerOutput> {
return {
workspaceId: { type: 'string', description: 'The workspace ID' },
taskId: { type: 'string', description: 'The task ID' },
}
}
/**
* Comment event outputs.
* Attio payload uses object_id/record_id (not parent_*), plus list_id/entry_id.
*/
function buildCommentIdOutputs(): Record<string, TriggerOutput> {
return {
workspaceId: { type: 'string', description: 'The workspace ID' },
threadId: { type: 'string', description: 'The thread ID' },
commentId: { type: 'string', description: 'The comment ID' },
objectId: { type: 'string', description: 'The object type ID' },
recordId: { type: 'string', description: 'The record ID' },
listId: { type: 'string', description: 'The list ID (if comment is on a list entry)' },
entryId: { type: 'string', description: 'The list entry ID (if comment is on a list entry)' },
}
}
/**
* List entry event outputs.
*/
function buildListEntryIdOutputs(): Record<string, TriggerOutput> {
return {
workspaceId: { type: 'string', description: 'The workspace ID' },
listId: { type: 'string', description: 'The list ID' },
entryId: { type: 'string', description: 'The list entry ID' },
}
}
/**
* List entry updated event outputs (includes attributeId).
*/
function buildListEntryUpdatedIdOutputs(): Record<string, TriggerOutput> {
return {
...buildListEntryIdOutputs(),
attributeId: {
type: 'string',
description: 'The ID of the attribute that was updated on the list entry',
},
}
}
/** Record created/deleted outputs. */
export function buildRecordOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildRecordIdOutputs(),
}
}
/** Record updated outputs (includes attributeId). */
export function buildRecordUpdatedOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildRecordUpdatedIdOutputs(),
}
}
/** Record merged outputs. */
export function buildRecordMergedEventOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildRecordMergedOutputs(),
}
}
/** Note event outputs. */
export function buildNoteOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildNoteIdOutputs(),
}
}
/** Task event outputs. */
export function buildTaskOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildTaskIdOutputs(),
}
}
/** Comment event outputs. */
export function buildCommentOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildCommentIdOutputs(),
}
}
/**
* List event outputs.
*/
function buildListIdOutputs(): Record<string, TriggerOutput> {
return {
workspaceId: { type: 'string', description: 'The workspace ID' },
listId: { type: 'string', description: 'The list ID' },
}
}
/** List created/updated/deleted outputs. */
export function buildListOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildListIdOutputs(),
}
}
/**
* Workspace member event outputs.
*/
function buildWorkspaceMemberIdOutputs(): Record<string, TriggerOutput> {
return {
workspaceId: { type: 'string', description: 'The workspace ID' },
workspaceMemberId: { type: 'string', description: 'The workspace member ID' },
}
}
/** Workspace member outputs. */
export function buildWorkspaceMemberOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildWorkspaceMemberIdOutputs(),
}
}
/** List entry created/deleted outputs. */
export function buildListEntryOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildListEntryIdOutputs(),
}
}
/** List entry updated outputs (includes attributeId). */
export function buildListEntryUpdatedOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
...buildListEntryUpdatedIdOutputs(),
}
}
/** Generic webhook outputs covering all event types. */
export function buildGenericWebhookOutputs(): Record<string, TriggerOutput> {
return {
...buildBaseWebhookOutputs(),
id: { type: 'json', description: 'The event ID object containing resource identifiers' },
parentObjectId: {
type: 'string',
description: 'The parent object type ID (if applicable)',
},
parentRecordId: {
type: 'string',
description: 'The parent record ID (if applicable)',
},
}
}
/**
* Maps trigger IDs to the exact Attio event type strings.
*/
export const TRIGGER_EVENT_MAP: Record<string, string[]> = {
attio_record_created: ['record.created'],
attio_record_updated: ['record.updated'],
attio_record_deleted: ['record.deleted'],
attio_record_merged: ['record.merged'],
attio_note_created: ['note.created'],
attio_note_updated: ['note.updated', 'note-content.updated'],
attio_note_deleted: ['note.deleted'],
attio_task_created: ['task.created'],
attio_task_updated: ['task.updated'],
attio_task_deleted: ['task.deleted'],
attio_comment_created: ['comment.created'],
attio_comment_resolved: ['comment.resolved'],
attio_comment_unresolved: ['comment.unresolved'],
attio_comment_deleted: ['comment.deleted'],
attio_list_entry_created: ['list-entry.created'],
attio_list_entry_updated: ['list-entry.updated'],
attio_list_entry_deleted: ['list-entry.deleted'],
attio_list_created: ['list.created'],
attio_list_updated: ['list.updated'],
attio_list_deleted: ['list.deleted'],
attio_workspace_member_created: ['workspace-member.created'],
}
/**
* Extracts the first event from an Attio webhook payload.
* Attio wraps events in an `events` array: `{ webhook_id, events: [{ event_type, id, ... }] }`.
*/
export function getAttioEvent(body: Record<string, unknown>): Record<string, unknown> | undefined {
const events = body.events as Array<Record<string, unknown>> | undefined
return events?.[0]
}
/**
* Checks if an Attio webhook payload matches a trigger.
*/
export function isAttioPayloadMatch(triggerId: string, body: Record<string, unknown>): boolean {
if (triggerId === 'attio_webhook') {
return true
}
const event = getAttioEvent(body)
const eventType = event?.event_type as string | undefined
if (!eventType) {
return false
}
const acceptedEvents = TRIGGER_EVENT_MAP[triggerId]
return acceptedEvents ? acceptedEvents.includes(eventType) : false
}
/**
* Extracts formatted data from an Attio record event payload.
* Used for record.created, record.deleted triggers.
*/
export function extractAttioRecordData(body: Record<string, unknown>): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
objectId: id.object_id ?? null,
recordId: id.record_id ?? null,
}
}
/**
* Extracts formatted data from an Attio record.updated event payload.
*/
export function extractAttioRecordUpdatedData(
body: Record<string, unknown>
): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
objectId: id.object_id ?? null,
recordId: id.record_id ?? null,
attributeId: id.attribute_id ?? null,
}
}
/**
* Extracts formatted data from an Attio record.merged event payload.
*/
export function extractAttioRecordMergedData(
body: Record<string, unknown>
): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
objectId: id.object_id ?? null,
recordId: id.record_id ?? null,
duplicateObjectId: (event.duplicate_object_id as string) ?? null,
duplicateRecordId: (event.duplicate_record_id as string) ?? null,
}
}
/**
* Extracts formatted data from an Attio note event payload.
*/
export function extractAttioNoteData(body: Record<string, unknown>): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
noteId: id.note_id ?? null,
parentObjectId: (event.parent_object_id as string) ?? null,
parentRecordId: (event.parent_record_id as string) ?? null,
}
}
/**
* Extracts formatted data from an Attio task event payload.
*/
export function extractAttioTaskData(body: Record<string, unknown>): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
taskId: id.task_id ?? null,
}
}
/**
* Extracts formatted data from an Attio comment event payload.
*/
export function extractAttioCommentData(body: Record<string, unknown>): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
threadId: (event.thread_id as string) ?? null,
commentId: id.comment_id ?? null,
objectId: (event.object_id as string) ?? null,
recordId: (event.record_id as string) ?? null,
listId: (event.list_id as string) ?? null,
entryId: (event.entry_id as string) ?? null,
}
}
/**
* Extracts formatted data from an Attio list-entry event payload.
* Used for list-entry.created, list-entry.deleted triggers.
*/
export function extractAttioListEntryData(body: Record<string, unknown>): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
listId: id.list_id ?? null,
entryId: id.entry_id ?? null,
}
}
/**
* Extracts formatted data from an Attio list-entry.updated event payload.
*/
export function extractAttioListEntryUpdatedData(
body: Record<string, unknown>
): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
listId: id.list_id ?? null,
entryId: id.entry_id ?? null,
attributeId: id.attribute_id ?? null,
}
}
/**
* Extracts formatted data from an Attio list event payload.
* Used for list.created, list.updated, list.deleted triggers.
*/
export function extractAttioListData(body: Record<string, unknown>): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
listId: id.list_id ?? null,
}
}
/**
* Extracts formatted data from an Attio workspace-member.created event payload.
*/
export function extractAttioWorkspaceMemberData(
body: Record<string, unknown>
): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
workspaceId: id.workspace_id ?? null,
workspaceMemberId: id.workspace_member_id ?? null,
}
}
/**
* Extracts formatted data from a generic Attio webhook payload.
* Passes through the first event with camelCase field mapping.
*/
export function extractAttioGenericData(body: Record<string, unknown>): Record<string, unknown> {
const event = getAttioEvent(body) ?? {}
const id = (event.id as Record<string, unknown>) ?? {}
return {
eventType: event.event_type ?? null,
id,
parentObjectId: (event.parent_object_id as string) ?? null,
parentRecordId: (event.parent_record_id as string) ?? null,
}
}
+29
View File
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildGenericWebhookOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Generic Attio Webhook Trigger
*
* Captures all Attio webhook events without filtering.
*/
export const attioWebhookTrigger: TriggerConfig = {
id: 'attio_webhook',
name: 'Attio Webhook (All Events)',
provider: 'attio',
description: 'Trigger workflow on any Attio webhook event',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_webhook'),
outputs: buildGenericWebhookOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}
@@ -0,0 +1,29 @@
import { AttioIcon } from '@/components/icons'
import { buildAttioTriggerSubBlocks, buildWorkspaceMemberOutputs } from '@/triggers/attio/utils'
import type { TriggerConfig } from '@/triggers/types'
/**
* Attio Workspace Member Created Trigger
*
* Triggers when a new member is added to the Attio workspace.
*/
export const attioWorkspaceMemberCreatedTrigger: TriggerConfig = {
id: 'attio_workspace_member_created',
name: 'Attio Workspace Member Created',
provider: 'attio',
description: 'Trigger workflow when a new member is added to the Attio workspace',
version: '1.0.0',
icon: AttioIcon,
subBlocks: buildAttioTriggerSubBlocks('attio_workspace_member_created'),
outputs: buildWorkspaceMemberOutputs(),
webhook: {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Attio-Signature': 'hmac-sha256-signature',
},
},
}