PipedreamHQ / PipedreamHQ/pipedream
Salesforce 'New Object' trigger: Inconsistent event format between deploy-time and real-time events
- Dominant language
- JavaScript
- Stars
- 11.7k
- Forks
- 5.8k
- Avg merge
- 3d 10h
- Merged PRs (30d)
- 102
Description
## Description
The Salesforce "New Object" trigger (e.g., for Leads) emits events with inconsistent formats between:
1. **Historical events** emitted during initial deployment (`deploy()` hook)
2. **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
1. Create a workflow using the Salesforce "New Record (Instant)" trigger for the Lead object
2. Deploy the trigger
3. Observe the format of historical events emitted immediately after deployment
4. Create a new Lead in Salesforce
5. Observe the format of the real-time webhook event
6. 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)
```json
{
"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
```json
{
"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)
```javascript
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):
```javascript
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:
```javascript
const event = {
body: object, // No "New" wrapper
};
```
And update `generateWebhookMeta()` to read directly from `data.body`:
```javascript
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.mjs`
- `components/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`.
Contributor guide
Assessment
This issue has not been assessed yet.