Skip to content

Commit 2a2c81b

Browse files
PierrickVouletpierrick
andauthored
feat: add ooo-chat-app and schedule-meetings (#387)
Co-authored-by: pierrick <pierrick@google.com>
1 parent 4709e65 commit 2a2c81b

8 files changed

Lines changed: 751 additions & 0 deletions

File tree

apps-script/ooo-chat-app/Code.js

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
/*
2+
Copyright 2022 Google LLC
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
https://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
/**
15+
* Responds to an ADDED_TO_SPACE event in Chat.
16+
* @param {object} event the event object from Chat
17+
* @return {object} JSON-formatted response
18+
* @see https://developers.google.com/workspace/chat/receive-respond-interactions
19+
*/
20+
function onAddToSpace(event) {
21+
let message = "Thank you for adding me to ";
22+
if (event.space.type === "DM") {
23+
message += `a DM, ${event.user.displayName}!`;
24+
} else {
25+
message += event.space.displayName;
26+
}
27+
return { text: message };
28+
}
29+
30+
/**
31+
* Responds to a REMOVED_FROM_SPACE event in Chat.
32+
* @param {object} event the event object from Chat
33+
* @param {object} event the event object from Chat
34+
* @see https://developers.google.com/workspace/chat/receive-respond-interactions
35+
*/
36+
function onRemoveFromSpace(event) {
37+
console.log("App removed from ", event.space.name);
38+
}
39+
40+
/**
41+
* Responds to a MESSAGE event triggered in Chat.
42+
* @param {object} event the event object from Chat
43+
* @return {function} call the respective function
44+
*/
45+
function onMessage(event) {
46+
const message = event.message;
47+
48+
if (message.slashCommand) {
49+
switch (message.slashCommand.commandId) {
50+
case 1: // Help command
51+
return createHelpCard();
52+
case 2: // Block out day command
53+
return blockDayOut();
54+
case 3: // Cancel all meetings command
55+
return cancelAllMeetings();
56+
case 4: // Set auto reply command
57+
return setAutoReply();
58+
}
59+
}
60+
}
61+
62+
function createHelpCard() {
63+
return {
64+
cardsV2: [
65+
{
66+
cardId: "2",
67+
card: {
68+
sections: [
69+
{
70+
header: "",
71+
widgets: [
72+
{
73+
decoratedText: {
74+
topLabel: "",
75+
text: "Hi! 👋 I'm here to help you with your out of office tasks.<br><br>Here's a list of commands I understand.",
76+
wrapText: true,
77+
},
78+
},
79+
],
80+
},
81+
{
82+
widgets: [
83+
{
84+
decoratedText: {
85+
topLabel: "",
86+
text: "<b>/blockDayOut</b>: I will block out your calendar for you.",
87+
wrapText: true,
88+
},
89+
},
90+
{
91+
decoratedText: {
92+
topLabel: "",
93+
text: "<b>/cancelAllMeetings</b>: I will cancel all your meetings for the day.",
94+
wrapText: true,
95+
},
96+
},
97+
{
98+
decoratedText: {
99+
topLabel: "",
100+
text: "<b>/setAutoReply</b>: Set an out of office auto reply in Gmail.",
101+
wrapText: true,
102+
},
103+
},
104+
],
105+
},
106+
],
107+
header: {
108+
title: "OOO app",
109+
subtitle: "Helping you manage your OOO",
110+
imageUrl: "https://goo.gle/3SfMkjb",
111+
imageType: "SQUARE",
112+
},
113+
},
114+
},
115+
],
116+
};
117+
}
118+
119+
/**
120+
* Adds an all day event to the users Google Calendar.
121+
* @return {object} JSON-formatted response
122+
*/
123+
function blockDayOut() {
124+
blockOutCalendar();
125+
return createResponseCard("Your calendar has been blocked out for you.");
126+
}
127+
128+
/**
129+
* Cancels all of the users meeting for the current day.
130+
* @return {object} JSON-formatted response
131+
*/
132+
function cancelAllMeetings() {
133+
cancelMeetings();
134+
return createResponseCard("All your meetings have been canceled.");
135+
}
136+
137+
/**
138+
* Sets an out of office auto reply in the users Gmail account.
139+
* @return {object} JSON-formatted response
140+
*/
141+
function setAutoReply() {
142+
turnOnAutoResponder();
143+
return createResponseCard("The out of office auto reply has been turned on.");
144+
}
145+
146+
/**
147+
* Creates an out of office event in the user's Calendar.
148+
*/
149+
function blockOutCalendar() {
150+
/**
151+
* Helper function to get a the current date and set the time for the start and end of the event.
152+
* @param {number} hour The hour of the day for the new date.
153+
* @param {number} minutes The minutes of the day for the new date.
154+
* @return {Date} The new date.
155+
*/
156+
function getDateAndHours(hour, minutes) {
157+
const date = new Date();
158+
date.setHours(hour);
159+
date.setMinutes(minutes);
160+
date.setSeconds(0);
161+
date.setMilliseconds(0);
162+
return date.toISOString();
163+
}
164+
165+
const event = {
166+
start: { dateTime: getDateAndHours(9, 0) },
167+
end: { dateTime: getDateAndHours(17, 0) },
168+
eventType: "outOfOffice",
169+
summary: "Out of office",
170+
outOfOfficeProperties: {
171+
autoDeclineMode: "declineOnlyNewConflictingInvitations",
172+
declineMessage: "Declined because I am taking a day of.",
173+
},
174+
};
175+
Calendar.Events.insert(event, "primary");
176+
}
177+
178+
/**
179+
* Declines all meetings for the day.
180+
*/
181+
function cancelMeetings() {
182+
const events = CalendarApp.getEventsForDay(new Date());
183+
184+
for (const event of events) {
185+
if (event.getGuestList().length > 0) {
186+
event.setMyStatus(CalendarApp.GuestStatus.NO);
187+
}
188+
}
189+
}
190+
191+
/**
192+
* Turns on the user's vacation response for today in Gmail.
193+
*/
194+
function turnOnAutoResponder() {
195+
const ONE_DAY_MILLIS = 24 * 60 * 60 * 1000;
196+
const currentTime = new Date().getTime();
197+
Gmail.Users.Settings.updateVacation(
198+
{
199+
enableAutoReply: true,
200+
responseSubject: "I am out of the office today",
201+
responseBodyHtml:
202+
"I am out of the office today; will be back on the next business day.<br><br><i>Created by OOO Chat app!</i>",
203+
restrictToContacts: true,
204+
restrictToDomain: true,
205+
startTime: currentTime,
206+
endTime: currentTime + ONE_DAY_MILLIS,
207+
},
208+
"me",
209+
);
210+
}
211+
212+
function createResponseCard(responseText) {
213+
return {
214+
cardsV2: [
215+
{
216+
cardId: "1",
217+
card: {
218+
sections: [
219+
{
220+
widgets: [
221+
{
222+
decoratedText: {
223+
topLabel: "",
224+
text: responseText,
225+
startIcon: {
226+
knownIcon: "NONE",
227+
altText: "Task done",
228+
iconUrl:
229+
"https://fonts.gstatic.com/s/i/short-term/web/system/1x/task_alt_gm_grey_48dp.png",
230+
},
231+
wrapText: true,
232+
},
233+
},
234+
],
235+
},
236+
],
237+
header: {
238+
title: "OOO app",
239+
subtitle: "Helping you manage your OOO",
240+
imageUrl: "https://goo.gle/3SfMkjb",
241+
imageType: "CIRCLE",
242+
},
243+
},
244+
},
245+
],
246+
};
247+
}

apps-script/ooo-chat-app/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# OOO Chat App
2+
3+
Sample code for a custom Google Chat app that manages your out of office tasks.
4+
5+
Learn more about [Chat apps](https://developers.google.com/workspace/chat).
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"timeZone": "Europe/Madrid",
3+
"exceptionLogging": "STACKDRIVER",
4+
"runtimeVersion": "V8",
5+
"dependencies": {
6+
"enabledAdvancedServices": [
7+
{
8+
"userSymbol": "Gmail",
9+
"version": "v1",
10+
"serviceId": "gmail"
11+
},
12+
{
13+
"userSymbol": "Calendar",
14+
"version": "v3",
15+
"serviceId": "calendar"
16+
}
17+
]
18+
},
19+
"chat": {}
20+
}

0 commit comments

Comments
 (0)