Skip to content

Commit 016a21a

Browse files
authored
New Components - planning_center (#16625)
* new components * pnpm-lock.yaml
1 parent 09c3714 commit 016a21a

File tree

9 files changed

+277
-20
lines changed

9 files changed

+277
-20
lines changed

components/planning_center/.gitignore

Lines changed: 0 additions & 3 deletions
This file was deleted.

components/planning_center/app/planning_center.app.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
{
22
"name": "@pipedream/planning_center",
3-
"version": "0.0.2",
3+
"version": "0.1.0",
44
"description": "Pipedream Planning Center Components",
5-
"main": "dist/app/planning_center.app.mjs",
5+
"main": "planning_center.app.mjs",
66
"keywords": [
77
"pipedream",
88
"planning_center"
99
],
10-
"files": ["dist"],
1110
"homepage": "https://pipedream.com/apps/planning_center",
1211
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
1312
"publishConfig": {
1413
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.0.3"
1517
}
1618
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { axios } from "@pipedream/platform";
2+
const DEFAULT_LIMIT = 25;
3+
const MAX_LIMIT = 100;
4+
5+
export default {
6+
type: "app",
7+
app: "planning_center",
8+
propDefinitions: {
9+
listId: {
10+
type: "string",
11+
label: "List ID",
12+
description: "The ID of the list to monitor for new persons",
13+
async options({ page }) {
14+
const { data } = await this.listLists({
15+
params: {
16+
per_page: DEFAULT_LIMIT,
17+
offset: page * DEFAULT_LIMIT,
18+
},
19+
});
20+
return data?.map(({
21+
id: value, attributes,
22+
}) => ({
23+
label: attributes.name_or_description,
24+
value,
25+
})) || [];
26+
},
27+
},
28+
},
29+
methods: {
30+
_baseUrl() {
31+
return "https://api.planningcenteronline.com";
32+
},
33+
_makeRequest({
34+
$ = this,
35+
path,
36+
...otherOpts
37+
}) {
38+
return axios($, {
39+
url: `${this._baseUrl()}${path}`,
40+
headers: {
41+
Authorization: `Bearer ${this.$auth.oauth_access_token}`,
42+
},
43+
...otherOpts,
44+
});
45+
},
46+
getListResult({
47+
listId, ...opts
48+
}) {
49+
return this._makeRequest({
50+
path: `/people/v2/lists/${listId}/list_results`,
51+
...opts,
52+
});
53+
},
54+
listLists(opts = {}) {
55+
return this._makeRequest({
56+
path: "/people/v2/lists",
57+
...opts,
58+
});
59+
},
60+
listDonations(opts = {}) {
61+
return this._makeRequest({
62+
path: "/giving/v2/donations",
63+
...opts,
64+
});
65+
},
66+
getCalendarEvents(opts = {}) {
67+
return this._makeRequest({
68+
path: "/calendar/v2/events",
69+
...opts,
70+
});
71+
},
72+
async *paginate({
73+
fn, args, max,
74+
}) {
75+
args = {
76+
...args,
77+
params: {
78+
...args?.params,
79+
per_page: MAX_LIMIT,
80+
offset: 0,
81+
},
82+
};
83+
let total, count = 0;
84+
85+
do {
86+
const { data } = await fn(args);
87+
for (const item of data) {
88+
yield item;
89+
if (max && ++count >= max) {
90+
return;
91+
}
92+
}
93+
total = data?.length;
94+
args.params.offset += args.params.per_page;
95+
} while (total);
96+
},
97+
},
98+
};
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import planningCenter from "../../planning_center.app.mjs";
2+
import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
3+
4+
export default {
5+
props: {
6+
planningCenter,
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+
_getLastTs() {
17+
return this.db.get("lastTs") || 0;
18+
},
19+
_setLastTs(lastTs) {
20+
this.db.set("lastTs", lastTs);
21+
},
22+
getArgs() {
23+
return {};
24+
},
25+
getTs(item) {
26+
return Date.parse(item.attributes.created_at);
27+
},
28+
isSorted() {
29+
return true;
30+
},
31+
emitEvent(item) {
32+
const meta = this.generateMeta(item);
33+
this.$emit(item, meta);
34+
},
35+
generateMeta(item) {
36+
return {
37+
id: item.id,
38+
summary: this.getSummary(item),
39+
ts: this.getTs(item),
40+
};
41+
},
42+
async processEvent(max) {
43+
const lastTs = this._getLastTs();
44+
let maxTs = lastTs;
45+
const fn = this.getResourceFn();
46+
const args = this.getArgs();
47+
const isSorted = this.isSorted();
48+
49+
const results = this.planningCenter.paginate({
50+
fn,
51+
args,
52+
max,
53+
});
54+
55+
for await (const item of results) {
56+
const ts = this.getTs(item);
57+
if (ts >= lastTs) {
58+
this.emitEvent(item);
59+
maxTs = Math.max(ts, maxTs);
60+
} else if (isSorted) {
61+
break;
62+
}
63+
}
64+
65+
this._setLastTs(maxTs);
66+
},
67+
getResourceFn() {
68+
throw new Error("getResourceFn is not implemented");
69+
},
70+
getSummary() {
71+
throw new Error("getSummary is not implemented");
72+
},
73+
},
74+
hooks: {
75+
async deploy() {
76+
await this.processEvent(25);
77+
},
78+
},
79+
async run() {
80+
await this.processEvent();
81+
},
82+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import common from "../common/base.mjs";
2+
3+
export default {
4+
...common,
5+
key: "planning_center-new-calendar-event",
6+
name: "New Calendar Event",
7+
description: "Emit new event when a new calendar event is created. [See the documentation](https://developer.planning.center/docs/#/apps/calendar/2022-07-07/vertices/event)",
8+
version: "0.0.1",
9+
type: "source",
10+
dedupe: "unique",
11+
methods: {
12+
...common.methods,
13+
getResourceFn() {
14+
return this.planningCenter.getCalendarEvents;
15+
},
16+
isSorted() {
17+
return false;
18+
},
19+
getSummary(item) {
20+
return `New Calendar Event with ID: ${item.id}`;
21+
},
22+
},
23+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import common from "../common/base.mjs";
2+
3+
export default {
4+
...common,
5+
key: "planning_center-new-donation",
6+
name: "New Donation Received",
7+
description: "Emit new event when a donation is received. [See the documentation](https://developer.planning.center/docs/#/apps/giving/2019-10-18/vertices/donation)",
8+
version: "0.0.1",
9+
type: "source",
10+
dedupe: "unique",
11+
methods: {
12+
...common.methods,
13+
getResourceFn() {
14+
return this.planningCenter.listDonations;
15+
},
16+
getArgs() {
17+
return {
18+
params: {
19+
order: "-created_at",
20+
},
21+
};
22+
},
23+
getSummary(item) {
24+
return `New Donation with ID: ${item.id}`;
25+
},
26+
},
27+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import common from "../common/base.mjs";
2+
3+
export default {
4+
...common,
5+
key: "planning_center-new-list-result",
6+
name: "New Person Added to List",
7+
description: "Emit new event when a person is added to the specified list. [See the documentation](https://developer.planning.center/docs/#/apps/people/2025-03-20/vertices/list_result)",
8+
version: "0.0.1",
9+
type: "source",
10+
dedupe: "unique",
11+
props: {
12+
...common.props,
13+
listId: {
14+
propDefinition: [
15+
common.props.planningCenter,
16+
"listId",
17+
],
18+
},
19+
},
20+
methods: {
21+
...common.methods,
22+
getResourceFn() {
23+
return this.planningCenter.getListResult;
24+
},
25+
getArgs() {
26+
return {
27+
listId: this.listId,
28+
params: {
29+
order: "-created_at",
30+
},
31+
};
32+
},
33+
getSummary(item) {
34+
return `New List Result with ID: ${item.id}`;
35+
},
36+
},
37+
};

pnpm-lock.yaml

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)