В этом кратком руководстве создается простая надстройка Google Workspace, которая демонстрирует домашние страницы, контекстные триггеры и подключение к сторонним API.
Надстройка создает контекстные и неконтекстные интерфейсы в Gmail, Календаре и Диске. Дополнение отображает случайное изображение кошки с текстом, наложенным на изображение. Текст либо статический для домашних страниц, либо берется из контекста ведущего приложения для контекстных триггеров.
Цели
- Настройте свою среду.
- Настройте сценарий.
- Запустите сценарий.
Предварительные условия
Для использования этого образца необходимы следующие предварительные условия:
- Учетная запись Google (для учетных записей Google Workspace может потребоваться одобрение администратора).
Веб-браузер с доступом в Интернет.
Настройте свою среду
Откройте свой облачный проект в консоли Google Cloud.
Если он еще не открыт, откройте проект Cloud, который вы собираетесь использовать для этого примера:
- В консоли Google Cloud перейдите на страницу «Выбор проекта» .
- Выберите проект Google Cloud, который вы хотите использовать. Или нажмите «Создать проект» и следуйте инструкциям на экране. Если вы создаете проект Google Cloud, вам может потребоваться включить для него оплату .
Настройка экрана согласия OAuth
Для надстроек Google Workspace требуется настройка экрана согласия. Настройка экрана согласия OAuth вашего дополнения определяет, что Google отображает пользователям.
- В консоли Google Cloud выберите > API и службы > Экран согласия OAuth .
- В качестве типа пользователя выберите «Внутренний» , затем нажмите «Создать» .
- Заполните форму регистрации приложения, затем нажмите « Сохранить и продолжить» .
На данный момент вы можете пропустить добавление областей и нажать « Сохранить и продолжить» . В будущем, когда вы создадите приложение для использования за пределами вашей организации Google Workspace, вам необходимо изменить тип пользователя на Внешний , а затем добавить области авторизации, необходимые вашему приложению.
- Просмотрите сводку регистрации приложения. Чтобы внести изменения, нажмите «Изменить» . Если регистрация приложения выглядит нормально, нажмите «Вернуться на панель управления» .
Настройте сценарий
Создайте проект скрипта приложений.
- Чтобы создать новый проект Apps Script, перейдите по адресу script.new .
- Нажмите «Проект без названия» .
- Переименуйте проект Apps Script Cats и нажмите «Переименовать» .
- Рядом с файлом
Code.gs
нажмите Еще > Переименовать . Назовите файлCommon
. - Нажмите « > «Скрипт» . Назовите файл
Gmail
. файл» - Повторите шаг 5, чтобы создать еще два файла сценариев с именами
Calendar
иDrive
. Когда вы закончите, у вас должно получиться 4 отдельных файла сценариев. Замените содержимое каждого файла следующим соответствующим кодом:
Common.gs
/** * This simple Google Workspace Add-on shows a random image of a cat in the * sidebar. When opened manually (the homepage card), some static text is * overlayed on the image, but when contextual cards are opened a new cat image * is shown with the text taken from that context (such as a message's subject * line) overlaying the image. There is also a button that updates the card with * a new random cat image. * * Click "File > Make a copy..." to copy the script, and "Publish > Deploy from * manifest > Install add-on" to install it. */ /** * The maximum number of characters that can fit in the cat image. */ var MAX_MESSAGE_LENGTH = 40; /** * Callback for rendering the homepage card. * @return {CardService.Card} The card to show to the user. */ function onHomepage(e) { console.log(e); var hour = Number(Utilities.formatDate(new Date(), e.userTimezone.id, 'H')); var message; if (hour >= 6 && hour < 12) { message = 'Good morning'; } else if (hour >= 12 && hour < 18) { message = 'Good afternoon'; } else { message = 'Good night'; } message += ' ' + e.hostApp; return createCatCard(message, true); } /** * Creates a card with an image of a cat, overlayed with the text. * @param {String} text The text to overlay on the image. * @param {Boolean} isHomepage True if the card created here is a homepage; * false otherwise. Defaults to false. * @return {CardService.Card} The assembled card. */ function createCatCard(text, isHomepage) { // Explicitly set the value of isHomepage as false if null or undefined. if (!isHomepage) { isHomepage = false; } // Use the "Cat as a service" API to get the cat image. Add a "time" URL // parameter to act as a cache buster. var now = new Date(); // Replace forward slashes in the text, as they break the CataaS API. var caption = text.replace(/\//g, ' '); var imageUrl = Utilities.formatString('https://cataas.com/cat/says/%s?time=%s', encodeURIComponent(caption), now.getTime()); var image = CardService.newImage() .setImageUrl(imageUrl) .setAltText('Meow') // Create a button that changes the cat image when pressed. // Note: Action parameter keys and values must be strings. var action = CardService.newAction() .setFunctionName('onChangeCat') .setParameters({text: text, isHomepage: isHomepage.toString()}); var button = CardService.newTextButton() .setText('Change cat') .setOnClickAction(action) .setTextButtonStyle(CardService.TextButtonStyle.FILLED); var buttonSet = CardService.newButtonSet() .addButton(button); // Create a footer to be shown at the bottom. var footer = CardService.newFixedFooter() .setPrimaryButton(CardService.newTextButton() .setText('Powered by cataas.com') .setOpenLink(CardService.newOpenLink() .setUrl('https://cataas.com'))); // Assemble the widgets and return the card. var section = CardService.newCardSection() .addWidget(image) .addWidget(buttonSet); var card = CardService.newCardBuilder() .addSection(section) .setFixedFooter(footer); if (!isHomepage) { // Create the header shown when the card is minimized, // but only when this card is a contextual card. Peek headers // are never used by non-contexual cards like homepages. var peekHeader = CardService.newCardHeader() .setTitle('Contextual Cat') .setImageUrl('https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png') .setSubtitle(text); card.setPeekCardHeader(peekHeader) } return card.build(); } /** * Callback for the "Change cat" button. * @param {Object} e The event object, documented {@link * https://developers.google.com/gmail/add-ons/concepts/actions#action_event_objects * here}. * @return {CardService.ActionResponse} The action response to apply. */ function onChangeCat(e) { console.log(e); // Get the text that was shown in the current cat image. This was passed as a // parameter on the Action set for the button. var text = e.parameters.text; // The isHomepage parameter is passed as a string, so convert to a Boolean. var isHomepage = e.parameters.isHomepage === 'true'; // Create a new card with the same text. var card = createCatCard(text, isHomepage); // Create an action response that instructs the add-on to replace // the current card with the new one. var navigation = CardService.newNavigation() .updateCard(card); var actionResponse = CardService.newActionResponseBuilder() .setNavigation(navigation); return actionResponse.build(); } /** * Truncate a message to fit in the cat image. * @param {string} message The message to truncate. * @return {string} The truncated message. */ function truncate(message) { if (message.length > MAX_MESSAGE_LENGTH) { message = message.slice(0, MAX_MESSAGE_LENGTH); message = message.slice(0, message.lastIndexOf(' ')) + '...'; } return message; }
Gmail.gs
/** * Callback for rendering the card for a specific Gmail message. * @param {Object} e The event object. * @return {CardService.Card} The card to show to the user. */ function onGmailMessage(e) { console.log(e); // Get the ID of the message the user has open. var messageId = e.gmail.messageId; // Get an access token scoped to the current message and use it for GmailApp // calls. var accessToken = e.gmail.accessToken; GmailApp.setCurrentMessageAccessToken(accessToken); // Get the subject of the email. var message = GmailApp.getMessageById(messageId); var subject = message.getThread().getFirstMessageSubject(); // Remove labels and prefixes. subject = subject .replace(/^([rR][eE]|[fF][wW][dD])\:\s*/, '') .replace(/^\[.*?\]\s*/, ''); // If neccessary, truncate the subject to fit in the image. subject = truncate(subject); return createCatCard(subject); } /** * Callback for rendering the card for the compose action dialog. * @param {Object} e The event object. * @return {CardService.Card} The card to show to the user. */ function onGmailCompose(e) { console.log(e); var header = CardService.newCardHeader() .setTitle('Insert cat') .setSubtitle('Add a custom cat image to your email message.'); // Create text input for entering the cat's message. var input = CardService.newTextInput() .setFieldName('text') .setTitle('Caption') .setHint('What do you want the cat to say?'); // Create a button that inserts the cat image when pressed. var action = CardService.newAction() .setFunctionName('onGmailInsertCat'); var button = CardService.newTextButton() .setText('Insert cat') .setOnClickAction(action) .setTextButtonStyle(CardService.TextButtonStyle.FILLED); var buttonSet = CardService.newButtonSet() .addButton(button); // Assemble the widgets and return the card. var section = CardService.newCardSection() .addWidget(input) .addWidget(buttonSet); var card = CardService.newCardBuilder() .setHeader(header) .addSection(section); return card.build(); } /** * Callback for inserting a cat into the Gmail draft. * @param {Object} e The event object. * @return {CardService.UpdateDraftActionResponse} The draft update response. */ function onGmailInsertCat(e) { console.log(e); // Get the text that was entered by the user. var text = e.formInput.text; // Use the "Cat as a service" API to get the cat image. Add a "time" URL // parameter to act as a cache buster. var now = new Date(); var imageUrl = 'https://cataas.com/cat'; if (text) { // Replace forward slashes in the text, as they break the CataaS API. var caption = text.replace(/\//g, ' '); imageUrl += Utilities.formatString('/says/%s?time=%s', encodeURIComponent(caption), now.getTime()); } var imageHtmlContent = '<img style="display: block; max-height: 300px;" src="' + imageUrl + '"/>'; var response = CardService.newUpdateDraftActionResponseBuilder() .setUpdateDraftBodyAction(CardService.newUpdateDraftBodyAction() .addUpdateContent(imageHtmlContent,CardService.ContentType.MUTABLE_HTML) .setUpdateType(CardService.UpdateDraftBodyType.IN_PLACE_INSERT)) .build(); return response; }
Календарь.gs
/** * Callback for rendering the card for a specific Calendar event. * @param {Object} e The event object. * @return {CardService.Card} The card to show to the user. */ function onCalendarEventOpen(e) { console.log(e); var calendar = CalendarApp.getCalendarById(e.calendar.calendarId); // The event metadata doesn't include the event's title, so using the // calendar.readonly scope and fetching the event by it's ID. var event = calendar.getEventById(e.calendar.id); if (!event) { // This is a new event still being created. return createCatCard('A new event! Am I invited?'); } var title = event.getTitle(); // If necessary, truncate the title to fit in the image. title = truncate(title); return createCatCard(title); }
Drive.gs
/** * Callback for rendering the card for specific Drive items. * @param {Object} e The event object. * @return {CardService.Card} The card to show to the user. */ function onDriveItemsSelected(e) { console.log(e); var items = e.drive.selectedItems; // Include at most 5 items in the text. items = items.slice(0, 5); var text = items.map(function(item) { var title = item.title; // If neccessary, truncate the title to fit in the image. title = truncate(title); return title; }).join('\n'); return createCatCard(text); }
Нажмите «Настройки проекта». .
Установите флажок «Показывать файл манифеста «appsscript.json» в поле редактора» .
Нажмите
редактора» .Откройте файл
appsscript.json
и замените его содержимое следующим кодом, затем нажмите «Сохранить». .appsscript.json
{ "timeZone": "America/New_York", "dependencies": { }, "exceptionLogging": "STACKDRIVER", "oauthScopes": [ "https://www.googleapis.com/auth/calendar.addons.execute", "https://www.googleapis.com/auth/calendar.readonly", "https://www.googleapis.com/auth/drive.addons.metadata.readonly", "https://www.googleapis.com/auth/gmail.addons.current.action.compose", "https://www.googleapis.com/auth/gmail.addons.current.message.readonly", "https://www.googleapis.com/auth/gmail.addons.execute", "https://www.googleapis.com/auth/script.locale"], "runtimeVersion": "V8", "addOns": { "common": { "name": "Cats", "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png", "useLocaleFromApp": true, "homepageTrigger": { "runFunction": "onHomepage", "enabled": true }, "universalActions": [{ "label": "Learn more about Cataas", "openLink": "https://cataas.com" }] }, "gmail": { "contextualTriggers": [{ "unconditional": { }, "onTriggerFunction": "onGmailMessage" }], "composeTrigger": { "selectActions": [{ "text": "Insert cat", "runFunction": "onGmailCompose" }], "draftAccess": "NONE" } }, "drive": { "onItemsSelectedTrigger": { "runFunction": "onDriveItemsSelected" } }, "calendar": { "eventOpenTrigger": { "runFunction": "onCalendarEventOpen" } } } }
Скопируйте номер облачного проекта
- В консоли Google Cloud выберите > IAM и администрирование > Настройки .
- В поле Номер проекта скопируйте значение.
Установите облачный проект проекта Apps Script.
- В проекте Apps Script нажмите «Настройки проекта» . .
- В разделе «Проект Google Cloud Platform (GCP)» нажмите « Изменить проект» .
- В поле «Номер проекта GCP» вставьте номер проекта Google Cloud.
- Нажмите Установить проект .
Установите тестовое развертывание
- В проекте Apps Script нажмите редактора» .
- Щелкните Развертывание > Тестовые развертывания .
- Нажмите «Установить» > «Готово» .
Запустите сценарий
- Зайдите в Gmail .
- Чтобы открыть дополнение, на правой боковой панели нажмите «Кошки» .
- При появлении запроса авторизуйте надстройку.
- Дополнение отображает изображение и текст кота. Чтобы изменить изображение, нажмите « Изменить кота» .
- Если вы откроете электронное письмо, когда надстройка открыта, изображение обновится, а текст изменится на тему письма (обрезается, если он слишком длинный).
Вы можете увидеть аналогичные функции в Календаре и Диске. Вам не нужно повторно авторизовать надстройку, чтобы использовать ее в этих хост-приложениях.
Следующие шаги
- Расширьте Google Workspace с помощью надстроек
- Создание дополнений для Google Workspace
- Опубликовать приложение