@pipedream/salesforce_rest_api 1.11.8 → 1.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/actions/common/base-create-update.mjs +13 -6
  2. package/actions/create-account/create-account.mjs +1 -1
  3. package/actions/create-attachment/create-attachment.mjs +1 -1
  4. package/actions/create-campaign/create-campaign.mjs +1 -1
  5. package/actions/create-case/create-case.mjs +1 -1
  6. package/actions/create-casecomment/create-casecomment.mjs +1 -1
  7. package/actions/create-contact/create-contact.mjs +1 -1
  8. package/actions/create-content-note/create-content-note.mjs +1 -1
  9. package/actions/create-crm-record/create-crm-record.mjs +62 -0
  10. package/actions/create-event/create-event.mjs +1 -1
  11. package/actions/create-lead/create-lead.mjs +1 -1
  12. package/actions/create-note/create-note.mjs +1 -1
  13. package/actions/create-opportunity/create-opportunity.mjs +2 -1
  14. package/actions/create-record/create-record.mjs +1 -1
  15. package/actions/create-task/create-task.mjs +1 -1
  16. package/actions/create-user/create-user.mjs +1 -1
  17. package/actions/delete-crm-record/delete-crm-record.mjs +52 -0
  18. package/actions/describe-object/describe-object.mjs +86 -0
  19. package/actions/get-related-records/get-related-records.mjs +80 -0
  20. package/actions/get-user-info/get-user-info.mjs +44 -0
  21. package/actions/list-objects/list-objects.mjs +61 -0
  22. package/actions/soql-query/soql-query.mjs +87 -0
  23. package/actions/text-search/text-search.mjs +89 -0
  24. package/actions/update-account/update-account.mjs +1 -1
  25. package/actions/update-contact/update-contact.mjs +1 -1
  26. package/actions/update-content-note/update-content-note.mjs +1 -1
  27. package/actions/update-crm-record/update-crm-record.mjs +60 -0
  28. package/actions/update-email-template/update-email-template.mjs +1 -1
  29. package/actions/update-note/update-note.mjs +1 -1
  30. package/actions/update-opportunity/update-opportunity.mjs +2 -1
  31. package/actions/update-record/update-record.mjs +1 -1
  32. package/actions/upsert-record/upsert-record.mjs +1 -1
  33. package/package.json +4 -4
@@ -16,6 +16,7 @@ export function getProps({
16
16
  docsLink = "https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_concepts.htm",
17
17
  showDocsInfo = true,
18
18
  showDateInfo = false,
19
+ advancedProps = true,
19
20
  }) {
20
21
  let { initialProps } = objType;
21
22
  if (initialProps && createOrUpdate === "update") {
@@ -53,12 +54,18 @@ export function getProps({
53
54
  ? "createProps"
54
55
  : "updateProps"],
55
56
  ...initialProps,
56
- useAdvancedProps: {
57
- propDefinition: [
58
- salesforce,
59
- "useAdvancedProps",
60
- ],
61
- },
57
+ ...advancedProps
58
+ ? {
59
+ useAdvancedProps: {
60
+ propDefinition: [
61
+ salesforce,
62
+ "useAdvancedProps",
63
+ ],
64
+ },
65
+ }
66
+ : {
67
+ ...objType.extraProps,
68
+ },
62
69
  };
63
70
  }
64
71
 
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-create-account",
9
9
  name: "Create Account",
10
10
  description: `Creates a Salesforce account. [See the documentation](${docsLink})`,
11
- version: "0.3.5",
11
+ version: "0.3.6",
12
12
  annotations: {
13
13
  destructiveHint: false,
14
14
  openWorldHint: true,
@@ -18,7 +18,7 @@ export default {
18
18
  key: "salesforce_rest_api-create-attachment",
19
19
  name: "Create Attachment",
20
20
  description: `Creates an Attachment on a parent object. [See the documentation](${docsLink})`,
21
- version: "0.5.7",
21
+ version: "0.5.8",
22
22
  annotations: {
23
23
  destructiveHint: false,
24
24
  openWorldHint: true,
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-create-campaign",
9
9
  name: "Create Campaign",
10
10
  description: `Creates a marketing campaign. [See the documentation](${docsLink})`,
11
- version: "0.3.5",
11
+ version: "0.3.6",
12
12
  annotations: {
13
13
  destructiveHint: false,
14
14
  openWorldHint: true,
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-create-case",
9
9
  name: "Create Case",
10
10
  description: `Creates a Case, which represents a customer issue or problem. [See the documentation](${docsLink})`,
11
- version: "0.3.5",
11
+ version: "0.3.6",
12
12
  annotations: {
13
13
  destructiveHint: false,
14
14
  openWorldHint: true,
@@ -17,7 +17,7 @@ export default {
17
17
  key: "salesforce_rest_api-create-casecomment",
18
18
  name: "Create Case Comment",
19
19
  description: `Creates a Case Comment on a selected Case. [See the documentation](${docsLink})`,
20
- version: "0.3.5",
20
+ version: "0.3.6",
21
21
  annotations: {
22
22
  destructiveHint: false,
23
23
  openWorldHint: true,
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-create-contact",
9
9
  name: "Create Contact",
10
10
  description: `Creates a contact. [See the documentation](${docsLink})`,
11
- version: "0.3.5",
11
+ version: "0.3.6",
12
12
  annotations: {
13
13
  destructiveHint: false,
14
14
  openWorldHint: true,
@@ -28,7 +28,7 @@ export default {
28
28
  key: "salesforce_rest_api-create-content-note",
29
29
  name: "Create Content Note",
30
30
  description: `Creates a content note. [See the documentation](${docsLink}) and [Set Up Notes](https://help.salesforce.com/s/articleView?id=sales.notes_admin_setup.htm&type=5).`,
31
- version: "0.0.6",
31
+ version: "0.0.7",
32
32
  annotations: {
33
33
  destructiveHint: false,
34
34
  openWorldHint: true,
@@ -0,0 +1,62 @@
1
+ // vandelay-test-dr
2
+ import salesforce from "../../salesforce_rest_api.app.mjs";
3
+
4
+ export default {
5
+ key: "salesforce_rest_api-create-crm-record",
6
+ name: "Create Record",
7
+ description:
8
+ "Create a new Salesforce record of any object type."
9
+ + " Use **Describe Object** first if you're unsure what fields are available or required."
10
+ + " For picklist fields, use the API value from **Describe Object**, not the display label."
11
+ + "\n\n"
12
+ + "**Common required fields:**"
13
+ + "\n- Account: `Name`"
14
+ + "\n- Contact: `LastName`"
15
+ + "\n- Lead: `LastName`, `Company`"
16
+ + "\n- Opportunity: `Name`, `StageName`, `CloseDate`"
17
+ + "\n- Case: `Subject`"
18
+ + "\n- Task: `Subject`"
19
+ + "\n- Event: `Subject`, `StartDateTime`, `EndDateTime`"
20
+ + "\n\n"
21
+ + "To add a Contact/Lead to a Campaign, create a CampaignMember:"
22
+ + " `{\"CampaignId\": \"701xxx\", \"ContactId\": \"003xxx\"}` or `{\"CampaignId\": \"701xxx\", \"LeadId\": \"00Qxxx\"}`.",
23
+ version: "0.0.1",
24
+ type: "action",
25
+ annotations: {
26
+ readOnlyHint: false,
27
+ destructiveHint: false,
28
+ openWorldHint: true,
29
+ },
30
+ props: {
31
+ salesforce,
32
+ objectType: {
33
+ type: "string",
34
+ label: "Object Type",
35
+ description:
36
+ "The Salesforce object API name (e.g. `Account`, `Contact`, `Lead`, `Opportunity`, `Case`, `Task`, `Event`)."
37
+ + " Use **List Objects** to discover custom object types (ending in `__c`).",
38
+ },
39
+ properties: {
40
+ type: "object",
41
+ label: "Record Properties",
42
+ description:
43
+ "Field name → value pairs for the new record."
44
+ + " Example for Contact: `{\"FirstName\": \"Jane\", \"LastName\": \"Doe\", \"Email\": \"jane@example.com\", \"AccountId\": \"001xxx\"}`."
45
+ + " Example for Opportunity: `{\"Name\": \"Acme Deal\", \"StageName\": \"Prospecting\", \"CloseDate\": \"2025-12-31\", \"Amount\": 50000}`."
46
+ + " Use **Describe Object** to discover valid field names and picklist values.",
47
+ },
48
+ },
49
+ async run({ $ }) {
50
+ const response = await this.salesforce.createRecord(this.objectType, {
51
+ $,
52
+ data: this.properties,
53
+ });
54
+
55
+ $.export(
56
+ "$summary",
57
+ `Created ${this.objectType} with ID ${response.id}`,
58
+ );
59
+
60
+ return response;
61
+ },
62
+ };
@@ -9,7 +9,7 @@ export default {
9
9
  key: "salesforce_rest_api-create-event",
10
10
  name: "Create Event",
11
11
  description: `Creates an event. [See the documentation](${docsLink})`,
12
- version: "0.3.5",
12
+ version: "0.3.6",
13
13
  annotations: {
14
14
  destructiveHint: false,
15
15
  openWorldHint: true,
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-create-lead",
9
9
  name: "Create Lead",
10
10
  description: `Creates a lead. [See the documentation](${docsLink})`,
11
- version: "0.3.5",
11
+ version: "0.3.6",
12
12
  annotations: {
13
13
  destructiveHint: false,
14
14
  openWorldHint: true,
@@ -18,7 +18,7 @@ export default {
18
18
  key: "salesforce_rest_api-create-note",
19
19
  name: "Create Note",
20
20
  description: `Creates a note. [See the documentation](${docsLink})`,
21
- version: "0.3.6",
21
+ version: "0.3.7",
22
22
  annotations: {
23
23
  destructiveHint: false,
24
24
  openWorldHint: true,
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-create-opportunity",
9
9
  name: "Create Opportunity",
10
10
  description: `Creates an opportunity. [See the documentation](${docsLink})`,
11
- version: "0.3.5",
11
+ version: "0.3.6",
12
12
  annotations: {
13
13
  destructiveHint: false,
14
14
  openWorldHint: true,
@@ -28,6 +28,7 @@ export default {
28
28
  objType: opportunity,
29
29
  docsLink,
30
30
  showDateInfo: true,
31
+ advancedProps: false,
31
32
  }),
32
33
  async run({ $ }) {
33
34
  /* eslint-disable no-unused-vars */
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-create-record",
9
9
  name: "Create Record",
10
10
  description: "Create a record of a given object. [See the documentation](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_create.htm)",
11
- version: "0.3.5",
11
+ version: "0.3.6",
12
12
  annotations: {
13
13
  destructiveHint: false,
14
14
  openWorldHint: true,
@@ -9,7 +9,7 @@ export default {
9
9
  key: "salesforce_rest_api-create-task",
10
10
  name: "Create Task",
11
11
  description: `Creates a task. [See the documentation](${docsLink})`,
12
- version: "0.4.5",
12
+ version: "0.4.6",
13
13
  annotations: {
14
14
  destructiveHint: false,
15
15
  openWorldHint: true,
@@ -9,7 +9,7 @@ export default {
9
9
  key: "salesforce_rest_api-create-user",
10
10
  name: "Create User",
11
11
  description: `Creates a Salesforce user. [See the documentation](${docsLink})`,
12
- version: "0.1.5",
12
+ version: "0.1.6",
13
13
  annotations: {
14
14
  destructiveHint: false,
15
15
  openWorldHint: true,
@@ -0,0 +1,52 @@
1
+ // vandelay-test-dr
2
+ import salesforce from "../../salesforce_rest_api.app.mjs";
3
+
4
+ export default {
5
+ key: "salesforce_rest_api-delete-crm-record",
6
+ name: "Delete Record",
7
+ description:
8
+ "Permanently deletes a Salesforce record (moves to Recycle Bin for 15 days)."
9
+ + " Use **SOQL Query** to find the record ID if you only have the record name.",
10
+ version: "0.0.1",
11
+ type: "action",
12
+ annotations: {
13
+ readOnlyHint: false,
14
+ destructiveHint: true,
15
+ openWorldHint: true,
16
+ },
17
+ props: {
18
+ salesforce,
19
+ objectType: {
20
+ type: "string",
21
+ label: "Object Type",
22
+ description:
23
+ "The Salesforce object API name (e.g. `Account`, `Contact`, `Opportunity`).",
24
+ },
25
+ recordId: {
26
+ type: "string",
27
+ label: "Record ID",
28
+ description:
29
+ "The ID of the record to delete."
30
+ + " Use **SOQL Query** to find the ID if you only have the record name.",
31
+ },
32
+ },
33
+ async run({ $ }) {
34
+ await this.salesforce.deleteRecord({
35
+ sobjectType: this.objectType,
36
+ recordId: this.recordId,
37
+ $,
38
+ });
39
+
40
+ $.export(
41
+ "$summary",
42
+ `Deleted ${this.objectType} ${this.recordId}`,
43
+ );
44
+
45
+ return {
46
+ success: true,
47
+ objectType: this.objectType,
48
+ recordId: this.recordId,
49
+ deleted: true,
50
+ };
51
+ },
52
+ };
@@ -0,0 +1,86 @@
1
+ // vandelay-test-dr
2
+ import salesforce from "../../salesforce_rest_api.app.mjs";
3
+
4
+ export default {
5
+ key: "salesforce_rest_api-describe-object",
6
+ name: "Describe Object",
7
+ description:
8
+ "Get field metadata for a Salesforce object type, including field names, types, required status, and picklist values."
9
+ + " Use before **Create Record** or **Update Record** to discover available fields and valid picklist values."
10
+ + " For picklist fields (like `StageName` on Opportunity, `Status` on Case), this returns all valid values"
11
+ + " — use the API value, not the display label."
12
+ + " Use the `fieldsFilter` parameter to narrow results — full object descriptions can be very large (100+ fields)."
13
+ + " Use **List Objects** if you're unsure of the object's API name.",
14
+ version: "0.0.1",
15
+ type: "action",
16
+ annotations: {
17
+ readOnlyHint: true,
18
+ destructiveHint: false,
19
+ openWorldHint: false,
20
+ },
21
+ props: {
22
+ salesforce,
23
+ objectType: {
24
+ type: "string",
25
+ label: "Object Type",
26
+ description:
27
+ "The Salesforce object API name (e.g. `Account`, `Contact`, `Opportunity`, `CustomObject__c`)."
28
+ + " Use **List Objects** to discover available object types.",
29
+ },
30
+ fieldsFilter: {
31
+ type: "string",
32
+ label: "Fields Filter",
33
+ description:
34
+ "Optional keyword to filter field names and labels (case-insensitive)."
35
+ + " For example, `stage` returns fields like `StageName`, `ForecastCategoryName`."
36
+ + " Omit to return all fields.",
37
+ optional: true,
38
+ },
39
+ },
40
+ async run({ $ }) {
41
+ const fields = await this.salesforce.getFieldsForObjectType(this.objectType);
42
+
43
+ const filter = this.fieldsFilter?.toLowerCase();
44
+ const filtered = filter
45
+ ? fields.filter((f) =>
46
+ f.name.toLowerCase().includes(filter)
47
+ || f.label.toLowerCase().includes(filter))
48
+ : fields;
49
+
50
+ const result = filtered.map((f) => {
51
+ const field = {
52
+ name: f.name,
53
+ label: f.label,
54
+ type: f.type,
55
+ required: !f.nillable && !f.defaultedOnCreate,
56
+ updateable: f.updateable,
57
+ createable: f.createable,
58
+ };
59
+ if (f.type === "picklist" || f.type === "multipicklist") {
60
+ field.picklistValues = f.picklistValues
61
+ .filter((v) => v.active)
62
+ .map((v) => ({
63
+ value: v.value,
64
+ label: v.label,
65
+ defaultValue: v.defaultValue,
66
+ }));
67
+ }
68
+ if (f.type === "reference" && f.referenceTo?.length) {
69
+ field.referenceTo = f.referenceTo;
70
+ field.relationshipName = f.relationshipName;
71
+ }
72
+ return field;
73
+ });
74
+
75
+ $.export(
76
+ "$summary",
77
+ `Found ${result.length} field${result.length === 1
78
+ ? ""
79
+ : "s"} on ${this.objectType}${filter
80
+ ? ` matching "${this.fieldsFilter}"`
81
+ : ""}`,
82
+ );
83
+
84
+ return result;
85
+ },
86
+ };
@@ -0,0 +1,80 @@
1
+ // vandelay-test-dr
2
+ import salesforce from "../../salesforce_rest_api.app.mjs";
3
+
4
+ export default {
5
+ key: "salesforce_rest_api-get-related-records",
6
+ name: "Get Related Records",
7
+ description:
8
+ "Get child records related to a parent Salesforce record via a relationship."
9
+ + " Use to traverse relationships without writing SOQL joins."
10
+ + " Common relationships: Account → Contacts, Opportunities, Cases, Tasks;"
11
+ + " Contact → Cases, Opportunities, Tasks;"
12
+ + " Opportunity → OpportunityLineItems, Tasks."
13
+ + " Use **Describe Object** to discover available relationship names if unsure"
14
+ + " (look for `relationshipName` on reference fields).",
15
+ version: "0.0.1",
16
+ type: "action",
17
+ annotations: {
18
+ readOnlyHint: true,
19
+ destructiveHint: false,
20
+ openWorldHint: true,
21
+ },
22
+ props: {
23
+ salesforce,
24
+ objectType: {
25
+ type: "string",
26
+ label: "Parent Object Type",
27
+ description:
28
+ "The SObject API name of the parent record (e.g. `Account`, `Contact`, `Opportunity`).",
29
+ },
30
+ recordId: {
31
+ type: "string",
32
+ label: "Record ID",
33
+ description: "The ID of the parent record.",
34
+ },
35
+ relationshipName: {
36
+ type: "string",
37
+ label: "Relationship Name",
38
+ description:
39
+ "The API name of the relationship to traverse (e.g. `Contacts`, `Opportunities`, `Cases`, `Tasks`)."
40
+ + " This is the plural relationship name, not the field name."
41
+ + " Use **Describe Object** on the parent type to discover available relationships.",
42
+ },
43
+ fields: {
44
+ type: "string[]",
45
+ label: "Fields",
46
+ description:
47
+ "Fields to return on the related records (e.g. `[\"Id\", \"Name\", \"Email\"]`)."
48
+ + " If omitted, returns default fields.",
49
+ optional: true,
50
+ },
51
+ },
52
+ async run({ $ }) {
53
+ let url = `${this.salesforce._sObjectDetailsApiUrl(this.objectType, this.recordId)}/${this.relationshipName}`;
54
+
55
+ if (this.fields?.length) {
56
+ url += `?fields=${this.fields.join(",")}`;
57
+ }
58
+
59
+ const response = await this.salesforce._makeRequest({
60
+ $,
61
+ url,
62
+ });
63
+
64
+ const records = response.records || [];
65
+ const totalSize = response.totalSize || records.length;
66
+
67
+ $.export(
68
+ "$summary",
69
+ `Found ${totalSize} related ${this.relationshipName} record${totalSize === 1
70
+ ? ""
71
+ : "s"}`,
72
+ );
73
+
74
+ return {
75
+ totalSize,
76
+ records,
77
+ hasMore: totalSize > records.length,
78
+ };
79
+ },
80
+ };
@@ -0,0 +1,44 @@
1
+ // vandelay-test-dr
2
+ import salesforce from "../../salesforce_rest_api.app.mjs";
3
+
4
+ export default {
5
+ key: "salesforce_rest_api-get-user-info",
6
+ name: "Get User Info",
7
+ description:
8
+ "Get the current authenticated Salesforce user's identity, including user ID, email, org ID, and instance URL."
9
+ + " **Must be called before any query that uses first-person language ('my', 'I', 'me').**"
10
+ + " The `userId` can be used as an `OwnerId` filter in SOQL queries (e.g. `WHERE OwnerId = '{userId}'`)."
11
+ + " The `instanceUrl` is needed to construct clickable links to Salesforce records:"
12
+ + " `{instanceUrl}/lightning/r/{objectType}/{recordId}/view`.",
13
+ version: "0.0.1",
14
+ type: "action",
15
+ annotations: {
16
+ readOnlyHint: true,
17
+ destructiveHint: false,
18
+ openWorldHint: false,
19
+ },
20
+ props: {
21
+ salesforce,
22
+ },
23
+ async run({ $ }) {
24
+ const userInfo = await this.salesforce.getUserInfo(
25
+ this.salesforce._authToken(),
26
+ );
27
+
28
+ const result = {
29
+ userId: userInfo.user_id,
30
+ userName: userInfo.preferred_username || userInfo.email,
31
+ userEmail: userInfo.email,
32
+ displayName: userInfo.name,
33
+ orgId: userInfo.organization_id,
34
+ instanceUrl: this.salesforce._baseApiUrl(),
35
+ };
36
+
37
+ $.export(
38
+ "$summary",
39
+ `Authenticated as ${result.userEmail} (User ID: ${result.userId}, Org: ${result.orgId})`,
40
+ );
41
+
42
+ return result;
43
+ },
44
+ };
@@ -0,0 +1,61 @@
1
+ // vandelay-test-dr
2
+ import salesforce from "../../salesforce_rest_api.app.mjs";
3
+
4
+ export default {
5
+ key: "salesforce_rest_api-list-objects",
6
+ name: "List Objects",
7
+ description:
8
+ "List available Salesforce object types (SObjects) in the org."
9
+ + " Use when the user references an object type you're not sure about, or to discover custom objects."
10
+ + " Custom objects end in `__c`."
11
+ + " Standard CRM objects: Account, Contact, Lead, Opportunity, Case, Task, Event, Campaign, User."
12
+ + " Use **Describe Object** to get field details for a specific object type.",
13
+ version: "0.0.1",
14
+ type: "action",
15
+ annotations: {
16
+ readOnlyHint: true,
17
+ destructiveHint: false,
18
+ openWorldHint: false,
19
+ },
20
+ props: {
21
+ salesforce,
22
+ filter: {
23
+ type: "string",
24
+ label: "Filter",
25
+ description:
26
+ "Optional keyword to filter object names and labels (case-insensitive)."
27
+ + " For example, `custom` returns only custom objects, `account` returns Account-related objects.",
28
+ optional: true,
29
+ },
30
+ },
31
+ async run({ $ }) {
32
+ const { sobjects } = await this.salesforce.listSObjectTypes();
33
+
34
+ const filterLower = this.filter?.toLowerCase();
35
+ const filtered = filterLower
36
+ ? sobjects.filter((o) =>
37
+ o.name.toLowerCase().includes(filterLower)
38
+ || o.label.toLowerCase().includes(filterLower))
39
+ : sobjects;
40
+
41
+ const result = filtered.map((o) => ({
42
+ name: o.name,
43
+ label: o.label,
44
+ custom: o.custom,
45
+ queryable: o.queryable,
46
+ createable: o.createable,
47
+ updateable: o.updateable,
48
+ }));
49
+
50
+ $.export(
51
+ "$summary",
52
+ `Found ${result.length} object type${result.length === 1
53
+ ? ""
54
+ : "s"}${filterLower
55
+ ? ` matching "${this.filter}"`
56
+ : ""}`,
57
+ );
58
+
59
+ return result;
60
+ },
61
+ };
@@ -0,0 +1,87 @@
1
+ // vandelay-test-dr
2
+ import salesforce from "../../salesforce_rest_api.app.mjs";
3
+
4
+ export default {
5
+ key: "salesforce_rest_api-soql-query",
6
+ name: "SOQL Query",
7
+ description:
8
+ "Execute a SOQL query against Salesforce. This is the **primary tool for querying Salesforce data** — use for all structured queries."
9
+ + " For free-text search across multiple objects, use **Text Search** instead."
10
+ + "\n\n"
11
+ + "**When the user uses first-person language ('my', 'I', 'me'),** filter by `OwnerId` using the `userId` from **Get User Info**."
12
+ + " Use **Describe Object** to discover field names and picklist values before querying non-obvious fields."
13
+ + "\n\n"
14
+ + "**SOQL syntax reference:**"
15
+ + "\n- Basic: `SELECT Id, Name, Email FROM Contact WHERE AccountId = '001xxx'`"
16
+ + "\n- Operators: `=`, `!=`, `>`, `<`, `>=`, `<=`, `LIKE '%text%'`, `IN ('a','b')`, `NOT IN`"
17
+ + "\n- Date literals: `TODAY`, `THIS_MONTH`, `LAST_N_DAYS:30`, `THIS_QUARTER`, `LAST_QUARTER`, `THIS_YEAR`"
18
+ + "\n- NULL checks: `WHERE Email != null`"
19
+ + "\n- Aggregates: `SELECT StageName, COUNT(Id) c, SUM(Amount) s FROM Opportunity GROUP BY StageName`"
20
+ + "\n- **SOQL does NOT support the `AS` keyword** — write `COUNT(Id) c`, not `COUNT(Id) AS c`"
21
+ + "\n- **Reserved words cannot be aliases** — `count`, `sum`, `avg` are reserved. Use short aliases like `c`, `s`, `a`"
22
+ + "\n- **Cannot ORDER BY alias** — repeat the aggregate: `ORDER BY COUNT(Id) DESC`, not `ORDER BY c DESC`"
23
+ + "\n- Parent relationship: `SELECT Name, Account.Name FROM Contact`"
24
+ + "\n- Child subquery: `SELECT Name, (SELECT Name FROM Contacts) FROM Account`"
25
+ + "\n- Sorting/limits: `ORDER BY CreatedDate DESC LIMIT 10`"
26
+ + "\n\n"
27
+ + "**Always include `Id` in SELECT.** Include a clickable Salesforce link for every record"
28
+ + " using the format `{instanceUrl}/lightning/r/{objectType}/{Id}/view` (get `instanceUrl` from **Get User Info**).",
29
+ version: "0.0.1",
30
+ type: "action",
31
+ annotations: {
32
+ readOnlyHint: true,
33
+ destructiveHint: false,
34
+ openWorldHint: true,
35
+ },
36
+ props: {
37
+ salesforce,
38
+ query: {
39
+ type: "string",
40
+ label: "SOQL Query",
41
+ description:
42
+ "The SOQL query string to execute."
43
+ + " Example: `SELECT Id, Name, Amount, StageName FROM Opportunity WHERE OwnerId = '005xxx' AND StageName = 'Closed Won' ORDER BY Amount DESC LIMIT 10`",
44
+ },
45
+ },
46
+ async run({ $ }) {
47
+ const firstPage = await this.salesforce.query({
48
+ $,
49
+ query: this.query,
50
+ });
51
+
52
+ const totalSize = firstPage.totalSize;
53
+ const allRecords = [
54
+ ...(firstPage.records || []),
55
+ ];
56
+ let nextUrl = firstPage.nextRecordsUrl
57
+ ? `${this.salesforce._baseApiUrl()}${firstPage.nextRecordsUrl}`
58
+ : null;
59
+ const maxPages = 5;
60
+
61
+ for (let page = 1; page < maxPages && nextUrl; page++) {
62
+ const response = await this.salesforce._makeRequest({
63
+ $,
64
+ url: nextUrl,
65
+ });
66
+ allRecords.push(...(response.records || []));
67
+ nextUrl = response.nextRecordsUrl
68
+ ? `${this.salesforce._baseApiUrl()}${response.nextRecordsUrl}`
69
+ : null;
70
+ }
71
+
72
+ const result = {
73
+ totalSize,
74
+ records: allRecords,
75
+ hasMore: !!nextUrl,
76
+ };
77
+
78
+ $.export(
79
+ "$summary",
80
+ `Query returned ${totalSize} total record${totalSize === 1
81
+ ? ""
82
+ : "s"}, fetched ${allRecords.length}`,
83
+ );
84
+
85
+ return result;
86
+ },
87
+ };
@@ -0,0 +1,89 @@
1
+ // vandelay-test-dr
2
+ import salesforce from "../../salesforce_rest_api.app.mjs";
3
+
4
+ export default {
5
+ key: "salesforce_rest_api-text-search",
6
+ name: "Text Search",
7
+ description:
8
+ "Search Salesforce records by keyword across multiple object types simultaneously."
9
+ + " Use for free-text search when the user mentions a name, term, or keyword without specifying an object type."
10
+ + " Use **SOQL Query** instead for structured queries on a single object type with specific conditions."
11
+ + " Results are grouped by object type.",
12
+ version: "0.0.1",
13
+ type: "action",
14
+ annotations: {
15
+ readOnlyHint: true,
16
+ destructiveHint: false,
17
+ openWorldHint: true,
18
+ },
19
+ props: {
20
+ salesforce,
21
+ searchTerm: {
22
+ type: "string",
23
+ label: "Search Term",
24
+ description:
25
+ "The text to search for across Salesforce records."
26
+ + " Searches name fields and other indexed text fields.",
27
+ },
28
+ objectTypes: {
29
+ type: "string[]",
30
+ label: "Object Types",
31
+ description:
32
+ "SObject types to search. Default: Account, Contact, Lead, Opportunity."
33
+ + " Example: `[\"Account\", \"Contact\", \"Case\"]`.",
34
+ optional: true,
35
+ },
36
+ },
37
+ async run({ $ }) {
38
+ const objectTypes = this.objectTypes?.length
39
+ ? this.objectTypes
40
+ : [
41
+ "Account",
42
+ "Contact",
43
+ "Lead",
44
+ "Opportunity",
45
+ ];
46
+
47
+ const returningClause = objectTypes
48
+ .map((type) => `${type}(Id, Name)`)
49
+ .join(", ");
50
+
51
+ const escapedTerm = this.searchTerm.replace(/[?&|!{}[\]()^~*:\\"'+-]/g, "\\$&");
52
+ const sosl = `FIND {${escapedTerm}} IN ALL FIELDS RETURNING ${returningClause}`;
53
+
54
+ const response = await this.salesforce.search({
55
+ $,
56
+ search: sosl,
57
+ });
58
+
59
+ const results = response.searchRecords || [];
60
+ const groupedByType = {};
61
+ for (const record of results) {
62
+ const type = record.attributes?.type || "Unknown";
63
+ if (!groupedByType[type]) groupedByType[type] = [];
64
+ groupedByType[type].push(record);
65
+ }
66
+
67
+ const summary = Object.entries(groupedByType)
68
+ .map(([
69
+ type,
70
+ records,
71
+ ]) => `${records.length} ${type}`)
72
+ .join(", ");
73
+
74
+ $.export(
75
+ "$summary",
76
+ results.length
77
+ ? `Found ${results.length} result${results.length === 1
78
+ ? ""
79
+ : "s"}: ${summary}`
80
+ : `No results found for "${this.searchTerm}"`,
81
+ );
82
+
83
+ return {
84
+ totalSize: results.length,
85
+ searchRecords: results,
86
+ groupedByType,
87
+ };
88
+ },
89
+ };
@@ -15,7 +15,7 @@ export default {
15
15
  key: "salesforce_rest_api-update-account",
16
16
  name: "Update Account",
17
17
  description: `Updates a Salesforce account. [See the documentation](${docsLink})`,
18
- version: "0.3.5",
18
+ version: "0.3.6",
19
19
  annotations: {
20
20
  destructiveHint: true,
21
21
  openWorldHint: true,
@@ -16,7 +16,7 @@ export default {
16
16
  key: "salesforce_rest_api-update-contact",
17
17
  name: "Update Contact",
18
18
  description: `Updates a contact. [See the documentation](${docsLink})`,
19
- version: "0.3.5",
19
+ version: "0.3.6",
20
20
  annotations: {
21
21
  destructiveHint: true,
22
22
  openWorldHint: true,
@@ -17,7 +17,7 @@ export default {
17
17
  key: "salesforce_rest_api-update-content-note",
18
18
  name: "Update Content Note",
19
19
  description: `Updates an enhanced Salesforce content note, which can include formatted text and is part of Salesforce Files. [See the documentation](${docsLink}) and [Set Up Notes](https://help.salesforce.com/s/articleView?id=sales.notes_admin_setup.htm&type=5).`,
20
- version: "0.0.2",
20
+ version: "0.0.3",
21
21
  type: "action",
22
22
  annotations: {
23
23
  destructiveHint: true,
@@ -0,0 +1,60 @@
1
+ // vandelay-test-dr
2
+ import salesforce from "../../salesforce_rest_api.app.mjs";
3
+
4
+ export default {
5
+ key: "salesforce_rest_api-update-crm-record",
6
+ name: "Update Record",
7
+ description:
8
+ "Update an existing Salesforce record. Only pass fields you want to change — unspecified fields remain unchanged."
9
+ + " Use **Describe Object** for valid field names and picklist values."
10
+ + " Use **SOQL Query** to find the record ID if you only have the name.",
11
+ version: "0.0.1",
12
+ type: "action",
13
+ annotations: {
14
+ readOnlyHint: false,
15
+ destructiveHint: false,
16
+ openWorldHint: true,
17
+ },
18
+ props: {
19
+ salesforce,
20
+ objectType: {
21
+ type: "string",
22
+ label: "Object Type",
23
+ description:
24
+ "The Salesforce object API name (e.g. `Account`, `Contact`, `Opportunity`).",
25
+ },
26
+ recordId: {
27
+ type: "string",
28
+ label: "Record ID",
29
+ description:
30
+ "The ID of the record to update."
31
+ + " Use **SOQL Query** to find the ID if you only have the record name.",
32
+ },
33
+ properties: {
34
+ type: "object",
35
+ label: "Properties to Update",
36
+ description:
37
+ "Field name → new value pairs. Only include fields you want to change."
38
+ + " Example: `{\"StageName\": \"Closed Won\", \"Amount\": 75000}`."
39
+ + " Use **Describe Object** to discover valid field names and picklist values.",
40
+ },
41
+ },
42
+ async run({ $ }) {
43
+ await this.salesforce.updateRecord(this.objectType, {
44
+ $,
45
+ id: this.recordId,
46
+ data: this.properties,
47
+ });
48
+
49
+ $.export(
50
+ "$summary",
51
+ `Updated ${this.objectType} ${this.recordId}`,
52
+ );
53
+
54
+ return {
55
+ success: true,
56
+ objectType: this.objectType,
57
+ recordId: this.recordId,
58
+ };
59
+ },
60
+ };
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-update-email-template",
9
9
  name: "Update Email Template",
10
10
  description: "Updates an email template. [See the documentation](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_update_fields.htm)",
11
- version: "0.0.5",
11
+ version: "0.0.6",
12
12
  annotations: {
13
13
  destructiveHint: true,
14
14
  openWorldHint: true,
@@ -17,7 +17,7 @@ export default {
17
17
  key: "salesforce_rest_api-update-note",
18
18
  name: "Update Note",
19
19
  description: `Updates a classic Salesforce note, which can contain up to 32 KB of text and is associated with a parent record. [See the documentation](${docsLink})`,
20
- version: "0.0.2",
20
+ version: "0.0.3",
21
21
  type: "action",
22
22
  annotations: {
23
23
  destructiveHint: true,
@@ -9,6 +9,7 @@ const {
9
9
  objType: opportunity,
10
10
  docsLink,
11
11
  showDateInfo: true,
12
+ advancedProps: false,
12
13
  });
13
14
 
14
15
  export default {
@@ -16,7 +17,7 @@ export default {
16
17
  key: "salesforce_rest_api-update-opportunity",
17
18
  name: "Update Opportunity",
18
19
  description: `Updates an opportunity. [See the documentation](${docsLink})`,
19
- version: "0.3.5",
20
+ version: "0.3.6",
20
21
  annotations: {
21
22
  destructiveHint: true,
22
23
  openWorldHint: true,
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-update-record",
9
9
  name: "Update Record",
10
10
  description: "Update fields of a record. [See the documentation](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_update_fields.htm)",
11
- version: "0.3.6",
11
+ version: "0.3.7",
12
12
  annotations: {
13
13
  destructiveHint: true,
14
14
  openWorldHint: true,
@@ -8,7 +8,7 @@ export default {
8
8
  key: "salesforce_rest_api-upsert-record",
9
9
  name: "Upsert Record",
10
10
  description: "Create or update a record of a given object. [See the documentation](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_upsert.htm)",
11
- version: "0.0.6",
11
+ version: "0.0.7",
12
12
  annotations: {
13
13
  destructiveHint: true,
14
14
  openWorldHint: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/salesforce_rest_api",
3
- "version": "1.11.8",
3
+ "version": "1.12.1",
4
4
  "description": "Pipedream Salesforce (REST API) Components",
5
5
  "main": "salesforce_rest_api.app.mjs",
6
6
  "keywords": [
@@ -11,10 +11,10 @@
11
11
  "author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
12
12
  "dependencies": {
13
13
  "@pipedream/platform": "^3.1.1",
14
- "fast-xml-parser": "^5.3.8",
15
- "handlebars": "^4.7.7",
14
+ "fast-xml-parser": "^5.5.7",
15
+ "handlebars": "^4.7.9",
16
16
  "lodash": "^4.17.23",
17
- "lodash-es": "^4.17.23",
17
+ "lodash-es": "^4.18.1",
18
18
  "salesforce-webhooks": "^1.1.11",
19
19
  "uuid": "^9.0.1"
20
20
  },