Skip to content

Commit eab4f75

Browse files
committed
feat(smartlead): expand to the core workflow surface and fix review findings
Grows the block from 22 to 47 tools and fixes every defect found in review. New tools (all executed against the live API end to end): campaign email accounts (list/add/remove), duplicate, delete, CSV lead export, webhook delete + delivery summary, lead + mailbox statistics, top-level analytics by date, lead activities, get lead by id, unsubscribe from campaign, unsubscribe globally, mark complete, delete from campaign, master-inbox replies, lead lists (list/get/create/update/delete), email accounts, clients. The endpoint inventory was rebuilt by extracting method+path from all 212 reference pages, which corrected several earlier conclusions: get-lead-by-id is `/leads/{id}` (not under `/campaigns/`), lead lists are `/lead-list/` (singular), and lead activities are `/campaigns/all-leads-activities` with no campaign segment. More documented paths that 404 in reality: lead tags at `/crm/leads/tags`, and webhook delete at `/campaigns/{id}/webhooks/{id}` — deletion actually takes the id in the body. Shapes the docs got wrong again, caught live: `GET /leads/{id}` wraps the lead in a single-element `data` array; `DELETE .../leads/{id}` answers with the bare string `success`, not JSON; duplicate returns `newCampaignId`; create/update lead list take `listName`, and mark-complete takes `campaign_lead_map_id` where its siblings take `lead.id`. Review fixes: - get_campaign, get_campaign_analytics and get_lead_by_email reported an all-null success for a missing resource, because Smartlead answers HTTP 200 with `{}` (or an empty body) instead of 404. They now fail closed. - update_campaign_settings silently reset stop_lead_settings and send_as_plain_text: their dropdown defaults are materialized at block creation, so every settings update carried them. Both now default to "Leave unchanged". - Malformed JSON in Leads/Sequences/Custom Fields resolved to `undefined`, which overwrote the raw string the executor falls back on and dropped the field silently. Parsing now raises, and is scoped to the operation that consumes the field so a stale hidden value cannot fail an unrelated one. - The four documented import overrides (block/unsubscribe/duplicate/bounce lists) had no field, so the block's own skill instructions were unexecutable. - leadId did not distinguish lead.id from campaign_lead_map_id; passing the latter 404s, and list_campaign_leads surfaces it first. - Path ids are trimmed and escaped; dead code and a hand-rolled id mapper removed. Unverified and called out rather than guessed: add/remove email accounts to a campaign (no mailbox could be connected, so only their error shape was seen), and the row shapes for statistics, message history, inbox replies, email accounts and clients — every one of those collections was empty on the verification account, so their rows pass through unmapped.
1 parent 177543a commit eab4f75

55 files changed

Lines changed: 3828 additions & 122 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/docs/content/docs/en/integrations/smartlead.mdx

Lines changed: 1446 additions & 44 deletions
Large diffs are not rendered by default.

apps/sim/blocks/blocks/smartlead.ts

Lines changed: 420 additions & 31 deletions
Large diffs are not rendered by default.

apps/sim/lib/integrations/integrations.json

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17816,9 +17816,109 @@
1781617816
{
1781717817
"name": "Create or Update Webhook",
1781817818
"description": "Creates a webhook on a Smartlead campaign, or updates an existing one when a webhook ID is supplied. Smartlead requires at least one lead category."
17819+
},
17820+
{
17821+
"name": "Delete Campaign Webhook",
17822+
"description": "Deletes a webhook from a Smartlead campaign."
17823+
},
17824+
{
17825+
"name": "Get Webhook Summary",
17826+
"description": "Retrieves webhook delivery counts for a Smartlead campaign over a time window, for checking whether events are reaching their destination."
17827+
},
17828+
{
17829+
"name": "Duplicate Campaign",
17830+
"description": "Copies a Smartlead campaign, including its sequences and settings. The copy is named \"<original> - copy\" and starts in DRAFTED status."
17831+
},
17832+
{
17833+
"name": "Delete Campaign",
17834+
"description": "Permanently deletes a Smartlead campaign along with its sequences, leads, and webhooks. This cannot be undone."
17835+
},
17836+
{
17837+
"name": "Export Campaign Leads (CSV)",
17838+
"description": "Exports every lead in a Smartlead campaign as CSV, including engagement counts and the sequence step last sent to each lead."
17839+
},
17840+
{
17841+
"name": "List Campaign Email Accounts",
17842+
"description": "Retrieves the sending email accounts attached to a Smartlead campaign."
17843+
},
17844+
{
17845+
"name": "Add Email Accounts to Campaign",
17846+
"description": "Attaches sending email accounts to a Smartlead campaign. A campaign needs at least one attached account before it can start."
17847+
},
17848+
{
17849+
"name": "Remove Email Accounts from Campaign",
17850+
"description": "Detaches sending email accounts from a Smartlead campaign."
17851+
},
17852+
{
17853+
"name": "List Email Accounts",
17854+
"description": "Retrieves the sending email accounts on the Smartlead account, including their IDs for attaching to a campaign."
17855+
},
17856+
{
17857+
"name": "Get Campaign Lead Statistics",
17858+
"description": "Retrieves per-lead engagement statistics for a Smartlead campaign."
17859+
},
17860+
{
17861+
"name": "Get Campaign Mailbox Statistics",
17862+
"description": "Retrieves per-mailbox sending statistics for a Smartlead campaign, for spotting which sending accounts are underperforming."
17863+
},
17864+
{
17865+
"name": "Get Top-Level Analytics by Date",
17866+
"description": "Retrieves top-level Smartlead campaign counts for a date range, including positive replies, skipped, failed, and stopped counts not present in the standard analytics."
17867+
},
17868+
{
17869+
"name": "List Lead Activities",
17870+
"description": "Retrieves recent lead activity across Smartlead campaigns — opens, clicks, replies, and status changes."
17871+
},
17872+
{
17873+
"name": "Get Lead by ID",
17874+
"description": "Looks up a Smartlead lead by its ID."
17875+
},
17876+
{
17877+
"name": "Unsubscribe Lead from Campaign",
17878+
"description": "Unsubscribes a lead from a single Smartlead campaign, leaving it active in other campaigns."
17879+
},
17880+
{
17881+
"name": "Unsubscribe Lead Globally",
17882+
"description": "Unsubscribes a lead across every Smartlead campaign and adds it to the account-wide unsubscribe list."
17883+
},
17884+
{
17885+
"name": "Mark Lead Complete",
17886+
"description": "Marks a lead as completed in a Smartlead campaign so it stops receiving further sequence steps."
17887+
},
17888+
{
17889+
"name": "Delete Lead from Campaign",
17890+
"description": "Removes a lead from a Smartlead campaign. The lead record itself remains on the account."
17891+
},
17892+
{
17893+
"name": "List Inbox Replies",
17894+
"description": "Retrieves replies from the Smartlead master inbox, optionally limited to unread replies or a single campaign."
17895+
},
17896+
{
17897+
"name": "List Lead Lists",
17898+
"description": "Retrieves the lead lists on the Smartlead account with their lead counts."
17899+
},
17900+
{
17901+
"name": "Get Lead List",
17902+
"description": "Retrieves a single Smartlead lead list by ID."
17903+
},
17904+
{
17905+
"name": "Create Lead List",
17906+
"description": "Creates a lead list on the Smartlead account."
17907+
},
17908+
{
17909+
"name": "Update Lead List",
17910+
"description": "Renames a Smartlead lead list."
17911+
},
17912+
{
17913+
"name": "Delete Lead List",
17914+
"description": "Deletes a Smartlead lead list."
17915+
},
17916+
{
17917+
"name": "List Clients",
17918+
"description": "Retrieves the clients on a Smartlead agency account, including the client IDs used to scope campaigns and email accounts."
1781917919
}
1782017920
],
17821-
"operationCount": 22,
17921+
"operationCount": 47,
1782217922
"triggers": [],
1782317923
"triggerCount": 0,
1782417924
"authType": "api-key",

apps/sim/tools/generated/tool-ids.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

apps/sim/tools/generated/tool-metadata.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

apps/sim/tools/generated/tool-outputs.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

apps/sim/tools/registry.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3692,26 +3692,51 @@ import {
36923692
slackUpdateViewTool,
36933693
} from '@/tools/slack'
36943694
import {
3695+
smartleadAddEmailAccountsToCampaignTool,
36953696
smartleadAddLeadsToCampaignTool,
36963697
smartleadCreateCampaignTool,
3698+
smartleadCreateLeadListTool,
3699+
smartleadDeleteCampaignTool,
3700+
smartleadDeleteCampaignWebhookTool,
3701+
smartleadDeleteLeadFromCampaignTool,
3702+
smartleadDeleteLeadListTool,
3703+
smartleadDuplicateCampaignTool,
3704+
smartleadExportCampaignLeadsTool,
36973705
smartleadGetCampaignAnalyticsByDateTool,
36983706
smartleadGetCampaignAnalyticsTool,
3707+
smartleadGetCampaignLeadStatisticsTool,
3708+
smartleadGetCampaignMailboxStatisticsTool,
36993709
smartleadGetCampaignSequencesTool,
37003710
smartleadGetCampaignStatisticsTool,
37013711
smartleadGetCampaignTool,
3712+
smartleadGetCampaignTopLevelAnalyticsByDateTool,
3713+
smartleadGetCampaignWebhookSummaryTool,
37023714
smartleadGetLeadByEmailTool,
3715+
smartleadGetLeadByIdTool,
3716+
smartleadGetLeadListTool,
37033717
smartleadGetLeadMessageHistoryTool,
3718+
smartleadListCampaignEmailAccountsTool,
37043719
smartleadListCampaignLeadsTool,
37053720
smartleadListCampaignsTool,
37063721
smartleadListCampaignWebhooksTool,
3722+
smartleadListClientsTool,
3723+
smartleadListEmailAccountsTool,
3724+
smartleadListInboxRepliesTool,
3725+
smartleadListLeadActivitiesTool,
37073726
smartleadListLeadCategoriesTool,
3727+
smartleadListLeadListsTool,
3728+
smartleadMarkLeadCompleteTool,
37083729
smartleadPauseLeadTool,
3730+
smartleadRemoveEmailAccountsFromCampaignTool,
37093731
smartleadResumeLeadTool,
37103732
smartleadSaveCampaignSequencesTool,
3733+
smartleadUnsubscribeLeadFromCampaignTool,
3734+
smartleadUnsubscribeLeadGloballyTool,
37113735
smartleadUpdateCampaignScheduleTool,
37123736
smartleadUpdateCampaignSettingsTool,
37133737
smartleadUpdateCampaignStatusTool,
37143738
smartleadUpdateLeadCategoryTool,
3739+
smartleadUpdateLeadListTool,
37153740
smartleadUpdateLeadTool,
37163741
smartleadUpsertCampaignWebhookTool,
37173742
} from '@/tools/smartlead'
@@ -5788,6 +5813,32 @@ export const tools: Record<string, ToolConfig> = {
57885813
smartlead_get_lead_message_history: smartleadGetLeadMessageHistoryTool,
57895814
smartlead_list_campaign_webhooks: smartleadListCampaignWebhooksTool,
57905815
smartlead_upsert_campaign_webhook: smartleadUpsertCampaignWebhookTool,
5816+
smartlead_delete_campaign_webhook: smartleadDeleteCampaignWebhookTool,
5817+
smartlead_get_campaign_webhook_summary: smartleadGetCampaignWebhookSummaryTool,
5818+
smartlead_duplicate_campaign: smartleadDuplicateCampaignTool,
5819+
smartlead_delete_campaign: smartleadDeleteCampaignTool,
5820+
smartlead_export_campaign_leads: smartleadExportCampaignLeadsTool,
5821+
smartlead_list_campaign_email_accounts: smartleadListCampaignEmailAccountsTool,
5822+
smartlead_add_email_accounts_to_campaign: smartleadAddEmailAccountsToCampaignTool,
5823+
smartlead_remove_email_accounts_from_campaign: smartleadRemoveEmailAccountsFromCampaignTool,
5824+
smartlead_list_email_accounts: smartleadListEmailAccountsTool,
5825+
smartlead_get_campaign_lead_statistics: smartleadGetCampaignLeadStatisticsTool,
5826+
smartlead_get_campaign_mailbox_statistics: smartleadGetCampaignMailboxStatisticsTool,
5827+
smartlead_get_campaign_top_level_analytics_by_date:
5828+
smartleadGetCampaignTopLevelAnalyticsByDateTool,
5829+
smartlead_list_lead_activities: smartleadListLeadActivitiesTool,
5830+
smartlead_get_lead_by_id: smartleadGetLeadByIdTool,
5831+
smartlead_unsubscribe_lead_from_campaign: smartleadUnsubscribeLeadFromCampaignTool,
5832+
smartlead_unsubscribe_lead_globally: smartleadUnsubscribeLeadGloballyTool,
5833+
smartlead_mark_lead_complete: smartleadMarkLeadCompleteTool,
5834+
smartlead_delete_lead_from_campaign: smartleadDeleteLeadFromCampaignTool,
5835+
smartlead_list_inbox_replies: smartleadListInboxRepliesTool,
5836+
smartlead_list_lead_lists: smartleadListLeadListsTool,
5837+
smartlead_get_lead_list: smartleadGetLeadListTool,
5838+
smartlead_create_lead_list: smartleadCreateLeadListTool,
5839+
smartlead_update_lead_list: smartleadUpdateLeadListTool,
5840+
smartlead_delete_lead_list: smartleadDeleteLeadListTool,
5841+
smartlead_list_clients: smartleadListClientsTool,
57915842
github_repo_info: githubRepoInfoTool,
57925843
github_repo_info_v2: githubRepoInfoV2Tool,
57935844
github_latest_commit: githubLatestCommitTool,
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { ErrorExtractorId } from '@/tools/error-extractors'
2+
import type { SmartleadActionResponse, SmartleadCampaignIdParams } from '@/tools/smartlead/types'
3+
import {
4+
actionOutputs,
5+
isOk,
6+
pathSegment,
7+
smartleadBaseParamFields,
8+
smartleadCampaignIdParamField,
9+
smartleadHeaders,
10+
smartleadRecord,
11+
smartleadUrl,
12+
} from '@/tools/smartlead/utils'
13+
import type { ToolConfig } from '@/tools/types'
14+
15+
interface AddEmailAccountsParams extends SmartleadCampaignIdParams {
16+
emailAccountIds: number[]
17+
}
18+
19+
export const addEmailAccountsToCampaignTool: ToolConfig<
20+
AddEmailAccountsParams,
21+
SmartleadActionResponse
22+
> = {
23+
id: 'smartlead_add_email_accounts_to_campaign',
24+
name: 'Smartlead Add Email Accounts to Campaign',
25+
description:
26+
'Attaches sending email accounts to a Smartlead campaign. A campaign needs at least one attached account before it can start.',
27+
version: '1.0.0',
28+
errorExtractor: ErrorExtractorId.SMARTLEAD_ERRORS,
29+
params: {
30+
...smartleadBaseParamFields,
31+
...smartleadCampaignIdParamField,
32+
emailAccountIds: {
33+
type: 'array',
34+
required: true,
35+
visibility: 'user-or-llm',
36+
description: 'IDs of the email accounts to attach, from List Email Accounts',
37+
items: { type: 'number' },
38+
},
39+
},
40+
request: {
41+
url: (params) =>
42+
smartleadUrl(`/campaigns/${pathSegment(params.campaignId)}/email-accounts`, params.apiKey),
43+
method: 'POST',
44+
headers: smartleadHeaders,
45+
body: (params) => ({
46+
email_account_ids: Array.isArray(params.emailAccountIds) ? params.emailAccountIds : [],
47+
}),
48+
},
49+
transformResponse: async (response) => {
50+
const record = await smartleadRecord(response, 'email account attach')
51+
52+
return {
53+
success: true,
54+
output: { success: isOk(record) || record.success === true },
55+
}
56+
},
57+
outputs: actionOutputs,
58+
}

apps/sim/tools/smartlead/add_leads_to_campaign.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
addLeadsOutputs,
66
jsonBody,
77
mapLeadImportResult,
8+
pathSegment,
89
smartleadBaseParamFields,
910
smartleadCampaignIdParamField,
1011
smartleadHeaders,
@@ -95,7 +96,8 @@ export const addLeadsToCampaignTool: ToolConfig<
9596
},
9697
},
9798
request: {
98-
url: (params) => smartleadUrl(`/campaigns/${params.campaignId}/leads`, params.apiKey),
99+
url: (params) =>
100+
smartleadUrl(`/campaigns/${pathSegment(params.campaignId)}/leads`, params.apiKey),
99101
method: 'POST',
100102
headers: smartleadHeaders,
101103
body: (params) => ({

apps/sim/tools/smartlead/create_campaign.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { SmartleadBaseParams, SmartleadCreateCampaignResponse } from '@/too
33
import {
44
createCampaignOutputs,
55
jsonBody,
6+
mapCreatedCampaign,
67
smartleadBaseParamFields,
78
smartleadHeaders,
89
smartleadRecord,
@@ -53,11 +54,7 @@ export const createCampaignTool: ToolConfig<CreateCampaignParams, SmartleadCreat
5354

5455
return {
5556
success: true,
56-
output: {
57-
id: typeof record.id === 'number' ? record.id : Number(record.id) || null,
58-
name: typeof record.name === 'string' ? record.name : null,
59-
created_at: typeof record.created_at === 'string' ? record.created_at : null,
60-
},
57+
output: mapCreatedCampaign(record),
6158
}
6259
},
6360
outputs: createCampaignOutputs,

0 commit comments

Comments
 (0)