Skip to content

Commit 54b92af

Browse files
authored
Salesforce usability improvements (#12697)
1 parent 305c776 commit 54b92af

File tree

64 files changed

+9984
-2386
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+9984
-2386
lines changed
Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
1-
import salesForceRestApi from "../../salesforce_rest_api.app.mjs";
2-
import {
3-
removeNullEntries, toSingleLineString,
4-
} from "../../common/utils.mjs";
1+
import salesforce from "../../salesforce_rest_api.app.mjs";
52
import constants from "../../common/constants.mjs";
63

74
export default {
85
key: "salesforce_rest_api-add-contact-to-campaign",
96
name: "Add Contact to Campaign",
10-
description: toSingleLineString(`
11-
Adds an existing contact to an existing campaign.
12-
See [Event SObject](https://developer.salesforce.com/docs/atlas.en-us.228.0.object_reference.meta/object_reference/sforce_api_objects_campaignmember.htm)
13-
and [Create Record](https://developer.salesforce.com/docs/atlas.en-us.228.0.api_rest.meta/api_rest/dome_sobject_create.htm)
14-
`),
15-
version: "0.0.6",
7+
description: "Adds an existing contact to an existing campaign. [See the documentation](https://developer.salesforce.com/docs/atlas.en-us.228.0.object_reference.meta/object_reference/sforce_api_objects_campaignmember.htm)",
8+
version: "0.1.0",
169
type: "action",
1710
props: {
18-
salesForceRestApi,
11+
salesforce,
1912
campaignId: {
2013
propDefinition: [
21-
salesForceRestApi,
22-
"sobjectId",
14+
salesforce,
15+
"recordId",
2316
() => ({
24-
objectType: constants.OBJECT_TYPE.CAMPAIGN,
17+
objType: "Campaign",
18+
nameField: "Name",
2519
}),
2620
],
2721
label: "Campaign ID",
28-
description: "ID of the Campaign to which this Lead is associated.",
22+
description: "The Campaign to add a Contact to.",
2923
},
3024
contactId: {
3125
propDefinition: [
32-
salesForceRestApi,
33-
"sobjectId",
26+
salesforce,
27+
"recordId",
3428
() => ({
35-
objectType: constants.OBJECT_TYPE.CONTACT,
29+
objType: "Contact",
30+
nameField: "Name",
3631
}),
3732
],
3833
label: "Contact ID",
39-
description: "ID of the Contact who is associated with a Campaign.",
34+
description: "The Contact to add to the selected Campaign.",
4035
},
4136
},
4237
async run({ $ }) {
43-
const data = removeNullEntries({
44-
CampaignId: this.campaignId,
45-
ContactId: this.contactId,
38+
const {
39+
salesforce, campaignId, contactId,
40+
} = this;
41+
const response = await salesforce.createObject({
42+
$,
43+
objectType: constants.OBJECT_TYPE.CAMPAIGN_MEMBER,
44+
data: {
45+
CampaignId: campaignId,
46+
ContactId: contactId,
47+
},
4648
});
47-
const response = await this.salesForceRestApi
48-
.createObject(constants.OBJECT_TYPE.CAMPAIGN_MEMBER, data);
49-
response && $.export("$summary", "Successfully added contact to campaign");
49+
$.export("$summary", `Successfully added contact (ID: ${contactId}) to campaign (ID: ${campaignId})`);
5050
return response;
5151
},
5252
};
Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,52 @@
1-
import salesForceRestApi from "../../salesforce_rest_api.app.mjs";
2-
import {
3-
removeNullEntries, toSingleLineString,
4-
} from "../../common/utils.mjs";
1+
import salesforce from "../../salesforce_rest_api.app.mjs";
52
import constants from "../../common/constants.mjs";
63

74
export default {
85
key: "salesforce_rest_api-add-lead-to-campaign",
96
name: "Add Lead to Campaign",
10-
description: toSingleLineString(`
11-
Adds an existing lead to an existing campaign.
12-
See [Event SObject](https://developer.salesforce.com/docs/atlas.en-us.228.0.object_reference.meta/object_reference/sforce_api_objects_campaignmember.htm)
13-
and [Create Record](https://developer.salesforce.com/docs/atlas.en-us.228.0.api_rest.meta/api_rest/dome_sobject_create.htm)
14-
`),
15-
version: "0.0.6",
7+
description: "Adds an existing lead to an existing campaign. [See the documentation](https://developer.salesforce.com/docs/atlas.en-us.228.0.object_reference.meta/object_reference/sforce_api_objects_campaignmember.htm)",
8+
version: "0.1.0",
169
type: "action",
1710
props: {
18-
salesForceRestApi,
11+
salesforce,
1912
campaignId: {
2013
propDefinition: [
21-
salesForceRestApi,
22-
"sobjectId",
14+
salesforce,
15+
"recordId",
2316
() => ({
24-
objectType: constants.OBJECT_TYPE.CAMPAIGN,
17+
objType: "Campaign",
18+
nameField: "Name",
2519
}),
2620
],
2721
label: "Campaign ID",
28-
description: "ID of the Campaign to which this Lead is associated.",
22+
description: "The Campaign to add a Lead to.",
2923
},
3024
leadId: {
3125
propDefinition: [
32-
salesForceRestApi,
33-
"sobjectId",
26+
salesforce,
27+
"recordId",
3428
() => ({
35-
objectType: constants.OBJECT_TYPE.LEAD,
29+
objType: "Lead",
30+
nameField: "Name",
3631
}),
3732
],
3833
label: "Lead ID",
39-
description: "ID of the Lead who is associated with a Campaign.",
34+
description: "The Lead to add to the selected Campaign.",
4035
},
4136
},
4237
async run({ $ }) {
43-
const data = removeNullEntries({
44-
CampaignId: this.campaignId,
45-
LeadId: this.leadId,
38+
const {
39+
salesforce, campaignId, leadId,
40+
} = this;
41+
const response = await salesforce.createObject({
42+
$,
43+
objectType: constants.OBJECT_TYPE.CAMPAIGN_MEMBER,
44+
data: {
45+
CampaignId: campaignId,
46+
LeadId: leadId,
47+
},
4648
});
47-
const response = await this.salesForceRestApi.createObject("CampaignMember", data);
48-
response && $.export("$summary", "Successfully added lead to campaign");
49+
$.export("$summary", `Successfully added lead (ID: ${leadId}) to campaign (ID: ${campaignId})`);
4950
return response;
5051
},
5152
};
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { ConfigurationError } from "@pipedream/platform";
2+
import salesforce from "../../salesforce_rest_api.app.mjs";
3+
import { getAdditionalFields } from "../../common/props-utils.mjs";
4+
5+
export const additionalFields = {
6+
type: "object",
7+
label: "Additional Fields",
8+
description:
9+
"Other fields to set for this record. Values will be parsed as JSON where applicable.",
10+
optional: true,
11+
};
12+
13+
export function getProps({
14+
objType,
15+
createOrUpdate = "create",
16+
docsLink = "https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_concepts.htm",
17+
showDateInfo = false,
18+
}) {
19+
let { initialProps } = objType;
20+
if (initialProps && createOrUpdate === "update") {
21+
initialProps = Object.fromEntries(
22+
Object.entries(initialProps).map(([
23+
key,
24+
value,
25+
]) => [
26+
key,
27+
{
28+
...value,
29+
optional: true,
30+
},
31+
]),
32+
);
33+
}
34+
35+
return {
36+
salesforce,
37+
...showDateInfo && {
38+
dateInfo: {
39+
type: "alert",
40+
alertType: "warning",
41+
content: "Date fields should be a [valid date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format) or a Unix timestamp in milliseconds. Example values: `2022-01-15T18:30:00.000Z` or `1642271400000`.",
42+
},
43+
},
44+
...objType[createOrUpdate === "create"
45+
? "createProps"
46+
: "updateProps"],
47+
...initialProps,
48+
docsInfo: {
49+
type: "alert",
50+
alertType: "info",
51+
content: `[See the documentation](${docsLink}) for more information on available fields.`,
52+
},
53+
useAdvancedProps: {
54+
propDefinition: [
55+
salesforce,
56+
"useAdvancedProps",
57+
],
58+
},
59+
};
60+
}
61+
62+
export default {
63+
methods: {
64+
getObjectType() {
65+
return "";
66+
},
67+
getAdvancedProps() {
68+
return {};
69+
},
70+
getAdditionalFields,
71+
formatDateTimeProps(props = {}) {
72+
// https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_valid_date_formats.htm
73+
return Object.fromEntries(Object.entries(props).filter(([
74+
, value,
75+
]) => value !== undefined)
76+
.map(([
77+
key,
78+
value,
79+
]) => {
80+
const numValue = Number(value);
81+
const date = new Date(Number.isNaN(numValue)
82+
? value
83+
: numValue);
84+
if (Number.isNaN(date.valueOf())) {
85+
throw new ConfigurationError(`Invalid date format for prop \`${key}\`. Please provide a valid date format.`);
86+
}
87+
return [
88+
key,
89+
date.toISOString(),
90+
];
91+
}));
92+
},
93+
},
94+
async additionalProps() {
95+
const objectType = this.getObjectType();
96+
if (!this.useAdvancedProps || !objectType) return {};
97+
98+
const fields = (await this.salesforce.getFieldsForObjectType(objectType));
99+
const fieldNames = fields.map((f) => f.name);
100+
const filteredProps = Object.fromEntries(Object.entries(this.getAdvancedProps()).filter(([
101+
key,
102+
]) => fieldNames.includes(key) || key[0] === key[0].toLowerCase()));
103+
return {
104+
...filteredProps,
105+
additionalFields,
106+
};
107+
},
108+
};

components/salesforce_rest_api/actions/common/base.mjs

Lines changed: 0 additions & 18 deletions
This file was deleted.

components/salesforce_rest_api/actions/convert-soap-xml-to-json/convert-soap-xml-to-json.mjs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@ export default {
55
key: "salesforce_rest_api-convert-soap-xml-to-json",
66
name: "Convert SOAP XML Object to JSON",
77
description: "Converts a SOAP XML Object received from Salesforce to JSON",
8-
version: "0.0.5",
8+
version: "0.0.6",
99
type: "action",
1010
props: {
1111
salesforce_rest_api,
12+
infoBox: {
13+
type: "alert",
14+
alertType: "info",
15+
content: `This action is useful in conjunction with Salesforce Flow Builder, and is primarily used if Instant triggers are not working for your use case.
16+
\\
17+
[See the documentation](https://pipedream.com/apps/salesforce-rest-api#troubleshooting) for more details.`,
18+
},
1219
xml: {
1320
type: "string",
1421
label: "XML Soap Object",
@@ -17,14 +24,14 @@ export default {
1724
extractNotificationOnly: {
1825
type: "boolean",
1926
label: "Extract Notifications Only",
20-
description: "Extracts only the notification parts from the XML. Default: `true`.",
27+
description: "Whether to extract only the notification parts from the XML. Default: `true`.",
2128
optional: true,
2229
default: true,
2330
},
2431
failOnError: {
2532
type: "boolean",
2633
label: "Fail on Error",
27-
description: "If should fail on error when extracting notifications. Default: `false`.",
34+
description: "Whether the action should fail if an error occurs when extracting notifications. Default: `false`.",
2835
optional: true,
2936
default: false,
3037
},
@@ -44,6 +51,7 @@ export default {
4451
try {
4552
const notifications = json.elements[0].elements[0].elements[0].elements
4653
.filter(({ name }) => name === "Notification");
54+
$.export("$summary", "Successfully converted to JSON and extracted notifications");
4755
return {
4856
notifications,
4957
};

0 commit comments

Comments
 (0)