diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx
index dae53828ccb..c4bc260742b 100644
--- a/apps/docs/components/icons.tsx
+++ b/apps/docs/components/icons.tsx
@@ -415,6 +415,17 @@ export function MailIcon(props: SVGProps) {
)
}
+export function EmailBisonIcon(props: SVGProps) {
+ return (
+
+ )
+}
+
export function MailServerIcon(props: SVGProps) {
return (
`,
+ innerHtml: `${pageContent.replace(/"/g, '"').replace(/'/g, ''')}
`,
},
],
},
diff --git a/apps/sim/tools/sharepoint/get_list.ts b/apps/sim/tools/sharepoint/get_list.ts
index f5528ee95b6..bcf3036a977 100644
--- a/apps/sim/tools/sharepoint/get_list.ts
+++ b/apps/sim/tools/sharepoint/get_list.ts
@@ -4,6 +4,7 @@ import type {
SharepointList,
SharepointToolParams,
} from '@/tools/sharepoint/types'
+import { assertGraphNextPageUrl, getGraphNextPageUrl, optionalTrim } from '@/tools/sharepoint/utils'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('SharePointGetList')
@@ -12,7 +13,7 @@ export const getListTool: ToolConfig {
- const siteId = params.siteId || params.siteSelector || 'root'
+ if (params.nextPageUrl) {
+ return assertGraphNextPageUrl(params.nextPageUrl)
+ }
+
+ const siteId = optionalTrim(params.siteId) || optionalTrim(params.siteSelector) || 'root'
+ const listId = optionalTrim(params.listId)
- // If neither listId nor listTitle provided, list all lists in the site
- if (!params.listId) {
+ if (!listId) {
const baseUrl = `https://graph.microsoft.com/v1.0/sites/${siteId}/lists`
const url = new URL(baseUrl)
const finalUrl = url.toString()
@@ -63,11 +86,9 @@ export const getListTool: ToolConfig {
+ transformResponse: async (response: Response, params) => {
const data = await response.json()
// If the response is a collection of items (from the items endpoint)
@@ -122,25 +142,18 @@ export const getListTool: ToolConfig,
}))
- const nextLink: string | undefined = (data as any)['@odata.nextLink']
- const nextPageToken = nextLink
- ? (() => {
- try {
- const u = new URL(nextLink)
- return u.searchParams.get('$skiptoken') || u.searchParams.get('$skip') || undefined
- } catch {
- return undefined
- }
- })()
- : undefined
+ const nextPageUrl = getGraphNextPageUrl(data as Record)
return {
success: true,
- output: { list: { items } as SharepointList, nextPageToken },
+ output: {
+ list: { id: optionalTrim(params?.listId) || '', items } as SharepointList,
+ items,
+ nextPageUrl,
+ },
}
}
- // If this is a collection of lists (site-level)
if (Array.isArray((data as any).value)) {
const lists: SharepointList[] = (data as any).value.map((l: any) => ({
id: l.id,
@@ -152,25 +165,14 @@ export const getListTool: ToolConfig {
- try {
- const u = new URL(nextLink)
- return u.searchParams.get('$skiptoken') || u.searchParams.get('$skip') || undefined
- } catch {
- return undefined
- }
- })()
- : undefined
+ const nextPageUrl = getGraphNextPageUrl(data as Record)
return {
success: true,
- output: { lists, nextPageToken },
+ output: { lists, nextPageUrl },
}
}
- // Single list response (with optional expands)
const list: SharepointList = {
id: data.id,
displayName: data.displayName ?? data.name,
@@ -242,5 +244,21 @@ export const getListTool: ToolConfig = {
id: 'sharepoint_list_sites',
name: 'List SharePoint Sites',
description: 'List details of all SharePoint sites',
- version: '1.0',
+ version: '1.0.0',
oauth: {
required: true,
@@ -29,6 +30,12 @@ export const listSitesTool: ToolConfig {
+ if (params.nextPageUrl) {
+ return assertGraphNextPageUrl(params.nextPageUrl)
+ }
+
let baseUrl: string
+ const groupId = optionalTrim(params.groupId)
+ const siteId = optionalTrim(params.siteId) || optionalTrim(params.siteSelector)
- if (params.groupId) {
- // Access group team site
- baseUrl = `https://graph.microsoft.com/v1.0/groups/${params.groupId}/sites/root`
- } else if (params.siteId || params.siteSelector) {
- // Access specific site by ID
- const siteId = params.siteId || params.siteSelector
+ if (groupId) {
+ baseUrl = `https://graph.microsoft.com/v1.0/groups/${groupId}/sites/root`
+ } else if (siteId) {
baseUrl = `https://graph.microsoft.com/v1.0/sites/${siteId}`
} else {
- // get all sites
baseUrl = 'https://graph.microsoft.com/v1.0/sites?search=*'
}
const url = new URL(baseUrl)
- // Use Microsoft Graph $select parameter to get site details
url.searchParams.append(
'$select',
'id,name,displayName,webUrl,description,createdDateTime,lastModifiedDateTime,isPersonalSite,root,siteCollection'
@@ -71,12 +85,10 @@ export const listSitesTool: ToolConfig {
+ transformResponse: async (response: Response) => {
const data = await response.json()
- // Check if this is a search result (multiple sites) or single site
if (data.value && Array.isArray(data.value)) {
- // Multiple sites from search
return {
success: true,
output: {
@@ -89,10 +101,11 @@ export const listSitesTool: ToolConfig),
},
}
}
- // Single site response
+
return {
success: true,
output: {
@@ -155,5 +168,10 @@ export const listSitesTool: ToolConfig {
- // Use specific site if provided, otherwise use root site
- const siteId = params.siteId || params.siteSelector || 'root'
+ if (params.nextPageUrl) {
+ return assertGraphNextPageUrl(params.nextPageUrl)
+ }
+
+ const siteId = optionalTrim(params.siteId) || optionalTrim(params.siteSelector) || 'root'
+ const pageId = optionalTrim(params.pageId)
let baseUrl: string
- if (params.pageId) {
- // Read specific page by ID
- baseUrl = `https://graph.microsoft.com/v1.0/sites/${siteId}/pages/${params.pageId}`
+ if (pageId) {
+ baseUrl = `https://graph.microsoft.com/v1.0/sites/${siteId}/pages/${pageId}/microsoft.graph.sitePage`
} else {
- // List all pages (with optional filtering by name)
- baseUrl = `https://graph.microsoft.com/v1.0/sites/${siteId}/pages`
+ baseUrl = `https://graph.microsoft.com/v1.0/sites/${siteId}/pages/microsoft.graph.sitePage`
}
const url = new URL(baseUrl)
- // Use Microsoft Graph $select parameter to get page details
- // Only include valid properties for SharePoint pages
url.searchParams.append(
'$select',
- 'id,name,title,webUrl,pageLayout,createdDateTime,lastModifiedDateTime'
+ 'id,name,title,webUrl,pageLayout,description,createdDateTime,lastModifiedDateTime'
)
- // If searching by name, add filter
- if (params.pageName && !params.pageId) {
- // Try to handle both with and without .aspx extension
- const pageName = params.pageName
+ if (params.pageName && !pageId) {
+ const pageName = params.pageName.trim()
const pageNameWithAspx = pageName.endsWith('.aspx') ? pageName : `${pageName}.aspx`
-
- // Search for exact match first, then with .aspx if needed
- url.searchParams.append('$filter', `name eq '${pageName}' or name eq '${pageNameWithAspx}'`)
- url.searchParams.append('$top', '10') // Get more results to find matches
- } else if (!params.pageId && !params.pageName) {
- // When listing all pages, apply maxPages limit
- const maxPages = Math.min(params.maxPages || 10, 50) // Default 10, max 50
+ const escapedPageName = escapeODataString(pageName)
+ const escapedPageNameWithAspx = escapeODataString(pageNameWithAspx)
+
+ url.searchParams.append(
+ '$filter',
+ `name eq '${escapedPageName}' or name eq '${escapedPageNameWithAspx}'`
+ )
+ url.searchParams.append('$top', '10')
+ } else if (!pageId && !params.pageName) {
+ const requestedMaxPages =
+ typeof params.maxPages === 'number' ? params.maxPages : Number(params.maxPages || 10)
+ const maxPages = Math.min(Number.isFinite(requestedMaxPages) ? requestedMaxPages : 10, 50)
url.searchParams.append('$top', maxPages.toString())
}
- // Only expand content when getting a specific page by ID
- if (params.pageId) {
+ if (pageId) {
url.searchParams.append('$expand', 'canvasLayout')
}
@@ -112,7 +127,7 @@ export const readPageTool: ToolConfig
+ nextPageUrl?: string
}
}
@@ -155,12 +158,12 @@ export interface SharepointToolParams {
siteSelector?: string
pageId?: string
pageName?: string
- pageContent?: string
+ pageContent?: string | unknown[] | { columns?: unknown[] }
pageTitle?: string
publishingState?: string
query?: string
pageSize?: number
- pageToken?: string
+ nextPageUrl?: string
hostname?: string
serverRelativePath?: string
groupId?: string
@@ -188,6 +191,7 @@ export interface GraphApiResponse {
id?: string
name?: string
title?: string
+ description?: string | null
webUrl?: string
pageLayout?: string
createdDateTime?: string
@@ -203,6 +207,7 @@ export interface GraphApiPageItem {
id: string
name: string
title?: string
+ description?: string | null
webUrl?: string
pageLayout?: string
createdDateTime?: string
@@ -227,36 +232,6 @@ export interface CanvasLayout {
}>
}
-export interface SharepointReadSiteResponse extends ToolResponse {
- output: {
- site?: {
- id: string
- name: string
- displayName: string
- webUrl: string
- description?: string
- createdDateTime?: string
- lastModifiedDateTime?: string
- isPersonalSite?: boolean
- root?: {
- serverRelativeUrl: string
- }
- siteCollection?: {
- hostname: string
- }
- }
- sites?: Array<{
- id: string
- name: string
- displayName: string
- webUrl: string
- description?: string
- createdDateTime?: string
- lastModifiedDateTime?: string
- }>
- }
-}
-
export type SharepointResponse =
| SharepointListSitesResponse
| SharepointCreatePageResponse
@@ -272,7 +247,8 @@ export interface SharepointGetListResponse extends ToolResponse {
output: {
list?: SharepointList
lists?: SharepointList[]
- nextPageToken?: string
+ items?: SharepointListItem[]
+ nextPageUrl?: string
}
}
@@ -309,9 +285,25 @@ export interface SharepointUploadedFile {
lastModifiedDateTime?: string
}
+export interface SharepointSkippedFile {
+ name: string
+ size: number
+ limit: number
+ reason: string
+}
+
+export interface SharepointUploadError {
+ name: string
+ error: string
+ status?: number
+}
+
export interface SharepointUploadFileResponse extends ToolResponse {
output: {
uploadedFiles: SharepointUploadedFile[]
fileCount: number
+ skippedFiles?: SharepointSkippedFile[]
+ skippedCount?: number
+ errors?: SharepointUploadError[]
}
}
diff --git a/apps/sim/tools/sharepoint/update_list.ts b/apps/sim/tools/sharepoint/update_list.ts
index d2a62227963..a0511e45f2b 100644
--- a/apps/sim/tools/sharepoint/update_list.ts
+++ b/apps/sim/tools/sharepoint/update_list.ts
@@ -3,6 +3,7 @@ import type {
SharepointToolParams,
SharepointUpdateListItemResponse,
} from '@/tools/sharepoint/types'
+import { optionalTrim } from '@/tools/sharepoint/utils'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('SharePointUpdateListItem')
@@ -14,7 +15,7 @@ export const updateListItemTool: ToolConfig<
id: 'sharepoint_update_list',
name: 'Update SharePoint List Item',
description: 'Update the properties (fields) on a SharePoint list item',
- version: '1.0',
+ version: '1.0.0',
oauth: {
required: true,
@@ -42,7 +43,7 @@ export const updateListItemTool: ToolConfig<
},
listId: {
type: 'string',
- required: false,
+ required: true,
visibility: 'user-or-llm',
description:
'The ID of the list containing the item. Example: b!abc123def456 or a GUID like 12345678-1234-1234-1234-123456789012',
@@ -54,7 +55,7 @@ export const updateListItemTool: ToolConfig<
description: 'The ID of the list item to update. Example: 1, 42, or 123',
},
listItemFields: {
- type: 'object',
+ type: 'json',
required: true,
visibility: 'user-only',
description: 'Field values to update on the list item',
@@ -63,13 +64,15 @@ export const updateListItemTool: ToolConfig<
request: {
url: (params) => {
- const siteId = params.siteId || params.siteSelector || 'root'
- if (!params.itemId) throw new Error('itemId is required')
- if (!params.listId) {
+ const siteId = optionalTrim(params.siteId) || optionalTrim(params.siteSelector) || 'root'
+ const itemId = optionalTrim(params.itemId)
+ const listId = optionalTrim(params.listId)
+ if (!itemId) throw new Error('itemId is required')
+ if (!listId) {
throw new Error('listId must be provided')
}
- const listSegment = params.listId
- return `https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${listSegment}/items/${params.itemId}/fields`
+ const listSegment = encodeURIComponent(listId)
+ return `https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${listSegment}/items/${encodeURIComponent(itemId)}/fields`
},
method: 'PATCH',
headers: (params) => ({
diff --git a/apps/sim/tools/sharepoint/upload_file.ts b/apps/sim/tools/sharepoint/upload_file.ts
index 8728e4ea673..94626a82ee6 100644
--- a/apps/sim/tools/sharepoint/upload_file.ts
+++ b/apps/sim/tools/sharepoint/upload_file.ts
@@ -1,11 +1,12 @@
import type { SharepointToolParams, SharepointUploadFileResponse } from '@/tools/sharepoint/types'
+import { optionalTrim } from '@/tools/sharepoint/utils'
import type { ToolConfig } from '@/tools/types'
export const uploadFileTool: ToolConfig = {
id: 'sharepoint_upload_file',
name: 'Upload File to SharePoint',
description: 'Upload files to a SharePoint document library',
- version: '1.0',
+ version: '1.0.0',
oauth: {
required: true,
@@ -47,7 +48,7 @@ export const uploadFileTool: ToolConfig {
return {
accessToken: params.accessToken,
- siteId: params.siteId || 'root',
- driveId: params.driveId || null,
- folderPath: params.folderPath || null,
- fileName: params.fileName || null,
+ siteId: optionalTrim(params.siteId) || 'root',
+ driveId: optionalTrim(params.driveId) || null,
+ folderPath: optionalTrim(params.folderPath) || null,
+ fileName: optionalTrim(params.fileName) || null,
files: params.files || null,
}
},
@@ -73,15 +74,17 @@ export const uploadFileTool: ToolConfig {
const data = await response.json()
- if (!data.success) {
- throw new Error(data.error || 'Failed to upload files to SharePoint')
- }
+ const output = data.output ?? {}
return {
- success: true,
+ success: Boolean(data.success),
output: {
- uploadedFiles: data.output.uploadedFiles,
- fileCount: data.output.fileCount,
+ uploadedFiles: output.uploadedFiles ?? [],
+ fileCount: output.fileCount ?? 0,
+ skippedFiles: output.skippedFiles ?? [],
+ skippedCount: output.skippedCount ?? 0,
+ errors: output.errors ?? [],
},
+ error: data.success ? undefined : data.error || 'Failed to upload files to SharePoint',
}
},
@@ -105,5 +108,38 @@ export const uploadFileTool: ToolConfig)['@odata.nextLink']
+ return typeof nextLink === 'string' ? nextLink : undefined
+}
+
+export function assertGraphNextPageUrl(nextPageUrl: string): string {
+ const trimmed = nextPageUrl.trim()
+ const url = new URL(trimmed)
+ if (url.origin !== 'https://graph.microsoft.com') {
+ throw new Error('nextPageUrl must be a Microsoft Graph @odata.nextLink URL')
+ }
+ return url.toString()
+}
+
function stripHtmlTags(html: string): string {
let text = html
let previous: string
diff --git a/apps/sim/triggers/emailbison/email_account_added.ts b/apps/sim/triggers/emailbison/email_account_added.ts
new file mode 100644
index 00000000000..24669f31bcc
--- /dev/null
+++ b/apps/sim/triggers/emailbison/email_account_added.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonEmailAccountAddedOutputs,
+ buildEmailBisonExtraFields,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonEmailAccountAddedTrigger: TriggerConfig = {
+ id: 'emailbison_email_account_added',
+ name: 'Email Bison Email Account Added',
+ provider: 'emailbison',
+ description: 'Trigger when a sender email account is added to Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_email_account_added',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Email Account Added'),
+ extraFields: buildEmailBisonExtraFields('emailbison_email_account_added'),
+ }),
+ outputs: buildEmailBisonEmailAccountAddedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/email_account_disconnected.ts b/apps/sim/triggers/emailbison/email_account_disconnected.ts
new file mode 100644
index 00000000000..ea70ad995d7
--- /dev/null
+++ b/apps/sim/triggers/emailbison/email_account_disconnected.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonEmailAccountDisconnectedOutputs,
+ buildEmailBisonExtraFields,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonEmailAccountDisconnectedTrigger: TriggerConfig = {
+ id: 'emailbison_email_account_disconnected',
+ name: 'Email Bison Email Account Disconnected',
+ provider: 'emailbison',
+ description: 'Trigger when a sender email account disconnects in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_email_account_disconnected',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Email Account Disconnected'),
+ extraFields: buildEmailBisonExtraFields('emailbison_email_account_disconnected'),
+ }),
+ outputs: buildEmailBisonEmailAccountDisconnectedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/email_account_reconnected.ts b/apps/sim/triggers/emailbison/email_account_reconnected.ts
new file mode 100644
index 00000000000..3b05d36205c
--- /dev/null
+++ b/apps/sim/triggers/emailbison/email_account_reconnected.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonEmailAccountReconnectedOutputs,
+ buildEmailBisonExtraFields,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonEmailAccountReconnectedTrigger: TriggerConfig = {
+ id: 'emailbison_email_account_reconnected',
+ name: 'Email Bison Email Account Reconnected',
+ provider: 'emailbison',
+ description: 'Trigger when a sender email account reconnects in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_email_account_reconnected',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Email Account Reconnected'),
+ extraFields: buildEmailBisonExtraFields('emailbison_email_account_reconnected'),
+ }),
+ outputs: buildEmailBisonEmailAccountReconnectedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/email_account_removed.ts b/apps/sim/triggers/emailbison/email_account_removed.ts
new file mode 100644
index 00000000000..6ea2038c287
--- /dev/null
+++ b/apps/sim/triggers/emailbison/email_account_removed.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonEmailAccountRemovedOutputs,
+ buildEmailBisonExtraFields,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonEmailAccountRemovedTrigger: TriggerConfig = {
+ id: 'emailbison_email_account_removed',
+ name: 'Email Bison Email Account Removed',
+ provider: 'emailbison',
+ description: 'Trigger when a sender email account is removed from Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_email_account_removed',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Email Account Removed'),
+ extraFields: buildEmailBisonExtraFields('emailbison_email_account_removed'),
+ }),
+ outputs: buildEmailBisonEmailAccountRemovedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/email_bounced.ts b/apps/sim/triggers/emailbison/email_bounced.ts
new file mode 100644
index 00000000000..adfee951386
--- /dev/null
+++ b/apps/sim/triggers/emailbison/email_bounced.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonEmailBouncedOutputs,
+ buildEmailBisonExtraFields,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonEmailBouncedTrigger: TriggerConfig = {
+ id: 'emailbison_email_bounced',
+ name: 'Email Bison Email Bounced',
+ provider: 'emailbison',
+ description: 'Trigger when an Email Bison campaign email bounces',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_email_bounced',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Email Bounced'),
+ extraFields: buildEmailBisonExtraFields('emailbison_email_bounced'),
+ }),
+ outputs: buildEmailBisonEmailBouncedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/email_opened.ts b/apps/sim/triggers/emailbison/email_opened.ts
new file mode 100644
index 00000000000..53e7bc9e5f6
--- /dev/null
+++ b/apps/sim/triggers/emailbison/email_opened.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonEmailOpenedOutputs,
+ buildEmailBisonExtraFields,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonEmailOpenedTrigger: TriggerConfig = {
+ id: 'emailbison_email_opened',
+ name: 'Email Bison Email Opened',
+ provider: 'emailbison',
+ description: 'Trigger when an Email Bison campaign email is opened',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_email_opened',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Email Opened'),
+ extraFields: buildEmailBisonExtraFields('emailbison_email_opened'),
+ }),
+ outputs: buildEmailBisonEmailOpenedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/email_sent.ts b/apps/sim/triggers/emailbison/email_sent.ts
new file mode 100644
index 00000000000..3b7bcbabfd4
--- /dev/null
+++ b/apps/sim/triggers/emailbison/email_sent.ts
@@ -0,0 +1,27 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonEmailSentOutputs,
+ buildEmailBisonExtraFields,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonEmailSentTrigger: TriggerConfig = {
+ id: 'emailbison_email_sent',
+ name: 'Email Bison Email Sent',
+ provider: 'emailbison',
+ description: 'Trigger when a campaign email is sent in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_email_sent',
+ triggerOptions: emailBisonTriggerOptions,
+ includeDropdown: true,
+ setupInstructions: emailBisonSetupInstructions('Email Sent'),
+ extraFields: buildEmailBisonExtraFields('emailbison_email_sent'),
+ }),
+ outputs: buildEmailBisonEmailSentOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/index.ts b/apps/sim/triggers/emailbison/index.ts
new file mode 100644
index 00000000000..7876e0731c6
--- /dev/null
+++ b/apps/sim/triggers/emailbison/index.ts
@@ -0,0 +1,17 @@
+export { emailBisonEmailAccountAddedTrigger } from '@/triggers/emailbison/email_account_added'
+export { emailBisonEmailAccountDisconnectedTrigger } from '@/triggers/emailbison/email_account_disconnected'
+export { emailBisonEmailAccountReconnectedTrigger } from '@/triggers/emailbison/email_account_reconnected'
+export { emailBisonEmailAccountRemovedTrigger } from '@/triggers/emailbison/email_account_removed'
+export { emailBisonEmailBouncedTrigger } from '@/triggers/emailbison/email_bounced'
+export { emailBisonEmailOpenedTrigger } from '@/triggers/emailbison/email_opened'
+export { emailBisonEmailSentTrigger } from '@/triggers/emailbison/email_sent'
+export { emailBisonLeadFirstContactedTrigger } from '@/triggers/emailbison/lead_first_contacted'
+export { emailBisonLeadInterestedTrigger } from '@/triggers/emailbison/lead_interested'
+export { emailBisonLeadRepliedTrigger } from '@/triggers/emailbison/lead_replied'
+export { emailBisonLeadUnsubscribedTrigger } from '@/triggers/emailbison/lead_unsubscribed'
+export { emailBisonManualEmailSentTrigger } from '@/triggers/emailbison/manual_email_sent'
+export { emailBisonTagAttachedTrigger } from '@/triggers/emailbison/tag_attached'
+export { emailBisonTagRemovedTrigger } from '@/triggers/emailbison/tag_removed'
+export { emailBisonUntrackedReplyReceivedTrigger } from '@/triggers/emailbison/untracked_reply_received'
+export { emailBisonWarmupDisabledCausingBouncesTrigger } from '@/triggers/emailbison/warmup_disabled_causing_bounces'
+export { emailBisonWarmupDisabledReceivingBouncesTrigger } from '@/triggers/emailbison/warmup_disabled_receiving_bounces'
diff --git a/apps/sim/triggers/emailbison/lead_first_contacted.ts b/apps/sim/triggers/emailbison/lead_first_contacted.ts
new file mode 100644
index 00000000000..406940ce0b0
--- /dev/null
+++ b/apps/sim/triggers/emailbison/lead_first_contacted.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonLeadFirstContactedOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonLeadFirstContactedTrigger: TriggerConfig = {
+ id: 'emailbison_lead_first_contacted',
+ name: 'Email Bison Contact First Emailed',
+ provider: 'emailbison',
+ description: 'Trigger when a contact receives their first campaign email in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_lead_first_contacted',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Contact First Emailed'),
+ extraFields: buildEmailBisonExtraFields('emailbison_lead_first_contacted'),
+ }),
+ outputs: buildEmailBisonLeadFirstContactedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/lead_interested.ts b/apps/sim/triggers/emailbison/lead_interested.ts
new file mode 100644
index 00000000000..b4fbdbd5202
--- /dev/null
+++ b/apps/sim/triggers/emailbison/lead_interested.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonLeadInterestedOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonLeadInterestedTrigger: TriggerConfig = {
+ id: 'emailbison_lead_interested',
+ name: 'Email Bison Contact Interested',
+ provider: 'emailbison',
+ description: 'Trigger when a reply is marked interested in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_lead_interested',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Contact Interested'),
+ extraFields: buildEmailBisonExtraFields('emailbison_lead_interested'),
+ }),
+ outputs: buildEmailBisonLeadInterestedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/lead_replied.ts b/apps/sim/triggers/emailbison/lead_replied.ts
new file mode 100644
index 00000000000..6b47967e42a
--- /dev/null
+++ b/apps/sim/triggers/emailbison/lead_replied.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonLeadRepliedOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonLeadRepliedTrigger: TriggerConfig = {
+ id: 'emailbison_lead_replied',
+ name: 'Email Bison Contact Replied',
+ provider: 'emailbison',
+ description: 'Trigger when a campaign lead replies in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_lead_replied',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Contact Replied'),
+ extraFields: buildEmailBisonExtraFields('emailbison_lead_replied'),
+ }),
+ outputs: buildEmailBisonLeadRepliedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/lead_unsubscribed.ts b/apps/sim/triggers/emailbison/lead_unsubscribed.ts
new file mode 100644
index 00000000000..ce7f5f7aef4
--- /dev/null
+++ b/apps/sim/triggers/emailbison/lead_unsubscribed.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonLeadUnsubscribedOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonLeadUnsubscribedTrigger: TriggerConfig = {
+ id: 'emailbison_lead_unsubscribed',
+ name: 'Email Bison Contact Unsubscribed',
+ provider: 'emailbison',
+ description: 'Trigger when a contact unsubscribes in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_lead_unsubscribed',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Contact Unsubscribed'),
+ extraFields: buildEmailBisonExtraFields('emailbison_lead_unsubscribed'),
+ }),
+ outputs: buildEmailBisonLeadUnsubscribedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/manual_email_sent.ts b/apps/sim/triggers/emailbison/manual_email_sent.ts
new file mode 100644
index 00000000000..772b88e5c06
--- /dev/null
+++ b/apps/sim/triggers/emailbison/manual_email_sent.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonManualEmailSentOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonManualEmailSentTrigger: TriggerConfig = {
+ id: 'emailbison_manual_email_sent',
+ name: 'Email Bison Manual Email Sent',
+ provider: 'emailbison',
+ description: 'Trigger when a manual email is sent in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_manual_email_sent',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Manual Email Sent'),
+ extraFields: buildEmailBisonExtraFields('emailbison_manual_email_sent'),
+ }),
+ outputs: buildEmailBisonManualEmailSentOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/tag_attached.ts b/apps/sim/triggers/emailbison/tag_attached.ts
new file mode 100644
index 00000000000..6d02e97f107
--- /dev/null
+++ b/apps/sim/triggers/emailbison/tag_attached.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonTagAttachedOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonTagAttachedTrigger: TriggerConfig = {
+ id: 'emailbison_tag_attached',
+ name: 'Email Bison Tag Attached',
+ provider: 'emailbison',
+ description: 'Trigger when a custom tag is attached to a taggable in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_tag_attached',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Tag Attached'),
+ extraFields: buildEmailBisonExtraFields('emailbison_tag_attached'),
+ }),
+ outputs: buildEmailBisonTagAttachedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/tag_removed.ts b/apps/sim/triggers/emailbison/tag_removed.ts
new file mode 100644
index 00000000000..cd128f8ec09
--- /dev/null
+++ b/apps/sim/triggers/emailbison/tag_removed.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonTagRemovedOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonTagRemovedTrigger: TriggerConfig = {
+ id: 'emailbison_tag_removed',
+ name: 'Email Bison Tag Removed',
+ provider: 'emailbison',
+ description: 'Trigger when a custom tag is removed from a taggable in Email Bison',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_tag_removed',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Tag Removed'),
+ extraFields: buildEmailBisonExtraFields('emailbison_tag_removed'),
+ }),
+ outputs: buildEmailBisonTagRemovedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/untracked_reply_received.ts b/apps/sim/triggers/emailbison/untracked_reply_received.ts
new file mode 100644
index 00000000000..6dbe61bd0ba
--- /dev/null
+++ b/apps/sim/triggers/emailbison/untracked_reply_received.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonUntrackedReplyReceivedOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonUntrackedReplyReceivedTrigger: TriggerConfig = {
+ id: 'emailbison_untracked_reply_received',
+ name: 'Email Bison Untracked Reply Received',
+ provider: 'emailbison',
+ description: 'Trigger when Email Bison receives a reply not tied to a scheduled campaign email',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_untracked_reply_received',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Untracked Reply Received'),
+ extraFields: buildEmailBisonExtraFields('emailbison_untracked_reply_received'),
+ }),
+ outputs: buildEmailBisonUntrackedReplyReceivedOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/utils.ts b/apps/sim/triggers/emailbison/utils.ts
new file mode 100644
index 00000000000..12d9ebbe789
--- /dev/null
+++ b/apps/sim/triggers/emailbison/utils.ts
@@ -0,0 +1,510 @@
+import type { SubBlockConfig } from '@/blocks/types'
+import type { TriggerOutput } from '@/triggers/types'
+
+export const EMAILBISON_TRIGGER_TO_EVENT_TYPE = {
+ emailbison_email_sent: 'email_sent',
+ emailbison_lead_first_contacted: 'lead_first_contacted',
+ emailbison_lead_replied: 'lead_replied',
+ emailbison_lead_interested: 'lead_interested',
+ emailbison_lead_unsubscribed: 'lead_unsubscribed',
+ emailbison_untracked_reply_received: 'untracked_reply_received',
+ emailbison_email_opened: 'email_opened',
+ emailbison_email_bounced: 'email_bounced',
+ emailbison_email_account_added: 'email_account_added',
+ emailbison_email_account_removed: 'email_account_removed',
+ emailbison_email_account_disconnected: 'email_account_disconnected',
+ emailbison_email_account_reconnected: 'email_account_reconnected',
+ emailbison_manual_email_sent: 'manual_email_sent',
+ emailbison_tag_attached: 'tag_attached',
+ emailbison_tag_removed: 'tag_removed',
+ emailbison_warmup_disabled_receiving_bounces: 'warmup_disabled_receiving_bounces',
+ emailbison_warmup_disabled_causing_bounces: 'warmup_disabled_causing_bounces',
+} as const
+
+export const emailBisonTriggerOptions = [
+ { label: 'Email Sent', id: 'emailbison_email_sent' },
+ { label: 'Contact First Emailed', id: 'emailbison_lead_first_contacted' },
+ { label: 'Contact Replied', id: 'emailbison_lead_replied' },
+ { label: 'Contact Interested', id: 'emailbison_lead_interested' },
+ { label: 'Contact Unsubscribed', id: 'emailbison_lead_unsubscribed' },
+ { label: 'Untracked Reply Received', id: 'emailbison_untracked_reply_received' },
+ { label: 'Email Opened', id: 'emailbison_email_opened' },
+ { label: 'Email Bounced', id: 'emailbison_email_bounced' },
+ { label: 'Email Account Added', id: 'emailbison_email_account_added' },
+ { label: 'Email Account Removed', id: 'emailbison_email_account_removed' },
+ { label: 'Email Account Disconnected', id: 'emailbison_email_account_disconnected' },
+ { label: 'Email Account Reconnected', id: 'emailbison_email_account_reconnected' },
+ { label: 'Manual Email Sent', id: 'emailbison_manual_email_sent' },
+ { label: 'Tag Attached', id: 'emailbison_tag_attached' },
+ { label: 'Tag Removed', id: 'emailbison_tag_removed' },
+ {
+ label: 'Warmup Disabled Receiving Bounces',
+ id: 'emailbison_warmup_disabled_receiving_bounces',
+ },
+ {
+ label: 'Warmup Disabled Causing Bounces',
+ id: 'emailbison_warmup_disabled_causing_bounces',
+ },
+]
+
+export function emailBisonSetupInstructions(eventType: string): string {
+ const instructions = [
+ 'Create an Email Bison API token in Settings > Developer API.',
+ 'Enter the Instance URL from Email Bison’s webhook payload, Full API Reference, or exported Postman collection.',
+ `Click Save Configuration to automatically create an Email Bison webhook for ${eventType}.`,
+ 'The webhook will be automatically deleted from Email Bison when this trigger is removed.',
+ ]
+
+ return instructions
+ .map(
+ (instruction, index) =>
+ `${index + 1}. ${instruction}
`
+ )
+ .join('')
+}
+
+export function buildEmailBisonExtraFields(triggerId: string): SubBlockConfig[] {
+ return [
+ {
+ id: 'apiKey',
+ title: 'API Key',
+ type: 'short-input',
+ placeholder: 'Enter your Email Bison API token',
+ password: true,
+ required: true,
+ paramVisibility: 'user-only',
+ mode: 'trigger',
+ condition: { field: 'selectedTriggerId', value: triggerId },
+ },
+ {
+ id: 'apiBaseUrl',
+ title: 'Instance URL',
+ type: 'short-input',
+ placeholder: 'https://your-emailbison-workspace.com',
+ required: true,
+ paramVisibility: 'user-only',
+ mode: 'trigger',
+ condition: { field: 'selectedTriggerId', value: triggerId },
+ },
+ ]
+}
+
+export function buildEmailBisonOutputs(): Record {
+ return {
+ eventType: { type: 'string', description: 'Email Bison webhook event type' },
+ eventName: { type: 'string', description: 'Human-readable Email Bison event name' },
+ instanceUrl: { type: 'string', description: 'Email Bison instance URL' },
+ workspaceId: { type: 'number', description: 'Email Bison workspace ID' },
+ workspaceName: { type: 'string', description: 'Email Bison workspace name' },
+ event: { type: 'json', description: 'Raw Email Bison event metadata object' },
+ data: { type: 'json', description: 'Raw Email Bison event data object' },
+ }
+}
+
+export function buildEmailBisonEmailSentOutputs(): Record {
+ return {
+ ...buildEmailBisonOutputs(),
+ scheduledEmail: {
+ id: { type: 'number', description: 'Scheduled email ID' },
+ lead_id: { type: 'number', description: 'Lead ID' },
+ sequence_step_id: { type: 'number', description: 'Sequence step ID' },
+ sequence_step_order: { type: 'number', description: 'Sequence step order' },
+ sequence_step_variant: { type: 'number', description: 'Sequence step variant' },
+ email_subject: { type: 'string', description: 'Email subject' },
+ email_body: { type: 'string', description: 'Email body HTML' },
+ status: { type: 'string', description: 'Scheduled email status' },
+ scheduled_date_est: { type: 'string', description: 'Scheduled date in EST' },
+ scheduled_date_local: { type: 'string', description: 'Scheduled date in local timezone' },
+ local_timezone: { type: 'string', description: 'Scheduled email local timezone' },
+ sent_at: { type: 'string', description: 'Email sent timestamp' },
+ opens: { type: 'number', description: 'Open count' },
+ replies: { type: 'number', description: 'Reply count' },
+ unique_opens: { type: 'number', description: 'Unique open count' },
+ unique_replies: { type: 'number', description: 'Unique reply count' },
+ interested: { type: 'string', description: 'Interested status' },
+ raw_message_id: { type: 'string', description: 'Raw email message ID' },
+ },
+ campaignEvent: {
+ id: { type: 'number', description: 'Campaign event ID' },
+ event_type: { type: 'string', description: 'Campaign event type' },
+ created_at_local: { type: 'string', description: 'Campaign event local creation timestamp' },
+ local_timezone: { type: 'string', description: 'Campaign event local timezone' },
+ created_at: { type: 'string', description: 'Campaign event creation timestamp' },
+ },
+ lead: {
+ id: { type: 'number', description: 'Lead ID' },
+ email: { type: 'string', description: 'Lead email address' },
+ first_name: { type: 'string', description: 'Lead first name' },
+ last_name: { type: 'string', description: 'Lead last name' },
+ status: { type: 'string', description: 'Lead status' },
+ title: { type: 'string', description: 'Lead title' },
+ company: { type: 'string', description: 'Lead company' },
+ custom_variables: { type: 'json', description: 'Lead custom variables' },
+ emails_sent: { type: 'number', description: 'Lead emails sent count' },
+ opens: { type: 'number', description: 'Lead open count' },
+ unique_opens: { type: 'number', description: 'Lead unique open count' },
+ replies: { type: 'number', description: 'Lead reply count' },
+ unique_replies: { type: 'number', description: 'Lead unique reply count' },
+ bounces: { type: 'number', description: 'Lead bounce count' },
+ },
+ campaign: {
+ id: { type: 'number', description: 'Campaign ID' },
+ name: { type: 'string', description: 'Campaign name' },
+ },
+ senderEmail: {
+ id: { type: 'number', description: 'Sender email ID' },
+ name: { type: 'string', description: 'Sender email name' },
+ email: { type: 'string', description: 'Sender email address' },
+ status: { type: 'string', description: 'Sender email status' },
+ account_type: { type: 'string', description: 'Sender email connection type' },
+ daily_limit: { type: 'number', description: 'Sender email daily limit' },
+ emails_sent: { type: 'number', description: 'Sender email sent count' },
+ replied: { type: 'number', description: 'Sender email replied count' },
+ opened: { type: 'number', description: 'Sender email opened count' },
+ unsubscribed: { type: 'number', description: 'Sender email unsubscribed count' },
+ bounced: { type: 'number', description: 'Sender email bounced count' },
+ unique_replies: { type: 'number', description: 'Sender email unique reply count' },
+ unique_opens: { type: 'number', description: 'Sender email unique open count' },
+ total_leads_contacted: { type: 'number', description: 'Sender email total leads contacted' },
+ interested: { type: 'number', description: 'Sender email interested count' },
+ created_at: { type: 'string', description: 'Sender email creation timestamp' },
+ updated_at: { type: 'string', description: 'Sender email update timestamp' },
+ },
+ }
+}
+
+export function buildEmailBisonLeadFirstContactedOutputs(): Record {
+ return buildEmailBisonEmailSentOutputs()
+}
+
+export function buildEmailBisonLeadUnsubscribedOutputs(): Record {
+ return buildEmailBisonEmailSentOutputs()
+}
+
+export function buildEmailBisonEmailOpenedOutputs(): Record {
+ return buildEmailBisonEmailSentOutputs()
+}
+
+export function buildEmailBisonLeadRepliedOutputs(): Record {
+ return {
+ ...buildEmailBisonOutputs(),
+ reply: {
+ id: { type: 'number', description: 'Reply ID' },
+ uuid: { type: 'string', description: 'Reply UUID' },
+ email_subject: { type: 'string', description: 'Reply email subject' },
+ interested: { type: 'boolean', description: 'Whether the reply is marked interested' },
+ automated_reply: { type: 'boolean', description: 'Whether the reply is automated' },
+ html_body: { type: 'string', description: 'Reply HTML body' },
+ text_body: { type: 'string', description: 'Reply plain text body' },
+ raw_body: { type: 'string', description: 'Raw MIME reply body' },
+ headers: { type: 'string', description: 'Encoded raw email headers' },
+ date_received: { type: 'string', description: 'Reply received timestamp' },
+ from_name: { type: 'string', description: 'Reply sender name' },
+ from_email_address: { type: 'string', description: 'Reply sender email address' },
+ primary_to_email_address: { type: 'string', description: 'Primary recipient email address' },
+ to: { type: 'json', description: 'Reply To recipients' },
+ cc: { type: 'json', description: 'Reply CC recipients' },
+ bcc: { type: 'json', description: 'Reply BCC recipients' },
+ parent_id: { type: 'number', description: 'Parent reply ID' },
+ reply_type: { type: 'string', description: 'Reply type' },
+ folder: { type: 'string', description: 'Reply folder' },
+ raw_message_id: { type: 'string', description: 'Raw email message ID' },
+ created_at: { type: 'string', description: 'Reply creation timestamp' },
+ updated_at: { type: 'string', description: 'Reply update timestamp' },
+ attachments: { type: 'json', description: 'Reply attachments' },
+ },
+ campaignEvent: {
+ id: { type: 'number', description: 'Campaign event ID' },
+ event_type: { type: 'string', description: 'Campaign event type' },
+ created_at_local: { type: 'string', description: 'Campaign event local creation timestamp' },
+ local_timezone: { type: 'string', description: 'Campaign event local timezone' },
+ created_at: { type: 'string', description: 'Campaign event creation timestamp' },
+ },
+ lead: {
+ id: { type: 'number', description: 'Lead ID' },
+ email: { type: 'string', description: 'Lead email address' },
+ first_name: { type: 'string', description: 'Lead first name' },
+ last_name: { type: 'string', description: 'Lead last name' },
+ status: { type: 'string', description: 'Lead status' },
+ title: { type: 'string', description: 'Lead title' },
+ company: { type: 'string', description: 'Lead company' },
+ custom_variables: { type: 'json', description: 'Lead custom variables' },
+ emails_sent: { type: 'number', description: 'Lead emails sent count' },
+ opens: { type: 'number', description: 'Lead open count' },
+ unique_opens: { type: 'number', description: 'Lead unique open count' },
+ replies: { type: 'number', description: 'Lead reply count' },
+ unique_replies: { type: 'number', description: 'Lead unique reply count' },
+ bounces: { type: 'number', description: 'Lead bounce count' },
+ },
+ campaign: {
+ id: { type: 'number', description: 'Campaign ID' },
+ name: { type: 'string', description: 'Campaign name' },
+ },
+ scheduledEmail: {
+ id: { type: 'number', description: 'Scheduled email ID' },
+ sequence_step_id: { type: 'number', description: 'Sequence step ID' },
+ sequence_step_order: { type: 'number', description: 'Sequence step order' },
+ sequence_step_variant: { type: 'number', description: 'Sequence step variant' },
+ status: { type: 'string', description: 'Scheduled email status' },
+ scheduled_date_est: { type: 'string', description: 'Scheduled date in EST' },
+ scheduled_date_local: { type: 'string', description: 'Scheduled date in local timezone' },
+ local_timezone: { type: 'string', description: 'Scheduled email local timezone' },
+ sent_at: { type: 'string', description: 'Email sent timestamp' },
+ opens: { type: 'number', description: 'Open count' },
+ replies: { type: 'number', description: 'Reply count' },
+ unique_opens: { type: 'number', description: 'Unique open count' },
+ unique_replies: { type: 'number', description: 'Unique reply count' },
+ interested: { type: 'string', description: 'Interested status' },
+ raw_message_id: { type: 'string', description: 'Raw email message ID' },
+ },
+ senderEmail: {
+ id: { type: 'number', description: 'Sender email ID' },
+ name: { type: 'string', description: 'Sender email name' },
+ email: { type: 'string', description: 'Sender email address' },
+ status: { type: 'string', description: 'Sender email status' },
+ account_type: { type: 'string', description: 'Sender email connection type' },
+ daily_limit: { type: 'number', description: 'Sender email daily limit' },
+ emails_sent: { type: 'number', description: 'Sender email sent count' },
+ replied: { type: 'number', description: 'Sender email replied count' },
+ opened: { type: 'number', description: 'Sender email opened count' },
+ unsubscribed: { type: 'number', description: 'Sender email unsubscribed count' },
+ bounced: { type: 'number', description: 'Sender email bounced count' },
+ unique_replies: { type: 'number', description: 'Sender email unique reply count' },
+ unique_opens: { type: 'number', description: 'Sender email unique open count' },
+ total_leads_contacted: { type: 'number', description: 'Sender email total leads contacted' },
+ interested: { type: 'number', description: 'Sender email interested count' },
+ created_at: { type: 'string', description: 'Sender email creation timestamp' },
+ updated_at: { type: 'string', description: 'Sender email update timestamp' },
+ },
+ }
+}
+
+export function buildEmailBisonLeadInterestedOutputs(): Record {
+ return buildEmailBisonLeadRepliedOutputs()
+}
+
+export function buildEmailBisonEmailBouncedOutputs(): Record {
+ return buildEmailBisonLeadRepliedOutputs()
+}
+
+export function buildEmailBisonManualEmailSentOutputs(): Record {
+ return {
+ ...buildEmailBisonOutputs(),
+ reply: {
+ id: { type: 'number', description: 'Reply ID' },
+ email_subject: { type: 'string', description: 'Reply email subject' },
+ interested: { type: 'boolean', description: 'Whether the reply is marked interested' },
+ automated_reply: { type: 'boolean', description: 'Whether the reply is automated' },
+ html_body: { type: 'string', description: 'Reply HTML body' },
+ text_body: { type: 'string', description: 'Reply plain text body' },
+ raw_body: { type: 'string', description: 'Raw MIME reply body' },
+ headers: { type: 'string', description: 'Encoded raw email headers' },
+ date_received: { type: 'string', description: 'Reply received timestamp' },
+ reply_type: { type: 'string', description: 'Reply type' },
+ from_name: { type: 'string', description: 'Reply sender name' },
+ from_email_address: { type: 'string', description: 'Reply sender email address' },
+ primary_to_email_address: { type: 'string', description: 'Primary recipient email address' },
+ to: { type: 'json', description: 'Reply To recipients' },
+ cc: { type: 'json', description: 'Reply CC recipients' },
+ bcc: { type: 'json', description: 'Reply BCC recipients' },
+ parent_id: { type: 'json', description: 'Parent reply ID' },
+ folder: { type: 'string', description: 'Reply folder' },
+ raw_message_id: { type: 'string', description: 'Raw email message ID' },
+ created_at: { type: 'string', description: 'Reply creation timestamp' },
+ updated_at: { type: 'string', description: 'Reply update timestamp' },
+ attachments: { type: 'json', description: 'Reply attachments' },
+ },
+ lead: {
+ id: { type: 'number', description: 'Lead ID' },
+ email: { type: 'string', description: 'Lead email address' },
+ first_name: { type: 'string', description: 'Lead first name' },
+ last_name: { type: 'string', description: 'Lead last name' },
+ status: { type: 'string', description: 'Lead status' },
+ title: { type: 'string', description: 'Lead title' },
+ company: { type: 'string', description: 'Lead company' },
+ custom_variables: { type: 'json', description: 'Lead custom variables' },
+ emails_sent: { type: 'number', description: 'Lead emails sent count' },
+ opens: { type: 'number', description: 'Lead open count' },
+ unique_opens: { type: 'number', description: 'Lead unique open count' },
+ replies: { type: 'number', description: 'Lead reply count' },
+ unique_replies: { type: 'number', description: 'Lead unique reply count' },
+ bounces: { type: 'number', description: 'Lead bounce count' },
+ },
+ campaign: {
+ id: { type: 'number', description: 'Campaign ID' },
+ name: { type: 'string', description: 'Campaign name' },
+ },
+ scheduledEmail: {
+ id: { type: 'number', description: 'Scheduled email ID' },
+ sequence_step_id: { type: 'number', description: 'Sequence step ID' },
+ sequence_step_order: { type: 'number', description: 'Sequence step order' },
+ sequence_step_variant: { type: 'number', description: 'Sequence step variant' },
+ status: { type: 'string', description: 'Scheduled email status' },
+ scheduled_date_est: { type: 'string', description: 'Scheduled date in EST' },
+ scheduled_date_local: { type: 'string', description: 'Scheduled date in local timezone' },
+ local_timezone: { type: 'string', description: 'Scheduled email local timezone' },
+ sent_at: { type: 'string', description: 'Email sent timestamp' },
+ opens: { type: 'number', description: 'Open count' },
+ replies: { type: 'number', description: 'Reply count' },
+ unique_opens: { type: 'number', description: 'Unique open count' },
+ unique_replies: { type: 'number', description: 'Unique reply count' },
+ interested: { type: 'json', description: 'Interested status' },
+ raw_message_id: { type: 'string', description: 'Raw email message ID' },
+ },
+ senderEmail: {
+ id: { type: 'number', description: 'Sender email ID' },
+ name: { type: 'string', description: 'Sender email name' },
+ email: { type: 'string', description: 'Sender email address' },
+ status: { type: 'string', description: 'Sender email status' },
+ account_type: { type: 'string', description: 'Sender email connection type' },
+ daily_limit: { type: 'number', description: 'Sender email daily limit' },
+ emails_sent: { type: 'number', description: 'Sender email sent count' },
+ replied: { type: 'number', description: 'Sender email replied count' },
+ opened: { type: 'number', description: 'Sender email opened count' },
+ unsubscribed: { type: 'number', description: 'Sender email unsubscribed count' },
+ bounced: { type: 'number', description: 'Sender email bounced count' },
+ unique_replies: { type: 'number', description: 'Sender email unique reply count' },
+ unique_opens: { type: 'number', description: 'Sender email unique open count' },
+ total_leads_contacted: { type: 'number', description: 'Sender email total leads contacted' },
+ interested: { type: 'number', description: 'Sender email interested count' },
+ created_at: { type: 'string', description: 'Sender email creation timestamp' },
+ updated_at: { type: 'string', description: 'Sender email update timestamp' },
+ },
+ }
+}
+
+export function buildEmailBisonTagAttachedOutputs(): Record {
+ return {
+ ...buildEmailBisonOutputs(),
+ tagId: { type: 'number', description: 'Email Bison tag ID' },
+ tagName: { type: 'string', description: 'Email Bison tag name' },
+ taggableId: { type: 'number', description: 'ID of the tagged resource' },
+ taggableType: { type: 'string', description: 'Type of the tagged resource' },
+ }
+}
+
+export function buildEmailBisonTagRemovedOutputs(): Record {
+ return buildEmailBisonTagAttachedOutputs()
+}
+
+export function buildEmailBisonEmailAccountAddedOutputs(): Record {
+ return {
+ ...buildEmailBisonOutputs(),
+ senderEmail: {
+ id: { type: 'number', description: 'Sender email ID' },
+ name: { type: 'string', description: 'Sender email name' },
+ email: { type: 'string', description: 'Sender email address' },
+ status: { type: 'string', description: 'Sender email status' },
+ account_type: { type: 'string', description: 'Sender email connection type' },
+ daily_limit: { type: 'number', description: 'Sender email daily limit' },
+ emails_sent: { type: 'number', description: 'Sender email sent count' },
+ replied: { type: 'number', description: 'Sender email replied count' },
+ opened: { type: 'number', description: 'Sender email opened count' },
+ unsubscribed: { type: 'number', description: 'Sender email unsubscribed count' },
+ bounced: { type: 'number', description: 'Sender email bounced count' },
+ unique_replies: { type: 'number', description: 'Sender email unique reply count' },
+ unique_opens: { type: 'number', description: 'Sender email unique open count' },
+ total_leads_contacted: { type: 'number', description: 'Sender email total leads contacted' },
+ interested: { type: 'number', description: 'Sender email interested count' },
+ created_at: { type: 'string', description: 'Sender email creation timestamp' },
+ updated_at: { type: 'string', description: 'Sender email update timestamp' },
+ },
+ }
+}
+
+export function buildEmailBisonEmailAccountRemovedOutputs(): Record {
+ return buildEmailBisonEmailAccountAddedOutputs()
+}
+
+export function buildEmailBisonEmailAccountDisconnectedOutputs(): Record {
+ return buildEmailBisonEmailAccountAddedOutputs()
+}
+
+export function buildEmailBisonEmailAccountReconnectedOutputs(): Record {
+ return buildEmailBisonEmailAccountAddedOutputs()
+}
+
+export function buildEmailBisonWarmupDisabledReceivingBouncesOutputs(): Record<
+ string,
+ TriggerOutput
+> {
+ return buildEmailBisonEmailAccountAddedOutputs()
+}
+
+export function buildEmailBisonWarmupDisabledCausingBouncesOutputs(): Record<
+ string,
+ TriggerOutput
+> {
+ return buildEmailBisonEmailAccountAddedOutputs()
+}
+
+export function buildEmailBisonUntrackedReplyReceivedOutputs(): Record {
+ return {
+ ...buildEmailBisonOutputs(),
+ reply: {
+ id: { type: 'number', description: 'Reply ID' },
+ uuid: { type: 'string', description: 'Reply UUID' },
+ email_subject: { type: 'string', description: 'Reply email subject' },
+ interested: { type: 'boolean', description: 'Whether the reply is marked interested' },
+ automated_reply: { type: 'boolean', description: 'Whether the reply is automated' },
+ html_body: { type: 'string', description: 'Reply HTML body' },
+ text_body: { type: 'string', description: 'Reply plain text body' },
+ raw_body: { type: 'string', description: 'Raw MIME reply body' },
+ headers: { type: 'string', description: 'Encoded raw email headers' },
+ date_received: { type: 'string', description: 'Reply received timestamp' },
+ from_name: { type: 'string', description: 'Reply sender name' },
+ from_email_address: { type: 'string', description: 'Reply sender email address' },
+ primary_to_email_address: { type: 'string', description: 'Primary recipient email address' },
+ to: { type: 'json', description: 'Reply To recipients' },
+ cc: { type: 'json', description: 'Reply CC recipients' },
+ bcc: { type: 'json', description: 'Reply BCC recipients' },
+ parent_id: { type: 'number', description: 'Parent reply ID' },
+ reply_type: { type: 'string', description: 'Reply type' },
+ folder: { type: 'string', description: 'Reply folder' },
+ raw_message_id: { type: 'string', description: 'Raw email message ID' },
+ created_at: { type: 'string', description: 'Reply creation timestamp' },
+ updated_at: { type: 'string', description: 'Reply update timestamp' },
+ attachments: { type: 'json', description: 'Reply attachments' },
+ },
+ senderEmail: {
+ id: { type: 'number', description: 'Sender email ID' },
+ name: { type: 'string', description: 'Sender email name' },
+ email: { type: 'string', description: 'Sender email address' },
+ status: { type: 'string', description: 'Sender email status' },
+ account_type: { type: 'string', description: 'Sender email connection type' },
+ daily_limit: { type: 'number', description: 'Sender email daily limit' },
+ emails_sent: { type: 'number', description: 'Sender email sent count' },
+ replied: { type: 'number', description: 'Sender email replied count' },
+ opened: { type: 'number', description: 'Sender email opened count' },
+ unsubscribed: { type: 'number', description: 'Sender email unsubscribed count' },
+ bounced: { type: 'number', description: 'Sender email bounced count' },
+ unique_replies: { type: 'number', description: 'Sender email unique reply count' },
+ unique_opens: { type: 'number', description: 'Sender email unique open count' },
+ total_leads_contacted: { type: 'number', description: 'Sender email total leads contacted' },
+ interested: { type: 'number', description: 'Sender email interested count' },
+ created_at: { type: 'string', description: 'Sender email creation timestamp' },
+ updated_at: { type: 'string', description: 'Sender email update timestamp' },
+ },
+ }
+}
+
+export function getEmailBisonEventTypeForTrigger(triggerId: string): string | undefined {
+ return EMAILBISON_TRIGGER_TO_EVENT_TYPE[
+ triggerId as keyof typeof EMAILBISON_TRIGGER_TO_EVENT_TYPE
+ ]
+}
+
+export function isEmailBisonEventMatch(triggerId: string, body: Record): boolean {
+ const expectedEventType = getEmailBisonEventTypeForTrigger(triggerId)
+ if (!expectedEventType) return false
+
+ const event = body.event
+ if (!isRecord(event)) return false
+
+ const actualEventType = event.type
+ return typeof actualEventType === 'string' && actualEventType.toLowerCase() === expectedEventType
+}
+
+function isRecord(value: unknown): value is Record {
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
+}
diff --git a/apps/sim/triggers/emailbison/warmup_disabled_causing_bounces.ts b/apps/sim/triggers/emailbison/warmup_disabled_causing_bounces.ts
new file mode 100644
index 00000000000..341138bb833
--- /dev/null
+++ b/apps/sim/triggers/emailbison/warmup_disabled_causing_bounces.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonWarmupDisabledCausingBouncesOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonWarmupDisabledCausingBouncesTrigger: TriggerConfig = {
+ id: 'emailbison_warmup_disabled_causing_bounces',
+ name: 'Email Bison Warmup Disabled Causing Bounces',
+ provider: 'emailbison',
+ description: 'Trigger when warmup is disabled for a sender email causing too many bounces',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_warmup_disabled_causing_bounces',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Warmup Disabled Causing Bounces'),
+ extraFields: buildEmailBisonExtraFields('emailbison_warmup_disabled_causing_bounces'),
+ }),
+ outputs: buildEmailBisonWarmupDisabledCausingBouncesOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/emailbison/warmup_disabled_receiving_bounces.ts b/apps/sim/triggers/emailbison/warmup_disabled_receiving_bounces.ts
new file mode 100644
index 00000000000..6ecfcf2b4e1
--- /dev/null
+++ b/apps/sim/triggers/emailbison/warmup_disabled_receiving_bounces.ts
@@ -0,0 +1,26 @@
+import { EmailBisonIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildEmailBisonExtraFields,
+ buildEmailBisonWarmupDisabledReceivingBouncesOutputs,
+ emailBisonSetupInstructions,
+ emailBisonTriggerOptions,
+} from '@/triggers/emailbison/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+export const emailBisonWarmupDisabledReceivingBouncesTrigger: TriggerConfig = {
+ id: 'emailbison_warmup_disabled_receiving_bounces',
+ name: 'Email Bison Warmup Disabled Receiving Bounces',
+ provider: 'emailbison',
+ description: 'Trigger when warmup is disabled for a sender email receiving too many bounces',
+ version: '1.0.0',
+ icon: EmailBisonIcon,
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'emailbison_warmup_disabled_receiving_bounces',
+ triggerOptions: emailBisonTriggerOptions,
+ setupInstructions: emailBisonSetupInstructions('Warmup Disabled Receiving Bounces'),
+ extraFields: buildEmailBisonExtraFields('emailbison_warmup_disabled_receiving_bounces'),
+ }),
+ outputs: buildEmailBisonWarmupDisabledReceivingBouncesOutputs(),
+ webhook: { method: 'POST', headers: { 'Content-Type': 'application/json' } },
+}
diff --git a/apps/sim/triggers/registry.ts b/apps/sim/triggers/registry.ts
index b32941173ab..b1d747f529f 100644
--- a/apps/sim/triggers/registry.ts
+++ b/apps/sim/triggers/registry.ts
@@ -78,6 +78,25 @@ import {
confluenceUserCreatedTrigger,
confluenceWebhookTrigger,
} from '@/triggers/confluence'
+import {
+ emailBisonEmailAccountAddedTrigger,
+ emailBisonEmailAccountDisconnectedTrigger,
+ emailBisonEmailAccountReconnectedTrigger,
+ emailBisonEmailAccountRemovedTrigger,
+ emailBisonEmailBouncedTrigger,
+ emailBisonEmailOpenedTrigger,
+ emailBisonEmailSentTrigger,
+ emailBisonLeadFirstContactedTrigger,
+ emailBisonLeadInterestedTrigger,
+ emailBisonLeadRepliedTrigger,
+ emailBisonLeadUnsubscribedTrigger,
+ emailBisonManualEmailSentTrigger,
+ emailBisonTagAttachedTrigger,
+ emailBisonTagRemovedTrigger,
+ emailBisonUntrackedReplyReceivedTrigger,
+ emailBisonWarmupDisabledCausingBouncesTrigger,
+ emailBisonWarmupDisabledReceivingBouncesTrigger,
+} from '@/triggers/emailbison'
import { fathomNewMeetingTrigger, fathomWebhookTrigger } from '@/triggers/fathom'
import { firefliesTranscriptionCompleteTrigger } from '@/triggers/fireflies'
import { genericWebhookTrigger } from '@/triggers/generic'
@@ -379,6 +398,23 @@ export const TRIGGER_REGISTRY: TriggerRegistry = {
confluence_space_removed: confluenceSpaceRemovedTrigger,
confluence_page_permissions_updated: confluencePagePermissionsUpdatedTrigger,
confluence_user_created: confluenceUserCreatedTrigger,
+ emailbison_email_sent: emailBisonEmailSentTrigger,
+ emailbison_lead_first_contacted: emailBisonLeadFirstContactedTrigger,
+ emailbison_lead_replied: emailBisonLeadRepliedTrigger,
+ emailbison_lead_interested: emailBisonLeadInterestedTrigger,
+ emailbison_lead_unsubscribed: emailBisonLeadUnsubscribedTrigger,
+ emailbison_untracked_reply_received: emailBisonUntrackedReplyReceivedTrigger,
+ emailbison_email_opened: emailBisonEmailOpenedTrigger,
+ emailbison_email_bounced: emailBisonEmailBouncedTrigger,
+ emailbison_email_account_added: emailBisonEmailAccountAddedTrigger,
+ emailbison_email_account_removed: emailBisonEmailAccountRemovedTrigger,
+ emailbison_email_account_disconnected: emailBisonEmailAccountDisconnectedTrigger,
+ emailbison_email_account_reconnected: emailBisonEmailAccountReconnectedTrigger,
+ emailbison_manual_email_sent: emailBisonManualEmailSentTrigger,
+ emailbison_tag_attached: emailBisonTagAttachedTrigger,
+ emailbison_tag_removed: emailBisonTagRemovedTrigger,
+ emailbison_warmup_disabled_receiving_bounces: emailBisonWarmupDisabledReceivingBouncesTrigger,
+ emailbison_warmup_disabled_causing_bounces: emailBisonWarmupDisabledCausingBouncesTrigger,
generic_webhook: genericWebhookTrigger,
greenhouse_candidate_hired: greenhouseCandidateHiredTrigger,
greenhouse_new_application: greenhouseNewApplicationTrigger,