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

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
@@ -0,0 +1,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',
},
},
}
+38
View File
@@ -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',
},
},
}
+38
View File
@@ -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',
},
},
}
+14
View File
@@ -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'
+38
View File
@@ -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',
},
},
}
+333
View File
@@ -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>
}
+38
View File
@@ -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',
},
},
}