@kody/salesforce
Salesforce REST helpers for identity, SOQL, multi-org routing, and error investigation.
AGENTS.md
144 lines · 4.3 KB · Markdown@kody/salesforce — agent notes
Human setup and intent live in README.md. This file is for
agents: imports, smoke/dryRun execute snippets, and edge cases. Never paste
OAuth client secrets or access tokens. Do not disable live webhooks or jobs.
Auth
| Item | Value |
|---|---|
| Integration | salesforce (or integrationName / provider=salesforce-*) |
| Login hosts | login.salesforce.com (prod) / test.salesforce.com (sandbox) |
| Instance host | exact org host from userinfo (must be added to requiredHosts) |
| Scopes | api, refresh_token, offline_access (+ more only if needed) |
Import paths
| Export | Import |
|---|---|
| root overview | kody:@kody/salesforce |
| smoke-test | kody:@kody/salesforce/smoke-test |
| get-user-info | kody:@kody/salesforce/get-user-info |
| list-orgs | kody:@kody/salesforce/list-orgs |
| resolve-org | kody:@kody/salesforce/resolve-org |
| query | kody:@kody/salesforce/query |
| list-sobjects | kody:@kody/salesforce/list-sobjects |
| describe-sobject | kody:@kody/salesforce/describe-sobject |
| get-record | kody:@kody/salesforce/get-record |
| triage-error | kody:@kody/salesforce/triage-error |
| create-record | kody:@kody/salesforce/create-record |
| update-record | kody:@kody/salesforce/update-record |
| delete-record | kody:@kody/salesforce/delete-record |
| request | kody:@kody/salesforce/request |
Prefer static kody:@kody/salesforce/... imports from execute. Do not lead
with packages.invoke.
Smoke test (read-only)
import smokeTest from 'kody:@kody/salesforce/smoke-test'
export default async function main() {
return await smokeTest()
// verifies OAuth without returning profile PII
}Common snippets
import query from 'kody:@kody/salesforce/query'
export default async function main() {
return await query({
q: 'SELECT Id, Name, Email FROM Contact ORDER BY LastModifiedDate DESC LIMIT 10',
// integrationName: 'salesforce-sandbox', // optional; defaults to 'salesforce'
})
}import triageError from 'kody:@kody/salesforce/triage-error'
export default async function main() {
return await triageError({
error: [
{
message: 'Required fields are missing: [LastName]',
errorCode: 'REQUIRED_FIELD_MISSING',
fields: ['LastName'],
},
],
sobject: 'Lead',
organizationId: '00D000000000001AAA',
orgMap: { '00D000000000001AAA': 'salesforce-acme' },
dryRun: true,
})
}Org map (webhooks / triage)
Persist the map in a private package — live imports of @kody/salesforce
cannot use packageStorage:
import { packageStorage } from 'kody:runtime'
import listOrgs from 'kody:@kody/salesforce/list-orgs'
import triageError from 'kody:@kody/salesforce/triage-error'
export async function syncOrgMap() {
const { map } = await listOrgs()
await packageStorage().set('org-map', map)
return map
}
export async function handleWebhook(input) {
const orgMap = (await packageStorage().get('org-map')) ?? {}
return triageError({
error: input.request?.json ?? input,
orgMap,
})
}Prefer one minted webhook URL per client when Salesforce can be pointed per org. One shared URL is fine only if the handler fails closed on unknown org ids.
dryRun / confirm (writes)
Mutating helpers require confirm: true. Pass dryRun: true to inspect a
request without sending it. The generic request helper treats GET requests and
known read-only paths as safe; all other methods require confirmation.
triage-error is read-only: it never writes to Salesforce. Pass dryRun: true
to skip org lookups and return the local briefing plus suggested queries.
import createRecord from 'kody:@kody/salesforce/create-record'
export default async function main() {
return await createRecord({
sobject: 'Lead',
fields: {
FirstName: 'Ada',
LastName: 'Lovelace',
Company: 'Analytical Engines',
Email: 'ada@example.com',
},
dryRun: true,
})
}Set confirm: true only after the user has explicitly approved the exact
mutation target and field values.
Edge cases / fork notes
- After first successful identity call, add the exact instance host to
requiredHosts— wildcards in the connect URL are not expanded. - Pass
integrationNameon every call when more than one org is connected. - Never paste Salesforce Connected App secrets or access tokens into chat or logs.