Skip to content

Conversation

@icecrasher321
Copy link
Collaborator

@icecrasher321 icecrasher321 commented Jan 13, 2026

Summary

Multi part PR:

  1. Claude Code Skills for adding integrations:
  • /add-tools — Creates tool files (tools/{service}/) with types and API implementations
  • /add-block — Creates block file (blocks/blocks/{service}.ts) with subBlocks, conditions, and tool wiring
  • /add-trigger — Creates trigger files (triggers/{service}/) with webhook handlers and event definitions
  • /add-integration — Does all of the above in one go (tools + block + icon + optional triggers)

Quick path: Just use /add-integration — it orchestrates everything.

  1. Lemlist Trigger and Tools

  2. No more test webhook URL. Must deploy to test webhooks.

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link

vercel bot commented Jan 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Review Updated (UTC)
docs Skipped Skipped Jan 13, 2026 5:43am

@waleedlatif1
Copy link
Collaborator

🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 13, 2026

Greptile Overview

Greptile Summary

This PR adds three major features: Claude Code Skills for integration development, Lemlist integration with tools/blocks/triggers, and removal of test webhook functionality.

What Changed

1. Claude Code Skills (.claude/commands/)

Four new skills provide comprehensive guidance for adding integrations:

  • /add-integration - Orchestrates full integration creation
  • /add-tools - Creates API tool configurations
  • /add-block - Creates block UI configurations
  • /add-trigger - Creates webhook trigger configurations

These are well-documented guides with examples and checklists.

2. Lemlist Integration

Tools (3): Get Activities, Get Lead, Send Email - all properly structured with correct parameter visibility and nullable field handling.

Block: Single block with operation dropdown supporting all 3 tools, plus 9 webhook triggers. Uses API key authentication.

Triggers (9): Email Replied (primary with dropdown), LinkedIn Replied, Interested, Not Interested, Email Opened, Email Clicked, Email Bounced, Email Sent, and Generic Webhook.

Webhook Infrastructure: Automatic webhook creation/deletion in Lemlist API with proper error handling and rollback on failure.

3. Test Webhook Removal

Removed all test webhook functionality to force deployment-based testing:

  • Deleted test endpoints (/api/webhooks/test/*)
  • Removed test URL generation
  • Removed JWT token utilities for test webhooks
  • Updated processor to remove testMode flag
  • Cleaned up related tests

Critical Issues Found

1. Duplicate SubBlock ID (BLOCKER)

apps/sim/blocks/blocks/lemlist.ts has two subblocks with id: 'leadId' (lines 55 and 122). This causes configuration conflicts and data loss as the serializer can only preserve one value.

2. Missing Webhook Event Filtering (HIGH)

  • shouldSkipWebhookEvent() in processor.ts doesn't implement Lemlist filtering
  • Generic webhook's eventTypes configuration is ignored
  • All events will trigger workflows even when specific types are selected

3. Unused Webhook Processing Functions (HIGH)

isLemlistEventMatch() and extractLemlistData() in utils.ts are defined but never used. These should validate events and normalize webhook payloads.

4. Generic Webhook Configuration Issues (MEDIUM)

  • Missing API key in extraFields for automatic webhook creation
  • Event type filtering not implemented in webhook creation function
  • UI allows selecting multiple event types but Lemlist API may only support single type per webhook

Positive Aspects

  • Tool implementations follow best practices with proper error handling
  • Webhook auto-creation/deletion works correctly with rollback on failure
  • Trigger structure uses generic builder pattern consistently
  • All resources properly registered in registries
  • Claude Code Skills provide excellent developer documentation
  • Test webhook removal is clean and complete

Confidence Score: 2/5

  • This PR has critical bugs that will cause runtime issues and should not be merged without fixes
  • Score of 2/5 reflects one blocking bug (duplicate subblock IDs causing data loss), two high-priority issues (missing event filtering logic and unused webhook processing functions), and several medium-priority configuration issues. The duplicate leadId will definitely break the UI when users try to configure the "Send Email" operation. The missing event filtering means the generic webhook feature won't work as designed. While the tools are well-implemented and the test webhook removal is clean, the integration's core functionality has significant gaps that need to be addressed before deployment.
  • Pay close attention to apps/sim/blocks/blocks/lemlist.ts (fix duplicate leadId immediately), apps/sim/lib/webhooks/processor.ts (add Lemlist event filtering), and apps/sim/triggers/lemlist/webhook.ts (fix configuration to match implementation or vice versa)

Important Files Changed

File Analysis

Filename Score Overview
apps/sim/blocks/blocks/lemlist.ts 2/5 Critical bug: Duplicate leadId subblock IDs (lines 55 & 122) causing configuration conflicts and data loss
apps/sim/lib/webhooks/processor.ts 2/5 Missing Lemlist event filtering in shouldSkipWebhookEvent - generic webhook will not filter events properly
apps/sim/triggers/lemlist/utils.ts 2/5 Unused webhook processing functions (isLemlistEventMatch, extractLemlistData) - webhook validation logic not integrated
apps/sim/triggers/lemlist/webhook.ts 2/5 Missing API key in extraFields and event filtering not implemented - webhook configuration incomplete
apps/sim/app/api/webhooks/route.ts 3/5 Added Lemlist webhook auto-creation with proper error handling, but generic webhook eventTypes filtering not implemented
apps/sim/tools/lemlist/get_lead.ts 5/5 Well-implemented tool with proper error handling, nullable field handling, and correct visibility settings
apps/sim/lib/webhooks/provider-subscriptions.ts 5/5 Added Lemlist webhook deletion with proper error handling and graceful failure (non-fatal)
apps/sim/triggers/lemlist/email_replied.ts 5/5 Correctly configured as primary trigger with dropdown, using generic builder pattern properly

Sequence Diagram

sequenceDiagram
    participant User
    participant WebhookAPI as Webhook API<br/>(POST /api/webhooks)
    participant DB as Database
    participant Lemlist as Lemlist API
    participant TriggerAPI as Trigger API<br/>(/api/webhooks/trigger/{path})
    participant Processor as Webhook Processor
    participant Queue as Trigger.dev Queue
    participant Workflow as Workflow Engine

    Note over User,Workflow: Webhook Setup Flow
    User->>WebhookAPI: Create webhook with apiKey + triggerId
    WebhookAPI->>DB: Save webhook record
    DB-->>WebhookAPI: savedWebhook
    
    alt provider === 'lemlist'
        WebhookAPI->>WebhookAPI: createLemlistWebhookSubscription()
        WebhookAPI->>Lemlist: POST /api/hooks<br/>{targetUrl, type, campaignId}
        alt Success
            Lemlist-->>WebhookAPI: {_id: webhookId}
            WebhookAPI->>DB: Update with externalId
        else API Error (401/403)
            Lemlist-->>WebhookAPI: Error
            WebhookAPI->>DB: Rollback - delete webhook
            WebhookAPI-->>User: Error: Invalid API Key
        end
    end
    
    WebhookAPI-->>User: Webhook created

    Note over User,Workflow: Webhook Trigger Flow
    Lemlist->>TriggerAPI: POST /api/webhooks/trigger/{path}<br/>{type, leadId, campaignId...}
    TriggerAPI->>Processor: findAllWebhooksForPath(path)
    Processor->>DB: Query webhooks by path
    DB-->>Processor: webhooks
    
    TriggerAPI->>Processor: checkWebhookPreprocessing()
    Processor->>Processor: Check rate limits & deployment
    
    TriggerAPI->>Processor: shouldSkipWebhookEvent()
    Note right of Processor: ⚠️ Missing Lemlist filtering!<br/>Should check eventTypes
    
    TriggerAPI->>Processor: queueWebhookExecution()
    Processor->>Queue: trigger('webhook-execution', payload)
    Queue->>Workflow: Execute with triggerData
    Workflow-->>User: Workflow runs
    
    TriggerAPI-->>Lemlist: 200 OK

    Note over User,Workflow: Webhook Deletion Flow
    User->>WebhookAPI: DELETE webhook
    WebhookAPI->>DB: Delete webhook record
    WebhookAPI->>Processor: cleanupExternalWebhook()
    
    alt provider === 'lemlist'
        Processor->>Processor: deleteLemlistWebhook()
        Processor->>Lemlist: DELETE /api/hooks/{externalId}
        alt Success or 404
            Lemlist-->>Processor: OK
        else Error (non-fatal)
            Lemlist-->>Processor: Error
            Note right of Processor: Log warning, continue
        end
    end
    
    WebhookAPI-->>User: Deleted
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, 5 comments

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 13, 2026

Additional Comments (1)

apps/sim/lib/webhooks/processor.ts
Missing Lemlist event filtering logic in shouldSkipWebhookEvent. The PR adds a generic Lemlist webhook trigger (lemlist_webhook) that supports eventTypes filtering (see apps/sim/triggers/lemlist/webhook.ts lines 28-56), but this function doesn't implement the filtering logic.

Without this, the lemlist_webhook trigger will receive ALL events even when specific eventTypes are configured, defeating the purpose of the filter.

Impact: Users who configure lemlist_webhook with specific event types (e.g., only "Email Sent" and "Email Opened") will still receive all event types, causing unnecessary workflow executions.

Fix: Add Lemlist event filtering similar to Stripe and Grain:

  if (webhook.provider === 'grain') {
    const eventTypes = providerConfig.eventTypes
    if (eventTypes && Array.isArray(eventTypes) && eventTypes.length > 0) {
      const eventType = body?.type
      if (eventType && !eventTypes.includes(eventType)) {
        logger.info(
          `[${requestId}] Grain event type '${eventType}' not in allowed list for webhook ${webhook.id}, skipping`
        )
        return true
      }
    }
  }

  if (webhook.provider === 'lemlist') {
    const eventTypes = providerConfig.eventTypes
    if (eventTypes && Array.isArray(eventTypes) && eventTypes.length > 0) {
      const eventType = body?.type || body?.eventType
      if (eventType && !eventTypes.includes(eventType)) {
        logger.info(
          `[${requestId}] Lemlist event type '${eventType}' not in allowed list for webhook ${webhook.id}, skipping`
        )
        return true
      }
    }
  }

  return false
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/lib/webhooks/processor.ts
Line: 225:255

Comment:
Missing Lemlist event filtering logic in `shouldSkipWebhookEvent`. The PR adds a generic Lemlist webhook trigger (`lemlist_webhook`) that supports `eventTypes` filtering (see `apps/sim/triggers/lemlist/webhook.ts` lines 28-56), but this function doesn't implement the filtering logic.

Without this, the `lemlist_webhook` trigger will receive ALL events even when specific `eventTypes` are configured, defeating the purpose of the filter.

**Impact:** Users who configure `lemlist_webhook` with specific event types (e.g., only "Email Sent" and "Email Opened") will still receive all event types, causing unnecessary workflow executions.

**Fix:** Add Lemlist event filtering similar to Stripe and Grain:
```suggestion
  if (webhook.provider === 'grain') {
    const eventTypes = providerConfig.eventTypes
    if (eventTypes && Array.isArray(eventTypes) && eventTypes.length > 0) {
      const eventType = body?.type
      if (eventType && !eventTypes.includes(eventType)) {
        logger.info(
          `[${requestId}] Grain event type '${eventType}' not in allowed list for webhook ${webhook.id}, skipping`
        )
        return true
      }
    }
  }

  if (webhook.provider === 'lemlist') {
    const eventTypes = providerConfig.eventTypes
    if (eventTypes && Array.isArray(eventTypes) && eventTypes.length > 0) {
      const eventType = body?.type || body?.eventType
      if (eventType && !eventTypes.includes(eventType)) {
        logger.info(
          `[${requestId}] Lemlist event type '${eventType}' not in allowed list for webhook ${webhook.id}, skipping`
        )
        return true
      }
    }
  }

  return false
}
```

How can I resolve this? If you propose a fix, please make it concise.

@icecrasher321 icecrasher321 merged commit a05003a into staging Jan 13, 2026
10 checks passed
@waleedlatif1 waleedlatif1 deleted the feat/integration-agent branch January 13, 2026 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants