Skip to content

Commit 9779bfb

Browse files
committed
refiner init
1 parent d57c8f6 commit 9779bfb

File tree

6 files changed

+382
-2
lines changed

6 files changed

+382
-2
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import refiner from "../../refiner.app.mjs";
2+
import { axios } from "@pipedream/platform";
3+
4+
export default {
5+
key: "refiner-identify-user",
6+
name: "Identify User",
7+
description: "Creates or updates a user profile in Refiner. [See the documentation]()",
8+
version: "0.0.{{ts}}",
9+
type: "action",
10+
props: {
11+
refiner,
12+
userId: {
13+
propDefinition: [
14+
refiner,
15+
"userId",
16+
],
17+
},
18+
email: {
19+
propDefinition: [
20+
refiner,
21+
"email",
22+
],
23+
},
24+
},
25+
async run({ $ }) {
26+
const response = await this.refiner.identifyUser({
27+
userId: this.userId,
28+
email: this.email,
29+
});
30+
31+
$.export("$summary", `User identified successfully. Contact UUID: ${response.contact_uuid}`);
32+
return response;
33+
},
34+
};
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import refiner from "../../refiner.app.mjs";
2+
import { axios } from "@pipedream/platform";
3+
4+
export default {
5+
key: "refiner-track-event",
6+
name: "Track Event",
7+
description: "Tracks a user event in Refiner. [See the documentation](https://refiner.io/docs/api/)",
8+
version: "0.0.{{ts}}",
9+
type: "action",
10+
props: {
11+
refiner,
12+
eventName: {
13+
propDefinition: [
14+
refiner,
15+
"eventName",
16+
],
17+
},
18+
userId: {
19+
propDefinition: [
20+
refiner,
21+
"userId",
22+
],
23+
optional: true,
24+
},
25+
email: {
26+
propDefinition: [
27+
refiner,
28+
"email",
29+
],
30+
optional: true,
31+
},
32+
},
33+
async run({ $ }) {
34+
if (!this.userId && !this.email) {
35+
throw new Error("Either userId or email must be provided to track the event.");
36+
}
37+
38+
const response = await this.refiner.trackEvent({
39+
eventName: this.eventName,
40+
userId: this.userId,
41+
email: this.email,
42+
});
43+
44+
$.export("$summary", `Tracked event "${this.eventName}" successfully.`);
45+
return response;
46+
},
47+
};

components/refiner/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
"publishConfig": {
1313
"access": "public"
1414
}
15-
}
15+
}

components/refiner/refiner.app.mjs

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,110 @@
1+
import { axios } from "@pipedream/platform";
2+
13
export default {
24
type: "app",
35
app: "refiner",
4-
propDefinitions: {},
6+
version: "0.0.{{ts}}",
7+
propDefinitions: {
8+
userId: {
9+
type: "string",
10+
label: "User ID",
11+
description: "The ID of the user to identify or track events for.",
12+
optional: true,
13+
},
14+
email: {
15+
type: "string",
16+
label: "Email",
17+
description: "The email address of the user to identify or track events for.",
18+
optional: true,
19+
},
20+
eventName: {
21+
type: "string",
22+
label: "Event Name",
23+
description: "The name of the event or signal being tracked.",
24+
},
25+
},
526
methods: {
627
// this.$auth contains connected account data
728
authKeys() {
829
console.log(Object.keys(this.$auth));
930
},
31+
_baseUrl() {
32+
return "https://api.refiner.io/v1";
33+
},
34+
async _makeRequest(opts = {}) {
35+
const {
36+
$ = this, method = "GET", path = "/", headers, ...otherOpts
37+
} = opts;
38+
return axios($, {
39+
method,
40+
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,
48+
});
49+
},
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+
};
66+
return this._makeRequest({
67+
method: "POST",
68+
path: "/identify-user",
69+
data,
70+
});
71+
},
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+
};
91+
return this._makeRequest({
92+
method: "POST",
93+
path: "/track-event",
94+
data,
95+
});
96+
},
97+
async emitSurveyCompleted() {
98+
return this._makeRequest({
99+
method: "POST",
100+
path: "/emit-survey-completed",
101+
});
102+
},
103+
async emitSegmentEntered() {
104+
return this._makeRequest({
105+
method: "POST",
106+
path: "/emit-segment-entered",
107+
});
108+
},
10109
},
11110
};
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import {
2+
axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
3+
} from "@pipedream/platform";
4+
import refiner from "../../refiner.app.mjs";
5+
6+
export default {
7+
key: "refiner-new-segment-entry",
8+
name: "New Segment Entry",
9+
description: "Emits a new event whenever a user enters a segment in Refiner. [See the documentation]()",
10+
version: "0.0.{{ts}}",
11+
type: "source",
12+
dedupe: "unique",
13+
props: {
14+
refiner: {
15+
type: "app",
16+
app: "refiner",
17+
},
18+
db: {
19+
type: "$.service.db",
20+
},
21+
timer: {
22+
type: "$.interface.timer",
23+
default: {
24+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
25+
},
26+
},
27+
},
28+
hooks: {
29+
async deploy() {
30+
const MAX_EVENTS = 50;
31+
const lastTs = await this.db.get("lastTs") || 0;
32+
33+
const entries = await this.refiner._makeRequest({
34+
method: "GET",
35+
path: "/segment-entries",
36+
params: {
37+
since: lastTs,
38+
limit: MAX_EVENTS,
39+
sort: "desc",
40+
},
41+
});
42+
43+
let newLastTs = lastTs;
44+
45+
for (const entry of entries) {
46+
const ts = entry.timestamp
47+
? Date.parse(entry.timestamp)
48+
: Date.now();
49+
this.$emit(entry, {
50+
id: entry.id ?? ts,
51+
summary: `User ${entry.userId} entered segment ${entry.segmentId}`,
52+
ts,
53+
});
54+
55+
if (ts > newLastTs) {
56+
newLastTs = ts;
57+
}
58+
59+
if (--MAX_EVENTS <= 0) break;
60+
}
61+
62+
await this.db.set("lastTs", newLastTs);
63+
},
64+
async activate() {
65+
// Activation logic if any
66+
},
67+
async deactivate() {
68+
// Deactivation logic if any
69+
},
70+
},
71+
async run() {
72+
const lastTs = await this.db.get("lastTs") || 0;
73+
74+
const entries = await this.refiner._makeRequest({
75+
method: "GET",
76+
path: "/segment-entries",
77+
params: {
78+
since: lastTs,
79+
sort: "asc",
80+
},
81+
});
82+
83+
let newLastTs = lastTs;
84+
85+
for (const entry of entries) {
86+
const ts = entry.timestamp
87+
? Date.parse(entry.timestamp)
88+
: Date.now();
89+
this.$emit(entry, {
90+
id: entry.id ?? ts,
91+
summary: `User ${entry.userId} entered segment ${entry.segmentId}`,
92+
ts,
93+
});
94+
95+
if (ts > newLastTs) {
96+
newLastTs = ts;
97+
}
98+
}
99+
100+
await this.db.set("lastTs", newLastTs);
101+
},
102+
};

0 commit comments

Comments
 (0)