Tạo chương trình làm việc cho cuộc họp

Cấp độ lập trình: Người mới bắt đầu
Thời lượng: 15 phút
Loại dự án: Tự động hoá bằng điều kiện kích hoạt dựa trên sự kiện

Mục tiêu

  • Hiểu rõ chức năng của giải pháp.
  • Hiểu rõ chức năng của các dịch vụ Apps Script trong giải pháp.
  • Thiết lập tập lệnh.
  • Chạy tập lệnh.

Giới thiệu về giải pháp này

Tự động tạo tài liệu chương trình làm việc trong Google Tài liệu và đính kèm vào các cuộc họp trên Lịch Google.

Tài liệu chương trình nghị sự được đính kèm vào một sự kiện trên Lịch Google

Cách hoạt động

Tập lệnh tạo một mẫu tài liệu cho chương trình làm việc. Khi bạn cập nhật lịch, tập lệnh sẽ kiểm tra xem có sự kiện nào mà bạn sở hữu có chứa "#agenda" trong phần mô tả hay không. Nếu có thẻ này, tập lệnh sẽ tạo một bản sao của mẫu, thêm bản sao đó vào sự kiện trên lịch và chia sẻ với những người tham dự sự kiện.

Dịch vụ Google Apps Script

Giải pháp này sử dụng các dịch vụ sau:

  • Dịch vụ Google Drive: Kiểm tra xem tài liệu mẫu có tồn tại hay không. Nếu không, tập lệnh sẽ tạo một thư mục mới cho tài liệu mẫu và tạo một bản sao của tài liệu mẫu cho mỗi chương trình làm việc mới.
  • Dịch vụ Tài liệu: Tạo mẫu chương trình làm việc.
  • Dịch vụ Lịch: Kiểm tra các sự kiện có thẻ "#agenda" và cập nhật phần mô tả sự kiện bằng đường liên kết đến tài liệu chương trình làm việc.
  • Dịch vụ cơ sở: Sử dụng lớp Session để lấy email của người dùng. Điều này giúp tạo điều kiện kích hoạt cho người dùng hiện tại.
  • Dịch vụ tập lệnh: Tạo một điều kiện kích hoạt chạy bất cứ khi nào có thay đổi đối với lịch của người dùng.

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

Để sử dụng mẫu này, bạn cần đáp ứng 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).
  • Trình duyệt web có quyền truy cập vào Internet.

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

  1. Nhấp vào nút sau để mở dự án Apps Script mẫu Make an agenda for meetings (Tạo chương trình làm việc cho các cuộc họp):

    Mở dự án

  2. Nhấp vào Tổng quan .

  3. Trên trang tổng quan, hãy nhấp vào Tạo bản sao Biểu tượng tạo bản sao.

  4. Trong dự án đã sao chép, trong trình đơn thả xuống hàm, hãy chọn setUp.

  5. Nhấp vào Chạy.

  6. Khi được nhắc, hãy cho phép tập lệnh chạy. <<../_snippets/oauth.md>>

Chạy tập lệnh

  1. Mở Lịch.
  2. Tạo sự kiện mới hoặc chỉnh sửa một sự kiện hiện có.
  3. Trong phần mô tả, hãy thêm #agenda rồi lưu sự kiện.
  4. Kiểm tra email để tìm email thông báo rằng một tài liệu đã được chia sẻ với bạn hoặc làm mới Lịch rồi nhấp lại vào sự kiện để xem đường liên kết đến tài liệu chương trình làm việc.

Tất cả người tham dự đều nhận được email thông báo để xem chương trình làm việc. Tập lệnh cấp cho người tham dự quyền chỉnh sửa, nhưng bạn có thể chỉnh sửa tập lệnh để cập nhật quyền đối với tài liệu chương trình làm việc cho người tham dự.

Xem lại mã

Để xem lại mã Apps Script cho giải pháp này, hãy nhấp vào Xem mã nguồn:

Xem mã nguồn

Code.gs

solutions/automations/agenda-maker/Code.js
// To learn how to use this script, refer to the documentation:
// https://developers.google.com/apps-script/samples/automations/agenda-maker

/*
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.
*/

/**
 * Checks if the folder for Agenda docs exists, and creates it if it doesn't.
 *
 * @return {*} Drive folder ID for the app.
 */
function checkFolder() {
  const folders = DriveApp.getFoldersByName("Agenda Maker - App");
  // Finds the folder if it exists
  while (folders.hasNext()) {
    const folder = folders.next();
    if (
      folder.getDescription() ===
        "Apps Script App - Do not change this description" &&
      folder.getOwner().getEmail() === Session.getActiveUser().getEmail()
    ) {
      return folder.getId();
    }
  }
  // If the folder doesn't exist, creates one
  const folder = DriveApp.createFolder("Agenda Maker - App");
  folder.setDescription("Apps Script App - Do not change this description");
  return folder.getId();
}

/**
 * Finds the template agenda doc, or creates one if it doesn't exist.
 */
function getTemplateId(folderId) {
  const folder = DriveApp.getFolderById(folderId);
  const files = folder.getFilesByName("Agenda TEMPLATE##");

  // If there is a file, returns the ID.
  while (files.hasNext()) {
    const file = files.next();
    return file.getId();
  }

  // Otherwise, creates the agenda template.
  // You can adjust the default template here
  const doc = DocumentApp.create("Agenda TEMPLATE##");
  const body = doc.getBody();

  body
    .appendParagraph("##Attendees##")
    .setHeading(DocumentApp.ParagraphHeading.HEADING1)
    .editAsText()
    .setBold(true);
  body.appendParagraph(" ").editAsText().setBold(false);

  body
    .appendParagraph("Overview")
    .setHeading(DocumentApp.ParagraphHeading.HEADING1)
    .editAsText()
    .setBold(true);
  body.appendParagraph(" ");
  body.appendParagraph("- Topic 1: ").editAsText().setBold(true);
  body.appendParagraph(" ").editAsText().setBold(false);
  body.appendParagraph("- Topic 2: ").editAsText().setBold(true);
  body.appendParagraph(" ").editAsText().setBold(false);
  body.appendParagraph("- Topic 3: ").editAsText().setBold(true);
  body.appendParagraph(" ").editAsText().setBold(false);

  body
    .appendParagraph("Next Steps")
    .setHeading(DocumentApp.ParagraphHeading.HEADING1)
    .editAsText()
    .setBold(true);
  body.appendParagraph("- Takeaway 1: ").editAsText().setBold(true);
  body.appendParagraph("- Responsible: ").editAsText().setBold(false);
  body.appendParagraph("- Accountable: ");
  body.appendParagraph("- Consult: ");
  body.appendParagraph("- Inform: ");
  body.appendParagraph(" ");
  body.appendParagraph("- Takeaway 2: ").editAsText().setBold(true);
  body.appendParagraph("- Responsible: ").editAsText().setBold(false);
  body.appendParagraph("- Accountable: ");
  body.appendParagraph("- Consult: ");
  body.appendParagraph("- Inform: ");
  body.appendParagraph(" ");
  body.appendParagraph("- Takeaway 3: ").editAsText().setBold(true);
  body.appendParagraph("- Responsible: ").editAsText().setBold(false);
  body.appendParagraph("- Accountable: ");
  body.appendParagraph("- Consult: ");
  body.appendParagraph("- Inform: ");

  doc.saveAndClose();

  folder.addFile(DriveApp.getFileById(doc.getId()));

  return doc.getId();
}

/**
 * When there is a change to the calendar, searches for events that include "#agenda"
 * in the decrisption.
 *
 */
function onCalendarChange() {
  // Gets recent events with the #agenda tag
  const now = new Date();
  const events = CalendarApp.getEvents(
    now,
    new Date(now.getTime() + 2 * 60 * 60 * 1000000),
    { search: "#agenda" },
  );

  const folderId = checkFolder();
  const templateId = getTemplateId(folderId);

  const folder = DriveApp.getFolderById(folderId);

  // Loops through any events found
  for (i = 0; i < events.length; i++) {
    const event = events[i];

    // Confirms whether the event has the #agenda tag
    let description = event.getDescription();
    if (description.search("#agenda") === -1) continue;

    // Only works with events created by the owner of this calendar
    if (event.isOwnedByMe()) {
      // Creates a new document from the template for an agenda for this event
      const newDoc = DriveApp.getFileById(templateId).makeCopy();
      newDoc.setName(`Agenda for ${event.getTitle()}`);

      const file = DriveApp.getFileById(newDoc.getId());
      folder.addFile(file);

      const doc = DocumentApp.openById(newDoc.getId());
      const body = doc.getBody();

      // Fills in the template with information about the attendees from the
      // calendar event
      const conf = body.findText("##Attendees##");
      if (conf) {
        const ref = conf.getStartOffset();

        for (const i in event.getGuestList()) {
          const guest = event.getGuestList()[i];

          body.insertParagraph(ref + 2, guest.getEmail());
        }
        body.replaceText("##Attendees##", "Attendees");
      }

      // Replaces the tag with a link to the agenda document
      const agendaUrl = `https://docs.google.com/document/d/${newDoc.getId()}`;
      description = description.replace(
        "#agenda",
        `<a href=${agendaUrl}>Agenda Doc</a>`,
      );
      event.setDescription(description);

      // Invites attendees to the Google doc so they automatically receive access to the agenda
      newDoc.addEditor(newDoc.getOwner());

      for (const i in event.getGuestList()) {
        const guest = event.getGuestList()[i];

        newDoc.addEditor(guest.getEmail());
      }
    }
  }
  return;
}

/**
 * Creates an event-driven trigger that fires whenever there's a change to the calendar.
 */
function setUp() {
  const email = Session.getActiveUser().getEmail();
  ScriptApp.newTrigger("onCalendarChange")
    .forUserCalendar(email)
    .onEventUpdated()
    .create();
}
</section>

Sửa đổi

Bạn có thể chỉnh sửa mẫu bao nhiêu tuỳ thích để phù hợp với nhu cầu của mình. Sau đây là một vài thay đổi không bắt buộc mà bạn có thể thực hiện.

Cập nhật quyền đối với tài liệu chương trình làm việc cho người tham dự

Tập lệnh cấp cho người tham dự quyền chỉnh sửa. Nếu bạn muốn giới hạn quyền chỉ ở chế độ xem, hãy thay thế phương thức addEditor bằng phương thức addViewer trong phần mã sau:

     for (let i in event.getGuestList()) {
       let guest = event.getGuestList()[i];

       newDoc.addEditor(guest.getEmail());

Chỉnh sửa mẫu tài liệu chương trình làm việc

Để cập nhật mẫu tài liệu chương trình làm việc, hãy làm theo các bước sau:

  1. Sau khi tạo chương trình làm việc đầu tiên trong một sự kiện trên lịch, hãy mở Google Drive.
  2. Mở thư mục có tên là Agenda Maker – App (Trình tạo chương trình làm việc – Ứng dụng).
  3. Mở tài liệu Agenda TEMPLATE## (Mẫu chương trình làm việc) rồi chỉnh sửa.

Người đóng góp

Mẫu này do Jeremy Glassenberg, Chuyên gia tư vấn về chiến lược nền tảng và quản lý sản phẩm tạo ra. Tìm Jeremy trên Twitter @jglassenberg.

Mẫu này do Google duy trì với sự trợ giúp của các Google Developer Experts.

Các bước tiếp theo