-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Description
Description
The Salesforce "New Object" trigger (e.g., for Leads) emits events with inconsistent formats between:
- Historical events emitted during initial deployment (
deploy()hook) - Real-time events received via webhooks after deployment
This causes downstream workflows to fail or behave unexpectedly when they expect a consistent data structure.
Steps to Reproduce
- Create a workflow using the Salesforce "New Record (Instant)" trigger for the Lead object
- Deploy the trigger
- Observe the format of historical events emitted immediately after deployment
- Create a new Lead in Salesforce
- Observe the format of the real-time webhook event
- Compare the two formats
Expected Behavior
All events (both historical and real-time) should have the same consistent structure.
Actual Behavior
Historical Event Format (during deploy)
{
"body": {
"New": {
"attributes": {
"type": "Lead",
"url": "/services/data/v50.0/sobjects/Lead/00Q123456789ABC"
},
"Id": "00Q123456789ABC",
"LastName": "Doe",
"FirstName": "Jane",
"Company": "Example Corp",
"Status": "New",
"Email": "jane.doe@example.com",
"Phone": "555-0100",
"CreatedDate": "2025-11-01T12:00:00.000+0000",
"LastModifiedDate": "2025-11-01T12:00:00.000+0000"
},
"UserId": "00Q123456789ABC"
}
}Real-time Webhook Event Format
{
"body": {
"Id": "00Q123456789ABC",
"attributes": {
"type": "Lead",
"url": "/services/data/v50.0/sobjects/Lead/00Q123456789ABC"
},
"LastName": "Doe",
"FirstName": "Jane",
"Company": "Example Corp",
"Status": "New",
"Email": "jane.doe@example.com",
"Phone": "555-0100",
"CreatedDate": "2025-11-01T12:00:00.000+0000",
"LastModifiedDate": "2025-11-01T12:00:00.000+0000"
}
}Notice that historical events wrap the Salesforce object data inside a "New" property, while real-time webhook events place the data directly in the body.
Root Cause Analysis
The issue is in the deploy() hook of common-new-record.mjs:
File: components/salesforce_rest_api/sources/common/common-new-record.mjs (lines 19-26)
async deploy() {
// ... fetch recent items
for (const id of ids.slice(-25)) {
const object = await this.salesforce.getSObject(objectType, id);
const event = {
body: {
"New": object, // ← Manually wraps data in "New" property
"UserId": id,
},
};
this.processWebhookEvent(event);
}
}The deploy hook manually wraps the Salesforce object data in a "New" property to match what the generateWebhookMeta() method expects (line 83):
generateWebhookMeta(data) {
const nameField = this.getNameField();
const { New: newObject } = data.body; // ← Expects "New" property to exist
// ...
}However, the actual webhook events from the salesforce-webhooks npm package arrive with the data directly in the body without the "New" wrapper, causing the inconsistency.
Proposed Solutions
Option 1: Remove "New" wrapper from deploy hook (Recommended)
Modify the deploy hook to emit events in the same format as real webhooks:
const event = {
body: object, // No "New" wrapper
};And update generateWebhookMeta() to read directly from data.body:
generateWebhookMeta(data) {
const nameField = this.getNameField();
const {
CreatedDate: createdDate,
Id: id,
[nameField]: name,
} = data.body; // Read directly from body
// ...
}Option 2: Normalize webhook events
Add a wrapper to incoming webhook events to match the deploy format (though this seems less ideal).
Option 3: Support both formats
Make the event processing logic flexible enough to handle both formats (adds complexity).
Impact
- Users building workflows that access
event.body.New.*will work during testing (with historical events) but fail when real events arrive - Users accessing
event.body.*directly will experience the opposite problem - This creates confusion and unreliable workflows
Environment
- Component:
salesforce_rest_api - Affected files:
components/salesforce_rest_api/sources/common/common-new-record.mjscomponents/salesforce_rest_api/sources/common/common-webhook-methods.mjs
- Trigger: "New Record (Instant, of Selectable Type)" and all similar triggers
Additional Context
This issue likely affects other similar triggers that use the same pattern (e.g., new Case, new Opportunity, etc.) since they all inherit from common-new-record.mjs.