diff --git a/solutions/ooo-chat-app/Code.js b/solutions/ooo-chat-app/Code.js
deleted file mode 100644
index 3aae1a695..000000000
--- a/solutions/ooo-chat-app/Code.js
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
-Copyright 2022 Google LLC
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- https://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-/**
- * Responds to an ADDED_TO_SPACE event in Chat.
- * @param {object} event the event object from Chat
- * @return {object} JSON-formatted response
- * @see https://developers.google.com/hangouts/chat/reference/message-formats/events
- */
-function onAddToSpace(event) {
- let message = "Thank you for adding me to ";
- if (event.space.type === "DM") {
- message += `a DM, ${event.user.displayName}!`;
- } else {
- message += event.space.displayName;
- }
- return { text: message };
-}
-
-/**
- * Responds to a REMOVED_FROM_SPACE event in Chat.
- * @param {object} event the event object from Chat
- * @param {object} event the event object from Chat
- * @see https://developers.google.com/hangouts/chat/reference/message-formats/events
- */
-function onRemoveFromSpace(event) {
- console.log("App removed from ", event.space.name);
-}
-
-/**
- * Responds to a MESSAGE event triggered in Chat.
- * @param {object} event the event object from Chat
- * @return {function} call the respective function
- */
-function onMessage(event) {
- const message = event.message;
-
- if (message.slashCommand) {
- switch (message.slashCommand.commandId) {
- case 1: // Help command
- return createHelpCard();
- case 2: // Block out day command
- return blockDayOut();
- case 3: // Cancel all meetings command
- return cancelAllMeetings();
- case 4: // Set auto reply command
- return setAutoReply();
- }
- }
-}
-
-function createHelpCard() {
- return {
- cardsV2: [
- {
- cardId: "2",
- card: {
- sections: [
- {
- header: "",
- widgets: [
- {
- decoratedText: {
- topLabel: "",
- text: "Hi! 👋 I'm here to help you with your out of office tasks.
Here's a list of commands I understand.",
- wrapText: true,
- },
- },
- ],
- },
- {
- widgets: [
- {
- decoratedText: {
- topLabel: "",
- text: "/blockDayOut: I will block out your calendar for you.",
- wrapText: true,
- },
- },
- {
- decoratedText: {
- topLabel: "",
- text: "/cancelAllMeetings: I will cancel all your meetings for the day.",
- wrapText: true,
- },
- },
- {
- decoratedText: {
- topLabel: "",
- text: "/setAutoReply: Set an out of office auto reply in Gmail.",
- wrapText: true,
- },
- },
- ],
- },
- ],
- header: {
- title: "OOO app",
- subtitle: "Helping you manage your OOO",
- imageUrl: "https://goo.gle/3SfMkjb",
- imageType: "SQUARE",
- },
- },
- },
- ],
- };
-}
-
-/**
- * Adds an all day event to the users Google Calendar.
- * @return {object} JSON-formatted response
- */
-function blockDayOut() {
- blockOutCalendar();
- return createResponseCard("Your calendar has been blocked out for you.");
-}
-
-/**
- * Cancels all of the users meeting for the current day.
- * @return {object} JSON-formatted response
- */
-function cancelAllMeetings() {
- cancelMeetings();
- return createResponseCard("All your meetings have been canceled.");
-}
-
-/**
- * Sets an out of office auto reply in the users Gmail account.
- * @return {object} JSON-formatted response
- */
-function setAutoReply() {
- turnOnAutoResponder();
- return createResponseCard("The out of office auto reply has been turned on.");
-}
-
-/**
- * Creates an out of office event in the user's Calendar.
- */
-function blockOutCalendar() {
- /**
- * Helper function to get a the current date and set the time for the start and end of the event.
- * @param {number} hour The hour of the day for the new date.
- * @param {number} minutes The minutes of the day for the new date.
- * @return {Date} The new date.
- */
- function getDateAndHours(hour, minutes) {
- const date = new Date();
- date.setHours(hour);
- date.setMinutes(minutes);
- date.setSeconds(0);
- date.setMilliseconds(0);
- return date.toISOString();
- }
-
- const event = {
- start: { dateTime: getDateAndHours(9, 0) },
- end: { dateTime: getDateAndHours(17, 0) },
- eventType: "outOfOffice",
- summary: "Out of office",
- outOfOfficeProperties: {
- autoDeclineMode: "declineOnlyNewConflictingInvitations",
- declineMessage: "Declined because I am taking a day of.",
- },
- };
- Calendar.Events.insert(event, "primary");
-}
-
-/**
- * Declines all meetings for the day.
- */
-function cancelMeetings() {
- const events = CalendarApp.getEventsForDay(new Date());
-
- for (const event of events) {
- if (event.getGuestList().length > 0) {
- event.setMyStatus(CalendarApp.GuestStatus.NO);
- }
- }
-}
-
-/**
- * Turns on the user's vacation response for today in Gmail.
- */
-function turnOnAutoResponder() {
- const ONE_DAY_MILLIS = 24 * 60 * 60 * 1000;
- const currentTime = new Date().getTime();
- Gmail.Users.Settings.updateVacation(
- {
- enableAutoReply: true,
- responseSubject: "I am out of the office today",
- responseBodyHtml:
- "I am out of the office today; will be back on the next business day.
Created by OOO Chat app!",
- restrictToContacts: true,
- restrictToDomain: true,
- startTime: currentTime,
- endTime: currentTime + ONE_DAY_MILLIS,
- },
- "me",
- );
-}
-
-function createResponseCard(responseText) {
- return {
- cardsV2: [
- {
- cardId: "1",
- card: {
- sections: [
- {
- widgets: [
- {
- decoratedText: {
- topLabel: "",
- text: responseText,
- startIcon: {
- knownIcon: "NONE",
- altText: "Task done",
- iconUrl:
- "https://fonts.gstatic.com/s/i/short-term/web/system/1x/task_alt_gm_grey_48dp.png",
- },
- wrapText: true,
- },
- },
- ],
- },
- ],
- header: {
- title: "OOO app",
- subtitle: "Helping you manage your OOO",
- imageUrl: "https://goo.gle/3SfMkjb",
- imageType: "CIRCLE",
- },
- },
- },
- ],
- };
-}
diff --git a/solutions/ooo-chat-app/README.md b/solutions/ooo-chat-app/README.md
deleted file mode 100644
index 4d72f861a..000000000
--- a/solutions/ooo-chat-app/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# OOO Chat App
-
-Sample code for a custom Google Chat app that manages your out of office tasks.
-
-Learn more about [Chat apps](https://developers.google.com/chat).
diff --git a/solutions/ooo-chat-app/appsscript.json b/solutions/ooo-chat-app/appsscript.json
deleted file mode 100644
index 2d1fa08f5..000000000
--- a/solutions/ooo-chat-app/appsscript.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "timeZone": "Europe/Madrid",
- "exceptionLogging": "STACKDRIVER",
- "runtimeVersion": "V8",
- "dependencies": {
- "enabledAdvancedServices": [
- {
- "userSymbol": "Gmail",
- "version": "v1",
- "serviceId": "gmail"
- },
- {
- "userSymbol": "Calendar",
- "version": "v3",
- "serviceId": "calendar"
- }
- ]
- },
- "chat": {}
-}
diff --git a/solutions/schedule-meetings/.clasp.json b/solutions/schedule-meetings/.clasp.json
deleted file mode 100644
index d07e68bf6..000000000
--- a/solutions/schedule-meetings/.clasp.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "scriptId": "1NdhQ_nXfEUUhWcWKiY6WJjeunY70a1W9vnFdS7BCLPMFreSaHaOS3ucM" }
diff --git a/solutions/schedule-meetings/Code.js b/solutions/schedule-meetings/Code.js
deleted file mode 100644
index ae81986aa..000000000
--- a/solutions/schedule-meetings/Code.js
+++ /dev/null
@@ -1,182 +0,0 @@
-// To learn how to use this script, refer to the documentation:
-// https://developers.google.com/apps-script/samples/chat-apps/schedule-meetings
-
-/*
-Copyright 2022 Google LLC
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Application constants
-const APPNAME = "Chat Meeting Scheduler";
-const SLASHCOMMAND = {
- HELP: 1, // /help
- DIALOG: 2, // /schedule_Meeting
-};
-
-/**
- * Responds to an ADDED_TO_SPACE event in Google Chat.
- * Called when the Chat app is added to a space. The Chat app can either be directly added to the space
- * or added by a @mention. If the Chat app is added by a @mention, the event object includes a message property.
- * Returns a Message object, which is usually a welcome message informing users about the Chat app.
- *
- * @param {Object} event The event object from Google Chat
- */
-function onAddToSpace(event) {
- let message = "";
-
- // Personalizes the message depending on how the Chat app is called.
- if (event.space.singleUserBotDm) {
- message = `Hi ${event.user.displayName}!`;
- } else {
- const spaceName = event.space.displayName
- ? event.space.displayName
- : "this chat";
- message = `Hi! Thank you for adding me to ${spaceName}`;
- }
-
- // Lets users know what they can do and how they can get help.
- message = `${message}/nI can quickly schedule a meeting for you with just a few clicks.Try me out by typing */schedule_Meeting*. /nTo learn what else I can do, type */help*.`;
-
- return { text: message };
-}
-
-/**
- * Responds to a MESSAGE event triggered in Chat.
- * Called when the Chat app is already in the space and the user invokes it via @mention or / command.
- * Returns a message object containing the Chat app's response. For this Chat app, the response is either the
- * help text or the dialog to schedule a meeting.
- *
- * @param {object} event The event object from Google Chat
- * @return {object} JSON-formatted response as text or Card message
- */
-function onMessage(event) {
- // Handles regular onMessage logic.
- // Evaluates if and handles for all slash commands.
- if (event.message.slashCommand) {
- switch (event.message.slashCommand.commandId) {
- case SLASHCOMMAND.DIALOG: // Displays meeting dialog for /schedule_Meeting.
- // TODO update this with your own logic to set meeting recipients, subjects, etc (e.g. a group email).
- return getInputFormAsDialog_({
- invitee: "",
- startTime: getTopOfHourDateString_(),
- duration: 30,
- subject: "Status Stand-up",
- body: "Scheduling a quick status stand-up meeting.",
- });
-
- case SLASHCOMMAND.HELP: // Responds with help text for /help.
- return getHelpTextResponse_();
-
- /* TODO Add other use cases here. E.g:
- case SLASHCOMMAND.NEW_FEATURE: // Your Feature Here
- getDialogForAddContact(message);
- */
- }
- }
- // Returns text if users didn't invoke a slash command.
- return { text: "No action taken - use Slash Commands." };
-}
-
-/**
- * Responds to a CARD_CLICKED event triggered in Chat.
- * @param {object} event the event object from Chat
- * @return {object} JSON-formatted response
- * @see https://developers.google.com/chat/api/guides/message-formats/events
- */
-function onCardClick(event) {
- if (event.action.actionMethodName === "handleFormSubmit") {
- const recipients = getFieldValue_(event.common.formInputs, "email");
- const subject = getFieldValue_(event.common.formInputs, "subject");
- const body = getFieldValue_(event.common.formInputs, "body");
-
- // Assumes dialog card inputs for date and times are in the correct format. mm/dd/yyy HH:MM
- const dateTimeInput = getFieldValue_(event.common.formInputs, "date");
- const startTime = getStartTimeAsDateObject_(dateTimeInput);
- const duration = Number(
- getFieldValue_(event.common.formInputs, "duration"),
- );
-
- // Handles instances of missing or invalid input parameters.
- const errors = [];
-
- if (!recipients) {
- errors.push("Missing or invalid recipient email address.");
- }
- if (!subject) {
- errors.push("Missing subject line.");
- }
- if (!body) {
- errors.push("Missing event description.");
- }
- if (!startTime) {
- errors.push("Missing or invalid start time.");
- }
- if (!duration || Number.isNaN(duration)) {
- errors.push("Missing or invalid duration");
- }
- if (errors.length) {
- // Redisplays the form if missing or invalid inputs exist.
- return getInputFormAsDialog_({
- errors,
- invitee: recipients,
- startTime: dateTimeInput,
- duration,
- subject,
- body,
- });
- }
-
- // Calculates the end time via duration.
- const endTime = new Date(startTime.valueOf());
- endTime.setMinutes(endTime.getMinutes() + duration);
-
- // Creates calendar event with notification.
- const calendar = CalendarApp.getDefaultCalendar();
- const scheduledEvent = calendar.createEvent(subject, startTime, endTime, {
- guests: recipients,
- sendInvites: true,
- description: `${body}\nThis meeting scheduled by a Google Chat App!`,
- });
-
- // Gets a link to the Calendar event.
- const url = getCalendarEventURL_(scheduledEvent, calendar);
-
- return getConfirmationDialog_(url);
- }
- if (event.action.actionMethodName === "closeDialog") {
- // Returns this dialog as success.
- return {
- actionResponse: {
- type: "DIALOG",
- dialog_action: {
- actionStatus: "OK",
- },
- },
- };
- }
-}
-
-/**
- * Responds with help text about this Chat app.
- * @return {string} The help text as seen below
- */
-function getHelpTextResponse_() {
- const help = `*${APPNAME}* lets you quickly create meetings from Google Chat. Here\'s a list of all its commands:
- \`/schedule_Meeting\` Opens a dialog with editable, preset parameters to create a meeting event
- \`/help\` Displays this help message
-
- Learn more about creating Google Chat apps at https://developers.google.com/chat.`;
-
- return { text: help };
-}
diff --git a/solutions/schedule-meetings/Dialog.js b/solutions/schedule-meetings/Dialog.js
deleted file mode 100644
index b0f018723..000000000
--- a/solutions/schedule-meetings/Dialog.js
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * Copyright 2022 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Form input dialog as JSON.
- * @return {object} JSON-formatted cards for the dialog.
- */
-function getInputFormAsDialog_(options) {
- const form = getForm_(options);
- return {
- actionResponse: {
- type: "DIALOG",
- dialogAction: {
- dialog: {
- body: form,
- },
- },
- },
- };
-}
-
-/**
- * Form JSON to collect inputs regarding the meeting.
- * @return {object} JSON-formatted cards.
- */
-function getForm_(options) {
- const sections = [];
-
- // If errors present, display additional section with validation messages.
- if (options.errors?.length) {
- let errors = options.errors.reduce((str, err) => `${str}• ${err}
`, "");
- errors = `Errors:
${errors}`;
- const errorSection = {
- widgets: [
- {
- textParagraph: {
- text: errors,
- },
- },
- ],
- };
- sections.push(errorSection);
- }
- const formSection = {
- header: "Schedule meeting and send email to invited participants",
- widgets: [
- {
- textInput: {
- label: "Event Title",
- type: "SINGLE_LINE",
- name: "subject",
- value: options.subject,
- },
- },
- {
- textInput: {
- label: "Invitee Email Address",
- type: "SINGLE_LINE",
- name: "email",
- value: options.invitee,
- hintText: "Add team group email",
- },
- },
- {
- textInput: {
- label: "Description",
- type: "MULTIPLE_LINE",
- name: "body",
- value: options.body,
- },
- },
- {
- textInput: {
- label: "Meeting start date & time",
- type: "SINGLE_LINE",
- name: "date",
- value: options.startTime,
- hintText: "mm/dd/yyyy H:MM",
- },
- },
- {
- selectionInput: {
- type: "DROPDOWN",
- label: "Meeting Duration",
- name: "duration",
- items: [
- {
- text: "15 minutes",
- value: "15",
- selected: options.duration === 15,
- },
- {
- text: "30 minutes",
- value: "30",
- selected: options.duration === 30,
- },
- {
- text: "45 minutes",
- value: "45",
- selected: options.duration === 45,
- },
- {
- text: "1 Hour",
- value: "60",
- selected: options.duration === 60,
- },
- {
- text: "1.5 Hours",
- value: "90",
- selected: options.duration === 90,
- },
- {
- text: "2 Hours",
- value: "120",
- selected: options.duration === 120,
- },
- ],
- },
- },
- ],
- collapsible: false,
- };
- sections.push(formSection);
- const card = {
- sections: sections,
- name: "Google Chat Scheduled Meeting",
- fixedFooter: {
- primaryButton: {
- text: "Submit",
- onClick: {
- action: {
- function: "handleFormSubmit",
- },
- },
- altText: "Submit",
- },
- },
- };
- return card;
-}
-
-/**
- * Confirmation dialog after a calendar event is created successfully.
- * @param {string} url The Google Calendar Event url for link button
- * @return {object} JSON-formatted cards for the dialog
- */
-function getConfirmationDialog_(url) {
- return {
- actionResponse: {
- type: "DIALOG",
- dialogAction: {
- dialog: {
- body: {
- sections: [
- {
- widgets: [
- {
- textParagraph: {
- text: "Meeting created successfully!",
- },
- horizontalAlignment: "CENTER",
- },
- {
- buttonList: {
- buttons: [
- {
- text: "Open Calendar Event",
- onClick: {
- openLink: {
- url: url,
- },
- },
- },
- ],
- },
- horizontalAlignment: "CENTER",
- },
- ],
- },
- ],
- fixedFooter: {
- primaryButton: {
- text: "OK",
- onClick: {
- action: {
- function: "closeDialog",
- },
- },
- },
- },
- },
- },
- },
- },
- };
-}
diff --git a/solutions/schedule-meetings/README.md b/solutions/schedule-meetings/README.md
deleted file mode 100644
index 000aed7af..000000000
--- a/solutions/schedule-meetings/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Schedule meetings from Google Chat
-
-See [developers.google.com](https://developers.google.com/apps-script/samples/chat-apps/schedule-meetings) for additional details.
-
diff --git a/solutions/schedule-meetings/Utilities.js b/solutions/schedule-meetings/Utilities.js
deleted file mode 100644
index 6ecef73aa..000000000
--- a/solutions/schedule-meetings/Utilities.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Copyright 2022 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Helper function that gets the field value from the given form input.
- * @return {string}
- */
-function getFieldValue_(formInputs, fieldName) {
- return formInputs[fieldName][""].stringInputs.value[0];
-}
-
-// Regular expression to validate the date/time input.
-const DATE_TIME_PATTERN = /\d{1,2}\/\d{1,2}\/\d{4}\s+\d{1,2}:\d\d/;
-
-/**
- * Casts date and time from string to Date object.
- * @return {date}
- */
-function getStartTimeAsDateObject_(dateTimeStr) {
- if (!dateTimeStr || !dateTimeStr.match(DATE_TIME_PATTERN)) {
- return null;
- }
-
- const parts = dateTimeStr.split(" ");
- const [month, day, year] = parts[0].split("/").map(Number);
- const [hour, minute] = parts[1].split(":").map(Number);
-
- Session.getScriptTimeZone();
-
- return new Date(year, month - 1, day, hour, minute);
-}
-
-/**
- * Gets the current date and time for the upcoming top of the hour (e.g. 01/25/2022 18:00).
- * @return {string} date/time in mm/dd/yyy HH:MM format needed for use by Calendar
- */
-function getTopOfHourDateString_() {
- const date = new Date();
- date.setHours(date.getHours() + 1);
- date.setMinutes(0, 0, 0);
- // Adding the date as string might lead to an incorrect response due to time zone adjustments.
- return Utilities.formatDate(
- date,
- Session.getScriptTimeZone(),
- "MM/dd/yyyy H:mm",
- );
-}
-
-/**
- * Creates the URL for the Google Calendar event.
- *
- * @param {object} event The Google Calendar Event instance
- * @param {object} cal The associated Google Calendar
- * @return {string} URL in the form of 'https://www.google.com/calendar/event?eid={event-id}'
- */
-function getCalendarEventURL_(event, cal) {
- const baseCalUrl = "https://www.google.com/calendar";
- // Joins Calendar Event Id with Calendar Id, then base64 encode to derive the event URL.
- let encodedId = Utilities.base64Encode(
- `${event.getId().split("@")[0]} ${cal.getId()}`,
- ).replace(/\=/g, "");
- encodedId = `/event?eid=${encodedId}`;
- return baseCalUrl + encodedId;
-}
diff --git a/solutions/schedule-meetings/appsscript.json b/solutions/schedule-meetings/appsscript.json
deleted file mode 100644
index cf76895c9..000000000
--- a/solutions/schedule-meetings/appsscript.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "timeZone": "America/Los_Angeles",
- "exceptionLogging": "STACKDRIVER",
- "runtimeVersion": "V8",
- "chat": {
- "addToSpaceFallbackMessage": "Thank you for adding this Chat App!"
- }
-}