Skip to content

Commit dd912a3

Browse files
committed
Adding microsoft calendar source
1 parent 034ae38 commit dd912a3

File tree

3 files changed

+136
-2
lines changed

3 files changed

+136
-2
lines changed

components/google_calendar/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/google_calendar",
3-
"version": "0.5.13",
3+
"version": "0.6.0",
44
"description": "Pipedream Google_calendar Components",
55
"main": "google_calendar.app.mjs",
66
"keywords": [

components/microsoft_outlook_calendar/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/microsoft_outlook_calendar",
3-
"version": "0.3.4",
3+
"version": "0.4.0",
44
"description": "Pipedream Microsoft Outlook Calendar Components",
55
"main": "microsoft_outlook_calendar.app.mjs",
66
"keywords": [
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
2+
import microsoftOutlook from "../../microsoft_outlook_calendar.app.mjs";
3+
import sampleEmit from "./test-event.mjs";
4+
5+
export default {
6+
key: "microsoft_outlook_calendar-new-upcoming-event-polling",
7+
name: "New Upcoming Calendar Event (Polling)",
8+
description: "Emit new event based on a time interval before an upcoming calendar event. [See the documentation](https://docs.microsoft.com/en-us/graph/api/user-list-events)",
9+
version: "0.0.1",
10+
type: "source",
11+
dedupe: "unique",
12+
props: {
13+
microsoftOutlook,
14+
db: "$.service.db",
15+
timer: {
16+
type: "$.interface.timer",
17+
default: {
18+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
19+
},
20+
},
21+
pollingInfo: {
22+
type: "alert",
23+
alertType: "info",
24+
content: "Since this source executes based on a timer, event emission may be slightly delayed. For example, if the source runs every 5 minutes, the delay may be up to 5 minutes. You can use the `new-upcoming-event` source for instant event emission.",
25+
},
26+
minutesBefore: {
27+
type: "integer",
28+
label: "Minutes Before",
29+
description: "Number of minutes to trigger before the start of the calendar event.",
30+
min: 0,
31+
default: 30,
32+
},
33+
},
34+
methods: {
35+
_getEmittedEvents() {
36+
return this.db.get("emittedEvents") || {};
37+
},
38+
_setEmittedEvents(emittedEvents) {
39+
this.db.set("emittedEvents", emittedEvents);
40+
},
41+
_cleanupEmittedEvents(now) {
42+
const emittedEvents = this._getEmittedEvents();
43+
const cleanedEvents = {};
44+
let cleanedCount = 0;
45+
46+
// Keep only events that haven't passed yet
47+
for (const [
48+
eventId,
49+
startTime,
50+
] of Object.entries(emittedEvents)) {
51+
if (startTime > now.getTime()) {
52+
cleanedEvents[eventId] = startTime;
53+
} else {
54+
cleanedCount++;
55+
}
56+
}
57+
58+
if (cleanedCount > 0) {
59+
console.log(`Cleaned up ${cleanedCount} past event(s) from emitted events tracker`);
60+
this._setEmittedEvents(cleanedEvents);
61+
}
62+
63+
return cleanedEvents;
64+
},
65+
generateMeta(event) {
66+
return {
67+
id: `${event.id}-${Date.now()}`,
68+
summary: `Upcoming: ${event.subject || `Event ID: ${event.id}`}`,
69+
ts: Date.now(),
70+
};
71+
},
72+
},
73+
hooks: {
74+
async deploy() {
75+
// On initial deploy, don't emit historical events
76+
// Just initialize the emitted events tracker
77+
this._setEmittedEvents({});
78+
},
79+
},
80+
async run() {
81+
const now = new Date();
82+
const alertWindowMs = this.minutesBefore * 60 * 1000;
83+
const timeMax = new Date(now.getTime() + alertWindowMs).toISOString();
84+
85+
// Clean up old emitted events
86+
const emittedEvents = this._cleanupEmittedEvents(now);
87+
88+
// Fetch events within the alert window
89+
const { value: events } = await this.microsoftOutlook.listCalendarView({
90+
params: {
91+
startDateTime: now.toISOString(),
92+
endDateTime: timeMax,
93+
$orderby: "start/dateTime",
94+
},
95+
});
96+
97+
if (!events || events.length === 0) {
98+
console.log("No upcoming events found in the alert window");
99+
return;
100+
}
101+
102+
for (const event of events) {
103+
// Skip if already emitted
104+
if (emittedEvents[event.id]) {
105+
continue;
106+
}
107+
108+
const startTime = event.start
109+
? new Date(event.start.dateTime)
110+
: null;
111+
112+
if (!startTime) {
113+
continue;
114+
}
115+
116+
const timeRemaining = startTime.getTime() - now.getTime();
117+
if (timeRemaining < 0) {
118+
continue;
119+
}
120+
121+
const alertThresholdMs = this.minutesBefore * 60 * 1000;
122+
123+
// Emit if time remaining is less than or equal to the alert threshold
124+
if (timeRemaining <= alertThresholdMs) {
125+
emittedEvents[event.id] = startTime.getTime();
126+
this._setEmittedEvents(emittedEvents);
127+
128+
this.$emit(event, this.generateMeta(event));
129+
}
130+
}
131+
},
132+
sampleEmit,
133+
};
134+

0 commit comments

Comments
 (0)