Skip to content

feat(instantly): Instantly.ai cold email integration (#19)#74

Open
jackulau wants to merge 1 commit into
wespreadjam:mainfrom
jackulau:19
Open

feat(instantly): Instantly.ai cold email integration (#19)#74
jackulau wants to merge 1 commit into
wespreadjam:mainfrom
jackulau:19

Conversation

@jackulau

Copy link
Copy Markdown

Closes #19

Summary

Adds a new instantly integration to @jam-nodes/nodes with three operation nodes and a Bearer-token credential, following the existing apify integration pattern. Implements all five acceptance criteria from the issue with 33 unit tests and no regressions to the existing suite.

What's in this PR:

  • instantly_add_lead — add a lead to a cold email campaign (POST /leads)
  • instantly_create_campaign — create a campaign with a multi-step drip sequence (POST /campaigns)
  • instantly_get_analytics — fetch per-campaign metrics (GET /analytics/campaigns/:id)
  • instantlyCredential — Bearer-token credential definition via defineBearerCredential
  • instantly?: { apiKey: string } added to NodeCredentials in @jam-nodes/core
  • 33 unit tests covering credential metadata, schema validation, happy paths, error paths, body-level success: false, fallback branches, and error-text truncation

Design notes:

  • Follows packages/nodes/src/integrations/apify/ as the closest template (Bearer auth, multi-operation, flat test file, shared schemas.ts)
  • All three nodes stay pure per CLAUDE.md: no retry/cache/timeout logic in node bodies — that's delegated to fetchWithRetry config ({ maxRetries: 3, backoffMs: 1000, timeoutMs: 30000 })
  • No z.any() or as any anywhere
  • Error response text is truncated to 500 chars to avoid leaking large API responses into logs
  • Size caps on customVariables (max 50 keys), emailAccounts (max 50), and sequence (max 100 steps) to prevent unbounded payloads
  • When the API responds HTTP 200 with { success: false, error: ... }, the node returns { success: false, error } instead of silently surfacing the failure as success
  • getAnalytics URL-encodes campaignId via encodeURIComponent to defend against path injection
  • Exports wired through packages/nodes/src/integrations/index.ts and packages/nodes/src/index.ts following the Slack/Discord pattern

Test results:

  • Instantly test file: 33/33 passing (run: cd packages/nodes && npx vitest run src/integrations/instantly/instantly.test.ts)
  • Full @jam-nodes/nodes suite: 224/228 (baseline on main was 191/195 — this PR adds +33 passing tests and introduces zero regressions)
  • @jam-nodes/core typecheck: clean (cd packages/core && npm run typecheck → exit 0)
  • @jam-nodes/nodes typecheck: 324 errors on baseline, 324 errors with this PR — all pre-existing in src/transform/*.ts and src/logic/*.ts, unchanged by this PR

Acceptance Criteria

  • Credential definition
  • All 3 operations
  • Sequence support
  • Zod schemas
  • Unit tests

)

Adds a new integration with Bearer API-key credential and three nodes
following the established apify/slack pattern:

- instantly_add_lead — add a lead to a campaign
- instantly_create_campaign — create a campaign with a drip sequence
- instantly_get_analytics — fetch per-campaign metrics

Nodes stay pure per CLAUDE.md: retry/timeout handled by fetchWithRetry
config, no wrapper nodes, no z.any(). When the API returns a body with
`success: false`, the node surfaces that as a failure instead of silently
returning an empty id. Error response text is truncated to 500 chars to
avoid unbounded error payloads. Schema size caps on customVariables
(50 keys), emailAccounts (50), and sequence (100 steps) bound request
payloads.

- packages/core: register 'instantly' in NodeCredentials
- packages/nodes/src/integrations/instantly: schemas, credential,
  3 node files, barrel, and a 33-test suite
- packages/nodes/src/integrations/index.ts + src/index.ts: wire exports

Tests: 33 passing. Full suite: 224/228 (baseline 191/195; +33, 0 regressions).
Typecheck: 324 pre-existing errors in transform/* unchanged by this PR.

Closes wespreadjam#19
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.

[Integration] Instantly - Cold email automation

1 participant