@pipedream/google_calendar 0.6.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actions/add-attendees-to-event/add-attendees-to-event.mjs +1 -1
- package/actions/common/create-event-common.mjs +37 -20
- package/actions/create-event/create-event.mjs +70 -71
- package/actions/delete-event/delete-event.mjs +1 -1
- package/actions/get-calendar/get-calendar.mjs +1 -1
- package/actions/get-current-user/get-current-user.mjs +1 -1
- package/actions/get-date-time/get-date-time.mjs +59 -0
- package/actions/get-event/get-event.mjs +1 -1
- package/actions/list-calendars/list-calendars.mjs +1 -1
- package/actions/list-event-instances/list-event-instances.mjs +99 -0
- package/actions/list-events/list-events.mjs +1 -1
- package/actions/query-free-busy-calendars/query-free-busy-calendars.mjs +1 -1
- package/actions/quick-add-event/quick-add-event.mjs +1 -1
- package/actions/update-event/update-event.mjs +1 -1
- package/actions/update-event-instance/update-event-instance.mjs +135 -0
- package/actions/update-following-instances/update-following-instances.mjs +259 -0
- package/google_calendar.app.mjs +73 -0
- package/package.json +1 -1
- package/sources/event-cancelled/event-cancelled.mjs +1 -1
- package/sources/event-ended/event-ended.mjs +1 -1
- package/sources/new-calendar/new-calendar.mjs +1 -1
- package/sources/new-event-search/new-event-search.mjs +1 -1
- package/sources/new-or-updated-event-instant/new-or-updated-event-instant.mjs +1 -1
- package/sources/upcoming-event-alert/upcoming-event-alert.mjs +1 -1
- package/sources/upcoming-event-alert-polling/upcoming-event-alert-polling.mjs +1 -1
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
key: "google_calendar-add-attendees-to-event",
|
|
6
6
|
name: "Add Attendees To Event",
|
|
7
7
|
description: "Add attendees to an existing event. [See the documentation](https://googleapis.dev/nodejs/googleapis/latest/calendar/classes/Resource$Events.html#update)",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.6",
|
|
9
9
|
annotations: {
|
|
10
10
|
destructiveHint: true,
|
|
11
11
|
openWorldHint: true,
|
|
@@ -82,31 +82,48 @@ export default {
|
|
|
82
82
|
});
|
|
83
83
|
return timeZone;
|
|
84
84
|
},
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
selectedAttendees = selectedAttendees.includes("[") && selectedAttendees.includes("]")
|
|
97
|
-
? JSON.parse(selectedAttendees)
|
|
98
|
-
: selectedAttendees.replaceAll(" ", "").split(",");
|
|
85
|
+
parseEmails(input) {
|
|
86
|
+
if (typeof input === "string") {
|
|
87
|
+
return input.split(",")
|
|
88
|
+
.map((e) => e.trim())
|
|
89
|
+
.filter(Boolean);
|
|
90
|
+
}
|
|
91
|
+
if (Array.isArray(input)) {
|
|
92
|
+
return input
|
|
93
|
+
.filter((e) => typeof e === "string")
|
|
94
|
+
.map((e) => e.trim())
|
|
95
|
+
.filter(Boolean);
|
|
99
96
|
}
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
return [];
|
|
98
|
+
},
|
|
99
|
+
formatAttendees(selectedAttendees, currentAttendees) {
|
|
100
|
+
const emails = this.parseEmails(selectedAttendees);
|
|
101
|
+
|
|
102
|
+
if (emails.length) {
|
|
103
|
+
return emails.map((email) => ({
|
|
102
104
|
email,
|
|
103
105
|
}));
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Fall back to currentAttendees if no selectedAttendees
|
|
109
|
+
const fallbackEmails = this.parseEmails(currentAttendees);
|
|
110
|
+
if (fallbackEmails.length) {
|
|
111
|
+
return fallbackEmails.map((email) => ({
|
|
112
|
+
email,
|
|
107
113
|
}));
|
|
108
114
|
}
|
|
109
|
-
|
|
115
|
+
|
|
116
|
+
// Handle currentAttendees as array of attendee objects
|
|
117
|
+
if (Array.isArray(currentAttendees) && currentAttendees.length) {
|
|
118
|
+
return currentAttendees
|
|
119
|
+
.filter((a) => a && typeof a.email === "string")
|
|
120
|
+
.map((attendee) => ({
|
|
121
|
+
email: attendee.email.trim(),
|
|
122
|
+
}))
|
|
123
|
+
.filter((a) => a.email);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return [];
|
|
110
127
|
},
|
|
111
128
|
checkDateOrDateTimeInput(date, type) {
|
|
112
129
|
if (type === "date") {
|
|
@@ -7,7 +7,7 @@ export default {
|
|
|
7
7
|
key: "google_calendar-create-event",
|
|
8
8
|
name: "Create Event",
|
|
9
9
|
description: "Create an event in a Google Calendar. [See the documentation](https://developers.google.com/calendar/api/v3/reference/events/insert)",
|
|
10
|
-
version: "0.
|
|
10
|
+
version: "1.0.0",
|
|
11
11
|
annotations: {
|
|
12
12
|
destructiveHint: false,
|
|
13
13
|
openWorldHint: true,
|
|
@@ -16,68 +16,68 @@ export default {
|
|
|
16
16
|
type: "action",
|
|
17
17
|
props: {
|
|
18
18
|
googleCalendar,
|
|
19
|
-
addType: {
|
|
20
|
-
type: "string",
|
|
21
|
-
label: "Type of Add",
|
|
22
|
-
description: "Whether to perform a quick add or a detailed event",
|
|
23
|
-
options: [
|
|
24
|
-
{
|
|
25
|
-
label: "Add Detailed Event",
|
|
26
|
-
value: "detailed",
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
label: "Add Quick Event using Natural Language",
|
|
30
|
-
value: "quick",
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
reloadProps: true,
|
|
34
|
-
},
|
|
35
19
|
calendarId: {
|
|
36
20
|
propDefinition: [
|
|
37
21
|
googleCalendar,
|
|
38
22
|
"calendarId",
|
|
39
23
|
],
|
|
40
24
|
},
|
|
41
|
-
text: {
|
|
42
|
-
type: "string",
|
|
43
|
-
label: "Describe Event",
|
|
44
|
-
description: "Write a plain text description of event, and Google will parse this string to create the event. eg. 'Meet with Michael 10am 7/22/2024' or 'Call Sarah at 1:30PM on Friday'",
|
|
45
|
-
hidden: true,
|
|
46
|
-
},
|
|
47
25
|
summary: {
|
|
48
26
|
label: "Event Title",
|
|
49
27
|
type: "string",
|
|
50
28
|
description: "Enter a title for the event, (e.g., `My event`)",
|
|
29
|
+
},
|
|
30
|
+
eventStartDate: {
|
|
31
|
+
label: "Event Start Date",
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "For all-day events, enter the date in the format `yyyy-mm-dd` (e.g., `2025-01-15`). For events with time, format according to [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.html#section-1): `yyyy-mm-ddThh:mm:ss+01:00` (e.g., `2025-01-15T10:00:00-05:00`). A time zone offset is required unless a time zone is explicitly specified in timeZone.",
|
|
34
|
+
},
|
|
35
|
+
eventEndDate: {
|
|
36
|
+
label: "Event End Date",
|
|
37
|
+
type: "string",
|
|
38
|
+
description: "For all-day events, enter the date in the format `yyyy-mm-dd` (e.g., `2025-01-15`). For events with time, format according to [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.html#section-1): `yyyy-mm-ddThh:mm:ss+01:00` (e.g., `2025-01-15T11:00:00-05:00`). A time zone offset is required unless a time zone is explicitly specified in timeZone.",
|
|
39
|
+
},
|
|
40
|
+
location: {
|
|
41
|
+
label: "Event Location",
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "Specify the location of the event",
|
|
44
|
+
optional: true,
|
|
45
|
+
},
|
|
46
|
+
description: {
|
|
47
|
+
label: "Event Description",
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "Enter a description for the event",
|
|
50
|
+
optional: true,
|
|
51
|
+
},
|
|
52
|
+
attendees: {
|
|
53
|
+
label: "Attendees",
|
|
54
|
+
type: "string[]",
|
|
55
|
+
description: "An array of email addresses (e.g., `[\"alice@example.com\", \"bob@example.com\"]`)",
|
|
51
56
|
optional: true,
|
|
52
|
-
hidden: true,
|
|
53
57
|
},
|
|
54
58
|
colorId: {
|
|
55
59
|
propDefinition: [
|
|
56
60
|
googleCalendar,
|
|
57
61
|
"colorId",
|
|
58
62
|
],
|
|
59
|
-
hidden: true,
|
|
60
63
|
},
|
|
61
64
|
timeZone: {
|
|
62
65
|
propDefinition: [
|
|
63
66
|
googleCalendar,
|
|
64
67
|
"timeZone",
|
|
65
68
|
],
|
|
66
|
-
hidden: true,
|
|
67
69
|
},
|
|
68
70
|
sendUpdates: {
|
|
69
71
|
propDefinition: [
|
|
70
72
|
googleCalendar,
|
|
71
73
|
"sendUpdates",
|
|
72
74
|
],
|
|
73
|
-
hidden: true,
|
|
74
75
|
},
|
|
75
76
|
createMeetRoom: {
|
|
76
77
|
type: "boolean",
|
|
77
78
|
label: "Create Meet Room",
|
|
78
79
|
description: "Whether to create a Google Meet room for this event.",
|
|
79
80
|
optional: true,
|
|
80
|
-
hidden: true,
|
|
81
81
|
},
|
|
82
82
|
visibility: {
|
|
83
83
|
type: "string",
|
|
@@ -90,49 +90,45 @@ export default {
|
|
|
90
90
|
"confidential",
|
|
91
91
|
],
|
|
92
92
|
optional: true,
|
|
93
|
-
|
|
93
|
+
},
|
|
94
|
+
repeatFrequency: {
|
|
95
|
+
type: "string",
|
|
96
|
+
label: "Repeat Frequency",
|
|
97
|
+
description: "Select a frequency to make this event repeating",
|
|
98
|
+
optional: true,
|
|
99
|
+
options: Object.keys(constants.REPEAT_FREQUENCIES),
|
|
100
|
+
reloadProps: true,
|
|
94
101
|
},
|
|
95
102
|
},
|
|
96
|
-
async additionalProps(
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
return commonProps;
|
|
103
|
+
async additionalProps() {
|
|
104
|
+
const props = {};
|
|
105
|
+
const frequency = constants.REPEAT_FREQUENCIES[this.repeatFrequency];
|
|
106
|
+
if (frequency) {
|
|
107
|
+
props.repeatInterval = {
|
|
108
|
+
type: "integer",
|
|
109
|
+
label: "Repeat Interval",
|
|
110
|
+
description: `Enter 1 to "repeat every ${frequency}", enter 2 to "repeat every other ${frequency}", etc. Defaults to 1.`,
|
|
111
|
+
optional: true,
|
|
112
|
+
};
|
|
113
|
+
props.repeatUntil = {
|
|
114
|
+
type: "string",
|
|
115
|
+
label: "Repeat Until",
|
|
116
|
+
description: "The event will repeat only until this date (format: `yyyy-mm-dd`, e.g., `2025-12-31`)",
|
|
117
|
+
optional: true,
|
|
118
|
+
};
|
|
119
|
+
props.repeatTimes = {
|
|
120
|
+
type: "integer",
|
|
121
|
+
label: "Repeat How Many Times?",
|
|
122
|
+
description: "Limit the number of times this event will occur",
|
|
123
|
+
optional: true,
|
|
124
|
+
};
|
|
120
125
|
}
|
|
121
|
-
return
|
|
126
|
+
return props;
|
|
122
127
|
},
|
|
123
128
|
methods: {
|
|
124
129
|
...createEventCommon.methods,
|
|
125
130
|
},
|
|
126
131
|
async run({ $ }) {
|
|
127
|
-
if (this.addType === "quick") {
|
|
128
|
-
const quickResponse = await this.googleCalendar.quickAddEvent({
|
|
129
|
-
calendarId: this.calendarId,
|
|
130
|
-
text: this.text,
|
|
131
|
-
});
|
|
132
|
-
$.export("$summary", `Successfully added a quick event: "${quickResponse.id}"`);
|
|
133
|
-
return quickResponse;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
132
|
const timeZone = await this.getTimeZone(this.timeZone);
|
|
137
133
|
const attendees = this.formatAttendees(this.attendees);
|
|
138
134
|
const recurrence = this.formatRecurrence({
|
|
@@ -142,6 +138,9 @@ export default {
|
|
|
142
138
|
repeatUntil: this.repeatUntil,
|
|
143
139
|
});
|
|
144
140
|
|
|
141
|
+
const trimmedStart = this.eventStartDate?.trim();
|
|
142
|
+
const trimmedEnd = this.eventEndDate?.trim();
|
|
143
|
+
|
|
145
144
|
const data = {
|
|
146
145
|
calendarId: this.calendarId,
|
|
147
146
|
sendUpdates: this.sendUpdates,
|
|
@@ -150,20 +149,20 @@ export default {
|
|
|
150
149
|
location: this.location,
|
|
151
150
|
description: this.description,
|
|
152
151
|
start: {
|
|
153
|
-
date:
|
|
154
|
-
?
|
|
152
|
+
date: trimmedStart?.length <= 10
|
|
153
|
+
? trimmedStart
|
|
155
154
|
: undefined,
|
|
156
|
-
dateTime:
|
|
157
|
-
?
|
|
155
|
+
dateTime: trimmedStart?.length > 10
|
|
156
|
+
? trimmedStart
|
|
158
157
|
: undefined,
|
|
159
158
|
timeZone,
|
|
160
159
|
},
|
|
161
160
|
end: {
|
|
162
|
-
date:
|
|
163
|
-
?
|
|
161
|
+
date: trimmedEnd?.length <= 10
|
|
162
|
+
? trimmedEnd
|
|
164
163
|
: undefined,
|
|
165
|
-
dateTime:
|
|
166
|
-
?
|
|
164
|
+
dateTime: trimmedEnd?.length > 10
|
|
165
|
+
? trimmedEnd
|
|
167
166
|
: undefined,
|
|
168
167
|
timeZone,
|
|
169
168
|
},
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_calendar-delete-event",
|
|
5
5
|
name: "Delete an Event",
|
|
6
6
|
description: "Delete an event from a Google Calendar. [See the documentation](https://googleapis.dev/nodejs/googleapis/latest/calendar/classes/Resource$Events.html#delete)",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.9",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: true,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_calendar-get-calendar",
|
|
5
5
|
name: "Retrieve Calendar Details",
|
|
6
6
|
description: "Retrieve calendar details of a Google Calendar. [See the documentation](https://googleapis.dev/nodejs/googleapis/latest/calendar/classes/Resource$Calendars.html#get)",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.10",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -7,7 +7,7 @@ export default {
|
|
|
7
7
|
key: "google_calendar-get-current-user",
|
|
8
8
|
name: "Get Current User",
|
|
9
9
|
description: "Retrieve information about the authenticated Google Calendar account, including the primary calendar (summary, timezone, ACL flags), a list of accessible calendars, user-level settings (timezone, locale, week start), and the color palette that controls events and calendars. Ideal for confirming which calendar account is in use, customizing downstream scheduling, or equipping LLMs with the user’s context (timezones, available calendars) prior to creating or updating events. [See the documentation](https://developers.google.com/calendar/api/v3/reference/calendars/get).",
|
|
10
|
-
version: "0.0.
|
|
10
|
+
version: "0.0.2",
|
|
11
11
|
type: "action",
|
|
12
12
|
annotations: {
|
|
13
13
|
destructiveHint: false,
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import googleCalendar from "../../google_calendar.app.mjs";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
key: "google_calendar-get-date-time",
|
|
5
|
+
name: "Get Date Time",
|
|
6
|
+
description: "Get current date and time for use in Google Calendar actions. Useful for agents that need datetime awareness and timezone context before calling other Google Calendar tools.",
|
|
7
|
+
version: "0.0.1",
|
|
8
|
+
type: "action",
|
|
9
|
+
annotations: {
|
|
10
|
+
destructiveHint: false,
|
|
11
|
+
openWorldHint: true,
|
|
12
|
+
readOnlyHint: true,
|
|
13
|
+
},
|
|
14
|
+
props: {
|
|
15
|
+
googleCalendar,
|
|
16
|
+
},
|
|
17
|
+
async run({ $ }) {
|
|
18
|
+
const now = new Date();
|
|
19
|
+
|
|
20
|
+
// Date in local timezone (YYYY-MM-DD)
|
|
21
|
+
const year = now.getFullYear();
|
|
22
|
+
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
23
|
+
const day = String(now.getDate()).padStart(2, "0");
|
|
24
|
+
const date = `${year}-${month}-${day}`;
|
|
25
|
+
|
|
26
|
+
// Time in local timezone (HH:MM:SS)
|
|
27
|
+
const time = now.toTimeString().split(" ")[0];
|
|
28
|
+
|
|
29
|
+
// Timezone (IANA name)
|
|
30
|
+
// eslint-disable-next-line no-undef
|
|
31
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
32
|
+
|
|
33
|
+
// Timezone offset (±HH:MM)
|
|
34
|
+
const tzDate = new Date();
|
|
35
|
+
const tzDateUTC = new Date(tzDate.toLocaleString("en-US", {
|
|
36
|
+
timeZone: "UTC",
|
|
37
|
+
}));
|
|
38
|
+
const diff = (tzDate - tzDateUTC) / 60000;
|
|
39
|
+
const hours = Math.floor(Math.abs(diff) / 60);
|
|
40
|
+
const mins = Math.abs(diff) % 60;
|
|
41
|
+
const offsetSign = diff >= 0
|
|
42
|
+
? "+"
|
|
43
|
+
: "-";
|
|
44
|
+
const timezoneOffset = `${offsetSign}${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}`;
|
|
45
|
+
|
|
46
|
+
const result = {
|
|
47
|
+
date,
|
|
48
|
+
time,
|
|
49
|
+
timezone,
|
|
50
|
+
timezoneOffset,
|
|
51
|
+
timestamp: now.getTime(),
|
|
52
|
+
isoString: now.toISOString(),
|
|
53
|
+
rfc3339: `${date}T${time}${timezoneOffset}`,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
$.export("$summary", `Retrieved current date time: ${date} ${time} (${timezone || ""} ${timezoneOffset})`);
|
|
57
|
+
return result;
|
|
58
|
+
},
|
|
59
|
+
};
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_calendar-get-event",
|
|
5
5
|
name: "Retrieve Event Details",
|
|
6
6
|
description: "Retrieve event details from Google Calendar. [See the documentation](https://googleapis.dev/nodejs/googleapis/latest/calendar/classes/Resource$Events.html#get)",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.10",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_calendar-list-calendars",
|
|
5
5
|
name: "List Calendars",
|
|
6
6
|
description: "Retrieve a list of calendars from Google Calendar. [See the documentation](https://googleapis.dev/nodejs/googleapis/latest/calendar/classes/Resource$Calendarlist.html#list)",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.10",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import googleCalendar from "../../google_calendar.app.mjs";
|
|
2
|
+
import utils from "../../common/utils.mjs";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
key: "google_calendar-list-event-instances",
|
|
6
|
+
name: "List Event Instances",
|
|
7
|
+
description: "Retrieve instances of a recurring event. [See the documentation](https://developers.google.com/calendar/api/v3/reference/events/instances)",
|
|
8
|
+
version: "0.0.1",
|
|
9
|
+
type: "action",
|
|
10
|
+
annotations: {
|
|
11
|
+
destructiveHint: false,
|
|
12
|
+
openWorldHint: true,
|
|
13
|
+
readOnlyHint: true,
|
|
14
|
+
},
|
|
15
|
+
props: {
|
|
16
|
+
googleCalendar,
|
|
17
|
+
calendarId: {
|
|
18
|
+
propDefinition: [
|
|
19
|
+
googleCalendar,
|
|
20
|
+
"calendarId",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
eventId: {
|
|
24
|
+
propDefinition: [
|
|
25
|
+
googleCalendar,
|
|
26
|
+
"eventId",
|
|
27
|
+
(c) => ({
|
|
28
|
+
calendarId: c.calendarId,
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
description: "The recurring event identifier. Select an event from Google Calendar.",
|
|
32
|
+
},
|
|
33
|
+
maxAttendees: {
|
|
34
|
+
propDefinition: [
|
|
35
|
+
googleCalendar,
|
|
36
|
+
"maxAttendees",
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
maxResults: {
|
|
40
|
+
propDefinition: [
|
|
41
|
+
googleCalendar,
|
|
42
|
+
"maxResults",
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
showDeleted: {
|
|
46
|
+
propDefinition: [
|
|
47
|
+
googleCalendar,
|
|
48
|
+
"showDeleted",
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
timeMax: {
|
|
52
|
+
propDefinition: [
|
|
53
|
+
googleCalendar,
|
|
54
|
+
"timeMax",
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
timeMin: {
|
|
58
|
+
propDefinition: [
|
|
59
|
+
googleCalendar,
|
|
60
|
+
"timeMin",
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
timeZone: {
|
|
64
|
+
propDefinition: [
|
|
65
|
+
googleCalendar,
|
|
66
|
+
"timeZone",
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
async run({ $ }) {
|
|
71
|
+
const args = utils.filterEmptyValues({
|
|
72
|
+
calendarId: this.calendarId,
|
|
73
|
+
eventId: this.eventId,
|
|
74
|
+
maxAttendees: this.maxAttendees,
|
|
75
|
+
showDeleted: this.showDeleted,
|
|
76
|
+
timeMax: this.timeMax,
|
|
77
|
+
timeMin: this.timeMin,
|
|
78
|
+
timeZone: this.timeZone,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const instances = [];
|
|
82
|
+
do {
|
|
83
|
+
const {
|
|
84
|
+
items, nextPageToken,
|
|
85
|
+
} = await this.googleCalendar.listEventInstances(args);
|
|
86
|
+
instances.push(...items);
|
|
87
|
+
args.pageToken = nextPageToken;
|
|
88
|
+
} while (args.pageToken && (!this.maxResults || instances.length < this.maxResults));
|
|
89
|
+
if (instances.length > this.maxResults) {
|
|
90
|
+
instances.length = this.maxResults;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
$.export("$summary", `Successfully retrieved ${instances.length} instance${instances.length === 1
|
|
94
|
+
? ""
|
|
95
|
+
: "s"} of recurring event`);
|
|
96
|
+
|
|
97
|
+
return instances;
|
|
98
|
+
},
|
|
99
|
+
};
|
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
key: "google_calendar-list-events",
|
|
7
7
|
name: "List Events",
|
|
8
8
|
description: "Retrieve a list of event from the Google Calendar. [See the documentation](https://developers.google.com/calendar/api/v3/reference/events/list)",
|
|
9
|
-
version: "0.0.
|
|
9
|
+
version: "0.0.10",
|
|
10
10
|
annotations: {
|
|
11
11
|
destructiveHint: false,
|
|
12
12
|
openWorldHint: true,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "google_calendar-query-free-busy-calendars",
|
|
5
5
|
name: "Retrieve Free/Busy Calendar Details",
|
|
6
6
|
description: "Retrieve free/busy calendar details from Google Calendar. [See the documentation](https://googleapis.dev/nodejs/googleapis/latest/calendar/classes/Resource$Freebusy.html#query)",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.10",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
key: "google_calendar-quick-add-event",
|
|
7
7
|
name: "Add Quick Event",
|
|
8
8
|
description: "Create a quick event to the Google Calendar. [See the documentation](https://googleapis.dev/nodejs/googleapis/latest/calendar/classes/Resource$Events.html#quickAdd)",
|
|
9
|
-
version: "0.1.
|
|
9
|
+
version: "0.1.11",
|
|
10
10
|
annotations: {
|
|
11
11
|
destructiveHint: false,
|
|
12
12
|
openWorldHint: true,
|
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
key: "google_calendar-update-event",
|
|
7
7
|
name: "Update Event",
|
|
8
8
|
description: "Update an event from Google Calendar. [See the documentation](https://googleapis.dev/nodejs/googleapis/latest/calendar/classes/Resource$Events.html#update)",
|
|
9
|
-
version: "0.0.
|
|
9
|
+
version: "0.0.13",
|
|
10
10
|
annotations: {
|
|
11
11
|
destructiveHint: true,
|
|
12
12
|
openWorldHint: true,
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import googleCalendar from "../../google_calendar.app.mjs";
|
|
2
|
+
import createEventCommon from "../common/create-event-common.mjs";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
key: "google_calendar-update-event-instance",
|
|
6
|
+
name: "Update Event Instance",
|
|
7
|
+
description: "Update a specific instance of a recurring event. Changes apply only to the selected instance. [See the documentation](https://developers.google.com/calendar/api/v3/reference/events/update)",
|
|
8
|
+
version: "0.0.2",
|
|
9
|
+
type: "action",
|
|
10
|
+
annotations: {
|
|
11
|
+
destructiveHint: true,
|
|
12
|
+
openWorldHint: true,
|
|
13
|
+
readOnlyHint: false,
|
|
14
|
+
},
|
|
15
|
+
props: {
|
|
16
|
+
googleCalendar,
|
|
17
|
+
calendarId: {
|
|
18
|
+
propDefinition: [
|
|
19
|
+
googleCalendar,
|
|
20
|
+
"calendarId",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
recurringEventId: {
|
|
24
|
+
propDefinition: [
|
|
25
|
+
googleCalendar,
|
|
26
|
+
"recurringEventId",
|
|
27
|
+
({ calendarId }) => ({
|
|
28
|
+
calendarId,
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
instanceId: {
|
|
33
|
+
propDefinition: [
|
|
34
|
+
googleCalendar,
|
|
35
|
+
"instanceId",
|
|
36
|
+
({
|
|
37
|
+
calendarId,
|
|
38
|
+
recurringEventId,
|
|
39
|
+
}) => ({
|
|
40
|
+
calendarId,
|
|
41
|
+
recurringEventId,
|
|
42
|
+
}),
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
summary: {
|
|
46
|
+
label: "Event Title",
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "Enter a new title for this instance",
|
|
49
|
+
optional: true,
|
|
50
|
+
},
|
|
51
|
+
eventStartDate: {
|
|
52
|
+
label: "Event Start Date",
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "For all-day events, enter the Event day in the format `yyyy-mm-dd`. For events with time, format according to [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.html#section-1): `yyyy-mm-ddThh:mm:ss+01:00`. A time zone offset is required unless a time zone is explicitly specified in timeZone.",
|
|
55
|
+
optional: true,
|
|
56
|
+
},
|
|
57
|
+
eventEndDate: {
|
|
58
|
+
label: "Event End Date",
|
|
59
|
+
type: "string",
|
|
60
|
+
description: "For all-day events, enter the Event day in the format `yyyy-mm-dd`. For events with time, format according to [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.html#section-1): `yyyy-mm-ddThh:mm:ss+01:00`. A time zone offset is required unless a time zone is explicitly specified in timeZone.",
|
|
61
|
+
optional: true,
|
|
62
|
+
},
|
|
63
|
+
location: {
|
|
64
|
+
label: "Event Location",
|
|
65
|
+
type: "string",
|
|
66
|
+
description: "Specify a new location for this instance",
|
|
67
|
+
optional: true,
|
|
68
|
+
},
|
|
69
|
+
description: {
|
|
70
|
+
label: "Event Description",
|
|
71
|
+
type: "string",
|
|
72
|
+
description: "Enter a new description for this instance",
|
|
73
|
+
optional: true,
|
|
74
|
+
},
|
|
75
|
+
attendees: {
|
|
76
|
+
label: "Attendees",
|
|
77
|
+
type: "string",
|
|
78
|
+
description: "Enter either an array or a comma separated list of email addresses of attendees",
|
|
79
|
+
optional: true,
|
|
80
|
+
},
|
|
81
|
+
colorId: {
|
|
82
|
+
propDefinition: [
|
|
83
|
+
googleCalendar,
|
|
84
|
+
"colorId",
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
timeZone: {
|
|
88
|
+
propDefinition: [
|
|
89
|
+
googleCalendar,
|
|
90
|
+
"timeZone",
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
sendUpdates: {
|
|
94
|
+
propDefinition: [
|
|
95
|
+
googleCalendar,
|
|
96
|
+
"sendUpdates",
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
methods: createEventCommon.methods,
|
|
101
|
+
async run({ $ }) {
|
|
102
|
+
const currentEvent = await this.googleCalendar.getEvent({
|
|
103
|
+
calendarId: this.calendarId,
|
|
104
|
+
eventId: this.instanceId,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const timeZone = await this.getTimeZone(this.timeZone || currentEvent.start.timeZone);
|
|
108
|
+
const attendees = this.formatAttendees(this.attendees, currentEvent.attendees);
|
|
109
|
+
|
|
110
|
+
const response = await this.googleCalendar.updateEvent({
|
|
111
|
+
calendarId: this.calendarId,
|
|
112
|
+
eventId: this.instanceId,
|
|
113
|
+
sendUpdates: this.sendUpdates,
|
|
114
|
+
requestBody: {
|
|
115
|
+
summary: this.summary || currentEvent.summary,
|
|
116
|
+
location: this.location || currentEvent.location,
|
|
117
|
+
description: this.description || currentEvent.description,
|
|
118
|
+
start: this.getDateParam({
|
|
119
|
+
date: this.eventStartDate || currentEvent.start.dateTime || currentEvent.start.date,
|
|
120
|
+
timeZone: timeZone || currentEvent.start.timeZone,
|
|
121
|
+
}),
|
|
122
|
+
end: this.getDateParam({
|
|
123
|
+
date: this.eventEndDate || currentEvent.end.dateTime || currentEvent.end.date,
|
|
124
|
+
timeZone: timeZone || currentEvent.end.timeZone,
|
|
125
|
+
}),
|
|
126
|
+
attendees,
|
|
127
|
+
colorId: this.colorId || currentEvent.colorId,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
$.export("$summary", `Successfully updated event instance \`${response.id}\``);
|
|
132
|
+
|
|
133
|
+
return response;
|
|
134
|
+
},
|
|
135
|
+
};
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import googleCalendar from "../../google_calendar.app.mjs";
|
|
2
|
+
import createEventCommon from "../common/create-event-common.mjs";
|
|
3
|
+
import constants from "../../common/constants.mjs";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
key: "google_calendar-update-following-instances",
|
|
7
|
+
name: "Update Following Event Instances",
|
|
8
|
+
description: "Update all instances of a recurring event following a specific instance. This creates a new recurring event starting from the selected instance. [See the documentation](https://developers.google.com/calendar/api/guides/recurringevents#modifying_all_following_instances)",
|
|
9
|
+
version: "0.0.2",
|
|
10
|
+
type: "action",
|
|
11
|
+
annotations: {
|
|
12
|
+
destructiveHint: true,
|
|
13
|
+
openWorldHint: true,
|
|
14
|
+
readOnlyHint: false,
|
|
15
|
+
},
|
|
16
|
+
props: {
|
|
17
|
+
googleCalendar,
|
|
18
|
+
calendarId: {
|
|
19
|
+
propDefinition: [
|
|
20
|
+
googleCalendar,
|
|
21
|
+
"calendarId",
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
recurringEventId: {
|
|
25
|
+
propDefinition: [
|
|
26
|
+
googleCalendar,
|
|
27
|
+
"recurringEventId",
|
|
28
|
+
({ calendarId }) => ({
|
|
29
|
+
calendarId,
|
|
30
|
+
}),
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
instanceId: {
|
|
34
|
+
propDefinition: [
|
|
35
|
+
googleCalendar,
|
|
36
|
+
"instanceId",
|
|
37
|
+
({
|
|
38
|
+
calendarId,
|
|
39
|
+
recurringEventId,
|
|
40
|
+
}) => ({
|
|
41
|
+
calendarId,
|
|
42
|
+
recurringEventId,
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
description: "The instance where the split will occur. All instances from this point forward will be updated with your changes, while earlier instances remain unchanged. For example, selecting the 4th instance will keep instances 1-3 as-is and update instances 4 onwards.",
|
|
46
|
+
},
|
|
47
|
+
summary: {
|
|
48
|
+
label: "Event Title",
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "Enter a new title for all following instances",
|
|
51
|
+
optional: true,
|
|
52
|
+
},
|
|
53
|
+
eventStartDate: {
|
|
54
|
+
label: "Event Start Date",
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "For all-day events, enter the Event day in the format `yyyy-mm-dd`. For events with time, format according to [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.html#section-1): `yyyy-mm-ddThh:mm:ss+01:00`. A time zone offset is required unless a time zone is explicitly specified in timeZone.",
|
|
57
|
+
optional: true,
|
|
58
|
+
},
|
|
59
|
+
eventEndDate: {
|
|
60
|
+
label: "Event End Date",
|
|
61
|
+
type: "string",
|
|
62
|
+
description: "For all-day events, enter the Event day in the format `yyyy-mm-dd`. For events with time, format according to [RFC3339](https://www.rfc-editor.org/rfc/rfc3339.html#section-1): `yyyy-mm-ddThh:mm:ss+01:00`. A time zone offset is required unless a time zone is explicitly specified in timeZone.",
|
|
63
|
+
optional: true,
|
|
64
|
+
},
|
|
65
|
+
location: {
|
|
66
|
+
label: "Event Location",
|
|
67
|
+
type: "string",
|
|
68
|
+
description: "Specify a new location for all following instances",
|
|
69
|
+
optional: true,
|
|
70
|
+
},
|
|
71
|
+
description: {
|
|
72
|
+
label: "Event Description",
|
|
73
|
+
type: "string",
|
|
74
|
+
description: "Enter a new description for all following instances",
|
|
75
|
+
optional: true,
|
|
76
|
+
},
|
|
77
|
+
attendees: {
|
|
78
|
+
label: "Attendees",
|
|
79
|
+
type: "string",
|
|
80
|
+
description: "Enter either an array or a comma separated list of email addresses of attendees",
|
|
81
|
+
optional: true,
|
|
82
|
+
},
|
|
83
|
+
repeatFrequency: {
|
|
84
|
+
type: "string",
|
|
85
|
+
label: "New Repeat Frequency",
|
|
86
|
+
description: "Optionally change the repeat frequency for following instances",
|
|
87
|
+
optional: true,
|
|
88
|
+
options: Object.keys(constants.REPEAT_FREQUENCIES),
|
|
89
|
+
reloadProps: true,
|
|
90
|
+
},
|
|
91
|
+
repeatInterval: {
|
|
92
|
+
type: "integer",
|
|
93
|
+
label: "Repeat Interval",
|
|
94
|
+
description: "Repeat interval (e.g., 1 for every day, 2 for every other day)",
|
|
95
|
+
optional: true,
|
|
96
|
+
hidden: true,
|
|
97
|
+
},
|
|
98
|
+
repeatUntil: {
|
|
99
|
+
type: "string",
|
|
100
|
+
label: "Repeat Until",
|
|
101
|
+
description: "The event will repeat only until this date (format: yyyy-mm-dd)",
|
|
102
|
+
optional: true,
|
|
103
|
+
hidden: true,
|
|
104
|
+
},
|
|
105
|
+
repeatTimes: {
|
|
106
|
+
type: "integer",
|
|
107
|
+
label: "Number of Occurrences",
|
|
108
|
+
description: "Limit the number of times this event will occur",
|
|
109
|
+
optional: true,
|
|
110
|
+
hidden: true,
|
|
111
|
+
},
|
|
112
|
+
colorId: {
|
|
113
|
+
propDefinition: [
|
|
114
|
+
googleCalendar,
|
|
115
|
+
"colorId",
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
timeZone: {
|
|
119
|
+
propDefinition: [
|
|
120
|
+
googleCalendar,
|
|
121
|
+
"timeZone",
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
sendUpdates: {
|
|
125
|
+
propDefinition: [
|
|
126
|
+
googleCalendar,
|
|
127
|
+
"sendUpdates",
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
async additionalProps(props) {
|
|
132
|
+
if (this.repeatFrequency) {
|
|
133
|
+
const frequency = constants.REPEAT_FREQUENCIES[this.repeatFrequency];
|
|
134
|
+
props.repeatInterval.description = `Enter 1 to "repeat every ${frequency}", enter 2 to "repeat every other ${frequency}", etc. Defaults to 1.`;
|
|
135
|
+
}
|
|
136
|
+
props.repeatInterval.hidden = !this.repeatFrequency;
|
|
137
|
+
props.repeatUntil.hidden = !this.repeatFrequency;
|
|
138
|
+
props.repeatTimes.hidden = !this.repeatFrequency;
|
|
139
|
+
return {};
|
|
140
|
+
},
|
|
141
|
+
methods: {
|
|
142
|
+
...createEventCommon.methods,
|
|
143
|
+
calculateUntilDate(instanceStartDate) {
|
|
144
|
+
// Calculate UNTIL date (one second before the instance start)
|
|
145
|
+
// Format: YYYYMMDDTHHMMSSZ (UTC)
|
|
146
|
+
const targetDate = new Date(instanceStartDate);
|
|
147
|
+
targetDate.setSeconds(targetDate.getSeconds() - 1);
|
|
148
|
+
|
|
149
|
+
const year = targetDate.getUTCFullYear();
|
|
150
|
+
const month = String(targetDate.getUTCMonth() + 1).padStart(2, "0");
|
|
151
|
+
const day = String(targetDate.getUTCDate()).padStart(2, "0");
|
|
152
|
+
const hours = String(targetDate.getUTCHours()).padStart(2, "0");
|
|
153
|
+
const minutes = String(targetDate.getUTCMinutes()).padStart(2, "0");
|
|
154
|
+
const seconds = String(targetDate.getUTCSeconds()).padStart(2, "0");
|
|
155
|
+
|
|
156
|
+
return `${year}${month}${day}T${hours}${minutes}${seconds}Z`;
|
|
157
|
+
},
|
|
158
|
+
modifyRecurrenceRule(recurrenceArray, untilDate) {
|
|
159
|
+
// Modify the RRULE to add/update UNTIL parameter
|
|
160
|
+
if (!recurrenceArray || !recurrenceArray.length) {
|
|
161
|
+
return recurrenceArray;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return recurrenceArray.map((rule) => {
|
|
165
|
+
if (!rule.startsWith("RRULE:")) {
|
|
166
|
+
return rule;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Remove existing UNTIL or COUNT if present
|
|
170
|
+
let modifiedRule = rule.replace(/;UNTIL=[^;]+/g, "").replace(/;COUNT=[^;]+/g, "");
|
|
171
|
+
|
|
172
|
+
// Add new UNTIL
|
|
173
|
+
return `${modifiedRule};UNTIL=${untilDate}`;
|
|
174
|
+
});
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
async run({ $ }) {
|
|
178
|
+
// Step 1: Get the original recurring event
|
|
179
|
+
const originalEvent = await this.googleCalendar.getEvent({
|
|
180
|
+
calendarId: this.calendarId,
|
|
181
|
+
eventId: this.recurringEventId,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Step 2: Get the target instance
|
|
185
|
+
const targetInstance = await this.googleCalendar.getEvent({
|
|
186
|
+
calendarId: this.calendarId,
|
|
187
|
+
eventId: this.instanceId,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Calculate UNTIL date (one second before the target instance)
|
|
191
|
+
const instanceStartDate = targetInstance.start.dateTime || targetInstance.start.date;
|
|
192
|
+
const untilDate = this.calculateUntilDate(instanceStartDate);
|
|
193
|
+
|
|
194
|
+
// Step 3: Trim the original recurring event
|
|
195
|
+
const trimmedRecurrence = this.modifyRecurrenceRule(
|
|
196
|
+
originalEvent.recurrence,
|
|
197
|
+
untilDate,
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
await this.googleCalendar.updateEvent({
|
|
201
|
+
calendarId: this.calendarId,
|
|
202
|
+
eventId: this.recurringEventId,
|
|
203
|
+
sendUpdates: this.sendUpdates,
|
|
204
|
+
requestBody: {
|
|
205
|
+
...originalEvent,
|
|
206
|
+
recurrence: trimmedRecurrence,
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Step 4: Create new recurring event with changes
|
|
211
|
+
const timeZone = await this.getTimeZone(this.timeZone || targetInstance.start.timeZone);
|
|
212
|
+
const attendees = this.formatAttendees(this.attendees, originalEvent.attendees);
|
|
213
|
+
|
|
214
|
+
// Determine recurrence for new event
|
|
215
|
+
let newRecurrence;
|
|
216
|
+
if (this.repeatFrequency) {
|
|
217
|
+
newRecurrence = this.formatRecurrence({
|
|
218
|
+
repeatFrequency: this.repeatFrequency,
|
|
219
|
+
repeatInterval: this.repeatInterval,
|
|
220
|
+
repeatTimes: this.repeatTimes,
|
|
221
|
+
repeatUntil: this.repeatUntil,
|
|
222
|
+
});
|
|
223
|
+
} else {
|
|
224
|
+
// Use original recurrence rules
|
|
225
|
+
newRecurrence = originalEvent.recurrence;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const newEvent = await this.googleCalendar.createEvent({
|
|
229
|
+
calendarId: this.calendarId,
|
|
230
|
+
sendUpdates: this.sendUpdates,
|
|
231
|
+
resource: {
|
|
232
|
+
summary: this.summary || originalEvent.summary,
|
|
233
|
+
location: this.location || originalEvent.location,
|
|
234
|
+
description: this.description || originalEvent.description,
|
|
235
|
+
start: this.getDateParam({
|
|
236
|
+
date: this.eventStartDate || instanceStartDate,
|
|
237
|
+
timeZone: timeZone || targetInstance.start.timeZone,
|
|
238
|
+
}),
|
|
239
|
+
end: this.getDateParam({
|
|
240
|
+
date: this.eventEndDate || targetInstance.end.dateTime || targetInstance.end.date,
|
|
241
|
+
timeZone: timeZone || targetInstance.end.timeZone,
|
|
242
|
+
}),
|
|
243
|
+
recurrence: newRecurrence,
|
|
244
|
+
attendees,
|
|
245
|
+
colorId: this.colorId || originalEvent.colorId,
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
$.export("$summary", `Successfully split recurring event. Original trimmed, new event created with ID: \`${newEvent.id}\``);
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
originalEvent: {
|
|
253
|
+
id: this.recurringEventId,
|
|
254
|
+
trimmedRecurrence,
|
|
255
|
+
},
|
|
256
|
+
newEvent,
|
|
257
|
+
};
|
|
258
|
+
},
|
|
259
|
+
};
|
package/google_calendar.app.mjs
CHANGED
|
@@ -278,6 +278,72 @@ export default {
|
|
|
278
278
|
"workingLocation",
|
|
279
279
|
],
|
|
280
280
|
},
|
|
281
|
+
recurringEventId: {
|
|
282
|
+
label: "Recurring Event ID",
|
|
283
|
+
type: "string",
|
|
284
|
+
description: "The ID of the recurring event",
|
|
285
|
+
async options({ calendarId }) {
|
|
286
|
+
const monthAgo = new Date(new Date().setMonth(new Date().getMonth() - 1)).toISOString();
|
|
287
|
+
const response = await this.listEvents({
|
|
288
|
+
calendarId,
|
|
289
|
+
maxResults: 100,
|
|
290
|
+
timeMin: monthAgo,
|
|
291
|
+
});
|
|
292
|
+
const recurringEvents = response.items.filter((item) => item.recurrence);
|
|
293
|
+
const options = recurringEvents.map((item) => {
|
|
294
|
+
let label = item.summary || item.id;
|
|
295
|
+
const date = item.start && (item.start.date
|
|
296
|
+
? item.start.date
|
|
297
|
+
: item.start.dateTime.slice(0, 10));
|
|
298
|
+
if (date) {
|
|
299
|
+
label += ` - ${date}`;
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
label,
|
|
303
|
+
value: item.id,
|
|
304
|
+
};
|
|
305
|
+
});
|
|
306
|
+
return options.reverse();
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
instanceId: {
|
|
310
|
+
label: "Event Instance ID",
|
|
311
|
+
type: "string",
|
|
312
|
+
description: "The ID of the specific instance to update. Use List Event Instances action to get instance IDs.",
|
|
313
|
+
async options({
|
|
314
|
+
calendarId, recurringEventId,
|
|
315
|
+
}) {
|
|
316
|
+
if (!recurringEventId) {
|
|
317
|
+
return [];
|
|
318
|
+
}
|
|
319
|
+
const response = await this.listEventInstances({
|
|
320
|
+
calendarId,
|
|
321
|
+
eventId: recurringEventId,
|
|
322
|
+
maxResults: 50,
|
|
323
|
+
timeMin: new Date().toISOString(),
|
|
324
|
+
});
|
|
325
|
+
const options = response.items.map((item) => {
|
|
326
|
+
let label = item.summary || item.id;
|
|
327
|
+
const date = item.start && (item.start.date
|
|
328
|
+
? item.start.date
|
|
329
|
+
: item.start.dateTime.slice(0, 10));
|
|
330
|
+
const time = item.start?.dateTime
|
|
331
|
+
? item.start.dateTime.slice(11, 16)
|
|
332
|
+
: "";
|
|
333
|
+
if (date) {
|
|
334
|
+
label += ` - ${date}`;
|
|
335
|
+
}
|
|
336
|
+
if (time) {
|
|
337
|
+
label += ` ${time}`;
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
label,
|
|
341
|
+
value: item.id,
|
|
342
|
+
};
|
|
343
|
+
});
|
|
344
|
+
return options;
|
|
345
|
+
},
|
|
346
|
+
},
|
|
281
347
|
},
|
|
282
348
|
methods: {
|
|
283
349
|
_tokens() {
|
|
@@ -502,5 +568,12 @@ export default {
|
|
|
502
568
|
args,
|
|
503
569
|
});
|
|
504
570
|
},
|
|
571
|
+
async listEventInstances(args = {}) {
|
|
572
|
+
return this.requestHandler({
|
|
573
|
+
api: constants.API.EVENTS.NAME,
|
|
574
|
+
method: constants.API.EVENTS.METHOD.INSTANCES,
|
|
575
|
+
args,
|
|
576
|
+
});
|
|
577
|
+
},
|
|
505
578
|
},
|
|
506
579
|
};
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
key: "google_calendar-event-cancelled",
|
|
7
7
|
name: "New Cancelled Event",
|
|
8
8
|
description: "Emit new event when a Google Calendar event is cancelled or deleted",
|
|
9
|
-
version: "0.1.
|
|
9
|
+
version: "0.1.12",
|
|
10
10
|
type: "source",
|
|
11
11
|
dedupe: "unique",
|
|
12
12
|
props: {
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
key: "google_calendar-new-event-search",
|
|
6
6
|
name: "New Event Matching a Search",
|
|
7
7
|
description: "Emit new event when a Google Calendar event is created that matches a search",
|
|
8
|
-
version: "0.1.
|
|
8
|
+
version: "0.1.12",
|
|
9
9
|
type: "source",
|
|
10
10
|
dedupe: "unique",
|
|
11
11
|
props: {
|
|
@@ -8,7 +8,7 @@ export default {
|
|
|
8
8
|
type: "source",
|
|
9
9
|
name: "New Created or Updated Event (Instant)",
|
|
10
10
|
description: "Emit new event when a Google Calendar events is created or updated (does not emit cancelled events)",
|
|
11
|
-
version: "0.1.
|
|
11
|
+
version: "0.1.17",
|
|
12
12
|
dedupe: "unique",
|
|
13
13
|
props: {
|
|
14
14
|
googleCalendar,
|
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
key: "google_calendar-upcoming-event-alert",
|
|
7
7
|
name: "New Upcoming Event Alert",
|
|
8
8
|
description: "Emit new event based on a time interval before an upcoming event in the calendar.",
|
|
9
|
-
version: "0.1.
|
|
9
|
+
version: "0.1.2",
|
|
10
10
|
type: "source",
|
|
11
11
|
props: {
|
|
12
12
|
googleCalendar,
|
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
key: "google_calendar-upcoming-event-alert-polling",
|
|
7
7
|
name: "New Upcoming Event Alert (Polling)",
|
|
8
8
|
description: "Emit new event based on a time interval before an upcoming event in the calendar. [See the documentation](https://developers.google.com/calendar/api/v3/reference/events/list)",
|
|
9
|
-
version: "0.0.
|
|
9
|
+
version: "0.0.2",
|
|
10
10
|
type: "source",
|
|
11
11
|
dedupe: "unique",
|
|
12
12
|
props: {
|