Skill Tracer
Skills › Knowledge Work Plugins › crm-autopilot › salesforce-fields.md

salesforce-fields.md

122 lines · small-business/skills/crm-autopilot/reference/salesforce-fields.md at 2574e29

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Salesforce objects, fields, and activity types
2
3The Salesforce objects and fields the `crm-autopilot` skill reads and writes,
4and how it reaches them. Only the fields listed here are in scope; everything
5else in the org is left alone.
6
7**Source of these names.** Standard-object API names, plus the Headless 360
8tool contract Salesforce published. Any operation name `discover` returns is
9the truth over this file.
11---

Salesforce objects, fields, and activity types

The Salesforce objects and fields the crm-autopilot skill reads and writes, and how it reaches them. Only the fields listed here are in scope; everything else in the org is left alone.

Source of these names. Standard-object API names, plus the Headless 360 tool contract Salesforce published. Any operation name discover returns is the truth over this file.


Raw lines 1 to 12
13## How the connector works
15Salesforce is reached through the Headless 360 server, which the owner adds
16as a custom connector (it has a per-org address and its own OAuth client, so
17it is not in the plugin manifest). It exposes four tools, and every step in
18this skill is the same three-beat flow:
201. `discover` — say what you need in plain words ("find a contact by email",
21 "open opportunities with no recent activity", "log a completed call").
22 It returns ranked operations.
232. `describe` — the one you pick. Read its parameters and any ordered steps
24 before calling. Never skip this: parameter names are the operation's,
25 not this file's.
263. `dispatch_readonly` for any read; `dispatch` only for the one write the
27 owner approved. `dispatch` runs as the signed-in user with that user's
28 access, and there is no delete operation, which matches this skill's
29 first gate.
31Shape notes are in `../../../shared/connector-call-shapes.md`.
33---

How the connector works

Salesforce is reached through the Headless 360 server, which the owner adds as a custom connector (it has a per-org address and its own OAuth client, so it is not in the plugin manifest). It exposes four tools, and every step in this skill is the same three-beat flow:

  1. discover — say what you need in plain words ("find a contact by email", "open opportunities with no recent activity", "log a completed call"). It returns ranked operations.
  2. describe — the one you pick. Read its parameters and any ordered steps before calling. Never skip this: parameter names are the operation's, not this file's.
  3. dispatch_readonly for any read; dispatch only for the one write the owner approved. dispatch runs as the signed-in user with that user's access, and there is no delete operation, which matches this skill's first gate.

Shape notes are in ../../../shared/connector-call-shapes.md.


Raw lines 13 to 34
Starts an agent dispatch :26
35## Contacts — write (`Contact`)
37| Field | Usage |
38|---|---|
39| `Email` | Primary identifier for lookup and dedupe. Always set on creation. |
40| `FirstName` | From the email signature or calendar invite if available. |
41| `LastName` | Required by Salesforce. From the signature or invite; if unknown, ask before creating — do not invent one. |
42| `AccountId` | Set only when the company is unambiguous (an existing Account matching the email domain). Otherwise leave blank and say so. |
44Do not write any other contact field. `OwnerId`, `LeadSource`, and any custom
45field are user-managed.

Contacts — write (Contact)

FieldUsage
EmailPrimary identifier for lookup and dedupe. Always set on creation.
FirstNameFrom the email signature or calendar invite if available.
LastNameRequired by Salesforce. From the signature or invite; if unknown, ask before creating — do not invent one.
AccountIdSet only when the company is unambiguous (an existing Account matching the email domain). Otherwise leave blank and say so.

Do not write any other contact field. OwnerId, LeadSource, and any custom field are user-managed.

Raw lines 35 to 46
47## Contacts — read (for lookup)
49| Field | Usage |
50|---|---|
51| `Email` | Search key. Salesforce email matching is case-insensitive. |
52| `FirstName` · `LastName` · `Account.Name` | Shown to the owner during ambiguity resolution. |
53| `Id` | The `WhoId` on any activity logged against this person. |
55A person may exist as a `Lead` rather than a `Contact` (unconverted). Search
56both by email, with `IsConverted = false` on the Lead side — a converted lead's
57row persists and would otherwise match beside the Contact it became. A match
58on an unconverted `Lead` is reported as a lead, and the activity is
59logged with `WhoId` = the lead's `Id` **and no `WhatId`** — Salesforce
60rejects an activity that names a Lead and an Opportunity together. Say the
61deal is unset and that it attaches once the lead is converted.

Contacts — read (for lookup)

FieldUsage
EmailSearch key. Salesforce email matching is case-insensitive.
FirstName · LastName · Account.NameShown to the owner during ambiguity resolution.
IdThe WhoId on any activity logged against this person.

A person may exist as a Lead rather than a Contact (unconverted). Search both by email, with IsConverted = false on the Lead side — a converted lead's row persists and would otherwise match beside the Contact it became. A match on an unconverted Lead is reported as a lead, and the activity is logged with WhoId = the lead's Id **and no WhatId** — Salesforce rejects an activity that names a Lead and an Opportunity together. Say the deal is unset and that it attaches once the lead is converted.

Raw lines 47 to 62
63## Opportunities — read (all cleanup and resolution paths)
65| Field | Usage |
66|---|---|
67| `Name` | Shown to the owner; fuzzy-matched against the email subject or meeting title |
68| `StageName` | Read-only during cleanup — flag discrepancies, never change |
69| `Amount` | Read during cleanup; flag if a recent email or meeting implies a change |
70| `CloseDate` | Read during cleanup; flag if in the past on an open opportunity |
71| `NextStep` | Read, and propose updates during cleanup |
72| `OwnerId` → `Owner.Name` | Shown to the owner; never changed |
73| `IsClosed` | Open-pipeline filter |
74| `LastActivityDate` | Stale-deal detection. Set by completed Tasks and Events; **null on a record with no logged activity ever** — treat null as the quietest deal, not as "no data" |
75| `OpportunityContactRoles` (subquery) | Whether the email or meeting participants are on the opportunity. A child object, not a column: `SELECT Id, (SELECT ContactId, Role FROM OpportunityContactRoles) FROM Opportunity WHERE Id = ...` |

Opportunities — read (all cleanup and resolution paths)

FieldUsage
NameShown to the owner; fuzzy-matched against the email subject or meeting title
StageNameRead-only during cleanup — flag discrepancies, never change
AmountRead during cleanup; flag if a recent email or meeting implies a change
CloseDateRead during cleanup; flag if in the past on an open opportunity
NextStepRead, and propose updates during cleanup
OwnerId → Owner.NameShown to the owner; never changed
IsClosedOpen-pipeline filter
LastActivityDateStale-deal detection. Set by completed Tasks and Events; null on a record with no logged activity ever — treat null as the quietest deal, not as "no data"
OpportunityContactRoles (subquery)Whether the email or meeting participants are on the opportunity. A child object, not a column: SELECT Id, (SELECT ContactId, Role FROM OpportunityContactRoles) FROM Opportunity WHERE Id = ...
Raw lines 63 to 76
77## Opportunities — write (cleanup path only, with approval)
79| Field | Rule |
80|---|---|
81| `NextStep` | Proposed from the extracted next step; written only on approval |
82| `CloseDate` | Proposed when the evidence names a date; written only on approval |
83| `StageName`, `Amount` | **Never written by this skill.** Flag and defer; stage drives the forecast the owner reports to other people |
85Never create an Opportunity unprompted. Never close one.

Opportunities — write (cleanup path only, with approval)

FieldRule
NextStepProposed from the extracted next step; written only on approval
CloseDateProposed when the evidence names a date; written only on approval
StageName, AmountNever written by this skill. Flag and defer; stage drives the forecast the owner reports to other people

Never create an Opportunity unprompted. Never close one.

Raw lines 77 to 86
87## Activities — write
89| Activity | Object | Fields |
90|---|---|---|
91| Call | `Task` | `Subject`, `Description` (the summary, never the transcript), `ActivityDate` (the real date), `Status` = Completed, `TaskSubtype` = Call, `WhoId` (contact or lead), `WhatId` (opportunity) |
92| Email | `Task` | Same, `TaskSubtype` = Email |
93| Meeting | `Event` | `Subject`, `Description`, `StartDateTime` and `EndDateTime` (the real times), `WhoId`, `WhatId` |
95`WhoId` takes a Contact or Lead `Id`; `WhatId` takes an Opportunity or Account
96`Id`. Either may stand alone: a deal-only activity (`WhatId` set, no `WhoId`) is
97valid, and so is a contact-only one. The single constraint is that a Lead
98`WhoId` requires an empty `WhatId`. An activity with neither is orphaned and
99invisible from the deal; if the deal cannot be resolved, log against the
100contact and say the deal is unset.

Activities — write

ActivityObjectFields
CallTaskSubject, Description (the summary, never the transcript), ActivityDate (the real date), Status = Completed, TaskSubtype = Call, WhoId (contact or lead), WhatId (opportunity)
EmailTaskSame, TaskSubtype = Email
MeetingEventSubject, Description, StartDateTime and EndDateTime (the real times), WhoId, WhatId

WhoId takes a Contact or Lead Id; WhatId takes an Opportunity or Account Id. Either may stand alone: a deal-only activity (WhatId set, no WhoId) is valid, and so is a contact-only one. The single constraint is that a Lead WhoId requires an empty WhatId. An activity with neither is orphaned and invisible from the deal; if the deal cannot be resolved, log against the contact and say the deal is unset.

Raw lines 87 to 101
102## Association rules
104- A contact joins an opportunity through `OpportunityContactRole`; propose
105 adding a participant who is on the email or meeting but not on the
106 opportunity, never add silently.
107- A contact's company is `AccountId`. If the email domain matches exactly one
108 Account, propose it; if it matches none or several, leave it blank and say
109 so.
111---

Association rules

  • A contact joins an opportunity through OpportunityContactRole; propose adding a participant who is on the email or meeting but not on the opportunity, never add silently.
  • A contact's company is AccountId. If the email domain matches exactly one Account, propose it; if it matches none or several, leave it blank and say so.

Raw lines 102 to 112
113## What the Salesforce path cannot do here
115- **Delete.** No operation exists; the skill never wanted one.
116- **Arbitrary joins in one read.** SOQL covers parent lookups (contact →
117 account, opportunity → account) and one level of child subquery (an
118 opportunity's contact roles); anything wider is two reads, and the report
119 says so.
120- **Bypass the user's own access.** `dispatch` runs as the signed-in owner.
121 A field they cannot edit in Salesforce cannot be edited from here either,
122 and the error is reported as that, not as a plugin failure.

What the Salesforce path cannot do here

  • Delete. No operation exists; the skill never wanted one.
  • Arbitrary joins in one read. SOQL covers parent lookups (contact → account, opportunity → account) and one level of child subquery (an opportunity's contact roles); anything wider is two reads, and the report says so.
  • Bypass the user's own access. dispatch runs as the signed-in owner. A field they cannot edit in Salesforce cannot be edited from here either, and the error is reported as that, not as a plugin failure.
Raw lines 113 to 122
Starts an agent dispatch :120