Hướng dẫn bắt đầu nhanh về Tiện ích bổ sung của Google Workspace

Quá trình khởi động nhanh này sẽ tạo một Tiện ích bổ sung đơn giản của Google Workspace, giúp hiển thị trang chủ, trình kích hoạt theo ngữ cảnh và kết nối với API của bên thứ ba.

Tiện ích bổ sung tạo các giao diện theo bối cảnh và không theo ngữ cảnh trong Gmail, Lịch và Drive. Tiện ích bổ sung hiển thị hình ảnh ngẫu nhiên về một chú mèo bằng văn bản phủ lên hình ảnh. Văn bản tĩnh đối với trang chủ hoặc được lấy từ ngữ cảnh ứng dụng lưu trữ để kích hoạt ngữ cảnh.

Mục tiêu

  • Thiết lập môi trường.
  • Thiết lập tập lệnh.
  • Chạy tập lệnh.

Điều kiện tiên quyết

Để sử dụng mẫu này, bạn cần có các điều kiện tiên quyết sau:

  • Tài khoản Google (tài khoản Google Workspace có thể yêu cầu quản trị viên phê duyệt).
  • Một trình duyệt web có quyền truy cập vào Internet.

  • Một dự án Google Cloud.

Thiết lập môi trường

Mở dự án Cloud trong bảng điều khiển Google Cloud

Nếu nó chưa mở, hãy mở dự án Cloud mà bạn định sử dụng cho mẫu này:

  1. Trong bảng điều khiển của Google Cloud, hãy chuyển đến trang Select a project (Chọn một dự án).

    Chọn một dự án Cloud

  2. Chọn dự án Google Cloud mà bạn muốn sử dụng. Hoặc nhấp vào Tạo dự án rồi làm theo hướng dẫn trên màn hình. Nếu tạo một dự án Google Cloud, bạn có thể cần phải bật tính năng thanh toán cho dự án đó.

Tiện ích bổ sung của Google Workspace yêu cầu cấu hình màn hình xin phép. Định cấu hình màn hình đồng ý OAuth của tiện ích bổ sung sẽ xác định nội dung Google hiển thị cho người dùng.

  1. Trong bảng điều khiển của Google Cloud, hãy chuyển đến Trình đơn > API và dịch vụ > Màn hình xin phép bằng OAuth.

    Chuyển đến màn hình xin phép bằng OAuth

  2. Chọn loại người dùng cho ứng dụng của bạn, rồi nhấp vào Tạo.
  3. Hoàn thành biểu mẫu đăng ký ứng dụng, sau đó nhấp vào Lưu và tiếp tục.
  4. Hiện tại, bạn có thể bỏ qua bước thêm phạm vi rồi nhấp vào Lưu và tiếp tục. Trong tương lai, khi tạo một ứng dụng để dùng bên ngoài tổ chức Google Workspace, bạn phải thêm và xác minh phạm vi uỷ quyền mà ứng dụng của bạn yêu cầu.

  5. Nếu bạn chọn Bên ngoài cho loại người dùng, hãy thêm người dùng thử nghiệm:
    1. Trong phần Kiểm thử người dùng, hãy nhấp vào Thêm người dùng.
    2. Nhập địa chỉ email của bạn và những người dùng thử nghiệm được ủy quyền khác, sau đó nhấp vào Lưu và tiếp tục.
  6. Xem lại bản tóm tắt đăng ký ứng dụng của bạn. Để thực hiện thay đổi, hãy nhấp vào Chỉnh sửa. Nếu đơn đăng ký ứng dụng có vẻ ổn, hãy nhấp vào Quay lại trang tổng quan.

Thiết lập tập lệnh

Tạo dự án Apps Script

  1. Để tạo một dự án Apps Script mới, hãy chuyển đến script.new.
  2. Nhấp vào Dự án không có tiêu đề.
  3. Đổi tên dự án Apps Script Mèo rồi nhấp vào Đổi tên.
  4. Bên cạnh tệp Code.gs, nhấp vào biểu tượng Thêm > Đổi tên. Đặt tên Common cho tệp.
  5. Nhấp vào biểu tượng Thêm tệp > Tập lệnh. Đặt tên Gmail cho tệp.
  6. Lặp lại bước 5 để tạo thêm 2 tệp tập lệnh có tên CalendarDrive. Khi hoàn tất, bạn nên có 4 tệp tập lệnh riêng biệt.
  7. Thay thế nội dung của từng tệp bằng mã tương ứng sau:

    Chung.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;
    }
    
      

    Lịch.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);
    }
    
      

  8. Nhấp vào biểu tượng Cài đặt dự án Biểu tượng cho chế độ cài đặt dự án.

  9. Đánh dấu vào hộp Hiển thị tệp kê khai "appsscript.json" trong trình chỉnh sửa.

  10. Nhấp vào biểu tượng Trình chỉnh sửa .

  11. Mở tệp appsscript.json và thay thế nội dung bằng mã sau, sau đó nhấp vào Lưu Biểu tượng Lưu.

    appscript.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"
          }
        }
      }
    }
    
      

Sao chép số dự án trên đám mây

  1. Chuyển đến dự án Cloud của bạn trong bảng điều khiển Google Cloud.
  2. Nhấp vào Cài đặt và Tiện ích > Cài đặt dự án.
  3. Sao chép Số dự án.

Đặt dự án Cloud Script của dự án Apps Script

  1. Trong dự án Apps Script, hãy nhấp vào biểu tượng Project Settings (Cài đặt dự án) Biểu tượng cho chế độ cài đặt dự án.
  2. Trong Dự án Google Cloud Platform (GCP), hãy nhấp vào Thay đổi dự án.
  3. Trong số dự án GCP, hãy dán số dự án trên Google Cloud.
  4. Nhấp vào Đặt dự án.

Cài đặt bản triển khai thử nghiệm

  1. Trong dự án Apps Script, hãy nhấp vào Trình chỉnh sửa .
  2. Mở tệp Common.gs rồi nhấp vào Run (Chạy). Khi được nhắc, hãy cho phép tập lệnh.
  3. Nhấp vào Triển khai > Triển khai thử nghiệm.
  4. Nhấp vào Cài đặt > Xong.

Chạy tập lệnh

  1. Truy cập vào Gmail.
  2. Để mở tiện ích bổ sung, trong bảng điều khiển bên phải, hãy nhấp vào biểu tượng Mèo .
  3. Nếu được nhắc, hãy cho phép tiện ích bổ sung đó.
  4. Tiện ích bổ sung này hiển thị một hình ảnh và văn bản về mèo. Để thay đổi hình ảnh, hãy nhấp vào Thay đổi mèo.
  5. Nếu bạn mở email trong khi tiện ích bổ sung đang mở, thì hình ảnh sẽ được làm mới và văn bản sẽ thay đổi thành dòng tiêu đề của email (bị cắt bớt nếu quá dài).

Bạn có thể thấy chức năng tương tự trong Lịch và Drive. Bạn không cần phải ủy quyền lại tiện ích bổ sung để sử dụng trong các ứng dụng lưu trữ đó.

Các bước tiếp theo