Skip to content

Commit 06f6d11

Browse files
PierrickVouletpierrickvinay-google
authored
feat: add OOO assistant sample (#543)
* feat: add OOO assitant sample * Change title * Edit comment * Add license info * Fix typo Co-authored-by: Vinay Vyas <69166360+vinay-google@users.noreply.github.com> --------- Co-authored-by: pierrick <pierrick@google.com> Co-authored-by: Vinay Vyas <69166360+vinay-google@users.noreply.github.com>
1 parent c191441 commit 06f6d11

File tree

5 files changed

+244
-0
lines changed

5 files changed

+244
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "scriptId": "16L_UmGrkrDKYWrfw9YlnUnnnWOMBEWywyPrZDZIQqKF17Q97RtZeinqn" }

solutions/ooo-assistant/Chat.gs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright 2025 Google LLC.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
const APP_COMMAND = "app command";
18+
19+
/**
20+
* Responds to an ADDED_TO_SPACE event in Google Chat.
21+
* @param {Object} event the event object from Google Workspace Add On
22+
*/
23+
function onAddToSpace(event) {
24+
return sendCreateMessageAction(createCardMessage(help(APP_COMMAND)));
25+
}
26+
27+
/**
28+
* Responds to a MESSAGE event in Google Chat.
29+
* @param {Object} event the event object from Google Workspace Add On
30+
*/
31+
function onMessage(event) {
32+
return sendCreateMessageAction(createCardMessage(help(APP_COMMAND)));
33+
}
34+
35+
/**
36+
* Responds to a APP_COMMAND event in Google Chat.
37+
* @param {Object} event the event object from Google Workspace Add On
38+
*/
39+
function onAppCommand(event) {
40+
switch (event.chat.appCommandPayload.appCommandMetadata.appCommandId) {
41+
case 2: // Block out day
42+
return sendCreateMessageAction(createCardMessage(blockDayOut()));
43+
case 3: // Set auto reply
44+
return sendCreateMessageAction(createCardMessage(setAutoReply()));
45+
default: // Help, any other
46+
return sendCreateMessageAction(createCardMessage(help(APP_COMMAND)));
47+
}
48+
}
49+
50+
/**
51+
* Responds to a REMOVED_FROM_SPACE event in Google Chat.
52+
* @param {Object} event the event object from Google Workspace Add On
53+
*/
54+
function onRemoveFromSpace(event) {
55+
const space = event.chat.removedFromSpacePayload.space;
56+
console.info(`Chat app removed from ${(space.name || "this chat")}`);
57+
}
58+
59+
// ----------------------
60+
// Util functions
61+
// ----------------------
62+
63+
function createTextMessage(text) { return { text: text }; }
64+
65+
function createCardMessage(card) { return { cardsV2: [{ card: card }]}; }
66+
67+
function sendCreateMessageAction(message) {
68+
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: message }}}};
69+
}

solutions/ooo-assistant/Common.gs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/**
2+
* Copyright 2025 Google LLC.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
const UNIVERSAL_ACTION = "universal action";
18+
19+
// ----------------------
20+
// Homepage util functions
21+
// ----------------------
22+
23+
/**
24+
* Responds to homepage load request.
25+
*/
26+
function onHomepage() {
27+
return help();
28+
}
29+
30+
// ----------------------
31+
// Action util functions
32+
// ----------------------
33+
34+
// Help action: Show add-on details.
35+
function help(featureName = UNIVERSAL_ACTION) {
36+
return {
37+
header: addOnCardHeader(),
38+
sections: [{ widgets: [{
39+
decoratedText: { text: "Hi! 👋 Feel free to use the following " + featureName + "s:", wrapText: true }}, {
40+
decoratedText: { text: "<b>⛔ Block day out</b>: I will block out your calendar for today.", wrapText: true }}, {
41+
decoratedText: { text: "<b>↩️ Set auto reply</b>: I will set an OOO auto reply in your Gmail.", wrapText: true }
42+
}]}]
43+
};
44+
}
45+
46+
// Block day out action: Adds an all-day event to the user's Google Calendar.
47+
function blockDayOut() {
48+
blockOutCalendar();
49+
return createActionResponseCard('Your calendar is now blocked out for today.')
50+
}
51+
52+
// Creates an OOO event in the user's Calendar.
53+
function blockOutCalendar() {
54+
function getDateAndHours(hour, minutes) {
55+
const date = new Date();
56+
date.setHours(hour);
57+
date.setMinutes(minutes);
58+
date.setSeconds(0);
59+
date.setMilliseconds(0);
60+
return date.toISOString();
61+
}
62+
63+
const event = {
64+
start: { dateTime: getDateAndHours(9, 0) },
65+
end: { dateTime: getDateAndHours(17, 0) },
66+
eventType: 'outOfOffice',
67+
summary: 'OOO',
68+
outOfOfficeProperties: {
69+
autoDeclineMode: 'declineOnlyNewConflictingInvitations',
70+
declineMessage: 'Declined because OOO.',
71+
}
72+
}
73+
Calendar.Events.insert(event, 'primary');
74+
}
75+
76+
// Set auto reply action: Set OOO auto reply in the user's Gmail .
77+
function setAutoReply() {
78+
turnOnAutoResponder();
79+
return createActionResponseCard('The out of office auto reply has been turned on.')
80+
}
81+
82+
// Turns on the user's vacation response for today in Gmail.
83+
function turnOnAutoResponder() {
84+
const ONE_DAY_MILLIS = 24 * 60 * 60 * 1000;
85+
const currentTime = (new Date()).getTime();
86+
Gmail.Users.Settings.updateVacation({
87+
enableAutoReply: true,
88+
responseSubject: 'I am OOO today',
89+
responseBodyHtml: 'I am OOO today.<br><br><i>Created by OOO Assistant add-on!</i>',
90+
restrictToContacts: true,
91+
restrictToDomain: true,
92+
startTime: currentTime,
93+
endTime: currentTime + ONE_DAY_MILLIS
94+
}, 'me');
95+
}
96+
97+
// ----------------------
98+
// Card util functions
99+
// ----------------------
100+
101+
function addOnCardHeader() {
102+
return {
103+
title: "OOO Assistant",
104+
subtitle: "Helping manage your OOO",
105+
imageUrl: "https://goo.gle/3SfMkjb",
106+
};
107+
}
108+
109+
// Create an action response card
110+
function createActionResponseCard(text) {
111+
return {
112+
header: addOnCardHeader(),
113+
sections: [{ widgets: [{ decoratedText: {
114+
startIcon: { iconUrl: "https://fonts.gstatic.com/s/i/short-term/web/system/1x/task_alt_gm_grey_48dp.png" },
115+
text: text,
116+
wrapText: true
117+
}}]}]
118+
};
119+
}
120+
121+
// ----------------------
122+
// Universal action util functions
123+
// ----------------------
124+
125+
function respondToUniversalAction(card) {
126+
return CardService.newUniversalActionResponseBuilder().displayAddOnCards([card]).build();
127+
}

solutions/ooo-assistant/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Build a Google Workspace add-on extending all UIs
2+
3+
**Warning:** This sample builds a Chat app as a Google Workspace add-on. It's only available in the [Developer Preview Program](https://developers.google.com/workspace/preview).
4+
5+
The add-on extends the following Google Workspace UIs: Chat, Calendar, Gmail, Drive, Docs, Sheets, and Slides.
6+
7+
It relies on app commands in Chat, and homepage and universal actions in the others.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"timeZone": "America/New_York",
3+
"exceptionLogging": "STACKDRIVER",
4+
"runtimeVersion": "V8",
5+
"dependencies": {
6+
"enabledAdvancedServices": [{
7+
"userSymbol": "Gmail",
8+
"version": "v1",
9+
"serviceId": "gmail"
10+
},
11+
{
12+
"userSymbol": "Calendar",
13+
"version": "v3",
14+
"serviceId": "calendar"
15+
}]
16+
},
17+
"addOns": {
18+
"common": {
19+
"name": "OOO Assistant",
20+
"logoUrl": "https://goo.gle/3SfMkjb",
21+
"homepageTrigger": {
22+
"runFunction": "onHomepage"
23+
},
24+
"universalActions": [{
25+
"label": "Block day out",
26+
"runFunction": "blockDayOut"
27+
}, {
28+
"label": "Set auto reply",
29+
"runFunction": "setAutoReply"
30+
}]
31+
},
32+
"chat": {},
33+
"calendar": {},
34+
"gmail": {},
35+
"drive": {},
36+
"docs": {},
37+
"sheets": {},
38+
"slides": {}
39+
}
40+
}

0 commit comments

Comments
 (0)