@pipedream/salesforce_rest_api 0.3.3

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 (37) hide show
  1. package/LICENSE +7 -0
  2. package/actions/salesforce-create-account/salesforce-create-account.mjs +374 -0
  3. package/actions/salesforce-create-attachment/salesforce-create-attachment.mjs +73 -0
  4. package/actions/salesforce-create-campaign/salesforce-create-campaign.mjs +148 -0
  5. package/actions/salesforce-create-case/salesforce-create-case.mjs +179 -0
  6. package/actions/salesforce-create-casecomment/salesforce-create-casecomment.mjs +58 -0
  7. package/actions/salesforce-create-contact/salesforce-create-contact.mjs +340 -0
  8. package/actions/salesforce-create-event/salesforce-create-event.mjs +232 -0
  9. package/actions/salesforce-create-lead/salesforce-create-lead.mjs +267 -0
  10. package/actions/salesforce-create-note/salesforce-create-note.mjs +63 -0
  11. package/actions/salesforce-create-opportunity/salesforce-create-opportunity.mjs +170 -0
  12. package/actions/salesforce-create-record/salesforce-create-record.mjs +36 -0
  13. package/actions/salesforce-create-task/salesforce-create-task.mjs +219 -0
  14. package/actions/salesforce-delete-opportunity/salesforce-delete-opportunity.mjs +37 -0
  15. package/actions/salesforce-get-sobject-fields-values/salesforce-get-sobject-fields-values.mjs +37 -0
  16. package/actions/salesforce-insert-blob-data/salesforce-insert-blob-data.mjs +70 -0
  17. package/actions/salesforce-make-api-call/salesforce-make-api-call.mjs +56 -0
  18. package/actions/salesforce-soql-search/salesforce-soql-search.mjs +29 -0
  19. package/actions/salesforce-sosl-search/salesforce-sosl-search.mjs +30 -0
  20. package/actions/salesforce-update-account/salesforce-update-account.mjs +357 -0
  21. package/actions/salesforce-update-contact/salesforce-update-contact.mjs +345 -0
  22. package/actions/salesforce-update-opportunity/salesforce-update-opportunity.mjs +171 -0
  23. package/actions/salesforce-update-record/salesforce-update-record.mjs +40 -0
  24. package/package.json +21 -0
  25. package/salesforce_rest_api.app.mjs +247 -0
  26. package/sources/common-instant.mjs +134 -0
  27. package/sources/common.mjs +96 -0
  28. package/sources/new-object/new-object.mjs +69 -0
  29. package/sources/new-object-instant/new-object-instant.mjs +35 -0
  30. package/sources/new-outbound-message/new-outbound-message.mjs +105 -0
  31. package/sources/object-deleted/object-deleted.mjs +52 -0
  32. package/sources/object-deleted-instant/object-deleted-instant.mjs +36 -0
  33. package/sources/object-updated/object-updated.mjs +63 -0
  34. package/sources/object-updated-instant/object-updated-instant.mjs +36 -0
  35. package/sources/updated-field-on-record/updated-field-on-record.mjs +179 -0
  36. package/sources/updated-field-on-record-instant/updated-field-on-record-instant.mjs +76 -0
  37. package/utils.mjs +27 -0
@@ -0,0 +1,52 @@
1
+ import startCase from "lodash/startCase.js";
2
+
3
+ import common from "../common.mjs";
4
+
5
+ export default {
6
+ ...common,
7
+ type: "source",
8
+ name: "Object Deleted (of Selectable Type)",
9
+ key: "salesforce_rest_api-object-deleted",
10
+ description: "Emit new event (at regular intervals) when an object of arbitrary type (selected as an input parameter by the user) is deleted. [See the docs](https://sforce.co/3msDDEE) for more information.",
11
+ version: "0.0.5",
12
+ methods: {
13
+ ...common.methods,
14
+ generateMeta(item) {
15
+ const {
16
+ id,
17
+ deletedDate,
18
+ } = item;
19
+ const entityType = startCase(this.objectType);
20
+ const summary = `${entityType} deleted: ${id}`;
21
+ const ts = Date.parse(deletedDate);
22
+ return {
23
+ id,
24
+ summary,
25
+ ts,
26
+ };
27
+ },
28
+ async processEvent(eventData) {
29
+ const {
30
+ startTimestamp,
31
+ endTimestamp,
32
+ } = eventData;
33
+ const {
34
+ deletedRecords,
35
+ latestDateCovered,
36
+ } = await this.salesforce.getDeletedForObjectType(
37
+ this.objectType,
38
+ startTimestamp,
39
+ endTimestamp,
40
+ );
41
+
42
+ // When a record is deleted, the `getDeleted` API only shows the ID of the
43
+ // deleted item and the date in which it was deleted.
44
+ deletedRecords.forEach((item) => {
45
+ const meta = this.generateMeta(item);
46
+ this.$emit(item, meta);
47
+ });
48
+
49
+ this.setLatestDateCovered(latestDateCovered);
50
+ },
51
+ },
52
+ };
@@ -0,0 +1,36 @@
1
+ import startCase from "lodash/startCase.js";
2
+
3
+ import common from "../common-instant.mjs";
4
+
5
+ export default {
6
+ ...common,
7
+ type: "source",
8
+ name: "Object Deleted (Instant, of Selectable Type)",
9
+ key: "salesforce_rest_api-object-deleted-instant",
10
+ description: "Emit new event immediately after an object of arbitrary type (selected as an input parameter by the user) is deleted",
11
+ version: "0.0.5",
12
+ methods: {
13
+ ...common.methods,
14
+ generateMeta(data) {
15
+ const nameField = this.getNameField();
16
+ const { Old: oldObject } = data.body;
17
+ const {
18
+ LastModifiedDate: lastModifiedDate,
19
+ Id: id,
20
+ [nameField]: name,
21
+ } = oldObject;
22
+ const entityType = startCase(this.objectType);
23
+ const summary = `${entityType} deleted: ${name}`;
24
+ const ts = Date.parse(lastModifiedDate);
25
+ const compositeId = `${id}-${ts}`;
26
+ return {
27
+ id: compositeId,
28
+ summary,
29
+ ts,
30
+ };
31
+ },
32
+ getEventType() {
33
+ return "deleted";
34
+ },
35
+ },
36
+ };
@@ -0,0 +1,63 @@
1
+ import startCase from "lodash/startCase.js";
2
+
3
+ import common from "../common.mjs";
4
+
5
+ export default {
6
+ ...common,
7
+ type: "source",
8
+ name: "Object Updated (of Selectable Type)",
9
+ key: "salesforce_rest_api-object-updated",
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.0.5",
12
+ methods: {
13
+ ...common.methods,
14
+ generateMeta(item) {
15
+ const nameField = this.getNameField();
16
+ const {
17
+ LastModifiedDate: lastModifiedDate,
18
+ Id: id,
19
+ [nameField]: name,
20
+ } = item;
21
+ const entityType = startCase(this.objectType);
22
+ const summary = `${entityType} updated: ${name}`;
23
+ const ts = Date.parse(lastModifiedDate);
24
+ const compositeId = `${id}-${ts}`;
25
+ return {
26
+ id: compositeId,
27
+ summary,
28
+ ts,
29
+ };
30
+ },
31
+ async processEvent(eventData) {
32
+ const {
33
+ startTimestamp,
34
+ endTimestamp,
35
+ } = eventData;
36
+ const {
37
+ ids,
38
+ latestDateCovered,
39
+ } = await this.salesforce.getUpdatedForObjectType(
40
+ this.objectType,
41
+ startTimestamp,
42
+ endTimestamp,
43
+ );
44
+
45
+ // By the time we try to retrieve an item, it might've been deleted. This
46
+ // will cause `getSObject` to throw a 404 exception, which will reject its
47
+ // promise. Hence, we need to filter those items that we still in Salesforce
48
+ // and exclude those that are not.
49
+ const itemRetrievals = await Promise.allSettled(
50
+ ids.map((id) => this.salesforce.getSObject(this.objectType, id)),
51
+ );
52
+ itemRetrievals
53
+ .filter((result) => result.status === "fulfilled")
54
+ .map((result) => result.value)
55
+ .forEach((item) => {
56
+ const meta = this.generateMeta(item);
57
+ this.$emit(item, meta);
58
+ });
59
+
60
+ this.setLatestDateCovered(latestDateCovered);
61
+ },
62
+ },
63
+ };
@@ -0,0 +1,36 @@
1
+ import startCase from "lodash/startCase.js";
2
+
3
+ import common from "../common-instant.mjs";
4
+
5
+ export default {
6
+ ...common,
7
+ type: "source",
8
+ name: "Object Updated (Instant, of Selectable Type)",
9
+ key: "salesforce_rest_api-object-updated-instant",
10
+ description: "Emit new event immediately after an object of arbitrary type (selected as an input parameter by the user) is updated",
11
+ version: "0.0.5",
12
+ methods: {
13
+ ...common.methods,
14
+ generateMeta(data) {
15
+ const nameField = this.getNameField();
16
+ const { New: newObject } = data.body;
17
+ const {
18
+ LastModifiedDate: lastModifiedDate,
19
+ Id: id,
20
+ [nameField]: name,
21
+ } = newObject;
22
+ const entityType = startCase(this.objectType);
23
+ const summary = `${entityType} updated: ${name}`;
24
+ const ts = Date.parse(lastModifiedDate);
25
+ const compositeId = `${id}-${ts}`;
26
+ return {
27
+ id: compositeId,
28
+ summary,
29
+ ts,
30
+ };
31
+ },
32
+ getEventType() {
33
+ return "updated";
34
+ },
35
+ },
36
+ };
@@ -0,0 +1,179 @@
1
+ import startCase from "lodash/startCase.js";
2
+
3
+ import common from "../common.mjs";
4
+ const { salesforce } = common.props;
5
+
6
+ /**
7
+ * Uses the Salesforce REST API's [sObject Get Updated endpoint](https://sforce.co/3yPSJZy) on the
8
+ * [StandardObjectNamedHistory model](https://sforce.co/3Fn4lWB) to get changes to field values of
9
+ * an sObject type. Associated sObject records are retrieved and emitted for history object records
10
+ * matching configured `field` and `fieldUpdatedTo` prop values.
11
+ */
12
+ export default {
13
+ ...common,
14
+ type: "source",
15
+ name: "Updated Field on Record (of Selectable Type)",
16
+ key: "salesforce_rest_api-updated-field-on-record",
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.0.1",
19
+ props: {
20
+ ...common.props,
21
+ objectType: {
22
+ ...common.props.objectType,
23
+ label: common.props.objectType.label,
24
+ description: common.props.objectType.description,
25
+ async options(context) {
26
+ const { page } = context;
27
+ if (page !== 0) {
28
+ return {
29
+ options: [],
30
+ };
31
+ }
32
+
33
+ const { sobjects } = await this.salesforce.listSObjectTypes();
34
+ // Filter options to include only sObjects with associated
35
+ // [history](https://sforce.co/3Fn4lWB) objects
36
+ const options = sobjects
37
+ .filter(this.isValidSObject)
38
+ .map((sobject) => ({
39
+ label: sobjects.find((o) => o.name === sobject.associateParentEntity).label,
40
+ value: sobject.associateParentEntity,
41
+ }));
42
+ return {
43
+ options,
44
+ };
45
+ },
46
+ },
47
+ field: {
48
+ propDefinition: [
49
+ salesforce,
50
+ "field",
51
+ ({ objectType }) => ({
52
+ objectType,
53
+ }),
54
+ ],
55
+ },
56
+ fieldUpdatedTo: {
57
+ propDefinition: [
58
+ salesforce,
59
+ "fieldUpdatedTo",
60
+ ],
61
+ },
62
+ },
63
+ hooks: {
64
+ ...common.hooks,
65
+ async activate() {
66
+ await common.hooks.activate.call(this);
67
+ const historyObject = await this.salesforce.getHistorySObjectForObjectType(this.objectType);
68
+ if (!historyObject) {
69
+ throw new Error(`History object not found for "${this.objectType}"`);
70
+ }
71
+ this._setHistoryObjectType(historyObject.name);
72
+ },
73
+ },
74
+ methods: {
75
+ ...common.methods,
76
+ _getHistoryObjectType() {
77
+ return this.db.get("historyObjectType");
78
+ },
79
+ _setHistoryObjectType(historyObjectType) {
80
+ this.db.set("historyObjectType", historyObjectType);
81
+ },
82
+ _getParentId(item) {
83
+ const parentIdKey = `${this.objectType}Id`;
84
+ return item[parentIdKey] ?? item["ParentId"];
85
+ },
86
+ isValidSObject(sobject) {
87
+ // Only the activity of those SObject types that have the `replicateable`
88
+ // flag set is published via the `getUpdated` API.
89
+ //
90
+ // See the API docs here: https://sforce.co/3gDy3uP
91
+ return sobject.replicateable && this.salesforce.isHistorySObject(sobject);
92
+ },
93
+ isRelevant(item) {
94
+ const isFieldRelevant = item.Field === this.field;
95
+ const isFieldValueRelevant = !this.fieldUpdatedTo || item.NewValue === this.fieldUpdatedTo;
96
+ return isFieldRelevant && isFieldValueRelevant;
97
+ },
98
+ generateMeta(event) {
99
+ const nameField = this.getNameField();
100
+ const {
101
+ record: item = {},
102
+ update,
103
+ } = event;
104
+ const { [nameField]: name } = item;
105
+ const {
106
+ Id: id,
107
+ CreatedDate: createdDate,
108
+ } = update;
109
+ const entityType = startCase(this.objectType);
110
+ const summary = `${this.field} on ${entityType}: ${name}`;
111
+ const ts = Date.parse(createdDate);
112
+ const compositeId = `${id}-${ts}`;
113
+ return {
114
+ id: compositeId,
115
+ summary,
116
+ ts,
117
+ };
118
+ },
119
+ async processEvent(eventData) {
120
+ const {
121
+ startTimestamp,
122
+ endTimestamp,
123
+ } = eventData;
124
+ const historyObjectType = this._getHistoryObjectType();
125
+ const {
126
+ ids,
127
+ latestDateCovered,
128
+ } = await this.salesforce.getUpdatedForObjectType(
129
+ historyObjectType,
130
+ startTimestamp,
131
+ endTimestamp,
132
+ );
133
+
134
+ // By the time we try to retrieve an item, it might've been deleted. This
135
+ // will cause `getSObject` to throw a 404 exception, which will reject its
136
+ // promise. Hence, we need to filter those items that we still in Salesforce
137
+ // and exclude those that are not.
138
+ const historyItemRetrievals = await Promise.allSettled(
139
+ ids.map((id) => this.salesforce.getSObject(historyObjectType, id)),
140
+ );
141
+ const historyItems = historyItemRetrievals
142
+ .filter((result) => result.status === "fulfilled")
143
+ .map((result) => result.value)
144
+ .filter(this.isRelevant);
145
+
146
+ // To fetch associated sObject records only once, create a set of the "parent IDs" of the
147
+ // history object records
148
+ const parentIdSet = new Set(
149
+ historyItems
150
+ .map(this._getParentId)
151
+ .filter((id) => id),
152
+ );
153
+ const parentIds = Array.from(parentIdSet);
154
+
155
+ const itemRetrievals = await Promise.allSettled(
156
+ parentIds.map((id) => this.salesforce.getSObject(this.objectType, id)),
157
+ );
158
+ const itemsById = itemRetrievals
159
+ .filter((result) => result.status === "fulfilled")
160
+ .map((result) => result.value)
161
+ .reduce((acc, item) => {
162
+ acc[item.Id] = item;
163
+ return acc;
164
+ }, {});
165
+
166
+ const events = historyItems.map((item) => ({
167
+ update: item,
168
+ record: itemsById[this._getParentId(item)],
169
+ }));
170
+
171
+ events.forEach((event) => {
172
+ const meta = this.generateMeta(event);
173
+ this.$emit(event, meta);
174
+ });
175
+
176
+ this.setLatestDateCovered(latestDateCovered);
177
+ },
178
+ },
179
+ };
@@ -0,0 +1,76 @@
1
+ import startCase from "lodash/startCase.js";
2
+
3
+ import common from "../common-instant.mjs";
4
+ const { salesforce } = common.props;
5
+
6
+ export default {
7
+ ...common,
8
+ type: "source",
9
+ name: "Updated Field on Record (Instant, of Selectable Type)",
10
+ key: "salesforce_rest_api-updated-field-on-record-instant",
11
+ description: "Emit new event immediately after a field of your choosing is updated on any record of a specified Salesforce object",
12
+ version: "0.0.1",
13
+ props: {
14
+ ...common.props,
15
+ field: {
16
+ propDefinition: [
17
+ salesforce,
18
+ "field",
19
+ ({ objectType }) => ({
20
+ objectType,
21
+ }),
22
+ ],
23
+ },
24
+ fieldUpdatedTo: {
25
+ propDefinition: [
26
+ salesforce,
27
+ "fieldUpdatedTo",
28
+ ],
29
+ },
30
+ },
31
+ methods: {
32
+ ...common.methods,
33
+ isEventRelevant(event) {
34
+ if (!this.fieldUpdatedTo) {
35
+ return true;
36
+ }
37
+ const { New: newObject } = event.body;
38
+ const { [this.field]: newFieldValue } = newObject;
39
+ return !this.fieldUpdatedTo || this.fieldUpdatedTo === newFieldValue;
40
+ },
41
+ generateMeta(data) {
42
+ const nameField = this.getNameField();
43
+ const { New: newObject } = data.body;
44
+ const {
45
+ LastModifiedDate: lastModifiedDate,
46
+ Id: id,
47
+ [nameField]: name,
48
+ } = newObject;
49
+ const entityType = startCase(this.objectType);
50
+ const summary = `${this.field} on ${entityType}: ${name}`;
51
+ const ts = Date.parse(lastModifiedDate);
52
+ const compositeId = `${id}-${ts}`;
53
+ return {
54
+ id: compositeId,
55
+ summary,
56
+ ts,
57
+ };
58
+ },
59
+ processEvent(event) {
60
+ const { body } = event;
61
+ if (!this.isEventRelevant(event)) {
62
+ return;
63
+ }
64
+ const meta = this.generateMeta(event);
65
+ this.$emit(body, meta);
66
+ },
67
+ getEventType() {
68
+ return "updated";
69
+ },
70
+ getFieldsToCheck() {
71
+ return [
72
+ this.field,
73
+ ];
74
+ },
75
+ },
76
+ };
package/utils.mjs ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * A utility function that accepts a string as an argument and reformats it in
3
+ * order to remove newline characters and consecutive spaces. Useful when
4
+ * dealing with very long templated strings that are split into multiple lines.
5
+ *
6
+ * @example
7
+ * // returns "This is a much cleaner string"
8
+ * toSingleLineString(`
9
+ * This is a much
10
+ * cleaner string
11
+ * `);
12
+ *
13
+ * @param {string} multiLineString the input string to reformat
14
+ * @returns a formatted string based on the content of the input argument,
15
+ * without newlines and multiple spaces
16
+ * Source: {@linkcode ../aws/sources/common/utils.mjs utils.mjs}
17
+ */
18
+ function toSingleLineString(multiLineString) {
19
+ return multiLineString
20
+ .trim()
21
+ .replace(/\n/g, " ")
22
+ .replace(/\s{2,}/g, " ");
23
+ }
24
+
25
+ export {
26
+ toSingleLineString,
27
+ };