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
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:
@@ -0,0 +1,38 @@
|
||||
import { LemlistIcon } from '@/components/icons'
|
||||
import { buildTriggerSubBlocks } from '@/triggers'
|
||||
import {
|
||||
buildEmailBouncedOutputs,
|
||||
buildLemlistExtraFields,
|
||||
lemlistSetupInstructions,
|
||||
lemlistTriggerOptions,
|
||||
} from '@/triggers/lemlist/utils'
|
||||
import type { TriggerConfig } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Lemlist Email Bounced Trigger
|
||||
* Triggers when an email bounces in a Lemlist campaign
|
||||
*/
|
||||
export const lemlistEmailBouncedTrigger: TriggerConfig = {
|
||||
id: 'lemlist_email_bounced',
|
||||
name: 'Lemlist Email Bounced',
|
||||
provider: 'lemlist',
|
||||
description: 'Trigger workflow when an email bounces',
|
||||
version: '1.0.0',
|
||||
icon: LemlistIcon,
|
||||
|
||||
subBlocks: buildTriggerSubBlocks({
|
||||
triggerId: 'lemlist_email_bounced',
|
||||
triggerOptions: lemlistTriggerOptions,
|
||||
setupInstructions: lemlistSetupInstructions('emailsBounced'),
|
||||
extraFields: buildLemlistExtraFields('lemlist_email_bounced'),
|
||||
}),
|
||||
|
||||
outputs: buildEmailBouncedOutputs(),
|
||||
|
||||
webhook: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { LemlistIcon } from '@/components/icons'
|
||||
import { buildTriggerSubBlocks } from '@/triggers'
|
||||
import {
|
||||
buildEmailClickedOutputs,
|
||||
buildLemlistExtraFields,
|
||||
lemlistSetupInstructions,
|
||||
lemlistTriggerOptions,
|
||||
} from '@/triggers/lemlist/utils'
|
||||
import type { TriggerConfig } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Lemlist Email Clicked Trigger
|
||||
* Triggers when a lead clicks a link in an email
|
||||
*/
|
||||
export const lemlistEmailClickedTrigger: TriggerConfig = {
|
||||
id: 'lemlist_email_clicked',
|
||||
name: 'Lemlist Email Clicked',
|
||||
provider: 'lemlist',
|
||||
description: 'Trigger workflow when a lead clicks a link in an email',
|
||||
version: '1.0.0',
|
||||
icon: LemlistIcon,
|
||||
|
||||
subBlocks: buildTriggerSubBlocks({
|
||||
triggerId: 'lemlist_email_clicked',
|
||||
triggerOptions: lemlistTriggerOptions,
|
||||
setupInstructions: lemlistSetupInstructions('emailsClicked'),
|
||||
extraFields: buildLemlistExtraFields('lemlist_email_clicked'),
|
||||
}),
|
||||
|
||||
outputs: buildEmailClickedOutputs(),
|
||||
|
||||
webhook: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { LemlistIcon } from '@/components/icons'
|
||||
import { buildTriggerSubBlocks } from '@/triggers'
|
||||
import {
|
||||
buildEmailOpenedOutputs,
|
||||
buildLemlistExtraFields,
|
||||
lemlistSetupInstructions,
|
||||
lemlistTriggerOptions,
|
||||
} from '@/triggers/lemlist/utils'
|
||||
import type { TriggerConfig } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Lemlist Email Opened Trigger
|
||||
* Triggers when a lead opens an email in a Lemlist campaign
|
||||
*/
|
||||
export const lemlistEmailOpenedTrigger: TriggerConfig = {
|
||||
id: 'lemlist_email_opened',
|
||||
name: 'Lemlist Email Opened',
|
||||
provider: 'lemlist',
|
||||
description: 'Trigger workflow when a lead opens an email',
|
||||
version: '1.0.0',
|
||||
icon: LemlistIcon,
|
||||
|
||||
subBlocks: buildTriggerSubBlocks({
|
||||
triggerId: 'lemlist_email_opened',
|
||||
triggerOptions: lemlistTriggerOptions,
|
||||
setupInstructions: lemlistSetupInstructions('emailsOpened'),
|
||||
extraFields: buildLemlistExtraFields('lemlist_email_opened'),
|
||||
}),
|
||||
|
||||
outputs: buildEmailOpenedOutputs(),
|
||||
|
||||
webhook: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { LemlistIcon } from '@/components/icons'
|
||||
import { buildTriggerSubBlocks } from '@/triggers'
|
||||
import {
|
||||
buildEmailRepliedOutputs,
|
||||
buildLemlistExtraFields,
|
||||
lemlistSetupInstructions,
|
||||
lemlistTriggerOptions,
|
||||
} from '@/triggers/lemlist/utils'
|
||||
import type { TriggerConfig } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Lemlist Email Replied Trigger
|
||||
* Triggers when a lead replies to an email in a Lemlist campaign
|
||||
*
|
||||
* This is the PRIMARY trigger - it includes the dropdown for selecting trigger type.
|
||||
*/
|
||||
export const lemlistEmailRepliedTrigger: TriggerConfig = {
|
||||
id: 'lemlist_email_replied',
|
||||
name: 'Lemlist Email Replied',
|
||||
provider: 'lemlist',
|
||||
description: 'Trigger workflow when a lead replies to an email',
|
||||
version: '1.0.0',
|
||||
icon: LemlistIcon,
|
||||
|
||||
subBlocks: buildTriggerSubBlocks({
|
||||
triggerId: 'lemlist_email_replied',
|
||||
triggerOptions: lemlistTriggerOptions,
|
||||
includeDropdown: true,
|
||||
setupInstructions: lemlistSetupInstructions('emailsReplied'),
|
||||
extraFields: buildLemlistExtraFields('lemlist_email_replied'),
|
||||
}),
|
||||
|
||||
outputs: buildEmailRepliedOutputs(),
|
||||
|
||||
webhook: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { LemlistIcon } from '@/components/icons'
|
||||
import { buildTriggerSubBlocks } from '@/triggers'
|
||||
import {
|
||||
buildEmailSentOutputs,
|
||||
buildLemlistExtraFields,
|
||||
lemlistSetupInstructions,
|
||||
lemlistTriggerOptions,
|
||||
} from '@/triggers/lemlist/utils'
|
||||
import type { TriggerConfig } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Lemlist Email Sent Trigger
|
||||
* Triggers when an email is sent in a Lemlist campaign
|
||||
*/
|
||||
export const lemlistEmailSentTrigger: TriggerConfig = {
|
||||
id: 'lemlist_email_sent',
|
||||
name: 'Lemlist Email Sent',
|
||||
provider: 'lemlist',
|
||||
description: 'Trigger workflow when an email is sent',
|
||||
version: '1.0.0',
|
||||
icon: LemlistIcon,
|
||||
|
||||
subBlocks: buildTriggerSubBlocks({
|
||||
triggerId: 'lemlist_email_sent',
|
||||
triggerOptions: lemlistTriggerOptions,
|
||||
setupInstructions: lemlistSetupInstructions('emailsSent'),
|
||||
extraFields: buildLemlistExtraFields('lemlist_email_sent'),
|
||||
}),
|
||||
|
||||
outputs: buildEmailSentOutputs(),
|
||||
|
||||
webhook: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Lemlist Triggers
|
||||
* Export all Lemlist webhook triggers
|
||||
*/
|
||||
|
||||
export { lemlistEmailBouncedTrigger } from './email_bounced'
|
||||
export { lemlistEmailClickedTrigger } from './email_clicked'
|
||||
export { lemlistEmailOpenedTrigger } from './email_opened'
|
||||
export { lemlistEmailRepliedTrigger } from './email_replied'
|
||||
export { lemlistEmailSentTrigger } from './email_sent'
|
||||
export { lemlistInterestedTrigger } from './interested'
|
||||
export { lemlistLinkedInRepliedTrigger } from './linkedin_replied'
|
||||
export { lemlistNotInterestedTrigger } from './not_interested'
|
||||
export { lemlistWebhookTrigger } from './webhook'
|
||||
@@ -0,0 +1,38 @@
|
||||
import { LemlistIcon } from '@/components/icons'
|
||||
import { buildTriggerSubBlocks } from '@/triggers'
|
||||
import {
|
||||
buildInterestOutputs,
|
||||
buildLemlistExtraFields,
|
||||
lemlistSetupInstructions,
|
||||
lemlistTriggerOptions,
|
||||
} from '@/triggers/lemlist/utils'
|
||||
import type { TriggerConfig } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Lemlist Interested Trigger
|
||||
* Triggers when a lead is marked as interested in a Lemlist campaign
|
||||
*/
|
||||
export const lemlistInterestedTrigger: TriggerConfig = {
|
||||
id: 'lemlist_interested',
|
||||
name: 'Lemlist Lead Interested',
|
||||
provider: 'lemlist',
|
||||
description: 'Trigger workflow when a lead is marked as interested',
|
||||
version: '1.0.0',
|
||||
icon: LemlistIcon,
|
||||
|
||||
subBlocks: buildTriggerSubBlocks({
|
||||
triggerId: 'lemlist_interested',
|
||||
triggerOptions: lemlistTriggerOptions,
|
||||
setupInstructions: lemlistSetupInstructions('interested'),
|
||||
extraFields: buildLemlistExtraFields('lemlist_interested'),
|
||||
}),
|
||||
|
||||
outputs: buildInterestOutputs(),
|
||||
|
||||
webhook: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { LemlistIcon } from '@/components/icons'
|
||||
import { buildTriggerSubBlocks } from '@/triggers'
|
||||
import {
|
||||
buildLemlistExtraFields,
|
||||
buildLinkedInRepliedOutputs,
|
||||
lemlistSetupInstructions,
|
||||
lemlistTriggerOptions,
|
||||
} from '@/triggers/lemlist/utils'
|
||||
import type { TriggerConfig } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Lemlist LinkedIn Replied Trigger
|
||||
* Triggers when a lead replies to a LinkedIn message in a Lemlist campaign
|
||||
*/
|
||||
export const lemlistLinkedInRepliedTrigger: TriggerConfig = {
|
||||
id: 'lemlist_linkedin_replied',
|
||||
name: 'Lemlist LinkedIn Replied',
|
||||
provider: 'lemlist',
|
||||
description: 'Trigger workflow when a lead replies to a LinkedIn message',
|
||||
version: '1.0.0',
|
||||
icon: LemlistIcon,
|
||||
|
||||
subBlocks: buildTriggerSubBlocks({
|
||||
triggerId: 'lemlist_linkedin_replied',
|
||||
triggerOptions: lemlistTriggerOptions,
|
||||
setupInstructions: lemlistSetupInstructions('linkedinReplied'),
|
||||
extraFields: buildLemlistExtraFields('lemlist_linkedin_replied'),
|
||||
}),
|
||||
|
||||
outputs: buildLinkedInRepliedOutputs(),
|
||||
|
||||
webhook: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { LemlistIcon } from '@/components/icons'
|
||||
import { buildTriggerSubBlocks } from '@/triggers'
|
||||
import {
|
||||
buildInterestOutputs,
|
||||
buildLemlistExtraFields,
|
||||
lemlistSetupInstructions,
|
||||
lemlistTriggerOptions,
|
||||
} from '@/triggers/lemlist/utils'
|
||||
import type { TriggerConfig } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Lemlist Not Interested Trigger
|
||||
* Triggers when a lead is marked as not interested in a Lemlist campaign
|
||||
*/
|
||||
export const lemlistNotInterestedTrigger: TriggerConfig = {
|
||||
id: 'lemlist_not_interested',
|
||||
name: 'Lemlist Lead Not Interested',
|
||||
provider: 'lemlist',
|
||||
description: 'Trigger workflow when a lead is marked as not interested',
|
||||
version: '1.0.0',
|
||||
icon: LemlistIcon,
|
||||
|
||||
subBlocks: buildTriggerSubBlocks({
|
||||
triggerId: 'lemlist_not_interested',
|
||||
triggerOptions: lemlistTriggerOptions,
|
||||
setupInstructions: lemlistSetupInstructions('notInterested'),
|
||||
extraFields: buildLemlistExtraFields('lemlist_not_interested'),
|
||||
}),
|
||||
|
||||
outputs: buildInterestOutputs(),
|
||||
|
||||
webhook: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
import type { TriggerOutput } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Shared trigger dropdown options for all Lemlist triggers
|
||||
*/
|
||||
export const lemlistTriggerOptions = [
|
||||
{ label: 'Email Replied', id: 'lemlist_email_replied' },
|
||||
{ label: 'LinkedIn Replied', id: 'lemlist_linkedin_replied' },
|
||||
{ label: 'Lead Interested', id: 'lemlist_interested' },
|
||||
{ label: 'Lead Not Interested', id: 'lemlist_not_interested' },
|
||||
{ label: 'Email Opened', id: 'lemlist_email_opened' },
|
||||
{ label: 'Email Clicked', id: 'lemlist_email_clicked' },
|
||||
{ label: 'Email Bounced', id: 'lemlist_email_bounced' },
|
||||
{ label: 'Email Sent', id: 'lemlist_email_sent' },
|
||||
{ label: 'Generic Webhook (All Events)', id: 'lemlist_webhook' },
|
||||
]
|
||||
|
||||
/**
|
||||
* Generates setup instructions for Lemlist webhooks
|
||||
* The webhook is automatically created in Lemlist when you save
|
||||
*/
|
||||
export function lemlistSetupInstructions(eventType: string): string {
|
||||
const instructions = [
|
||||
'Enter your Lemlist API Key above.',
|
||||
'You can find your API key in Lemlist at <strong>Settings > Integrations</strong>. See the <a href="https://help.lemlist.com/en/articles/4452694-find-and-use-the-lemlist-api" target="_blank" rel="noopener noreferrer">Lemlist API documentation</a> for details.',
|
||||
'The webhook will be automatically deleted when you remove this trigger.',
|
||||
]
|
||||
|
||||
return instructions
|
||||
.map(
|
||||
(instruction, index) =>
|
||||
`<div class="mb-3"><strong>${index + 1}.</strong> ${instruction}</div>`
|
||||
)
|
||||
.join('')
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to build Lemlist-specific extra fields.
|
||||
* Includes API key (required) and optional campaign filter.
|
||||
* Use with the generic buildTriggerSubBlocks from @/triggers.
|
||||
*/
|
||||
export function buildLemlistExtraFields(triggerId: string) {
|
||||
return [
|
||||
{
|
||||
id: 'apiKey',
|
||||
title: 'API Key',
|
||||
type: 'short-input' as const,
|
||||
placeholder: 'Enter your Lemlist API key',
|
||||
description: 'Required to create the webhook in Lemlist.',
|
||||
password: true,
|
||||
required: true,
|
||||
mode: 'trigger' as const,
|
||||
condition: { field: 'selectedTriggerId', value: triggerId },
|
||||
},
|
||||
{
|
||||
id: 'campaignId',
|
||||
title: 'Campaign ID (Optional)',
|
||||
type: 'short-input' as const,
|
||||
placeholder: 'cam_xxxxx (leave empty for all campaigns)',
|
||||
description: 'Optionally scope the webhook to a specific campaign',
|
||||
mode: 'trigger' as const,
|
||||
condition: { field: 'selectedTriggerId', value: triggerId },
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Core fields present in ALL Lemlist webhook payloads
|
||||
* See: https://help.lemlist.com/en/articles/9423940-use-the-api-to-list-activity-types
|
||||
*/
|
||||
const coreOutputs = {
|
||||
_id: {
|
||||
type: 'string',
|
||||
description: 'Unique activity identifier',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
description: 'Activity type (e.g., emailsSent, emailsReplied)',
|
||||
},
|
||||
createdAt: {
|
||||
type: 'string',
|
||||
description: 'Activity creation timestamp (ISO 8601)',
|
||||
},
|
||||
teamId: {
|
||||
type: 'string',
|
||||
description: 'Lemlist team identifier',
|
||||
},
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Campaign-related fields - only present when activity is part of a campaign
|
||||
* These may be missing for first replies or activities outside campaign context
|
||||
*/
|
||||
const campaignOutputs = {
|
||||
leadId: {
|
||||
type: 'string',
|
||||
description: 'Lead identifier (only present for campaign activities)',
|
||||
},
|
||||
campaignId: {
|
||||
type: 'string',
|
||||
description: 'Campaign identifier (only present for campaign activities)',
|
||||
},
|
||||
campaignName: {
|
||||
type: 'string',
|
||||
description: 'Campaign name (only present for campaign activities)',
|
||||
},
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Lead fields present in webhook payloads
|
||||
*/
|
||||
const leadOutputs = {
|
||||
email: {
|
||||
type: 'string',
|
||||
description: 'Lead email address',
|
||||
},
|
||||
firstName: {
|
||||
type: 'string',
|
||||
description: 'Lead first name',
|
||||
},
|
||||
lastName: {
|
||||
type: 'string',
|
||||
description: 'Lead last name',
|
||||
},
|
||||
companyName: {
|
||||
type: 'string',
|
||||
description: 'Lead company name',
|
||||
},
|
||||
linkedinUrl: {
|
||||
type: 'string',
|
||||
description: 'Lead LinkedIn profile URL',
|
||||
},
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Sequence/campaign tracking fields for email activities
|
||||
*/
|
||||
const sequenceOutputs = {
|
||||
sequenceId: {
|
||||
type: 'string',
|
||||
description: 'Sequence identifier',
|
||||
},
|
||||
sequenceStep: {
|
||||
type: 'number',
|
||||
description: 'Current step in the sequence (0-indexed)',
|
||||
},
|
||||
totalSequenceStep: {
|
||||
type: 'number',
|
||||
description: 'Total number of steps in the sequence',
|
||||
},
|
||||
isFirst: {
|
||||
type: 'boolean',
|
||||
description: 'Whether this is the first activity of this type for this step',
|
||||
},
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Sender information fields
|
||||
*/
|
||||
const senderOutputs = {
|
||||
sendUserId: {
|
||||
type: 'string',
|
||||
description: 'Sender user identifier',
|
||||
},
|
||||
sendUserEmail: {
|
||||
type: 'string',
|
||||
description: 'Sender email address',
|
||||
},
|
||||
sendUserName: {
|
||||
type: 'string',
|
||||
description: 'Sender display name',
|
||||
},
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Email content fields
|
||||
*/
|
||||
const emailContentOutputs = {
|
||||
subject: {
|
||||
type: 'string',
|
||||
description: 'Email subject line',
|
||||
},
|
||||
text: {
|
||||
type: 'string',
|
||||
description: 'Email body content (HTML)',
|
||||
},
|
||||
messageId: {
|
||||
type: 'string',
|
||||
description: 'Email message ID (RFC 2822 format)',
|
||||
},
|
||||
emailId: {
|
||||
type: 'string',
|
||||
description: 'Lemlist email identifier',
|
||||
},
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Build outputs for email sent events
|
||||
*/
|
||||
export function buildEmailSentOutputs(): Record<string, TriggerOutput> {
|
||||
return {
|
||||
...coreOutputs,
|
||||
...campaignOutputs,
|
||||
...leadOutputs,
|
||||
...sequenceOutputs,
|
||||
...senderOutputs,
|
||||
...emailContentOutputs,
|
||||
} as Record<string, TriggerOutput>
|
||||
}
|
||||
|
||||
/**
|
||||
* Build outputs for email replied events
|
||||
*/
|
||||
export function buildEmailRepliedOutputs(): Record<string, TriggerOutput> {
|
||||
return {
|
||||
...coreOutputs,
|
||||
...campaignOutputs,
|
||||
...leadOutputs,
|
||||
...sequenceOutputs,
|
||||
...senderOutputs,
|
||||
...emailContentOutputs,
|
||||
} as Record<string, TriggerOutput>
|
||||
}
|
||||
|
||||
/**
|
||||
* Build outputs for email opened events
|
||||
*/
|
||||
export function buildEmailOpenedOutputs(): Record<string, TriggerOutput> {
|
||||
return {
|
||||
...coreOutputs,
|
||||
...campaignOutputs,
|
||||
...leadOutputs,
|
||||
...sequenceOutputs,
|
||||
...senderOutputs,
|
||||
messageId: {
|
||||
type: 'string',
|
||||
description: 'Email message ID that was opened',
|
||||
},
|
||||
} as Record<string, TriggerOutput>
|
||||
}
|
||||
|
||||
/**
|
||||
* Build outputs for email clicked events
|
||||
*/
|
||||
export function buildEmailClickedOutputs(): Record<string, TriggerOutput> {
|
||||
return {
|
||||
...coreOutputs,
|
||||
...campaignOutputs,
|
||||
...leadOutputs,
|
||||
...sequenceOutputs,
|
||||
...senderOutputs,
|
||||
messageId: {
|
||||
type: 'string',
|
||||
description: 'Email message ID containing the clicked link',
|
||||
},
|
||||
clickedUrl: {
|
||||
type: 'string',
|
||||
description: 'URL that was clicked',
|
||||
},
|
||||
} as Record<string, TriggerOutput>
|
||||
}
|
||||
|
||||
/**
|
||||
* Build outputs for email bounced events
|
||||
*/
|
||||
export function buildEmailBouncedOutputs(): Record<string, TriggerOutput> {
|
||||
return {
|
||||
...coreOutputs,
|
||||
...campaignOutputs,
|
||||
...leadOutputs,
|
||||
...sequenceOutputs,
|
||||
...senderOutputs,
|
||||
messageId: {
|
||||
type: 'string',
|
||||
description: 'Email message ID that bounced',
|
||||
},
|
||||
errorMessage: {
|
||||
type: 'string',
|
||||
description: 'Bounce error message',
|
||||
},
|
||||
} as Record<string, TriggerOutput>
|
||||
}
|
||||
|
||||
/**
|
||||
* Build outputs for LinkedIn replied events
|
||||
*/
|
||||
export function buildLinkedInRepliedOutputs(): Record<string, TriggerOutput> {
|
||||
return {
|
||||
...coreOutputs,
|
||||
...campaignOutputs,
|
||||
...leadOutputs,
|
||||
...sequenceOutputs,
|
||||
text: {
|
||||
type: 'string',
|
||||
description: 'LinkedIn message content',
|
||||
},
|
||||
} as Record<string, TriggerOutput>
|
||||
}
|
||||
|
||||
/**
|
||||
* Build outputs for interested/not interested events
|
||||
*/
|
||||
export function buildInterestOutputs(): Record<string, TriggerOutput> {
|
||||
return {
|
||||
...coreOutputs,
|
||||
...campaignOutputs,
|
||||
...leadOutputs,
|
||||
...sequenceOutputs,
|
||||
} as Record<string, TriggerOutput>
|
||||
}
|
||||
|
||||
/**
|
||||
* Build outputs for generic webhook (all events)
|
||||
* Includes all possible fields across event types
|
||||
*/
|
||||
export function buildLemlistOutputs(): Record<string, TriggerOutput> {
|
||||
return {
|
||||
...coreOutputs,
|
||||
...campaignOutputs,
|
||||
...leadOutputs,
|
||||
...sequenceOutputs,
|
||||
...senderOutputs,
|
||||
...emailContentOutputs,
|
||||
clickedUrl: {
|
||||
type: 'string',
|
||||
description: 'URL that was clicked (for emailsClicked events)',
|
||||
},
|
||||
errorMessage: {
|
||||
type: 'string',
|
||||
description: 'Error message (for bounce/failed events)',
|
||||
},
|
||||
} as Record<string, TriggerOutput>
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { LemlistIcon } from '@/components/icons'
|
||||
import { buildTriggerSubBlocks } from '@/triggers'
|
||||
import {
|
||||
buildLemlistExtraFields,
|
||||
buildLemlistOutputs,
|
||||
lemlistSetupInstructions,
|
||||
lemlistTriggerOptions,
|
||||
} from '@/triggers/lemlist/utils'
|
||||
import type { TriggerConfig } from '@/triggers/types'
|
||||
|
||||
/**
|
||||
* Generic Lemlist Webhook Trigger
|
||||
* Captures all Lemlist webhook events with optional filtering
|
||||
*/
|
||||
export const lemlistWebhookTrigger: TriggerConfig = {
|
||||
id: 'lemlist_webhook',
|
||||
name: 'Lemlist Webhook (All Events)',
|
||||
provider: 'lemlist',
|
||||
description: 'Trigger workflow on any Lemlist webhook event',
|
||||
version: '1.0.0',
|
||||
icon: LemlistIcon,
|
||||
|
||||
subBlocks: buildTriggerSubBlocks({
|
||||
triggerId: 'lemlist_webhook',
|
||||
triggerOptions: lemlistTriggerOptions,
|
||||
setupInstructions: lemlistSetupInstructions('All Events (no type filter)'),
|
||||
extraFields: buildLemlistExtraFields('lemlist_webhook'),
|
||||
}),
|
||||
|
||||
outputs: buildLemlistOutputs(),
|
||||
|
||||
webhook: {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user