@pipedream/salesforce_rest_api 1.0.1 → 1.0.2

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.
package/README.md CHANGED
@@ -1,13 +1,21 @@
1
1
  # Getting Started
2
2
 
3
- You can install the Pipedream Salesforce app in the [Accounts](https://pipedream.com/accounts) section of your account, or directly in a workflow.
3
+ You can install the Pipedream Salesforce app in the [Accounts](https://pipedream.com/accounts) section of your Pipedream account, or directly in a workflow.
4
4
 
5
- ## Configuring Webhook Sources in Salesforce
5
+ ## Prerequisite: Salesforce Edition with API Access
6
6
 
7
- The following three permissions must be configured on your Salesforce user in order to use the Salesforce Instant (webhook) triggers:
8
- 1. Apex REST Services
9
- 2. API Enabled
10
- 3. Author Apex (which adds in additional permissions.)
7
+ In order to use this application, you must be on a Salesforce Edition that has API Access, and API Access must be enabled. See [here](https://help.salesforce.com/s/articleView?id=000385436&type=1) for more details.
8
+
9
+ **Salesforce Editions with API Access**
10
+ * Enterprise Edition
11
+ * Unlimited Edition
12
+ * Developer Edition
13
+ * Performance Edition
14
+ * Professional Edition (API access available as an add-on)
15
+
16
+ ### Enabling API Access on Salesforce
17
+
18
+ Your Salesforce user needs a **System Administrator** profile in order to enable API access. If you don't have this on your Salesforce Profile, ask your System Administrator to enable API Access for your user.
11
19
 
12
20
  The most straightforward way to add these permissions is to create a new Permission Set in Salesforce, and to add it to the user once created.
13
21
 
@@ -18,13 +26,10 @@ Here is a step-by-step on how to do this:
18
26
  1. Navigate to your Salesforce instance, and click the Setup wheel in the top-right corner.
19
27
  2. Under the Administration tab on the lefthand sidebar, click Users --> Permission Sets.
20
28
  3. On the Permissions Set page, click New.
21
- 4. Create a new permission set, give it a label, API name, and description. Example:
29
+ 4. Create a new permission set, give it a label, API name, and description. Example: <br>
22
30
  **Label**: Pipedream API Access
23
31
  **API Name**: Pipedream
24
- **Description**: Adds a set of permissions required for Pipedream sources:
25
- - Apex REST Services
26
- - API Enabled
27
- - Author Apex
32
+ **Description**: Adds a set of permissions required for Pipedream.
28
33
 
29
34
  <img src="https://res.cloudinary.com/dpenc2lit/image/upload/v1702598220/Screenshot_2023-12-14_at_2.57.21_PM_dfgsrw.png" width=500>
30
35
 
@@ -36,13 +41,18 @@ Here is a step-by-step on how to do this:
36
41
  6. From System Permissions, click Edit.
37
42
  <img src="https://res.cloudinary.com/dpenc2lit/image/upload/v1702598417/Screenshot_2023-12-14_at_3.01.38_PM_pvbopv.png" width=500>
38
43
 
39
- 7. Select the following permissions, and click Save.
40
- - Apex REST Services
44
+ 7. Select the following permission, and click Save.
41
45
  - API Enabled
42
- - Author Apex (which adds in additional permissions.)
46
+
47
+ If you'd like to utilize Pipedream's webhook triggers, you will need to add the following permissions to the permissions set as well:
48
+ - Apex REST Services
49
+ - Author Apex
50
+ - View Roles and Role Hierarchy
51
+ - Modify Metadata Through Metadata API Functions
52
+ - View Setup and Configuration
43
53
  <img src="https://res.cloudinary.com/dpenc2lit/image/upload/v1702598514/Screenshot_2023-12-14_at_3.48.50_PM_pcychy.png" width=500>
44
54
 
45
- 8. The list of added permissions should look like this, and click save again.
55
+ 8. The list of added permissions (6) should look like this, and click save again.
46
56
  <img src="https://res.cloudinary.com/dpenc2lit/image/upload/v1702598417/Screenshot_2023-12-14_at_3.10.17_PM_urgge8.png" width=500>
47
57
 
48
58
  **Add Permission Set to User**
@@ -53,7 +63,8 @@ Here is a step-by-step on how to do this:
53
63
  10. Select the user you'd like to assign this permission set to, and click Assign. The user should now show up under Current Assignments.
54
64
  <img src="https://res.cloudinary.com/dpenc2lit/image/upload/v1702598514/Screenshot_2023-12-14_at_3.52.42_PM_w4ge4p.png" width=500>
55
65
 
56
- 11. You should now be able to use any of the Salesforce (Instant) Triggers on Pipedream!
66
+ 11. You should now be able to use the Salesforce integration along with the webhook triggers if you configured the required permissions above.
67
+
57
68
 
58
69
  # Troubleshooting
59
70
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/salesforce_rest_api",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Pipedream Salesforce (REST API) Components",
5
5
  "main": "salesforce_rest_api.app.mjs",
6
6
  "keywords": [
@@ -51,6 +51,19 @@ export default {
51
51
  processEvent() {
52
52
  throw new Error("processEvent is not implemented");
53
53
  },
54
+ chunkArray(array, chunkSize = 25) {
55
+ return array.reduce((chunks, item, index) => {
56
+ const chunkIndex = Math.floor(index / chunkSize);
57
+
58
+ if (!chunks[chunkIndex]) {
59
+ chunks[chunkIndex] = [];
60
+ }
61
+
62
+ chunks[chunkIndex].push(item);
63
+
64
+ return chunks;
65
+ }, []);
66
+ },
54
67
  getRelativeObjectUrl(id, historyObjectType) {
55
68
  const {
56
69
  salesforce,
@@ -73,6 +86,38 @@ export default {
73
86
  ...args,
74
87
  });
75
88
  },
89
+ makeChunkBatchRequests({
90
+ ids, objectType, ...args
91
+ } = {}) {
92
+ const {
93
+ batchRequest,
94
+ chunkArray,
95
+ } = this;
96
+
97
+ const chunks = chunkArray(ids);
98
+ const promises = chunks.map((ids) => batchRequest({
99
+ data: {
100
+ batchRequests: this.getBatchRequests(ids, objectType),
101
+ ...args?.data,
102
+ },
103
+ ...args,
104
+ }));
105
+ return Promise.all(promises);
106
+ },
107
+ getChunkBatchResults(responses) {
108
+ return responses.reduce((acc, { results }) => [
109
+ ...acc,
110
+ ...results,
111
+ ], []);
112
+ },
113
+ async makeChunkBatchRequestsAndGetResults(args) {
114
+ const {
115
+ makeChunkBatchRequests,
116
+ getChunkBatchResults,
117
+ } = this;
118
+ const responses = await makeChunkBatchRequests(args);
119
+ return getChunkBatchResults(responses);
120
+ },
76
121
  },
77
122
  async run(event) {
78
123
  const startTimestamp = this.getLatestDateCovered();
@@ -8,7 +8,7 @@ export default {
8
8
  name: "New Record (of Selectable Type)",
9
9
  key: "salesforce_rest_api-new-record",
10
10
  description: "Emit new event (at regular intervals) when a record of arbitrary object type (selected as an input parameter by the user) is created. See [the docs](https://sforce.co/3yPSJZy) for more information.",
11
- version: "0.0.2",
11
+ version: "0.0.3",
12
12
  methods: {
13
13
  ...common.methods,
14
14
  isItemRelevant(item, startTimestamp, endTimestamp) {
@@ -37,6 +37,16 @@ export default {
37
37
  };
38
38
  },
39
39
  async processEvent(eventData) {
40
+ const {
41
+ salesforce,
42
+ objectType,
43
+ setLatestDateCovered,
44
+ makeChunkBatchRequestsAndGetResults,
45
+ isItemRelevant,
46
+ generateMeta,
47
+ $emit: emit,
48
+ } = this;
49
+
40
50
  const {
41
51
  startTimestamp,
42
52
  endTimestamp,
@@ -44,21 +54,19 @@ export default {
44
54
  const {
45
55
  ids,
46
56
  latestDateCovered,
47
- } = await this.salesforce.getUpdatedForObjectType(
48
- this.objectType,
57
+ } = await salesforce.getUpdatedForObjectType(
58
+ objectType,
49
59
  startTimestamp,
50
60
  endTimestamp,
51
61
  );
52
- this.setLatestDateCovered(latestDateCovered);
62
+ setLatestDateCovered(latestDateCovered);
53
63
 
54
64
  if (!ids?.length) {
55
65
  return console.log("No batch requests to send");
56
66
  }
57
67
 
58
- const { results } = await this.batchRequest({
59
- data: {
60
- batchRequests: this.getBatchRequests(ids),
61
- },
68
+ const results = await makeChunkBatchRequestsAndGetResults({
69
+ ids,
62
70
  });
63
71
 
64
72
  results
@@ -66,10 +74,10 @@ export default {
66
74
  statusCode, result: item,
67
75
  }) =>
68
76
  statusCode === 200
69
- && this.isItemRelevant(item, startTimestamp, endTimestamp))
77
+ && isItemRelevant(item, startTimestamp, endTimestamp))
70
78
  .forEach(({ result: item }) => {
71
- const meta = this.generateMeta(item);
72
- this.$emit(item, meta);
79
+ const meta = generateMeta(item);
80
+ emit(item, meta);
73
81
  });
74
82
  },
75
83
  },
@@ -8,7 +8,7 @@ export default {
8
8
  name: "New Updated Object (of Selectable Type)",
9
9
  key: "salesforce_rest_api-object-updated",
10
10
  description: "Emit new event (at regular intervals) when an object of arbitrary type (selected as an input parameter by the user) is updated. [See the docs](https://sforce.co/3yPSJZy) for more information.",
11
- version: "0.1.7",
11
+ version: "0.1.8",
12
12
  methods: {
13
13
  ...common.methods,
14
14
  generateMeta(item) {
@@ -29,35 +29,43 @@ export default {
29
29
  };
30
30
  },
31
31
  async processEvent(eventData) {
32
+ const {
33
+ salesforce,
34
+ objectType,
35
+ setLatestDateCovered,
36
+ makeChunkBatchRequestsAndGetResults,
37
+ generateMeta,
38
+ $emit: emit,
39
+ } = this;
40
+
32
41
  const {
33
42
  startTimestamp,
34
43
  endTimestamp,
35
44
  } = eventData;
45
+
36
46
  const {
37
47
  ids,
38
48
  latestDateCovered,
39
- } = await this.salesforce.getUpdatedForObjectType(
40
- this.objectType,
49
+ } = await salesforce.getUpdatedForObjectType(
50
+ objectType,
41
51
  startTimestamp,
42
52
  endTimestamp,
43
53
  );
44
- this.setLatestDateCovered(latestDateCovered);
54
+ setLatestDateCovered(latestDateCovered);
45
55
 
46
56
  if (!ids?.length) {
47
57
  return console.log("No batch requests to send");
48
58
  }
49
59
 
50
- const { results } = await this.batchRequest({
51
- data: {
52
- batchRequests: this.getBatchRequests(ids),
53
- },
60
+ const results = await makeChunkBatchRequestsAndGetResults({
61
+ ids,
54
62
  });
55
63
 
56
64
  results
57
65
  .filter(({ statusCode }) => statusCode === 200)
58
66
  .forEach(({ result: item }) => {
59
- const meta = this.generateMeta(item);
60
- this.$emit(item, meta);
67
+ const meta = generateMeta(item);
68
+ emit(item, meta);
61
69
  });
62
70
  },
63
71
  },
@@ -15,7 +15,7 @@ export default {
15
15
  name: "New Updated Field on Record (of Selectable Type)",
16
16
  key: "salesforce_rest_api-updated-field-on-record",
17
17
  description: "Emit new event (at regular intervals) when a field of your choosing is updated on any record of a specified Salesforce object. Field history tracking must be enabled for the chosen field. See the docs on [field history tracking](https://sforce.co/3mtj0rF) and [history objects](https://sforce.co/3Fn4lWB) for more information.",
18
- version: "0.1.7",
18
+ version: "0.1.8",
19
19
  props: {
20
20
  ...common.props,
21
21
  objectType: {
@@ -130,8 +130,7 @@ export default {
130
130
  salesforce,
131
131
  _getHistoryObjectType,
132
132
  setLatestDateCovered,
133
- batchRequest,
134
- getBatchRequests,
133
+ makeChunkBatchRequestsAndGetResults,
135
134
  isRelevant,
136
135
  getUniqueParentIds,
137
136
  _getParentId,
@@ -154,11 +153,10 @@ export default {
154
153
  setLatestDateCovered((new Date(latestDateCovered)).toISOString());
155
154
 
156
155
  if (ids?.length) {
157
- ({ results: historyItemRetrievals } = await batchRequest({
158
- data: {
159
- batchRequests: getBatchRequests(ids, historyObjectType),
160
- },
161
- }));
156
+ historyItemRetrievals = await makeChunkBatchRequestsAndGetResults({
157
+ ids,
158
+ objectType: historyObjectType,
159
+ });
162
160
  }
163
161
 
164
162
  const historyItems = historyItemRetrievals
@@ -170,11 +168,9 @@ export default {
170
168
  const parentIds = getUniqueParentIds(historyItems);
171
169
 
172
170
  if (parentIds.length) {
173
- ({ results: itemRetrievals } = await batchRequest({
174
- data: {
175
- batchRequests: getBatchRequests(parentIds),
176
- },
177
- }));
171
+ itemRetrievals = await makeChunkBatchRequestsAndGetResults({
172
+ ids: parentIds,
173
+ });
178
174
  }
179
175
 
180
176
  const itemsById = itemRetrievals