npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jzakirov/smartlead

v0.3.2

Published

Smartlead plugin for OpenClaw. Adds webhook relay and skills for interacting with the Smartlead API.

Readme

openclaw-smartlead

Smartlead reply-webhook ingress adapter for OpenClaw.

This plugin is intentionally narrow:

  1. It exposes a Smartlead webhook endpoint (default /smartlead/webhook).
  2. It validates + parses + deduplicates Smartlead EMAIL_REPLY events.
  3. It forwards a normalized JSON payload to an OpenClaw mapped hook (default /hooks/smartlead).

Prompting, delivery routing, and branching logic should live in OpenClaw hooks.mappings / hook transforms.

npm Package

Published package name (configured for releases): @jzakirov/smartlead

Installation

From local path (dev/link):

openclaw plugins install -l /home/worker/code/openclaw-smartlead
openclaw plugins enable smartlead

Or copy install:

openclaw plugins install /home/worker/code/openclaw-smartlead
openclaw plugins enable smartlead

Architecture (recommended)

Flow:

  • Smartlead -> POST /smartlead/webhook (plugin route)
  • openclaw-smartlead plugin -> validates secret, normalizes payload, dedupes retries
  • Plugin -> POST /hooks/smartlead (OpenClaw native hook endpoint, with hook token auth)
  • OpenClaw hooks.mappings -> builds prompt / routes agent / optional branching transform
  • Agent uses smartlead CLI to fetch message history and summarize thread

OpenClaw Hooks Prerequisite

Because this plugin forwards Smartlead events to an OpenClaw mapped hook (/hooks/smartlead by default), enable webhook hooks in your OpenClaw config:

{
  hooks: {
    enabled: true,
    token: "${OPENCLAW_HOOKS_TOKEN}",
    path: "/hooks",
    allowedAgentIds: ["*"],
    defaultSessionKey: "hook:ingress",
    allowRequestSessionKey: false,

    // Smartlead workflow lives here now (generic OpenClaw hook mappings).
    mappings: [
      {
        id: "smartlead-reply",
        match: { path: "smartlead", source: "smartlead" },
        action: "agent",
        wakeMode: "now",
        name: "Smartlead Reply",

        // Keep one isolated session per lead thread (customize if needed).
        sessionKey: "hook:smartlead:{{campaign_id}}:{{lead_id}}",

        // Default behavior (can be replaced with transform-based branching).
        messageTemplate:
          "New lead answer\\n" +
          "Campaign: {{campaign_name}} (ID {{campaign_id}})\\n" +
          "Lead: {{lead_email}}\\n" +
          "Responder: {{responder_email}}\\n" +
          "Reply category: {{reply_category}}\\n" +
          "Preview: {{preview_text}}\\n\\n" +
          "Use smartlead CLI to fetch conversation history and summarize it.\\n" +
          "If lead_id exists: smartlead campaigns leads message-history {{campaign_id}} {{lead_id}}\\n" +
          "If lead_id is missing and lead_email exists: smartlead leads get-by-email --email {{lead_email}}",

        deliver: true,
        channel: "slack"
        // to: "C0123456789"
      }
    ]
  }
}

The plugin can auto-derive the mapped hook URL (/hooks/smartlead) and token from this config.

Plugin Configuration

Configure under plugins.entries.smartlead.config:

Minimal setup (recommended)

{
  plugins: {
    entries: {
      smartlead: {
        enabled: true,
        config: {
          webhookSecret: "optional-smartlead-secret"
        }
      }
    }
  }
}

Common optional overrides

Most setups do not need these. Only set them when OpenClaw cannot auto-derive values.

{
  plugins: {
    entries: {
      smartlead: {
        enabled: true,
        config: {
          webhookSecret: "optional-smartlead-secret",

          // Optional overrides (normally auto-derived from OpenClaw hooks config)
          openclawHookUrl: "http://127.0.0.1:18789/hooks/smartlead",
          openclawHookToken: "${OPENCLAW_HOOKS_TOKEN}",

          // Optional path override (default: /smartlead/webhook)
          inboundWebhookPath: "/smartlead/webhook"
        }
      }
    }
  }
}

Notes

  • webhookSecret is optional. If set, the plugin validates it against Smartlead payload secret_key (and also Authorization, x-smartlead-secret, and x-webhook-secret headers).
  • openclawHookUrl and openclawHookToken are usually auto-derived from OpenClaw gateway / hooks config.
  • Delivery channel, agentId, prompt text, and branching now belong in hooks.mappings (OpenClaw config), not plugin config.
  • The plugin currently accepts EMAIL_REPLY webhooks (reply flow). Other Smartlead webhook event types are ignored.

Smartlead Webhook Setup (Campaign)

Smartlead campaign webhook endpoints (per Smartlead docs):

  • GET /campaigns/<campaign-id>/webhooks
  • POST /campaigns/<campaign-id>/webhooks (add/update)

Example Smartlead webhook registration body (via Smartlead UI or smartlead CLI):

{
  "id": null,
  "name": "OpenClaw Reply Alerts",
  "webhook_url": "https://your-openclaw-host.example.com/smartlead/webhook",
  "event_types": ["EMAIL_REPLY"],
  "categories": ["Interested"]
}

Important:

  • categories must be a non-empty array in Smartlead webhook upsert requests.
  • categories values are Smartlead lead category labels from your workspace (for example Interested), not webhook event types.
  • Use smartlead webhooks upsert --help for the current event_types enum supported by the CLI.

What The Plugin Forwards To /hooks/smartlead

The plugin forwards normalized JSON (not a prebuilt prompt) so OpenClaw hooks.mappings can template/branch on it.

The forwarded payload includes:

  • source: "smartlead" (for match.source)
  • Flat aliases (easy template access):
    • campaign_id, campaign_name, campaign_status
    • lead_id, lead_map_id, lead_email
    • responder_email, responder_name, target_name
    • reply_category, replied_company_domain
    • subject, preview_text, event_timestamp
    • message_id, sequence_number, stats_id, app_url
  • context (same data grouped)
  • payloadSummary (presence/keys hints)
  • payload (sanitized raw Smartlead payload; secret_key redacted)

This makes branching via hook transforms practical (for example: positive reply vs decline vs OOO).

Optional Branching Transform (recommended for production)

Use a hook transform to keep deterministic branching out of the plugin. Example mapping:

{
  hooks: {
    mappings: [
      {
        id: "smartlead-reply",
        match: { path: "smartlead", source: "smartlead" },
        action: "agent",
        wakeMode: "now",
        name: "Smartlead Reply",
        sessionKey: "hook:smartlead:{{campaign_id}}:{{lead_id}}",
        deliver: true,
        channel: "slack",
        transform: { module: "smartlead-reply-branch.js" }
      }
    ]
  }
}

See examples/hooks-transforms/smartlead-reply-branch.example.js in this repo for a starter transform. Copy it into your OpenClaw transforms directory (typically ~/.openclaw/hooks/transforms/) before referencing it in hooks.mappings[].transform.module.

Reply Webhook Flow (What happens)

When Smartlead sends an EMAIL_REPLY webhook to inboundWebhookPath, the plugin:

  1. Validates and parses the payload.
  2. Deduplicates retries (TTL cache).
  3. Forwards normalized JSON to OpenClaw /hooks/smartlead (or your configured mapped hook URL).
  4. OpenClaw hooks.mappings (and optional transforms) decide:
    • prompt text
    • delivery channel/target
    • branching behavior
  5. The agent uses smartlead CLI to fetch message history and summarize the thread.

Final Usage Example (your target flow)

Resulting behavior after setup:

  • Lead replies to campaign email in Smartlead
  • Smartlead calls POST /smartlead/webhook
  • Plugin forwards normalized payload to POST /hooks/smartlead
  • OpenClaw mapping runs an isolated hook agent turn
  • OpenClaw sends a message to your configured channel with:
    • New lead answer
    • a short summary of prior conversation (fetched from Smartlead message history)

Bundled Skill

The plugin ships a bundled skill at skills/smartlead/SKILL.md so the LLM can operate Smartlead reliably (ID handling, webhook payload fields, CLI usage, and reply-workflow guidance).