Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 132 additions & 4 deletions components/easypromos/easypromos.app.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,139 @@
import { axios } from "@pipedream/platform";

export default {
type: "app",
app: "easypromos",
propDefinitions: {},
propDefinitions: {
userId: {
type: "integer",
label: "User ID",
description: "The ID of the user",
async options({
promotionId, prevContext,
}) {
const {
items, paging,
} = await this.getUsers({
promotionId,
params: {
next_cursor: prevContext.nextCursor,
},
});
return {
options: items.map(({
id: value, email: label,
}) => ({
label,
value,
})),
context: {
nextCursor: paging.next_cursor,
},
};
},
},
promotionId: {
type: "integer",
label: "Promotion ID",
description: "The ID of the promotion",
async options({ prevContext }) {
const {
items, paging,
} = await this.getPromotions({
params: {
next_cursor: prevContext.nextCursor,
},
});
return {
options: items.map(({
id, title, internal_ref: ref,
}) => ({
label: ref || title,
value: parseInt(id),
})),
context: {
nextCursor: paging.next_cursor,
},
};
},
},
},
methods: {
// this.$auth contains connected account data
authKeys() {
console.log(Object.keys(this.$auth));
_baseUrl() {
return "https://api.easypromosapp.com/v2";
},
_headers() {
return {
Authorization: `Bearer ${this.$auth.api_key}`,
};
},
_makeRequest({
$ = this, path, ...opts
}) {
return axios($, {
url: this._baseUrl() + path,
headers: this._headers(),
...opts,
});
},
getCoinTransactions({
promotionId, ...opts
}) {
return this._makeRequest({
path: `/coin_transactions/${promotionId}`,
...opts,
});
},
getUsers({
promotionId, ...opts
}) {
return this._makeRequest({
path: `/users/${promotionId}`,
...opts,
});
},
getParticipations({
promotionId, ...opts
}) {
return this._makeRequest({
path: `/participations/${promotionId}`,
...opts,
});
},
getPromotions(opts = {}) {
return this._makeRequest({
path: "/promotions",
...opts,
});
},
async *paginate({
fn, params = {}, maxResults = null, ...opts
}) {
let hasMore = false;
let count = 0;
let nextCursor = null;

do {
params.next_cursor = nextCursor;
const {
items,
paging: { next_cursor },
} = await fn({
params,
...opts,
});
for (const d of items) {
yield d;

if (maxResults && ++count === maxResults) {
return count;
}
}

nextCursor = next_cursor;
hasMore = nextCursor;

} while (hasMore);
},
},
};
7 changes: 5 additions & 2 deletions components/easypromos/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pipedream/easypromos",
"version": "0.0.1",
"version": "0.1.0",
"description": "Pipedream Easypromos Components",
"main": "easypromos.app.mjs",
"keywords": [
Expand All @@ -11,5 +11,8 @@
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@pipedream/platform": "^3.0.3"
}
}
}
87 changes: 87 additions & 0 deletions components/easypromos/sources/common/base.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {
ConfigurationError, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
} from "@pipedream/platform";
import easypromos from "../../easypromos.app.mjs";

export default {
props: {
easypromos,
db: "$.service.db",
timer: {
type: "$.interface.timer",
default: {
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
},
},
info: {

Check warning on line 16 in components/easypromos/sources/common/base.mjs

View workflow job for this annotation

GitHub Actions / Lint Code Base

Component prop info must have a label. See https://pipedream.com/docs/components/guidelines/#props

Check warning on line 16 in components/easypromos/sources/common/base.mjs

View workflow job for this annotation

GitHub Actions / Lint Code Base

Component prop info must have a description. See https://pipedream.com/docs/components/guidelines/#props
type: "alert",
alertType: "info",
content: "The Easypromos API only works with \"White Label\" promotions, any other type will not appear in the list.",
},
promotionId: {
propDefinition: [
easypromos,
"promotionId",
],
},
},
methods: {
_getLastId() {
return this.db.get("lastId") || 0;
},
_setLastId(lastId) {
this.db.set("lastId", lastId);
},
getOpts() {
return {};
},
async emitEvent(maxResults = false) {
const lastId = this._getLastId();
let responseArray = [];

try {
const response = this.easypromos.paginate({
fn: this.getFunction(),
...this.getOpts(),
params: {
order: "created_desc",
},
});

for await (const item of response) {
if (item.id <= lastId) break;
responseArray.push(item);
}
} catch (err) {
console.log(err);
if (err?.response?.data?.code === 0) {
throw new ConfigurationError("You can only use this trigger with promotions that have the 'Virtual Coins' feature enabled.");
}
throw new ConfigurationError(err);
}

if (responseArray.length) {
if (maxResults && (responseArray.length > maxResults)) {
responseArray.length = maxResults;
}
this._setLastId(responseArray[0].id);
}

for (const item of responseArray.reverse()) {
this.$emit(item, {
id: item.id || item.transaction.id,
summary: this.getSummary(item),
ts: Date.parse(item.created || new Date()),
});
}
},
},
hooks: {
async deploy() {
await this.emitEvent(25);
},
},
async run() {
await this.emitEvent();
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import common from "../common/base.mjs";
import sampleEmit from "./test-event.mjs";

export default {
...common,
key: "easypromos-new-coin-transaction",
name: "New Coin Transaction",
description: "Emit new event when a user earns or spends coins.",
version: "0.0.1",
type: "source",
dedupe: "unique",
props: {
...common.props,
info2: {

Check warning on line 14 in components/easypromos/sources/new-coin-transaction/new-coin-transaction.mjs

View workflow job for this annotation

GitHub Actions / Lint Code Base

Component prop info2 must have a label. See https://pipedream.com/docs/components/guidelines/#props

Check warning on line 14 in components/easypromos/sources/new-coin-transaction/new-coin-transaction.mjs

View workflow job for this annotation

GitHub Actions / Lint Code Base

Component prop info2 must have a description. See https://pipedream.com/docs/components/guidelines/#props
type: "alert",
alertType: "warning",
content: "You can only use this trigger with promotions that have the 'Virtual Coins' feature enabled.",
},
},
methods: {
...common.methods,
getFunction() {
return this.easypromos.getCoinTransactions;
},
getOpts() {
return {
promotionId: this.promotionId,
};
},
getSummary({
transaction, user,
}) {
return `Coin transaction: ${transaction.amount} for user ${user.email}`;
},
},
sampleEmit,
};
54 changes: 54 additions & 0 deletions components/easypromos/sources/new-coin-transaction/test-event.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export default {
"transaction": {
"id": 1,
"user_id": 1,
"promotion_id": 1,
"coin_id": 1,
"coin_name": "Points",
"amount": 5,
"balance": 5,
"created": "2019-08-24T14:15:22Z",
"transaction_type": 1,
"reason": "Earned for participating in a stage",
"extra": "string"
},
"user": {
"id": 1,
"promotion_id": 1,
"first_name": "John",
"last_name": "Smith",
"nickname": "jsmith",
"login_type": "email",
"social_id": "string",
"external_id": "string",
"status": 0,
"email": "[email protected]",
"phone": "string",
"birthday": "2019-08-24",
"created": "2019-08-24T14:15:22Z",
"avatar_img": "http://example.com",
"language": "ara",
"country": "FR",
"custom_properties": [
{
"id": 1,
"title": "Postal code",
"ref": "postalcode",
"value": "PC98776"
}
],
"meta_data": {
"utm_source": "instagram",
"utm_medium": "ads",
"utm_campaign": "campaign-week1",
"referral_url": "http://example.com",
"ip": "192.168.0.1",
"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",
"legals": {
"terms_url": "https://a.cstmapp.com/promo_terms/919755",
"privacy_url": "https://a.cstmapp.com/policy/987543",
"accepted_cookies": 1
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import common from "../common/base.mjs";
import sampleEmit from "./test-event.mjs";

export default {
...common,
key: "easypromos-new-participation",
name: "New Participation Submitted",
description: "Emit new event when a registered user submits a participation in the promotion.",
version: "0.0.1",
type: "source",
dedupe: "unique",
methods: {
...common.methods,
getFunction() {
return this.easypromos.getParticipations;
},
getOpts() {
return {
promotionId: this.promotionId,
};
},
getSummary(participation) {
return `New Participation: ${participation.id}`;
},
},
sampleEmit,
};
19 changes: 19 additions & 0 deletions components/easypromos/sources/new-participation/test-event.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export default {
"id": 1,
"promotion_id": 1,
"stage_id": 1,
"user_id": 1,
"created": "2019-08-24T14:15:22Z",
"ip": "192.168.0.1",
"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",
"points": 786.43,
"data": [
{
"ref": "Question1",
"title": "Pick your favorite city",
"values": [
"Barcelona"
]
}
]
}
Loading
Loading