Skip to content

Commit 720ad67

Browse files
committed
[Components] tinyurl #15135
Sources - New Survey Completion - New Segment Entry Actions - Identify User - Track Event
1 parent 9779bfb commit 720ad67

File tree

9 files changed

+290
-255
lines changed

9 files changed

+290
-255
lines changed

components/refiner/actions/identify-user/identify-user.mjs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
import { ConfigurationError } from "@pipedream/platform";
12
import refiner from "../../refiner.app.mjs";
2-
import { axios } from "@pipedream/platform";
33

44
export default {
55
key: "refiner-identify-user",
66
name: "Identify User",
7-
description: "Creates or updates a user profile in Refiner. [See the documentation]()",
8-
version: "0.0.{{ts}}",
7+
description: "Creates or updates a user profile in Refiner. [See the documentation](https://refiner.io/docs/api/#identify-user)",
8+
version: "0.0.1",
99
type: "action",
1010
props: {
1111
refiner,
@@ -14,18 +14,27 @@ export default {
1414
refiner,
1515
"userId",
1616
],
17+
optional: true,
1718
},
1819
email: {
1920
propDefinition: [
2021
refiner,
2122
"email",
2223
],
24+
optional: true,
2325
},
2426
},
2527
async run({ $ }) {
28+
if (!this.userId && !this.email) {
29+
throw new ConfigurationError("Either User Id or E mail must be provided to identify the user.");
30+
}
31+
2632
const response = await this.refiner.identifyUser({
27-
userId: this.userId,
28-
email: this.email,
33+
$,
34+
data: {
35+
id: this.userId,
36+
email: this.email,
37+
},
2938
});
3039

3140
$.export("$summary", `User identified successfully. Contact UUID: ${response.contact_uuid}`);

components/refiner/actions/track-event/track-event.mjs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import refiner from "../../refiner.app.mjs";
2-
import { axios } from "@pipedream/platform";
32

43
export default {
54
key: "refiner-track-event",
65
name: "Track Event",
7-
description: "Tracks a user event in Refiner. [See the documentation](https://refiner.io/docs/api/)",
8-
version: "0.0.{{ts}}",
6+
description: "Tracks a user event in Refiner. [See the documentation](https://refiner.io/docs/api/#track-event)",
7+
version: "0.0.1",
98
type: "action",
109
props: {
1110
refiner,
1211
eventName: {
13-
propDefinition: [
14-
refiner,
15-
"eventName",
16-
],
12+
type: "string",
13+
label: "Event Name",
14+
description: "The name of the event or signal being tracked.",
1715
},
1816
userId: {
1917
propDefinition: [
@@ -36,9 +34,12 @@ export default {
3634
}
3735

3836
const response = await this.refiner.trackEvent({
39-
eventName: this.eventName,
40-
userId: this.userId,
41-
email: this.email,
37+
$,
38+
data: {
39+
event: this.eventName,
40+
id: this.userId,
41+
email: this.email,
42+
},
4243
});
4344

4445
$.export("$summary", `Tracked event "${this.eventName}" successfully.`);

components/refiner/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/refiner",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"description": "Pipedream Refiner Components",
55
"main": "refiner.app.mjs",
66
"keywords": [
@@ -11,5 +11,8 @@
1111
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
1212
"publishConfig": {
1313
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.0.3"
1417
}
1518
}

components/refiner/refiner.app.mjs

Lines changed: 89 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,108 +3,131 @@ import { axios } from "@pipedream/platform";
33
export default {
44
type: "app",
55
app: "refiner",
6-
version: "0.0.{{ts}}",
76
propDefinitions: {
87
userId: {
98
type: "string",
109
label: "User ID",
1110
description: "The ID of the user to identify or track events for.",
12-
optional: true,
11+
async options({ page }) {
12+
const { items } = await this.listContacts({
13+
params: {
14+
page: page + 1,
15+
},
16+
});
17+
18+
return items.map(({
19+
uuid: value, email: label,
20+
}) => ({
21+
label,
22+
value,
23+
}));
24+
},
1325
},
1426
email: {
1527
type: "string",
1628
label: "Email",
1729
description: "The email address of the user to identify or track events for.",
1830
optional: true,
1931
},
20-
eventName: {
32+
segmentId: {
2133
type: "string",
22-
label: "Event Name",
23-
description: "The name of the event or signal being tracked.",
34+
label: "Segment ID",
35+
description: "The ID of the segment to emit events for.",
36+
async options({ page }) {
37+
const { items } = await this.listSegments({
38+
params: {
39+
page: page + 1,
40+
},
41+
});
42+
43+
return items.map(({
44+
uuid: value, name: label,
45+
}) => ({
46+
label,
47+
value,
48+
}));
49+
},
2450
},
2551
},
2652
methods: {
27-
// this.$auth contains connected account data
28-
authKeys() {
29-
console.log(Object.keys(this.$auth));
30-
},
3153
_baseUrl() {
3254
return "https://api.refiner.io/v1";
3355
},
34-
async _makeRequest(opts = {}) {
35-
const {
36-
$ = this, method = "GET", path = "/", headers, ...otherOpts
37-
} = opts;
56+
_headers() {
57+
return {
58+
"Authorization": `Bearer ${this.$auth.api_key}`,
59+
};
60+
},
61+
_makeRequest({
62+
$ = this, path, ...opts
63+
}) {
3864
return axios($, {
39-
method,
4065
url: this._baseUrl() + path,
41-
headers: {
42-
...headers,
43-
"Authorization": `Bearer ${this.$auth.api_key}`,
44-
"user-agent": "@PipedreamHQ/pipedream v0.1",
45-
"Content-Type": "application/json",
46-
},
47-
...otherOpts,
66+
headers: this._headers(),
67+
...opts,
4868
});
4969
},
50-
async identifyUser(opts = {}) {
51-
const {
52-
userId, email, ...attributes
53-
} = opts;
54-
if (!userId && !email) {
55-
throw new Error("Either userId or email must be provided to identify the user.");
56-
}
57-
const data = {
58-
...(userId && {
59-
id: userId,
60-
}),
61-
...(email && {
62-
email,
63-
}),
64-
...attributes,
65-
};
70+
listContacts(opts = {}) {
6671
return this._makeRequest({
67-
method: "POST",
68-
path: "/identify-user",
69-
data,
72+
path: "/contacts",
73+
...opts,
7074
});
7175
},
72-
async trackEvent(opts = {}) {
73-
const {
74-
eventName, userId, email,
75-
} = opts;
76-
if (!eventName) {
77-
throw new Error("eventName is required to track an event.");
78-
}
79-
if (!userId && !email) {
80-
throw new Error("Either userId or email must be provided to track the event.");
81-
}
82-
const data = {
83-
event: eventName,
84-
...(userId && {
85-
id: userId,
86-
}),
87-
...(email && {
88-
email,
89-
}),
90-
};
76+
listResponses(opts = {}) {
9177
return this._makeRequest({
92-
method: "POST",
93-
path: "/track-event",
94-
data,
78+
path: "/responses",
79+
...opts,
80+
});
81+
},
82+
listSegments(opts = {}) {
83+
return this._makeRequest({
84+
path: "/segments",
85+
...opts,
9586
});
9687
},
97-
async emitSurveyCompleted() {
88+
identifyUser(opts = {}) {
9889
return this._makeRequest({
9990
method: "POST",
100-
path: "/emit-survey-completed",
91+
path: "/identify-user",
92+
...opts,
10193
});
10294
},
103-
async emitSegmentEntered() {
95+
trackEvent(opts = {}) {
10496
return this._makeRequest({
10597
method: "POST",
106-
path: "/emit-segment-entered",
98+
path: "/track-event",
99+
...opts,
107100
});
108101
},
102+
async *paginate({
103+
fn, params = {}, maxResults = null, ...opts
104+
}) {
105+
let hasMore = false;
106+
let count = 0;
107+
let page = 0;
108+
109+
do {
110+
params.page = ++page;
111+
const {
112+
items,
113+
pagination: {
114+
current_page, last_page,
115+
},
116+
} = await fn({
117+
params,
118+
...opts,
119+
});
120+
for (const d of items) {
121+
yield d;
122+
123+
if (maxResults && ++count === maxResults) {
124+
return count;
125+
}
126+
}
127+
128+
hasMore = current_page < last_page;
129+
130+
} while (hasMore);
131+
},
109132
},
110133
};
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
2+
import refiner from "../../refiner.app.mjs";
3+
4+
export default {
5+
props: {
6+
refiner,
7+
db: "$.service.db",
8+
timer: {
9+
type: "$.interface.timer",
10+
default: {
11+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
12+
},
13+
},
14+
},
15+
methods: {
16+
_getLastDate() {
17+
return this.db.get("lastDate") || 0;
18+
},
19+
_setLastDate(lastDate) {
20+
this.db.set("lastDate", lastDate);
21+
},
22+
async emitEvent(maxResults = false) {
23+
const lastDate = this._getLastDate();
24+
25+
const response = this.refiner.paginate({
26+
fn: this.getFunction(),
27+
params: this.getParams(),
28+
});
29+
30+
let responseArray = [];
31+
for await (const item of response) {
32+
const itemDate = this.getItemDate(item);
33+
34+
if (!itemDate.length) continue;
35+
if (Date.parse(itemDate) <= lastDate) break;
36+
responseArray.push(item);
37+
}
38+
39+
if (responseArray.length) {
40+
if (maxResults && (responseArray.length > maxResults)) {
41+
responseArray.length = maxResults;
42+
}
43+
const itemDate = this.getItemDate(responseArray[0]);
44+
this._setLastDate(itemDate);
45+
}
46+
47+
for (const item of responseArray.reverse()) {
48+
const itemDate = this.getItemDate(item);
49+
50+
this.$emit(item, {
51+
id: item.uuid,
52+
summary: this.getSummary(item),
53+
ts: Date.parse(itemDate),
54+
});
55+
}
56+
},
57+
},
58+
hooks: {
59+
async deploy() {
60+
await this.emitEvent(25);
61+
},
62+
},
63+
async run() {
64+
await this.emitEvent();
65+
},
66+
};

0 commit comments

Comments
 (0)