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 trình kích hoạt do sự kiện điều khiển

Mục tiêu

  • Tìm hiểu chức năng của giải pháp.
  • Tìm hiểu 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 trong Google Tài liệu và đính kèm vào các cuộc họp trên Lịch Google.

Ảnh chụp màn hình về chương trình đã thêm vào sự kiện trên Lịch

Cách hoạt động

Tập lệnh này tạo một mẫu tài liệu cho một chương trình nghị sự. 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ụ Apps Script

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

  • Dịch vụ Drive – Kiểm tra xem tài liệu mẫu có tồn tại hay không. Nếu không, hãy tạo một thư mục mới cho tài liệu mẫu. Tạo bản sao của tài liệu mẫu cho mỗi chương trình nghị sự mới.
  • Dịch vụ tài liệu – Tạo mẫu chương trình nghị sự.
  • Dịch vụ lịch – Kiểm tra các sự kiện có thẻ "#agenda" và cập nhật nội dung 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 sẽ kích hoạt 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 có các điều kiện tiên quyết sau:

  • Tài khoản Google (có thể cần có sự phê duyệt của quản trị viên đối với tài khoản Google Workspace).
  • Một trình duyệt web có quyền truy cập Internet.

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

  1. Nhấp vào nút bên dưới để mở dự án Apps Script mẫu Tạo chương trình nghị sự cho cuộc họp.
    Mở dự án
  2. Nhấp vào biểu tượng Tổng quan .
  3. Trên trang tổng quan, hãy nhấp vào biểu tượng 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. Nếu màn hình đồng ý OAuth hiển thị cảnh báo Ứng dụng này chưa được xác minh, hãy tiếp tục bằng cách chọn Nâng cao > Chuyển đến {Project Name} (không an toàn).

Chạy tập lệnh

  1. Mở Lịch Google.
  2. Tạo sự kiện mới hoặc chỉnh sửa 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 để xem thông báo email về việc 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.

Tất cả người tham dự đều nhận được thông báo qua email để xem chương trình. Tập lệnh này 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 cho người tham dự.

Xem lại mã

Để xem xét mã Apps Script cho giải pháp này, hãy nhấp vào Xem mã nguồn bên dưới:

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()) {
    let 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
  let 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 (let i in event.getGuestList()) {
          let 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 (let i in event.getGuestList()) {
        let 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() {
  let email = Session.getActiveUser().getEmail();
  ScriptApp.newTrigger("onCalendarChange").forUserCalendar(email).onEventUpdated().create();
}

Sửa đổi

Bạn có thể chỉnh sửa mẫu theo ý muốn cho phù hợp với nhu cầu của mình. Dưới đây là một số 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 cho người tham dự

Tập lệnh này cấp cho người tham dự quyền chỉnh sửa. Nếu bạn muốn hạn chế quyền 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

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

  1. Sau khi bạn tạo chương trình nghị sự đầ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 Agenda Maker – App (Trình tạo chương trình – Ứng dụng).
  3. Mở tài liệu Agenda TEMPLATE## (Chương trình nghị sự TEMPLATE##) rồi chỉnh sửa.

Người đóng góp

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

Mẫu này do Google duy trì với sự trợ giúp của Chuyên gia phát triển của Google.

Các bước tiếp theo