Skip to content

Commit 5785b70

Browse files
authored
New Components - easypromos (#15201)
* easypromos init * [Components] easypromos #15197 Sources - New Coin Transaction - New Participation - New User * add info prop * pnpm update * pnpm update * some adjusts * some adjusts
1 parent 79b2546 commit 5785b70

File tree

10 files changed

+432
-7
lines changed

10 files changed

+432
-7
lines changed
+132-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,139 @@
1+
import { axios } from "@pipedream/platform";
2+
13
export default {
24
type: "app",
35
app: "easypromos",
4-
propDefinitions: {},
6+
propDefinitions: {
7+
userId: {
8+
type: "integer",
9+
label: "User ID",
10+
description: "The ID of the user",
11+
async options({
12+
promotionId, prevContext,
13+
}) {
14+
const {
15+
items, paging,
16+
} = await this.getUsers({
17+
promotionId,
18+
params: {
19+
next_cursor: prevContext.nextCursor,
20+
},
21+
});
22+
return {
23+
options: items.map(({
24+
id: value, email: label,
25+
}) => ({
26+
label,
27+
value,
28+
})),
29+
context: {
30+
nextCursor: paging.next_cursor,
31+
},
32+
};
33+
},
34+
},
35+
promotionId: {
36+
type: "integer",
37+
label: "Promotion ID",
38+
description: "The ID of the promotion",
39+
async options({ prevContext }) {
40+
const {
41+
items, paging,
42+
} = await this.getPromotions({
43+
params: {
44+
next_cursor: prevContext.nextCursor,
45+
},
46+
});
47+
return {
48+
options: items.map(({
49+
id, title, internal_ref: ref,
50+
}) => ({
51+
label: ref || title,
52+
value: parseInt(id),
53+
})),
54+
context: {
55+
nextCursor: paging.next_cursor,
56+
},
57+
};
58+
},
59+
},
60+
},
561
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
62+
_baseUrl() {
63+
return "https://api.easypromosapp.com/v2";
64+
},
65+
_headers() {
66+
return {
67+
Authorization: `Bearer ${this.$auth.api_key}`,
68+
};
69+
},
70+
_makeRequest({
71+
$ = this, path, ...opts
72+
}) {
73+
return axios($, {
74+
url: this._baseUrl() + path,
75+
headers: this._headers(),
76+
...opts,
77+
});
78+
},
79+
getCoinTransactions({
80+
promotionId, ...opts
81+
}) {
82+
return this._makeRequest({
83+
path: `/coin_transactions/${promotionId}`,
84+
...opts,
85+
});
86+
},
87+
getUsers({
88+
promotionId, ...opts
89+
}) {
90+
return this._makeRequest({
91+
path: `/users/${promotionId}`,
92+
...opts,
93+
});
94+
},
95+
getParticipations({
96+
promotionId, ...opts
97+
}) {
98+
return this._makeRequest({
99+
path: `/participations/${promotionId}`,
100+
...opts,
101+
});
102+
},
103+
getPromotions(opts = {}) {
104+
return this._makeRequest({
105+
path: "/promotions",
106+
...opts,
107+
});
108+
},
109+
async *paginate({
110+
fn, params = {}, maxResults = null, ...opts
111+
}) {
112+
let hasMore = false;
113+
let count = 0;
114+
let nextCursor = null;
115+
116+
do {
117+
params.next_cursor = nextCursor;
118+
const {
119+
items,
120+
paging: { next_cursor },
121+
} = await fn({
122+
params,
123+
...opts,
124+
});
125+
for (const d of items) {
126+
yield d;
127+
128+
if (maxResults && ++count === maxResults) {
129+
return count;
130+
}
131+
}
132+
133+
nextCursor = next_cursor;
134+
hasMore = nextCursor;
135+
136+
} while (hasMore);
9137
},
10138
},
11139
};

components/easypromos/package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/easypromos",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"description": "Pipedream Easypromos Components",
55
"main": "easypromos.app.mjs",
66
"keywords": [
@@ -11,5 +11,8 @@
1111
"author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
1212
"publishConfig": {
1313
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.0.3"
1417
}
15-
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import {
2+
ConfigurationError, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
3+
} from "@pipedream/platform";
4+
import easypromos from "../../easypromos.app.mjs";
5+
6+
export default {
7+
props: {
8+
easypromos,
9+
db: "$.service.db",
10+
timer: {
11+
type: "$.interface.timer",
12+
default: {
13+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
14+
},
15+
},
16+
info: {
17+
type: "alert",
18+
alertType: "info",
19+
content: "The Easypromos API only works with \"White Label\" promotions, any other type will not appear in the list.",
20+
},
21+
promotionId: {
22+
propDefinition: [
23+
easypromos,
24+
"promotionId",
25+
],
26+
},
27+
},
28+
methods: {
29+
_getLastId() {
30+
return this.db.get("lastId") || 0;
31+
},
32+
_setLastId(lastId) {
33+
this.db.set("lastId", lastId);
34+
},
35+
getOpts() {
36+
return {};
37+
},
38+
async emitEvent(maxResults = false) {
39+
const lastId = this._getLastId();
40+
let responseArray = [];
41+
42+
try {
43+
const response = this.easypromos.paginate({
44+
fn: this.getFunction(),
45+
...this.getOpts(),
46+
params: {
47+
order: "created_desc",
48+
},
49+
});
50+
51+
for await (const item of response) {
52+
if (item.id <= lastId) break;
53+
responseArray.push(item);
54+
}
55+
} catch (err) {
56+
console.log(err);
57+
if (err?.response?.data?.code === 0) {
58+
throw new ConfigurationError("You can only use this trigger with promotions that have the 'Virtual Coins' feature enabled.");
59+
}
60+
throw new ConfigurationError(err);
61+
}
62+
63+
if (responseArray.length) {
64+
if (maxResults && (responseArray.length > maxResults)) {
65+
responseArray.length = maxResults;
66+
}
67+
this._setLastId(responseArray[0].id);
68+
}
69+
70+
for (const item of responseArray.reverse()) {
71+
this.$emit(item, {
72+
id: item.id || item.transaction.id,
73+
summary: this.getSummary(item),
74+
ts: Date.parse(item.created || new Date()),
75+
});
76+
}
77+
},
78+
},
79+
hooks: {
80+
async deploy() {
81+
await this.emitEvent(25);
82+
},
83+
},
84+
async run() {
85+
await this.emitEvent();
86+
},
87+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import common from "../common/base.mjs";
2+
import sampleEmit from "./test-event.mjs";
3+
4+
export default {
5+
...common,
6+
key: "easypromos-new-coin-transaction",
7+
name: "New Coin Transaction",
8+
description: "Emit new event when a user earns or spends coins.",
9+
version: "0.0.1",
10+
type: "source",
11+
dedupe: "unique",
12+
props: {
13+
...common.props,
14+
info2: {
15+
type: "alert",
16+
alertType: "warning",
17+
content: "You can only use this trigger with promotions that have the 'Virtual Coins' feature enabled.",
18+
},
19+
},
20+
methods: {
21+
...common.methods,
22+
getFunction() {
23+
return this.easypromos.getCoinTransactions;
24+
},
25+
getOpts() {
26+
return {
27+
promotionId: this.promotionId,
28+
};
29+
},
30+
getSummary({
31+
transaction, user,
32+
}) {
33+
return `Coin transaction: ${transaction.amount} for user ${user.email}`;
34+
},
35+
},
36+
sampleEmit,
37+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
export default {
2+
"transaction": {
3+
"id": 1,
4+
"user_id": 1,
5+
"promotion_id": 1,
6+
"coin_id": 1,
7+
"coin_name": "Points",
8+
"amount": 5,
9+
"balance": 5,
10+
"created": "2019-08-24T14:15:22Z",
11+
"transaction_type": 1,
12+
"reason": "Earned for participating in a stage",
13+
"extra": "string"
14+
},
15+
"user": {
16+
"id": 1,
17+
"promotion_id": 1,
18+
"first_name": "John",
19+
"last_name": "Smith",
20+
"nickname": "jsmith",
21+
"login_type": "email",
22+
"social_id": "string",
23+
"external_id": "string",
24+
"status": 0,
25+
"email": "user@example.com",
26+
"phone": "string",
27+
"birthday": "2019-08-24",
28+
"created": "2019-08-24T14:15:22Z",
29+
"avatar_img": "http://example.com",
30+
"language": "ara",
31+
"country": "FR",
32+
"custom_properties": [
33+
{
34+
"id": 1,
35+
"title": "Postal code",
36+
"ref": "postalcode",
37+
"value": "PC98776"
38+
}
39+
],
40+
"meta_data": {
41+
"utm_source": "instagram",
42+
"utm_medium": "ads",
43+
"utm_campaign": "campaign-week1",
44+
"referral_url": "http://example.com",
45+
"ip": "192.168.0.1",
46+
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",
47+
"legals": {
48+
"terms_url": "https://a.cstmapp.com/promo_terms/919755",
49+
"privacy_url": "https://a.cstmapp.com/policy/987543",
50+
"accepted_cookies": 1
51+
}
52+
}
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import common from "../common/base.mjs";
2+
import sampleEmit from "./test-event.mjs";
3+
4+
export default {
5+
...common,
6+
key: "easypromos-new-participation",
7+
name: "New Participation Submitted",
8+
description: "Emit new event when a registered user submits a participation in the promotion.",
9+
version: "0.0.1",
10+
type: "source",
11+
dedupe: "unique",
12+
methods: {
13+
...common.methods,
14+
getFunction() {
15+
return this.easypromos.getParticipations;
16+
},
17+
getOpts() {
18+
return {
19+
promotionId: this.promotionId,
20+
};
21+
},
22+
getSummary(participation) {
23+
return `New Participation: ${participation.id}`;
24+
},
25+
},
26+
sampleEmit,
27+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export default {
2+
"id": 1,
3+
"promotion_id": 1,
4+
"stage_id": 1,
5+
"user_id": 1,
6+
"created": "2019-08-24T14:15:22Z",
7+
"ip": "192.168.0.1",
8+
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/201.0.429950705 Mobile/15E148 Safari/604.1",
9+
"points": 786.43,
10+
"data": [
11+
{
12+
"ref": "Question1",
13+
"title": "Pick your favorite city",
14+
"values": [
15+
"Barcelona"
16+
]
17+
}
18+
]
19+
}

0 commit comments

Comments
 (0)