Skip to content

feat(console): enrich Salesforce leads with Console account status - #54387

Merged
Slickstef11 merged 5 commits into
devfrom
salesforce-lead-sync
Oct 14, 2026
Merged

Slickstef11 merged 5 commits into
devfrom
salesforce-lead-sync

Conversation

@Slickstef11

@Slickstef11 Slickstef11 commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Issue for this PR

No issue; internal sales tooling. Replaces #54255, which was closed when dev moved to V2.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Sales needs to tell Enterprise form inquiries apart from Console signups in Salesforce, and to see whether someone already has a Console account.

  • Every Enterprise inquiry gets the source enterprise website form, from both the current opencode.ai/enterprise page and the new Console page. Monthly spend goes only in its own field, and Description is exactly the visitor's message.
  • The form asks Console whether the email has an account and fills three Console fields on the Lead. If Console errors or takes over 3 seconds, the Lead is still created with those fields blank.
  • New /api/console-signup endpoint, called by Console after a verified signup. It updates a matching Contact or Lead without changing its original source, or creates a console signup Lead. Company is the email domain, or Individual for personal email providers.
  • salesforce/ holds the field, layout, permission, and Lead-conversion metadata (already applied to our Salesforce org).

Both directions use a shared server token. Set the CONSOLE_CRM_TOKEN SST secret (same value as Console's) before deploying. Companion Console PR: anomalyco/opencode-console#3392.

How did you verify your code works?

  • bun test (Salesforce, signup, and CLI-response tests) and bun typecheck in packages/console/app; bun run check passes.
  • Before the V2 move, ran the form and signup flows locally against our Salesforce org.
  • Checked that a Console lookup that errors or hangs still creates the Lead.

Screenshots / recordings

No UI changes.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One of the four promised behaviours doesn't work yet: Enterprise form Leads still get LeadSource: "Website". I tested the handlers directly (no Salesforce org or Console lookup available).

How I checked

  • The three new test files pass (25 tests), and typecheck passes in packages/console/app.
  • I sent the exact body the /enterprise page posts through handleEnterpriseRequest, with the Console lookup set to fail. It returned 200 and the Lead was created with Description set to just the message, but with LeadSource: "Website". Details inline.

Public API: OpenCode's public API (SDK, server, plugins, config, CLI) is unchanged. On the Console website only, this adds a token-protected POST /api/console-signup endpoint, the CONSOLE_CRM_TOKEN secret and the CONSOLE_CRM_LOOKUP_URL link. The new endpoint needs Console to send a matching token, so the secret must be set on both sides before deploying.

Other concerns, most important first

  • Lead source: the form never sends leadSource (see inline).
  • Dev-only code in production: the dev-only hooks in the production handler and the sf CLI dev server (see inline).
  • Tests: they could be much smaller.
    • console-signup.test.ts makes its checks inside a fake Salesforce HTTP server and runs a 14-row table of email providers.
    • salesforce.test.ts starts a real server and rewrites process.env when the file loads.
    • Pure tests of syncConsoleAccount with a recording request function, plus a few company-name cases, would cover the same ground.
  • Salesforce metadata: salesforce/ checks in full copies of the org's Lead/Contact layouts and LeadSource values, and it's already applied to the org. That's a lot of org-specific config to keep in this open-source repo. Consider keeping only the field and permission metadata, or moving it next to the Console repo.

email: body.email,
phone: body.phone,
inferenceSpend: inferenceSpend?.salesforceValue,
leadSource: body.leadSource === "enterprise website form" ? body.leadSource : undefined,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Enterprise form Leads will still get LeadSource: "Website". This line only uses enterprise website form when the request body says so, and routes/enterprise/index.tsx posts formData(), which has no leadSource. Nothing else in the repo calls /api/enterprise.

I confirmed it by running the handler with the page's exact body: the payload came out with LeadSource: "Website". Since this endpoint only serves the Enterprise form, could it set the source on the server and drop the field from the request body? Then clients can't control the value either.

export async function handleEnterpriseRequest(
request: Request,
options: {
salesforceSubmit?: (payload: Record<string, unknown>) => Promise<boolean>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

salesforceSubmit and notifications exist only for script/dev-enterprise.ts and the tests, but they're now part of the production handler. dev-enterprise.ts also brings a sf-CLI transport (salesforce-cli-response.ts plus its test) and a new dev:enterprise script. That's a second way to run the endpoint, and it needs its own upkeep.

Could this PR keep only accountLookup (or no options at all) and leave the local sf dev server out? The syncConsoleAccount(account, request) split already makes the logic testable without these hooks.

@Slickstef11
Slickstef11 merged commit 07c0ff5 into dev Oct 14, 2026
9 checks passed
@Slickstef11
Slickstef11 deleted the salesforce-lead-sync branch October 14, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant