یک دستور کار برای جلسات تهیه کنید

سطح کدنویسی : مبتدی
مدت زمان : ۱۵ دقیقه
نوع پروژه : اتوماسیون با تریگر رویداد محور

اهداف

  • بفهمید که راه حل چه کاری انجام می‌دهد.
  • درک کنید که سرویس‌های Apps Script در این راهکار چه کاری انجام می‌دهند.
  • اسکریپت را تنظیم کنید.
  • اسکریپت را اجرا کنید.

درباره این راهکار

به طور خودکار اسناد دستور کار را در Google Docs ایجاد کنید و آنها را به جلسات تقویم Google خود پیوست کنید.

تصویر صفحه دستور جلسه اضافه شده به رویداد تقویم

چگونه کار می‌کند؟

این اسکریپت یک الگوی سند برای یک دستور جلسه ایجاد می‌کند. وقتی تقویم خود را به‌روزرسانی می‌کنید، اسکریپت بررسی می‌کند که آیا رویدادهایی که متعلق به شماست شامل "#agenda" در توضیحات هستند یا خیر. اگر این برچسب وجود داشته باشد، اسکریپت یک کپی از الگو تهیه می‌کند، آن را به رویداد تقویم اضافه می‌کند و آن را با شرکت‌کنندگان رویداد به اشتراک می‌گذارد.

سرویس‌های اسکریپت برنامه‌ها

این راهکار از سرویس‌های زیر استفاده می‌کند:

  • سرویس Drive – بررسی می‌کند که آیا سند الگو وجود دارد یا خیر و اگر وجود نداشته باشد، یک پوشه جدید برای سند الگو ایجاد می‌کند. برای هر دستور کار جدید، یک کپی از سند الگو ایجاد می‌کند.
  • سرویس سند - الگوی دستور کار را ایجاد می‌کند.
  • سرویس تقویم - رویدادهایی را که دارای برچسب "#agenda" هستند بررسی می‌کند و شرح رویداد را با پیوندی به سند دستور جلسه به‌روزرسانی می‌کند.
  • سرویس پایه - از کلاس Session برای دریافت ایمیل کاربر استفاده می‌کند. این به ساخت trigger برای کاربر فعلی کمک می‌کند.
  • سرویس اسکریپت - ماشه ای ایجاد می کند که هر زمان تغییری در تقویم کاربر ایجاد شود، فعال می شود.

پیش‌نیازها

برای استفاده از این نمونه، به پیش‌نیازهای زیر نیاز دارید:

  • یک حساب گوگل (حساب‌های کاربری گوگل ورک‌اسپیس ممکن است نیاز به تأیید مدیر داشته باشند).
  • یک مرورگر وب با دسترسی به اینترنت.

اسکریپت را تنظیم کنید

  1. برای باز کردن نمونه پروژه اسکریپت برنامه‌ها برای جلسات، روی دکمه زیر کلیک کنید.
    پروژه را باز کنید
  2. روی نمای کلی کلیک کنید.
  3. در صفحه مرور کلی، روی «ایجاد کپی» کلیک کنید آیکون مربوط به کپی کردن .
  4. در پروژه کپی شده خود، در منوی کشویی تابع، setUp را انتخاب کنید.
  5. روی اجرا کلیک کنید.
  6. وقتی از شما خواسته شد، اسکریپت را تأیید کنید. اگر صفحه رضایت OAuth هشدار « این برنامه تأیید نشده است» را نشان می‌دهد، با انتخاب Advanced > Go to {Project Name} (unsafe) ادامه دهید.

اسکریپت را اجرا کنید

  1. تقویم گوگل را باز کنید.
  2. یک رویداد جدید ایجاد کنید یا یک رویداد موجود را ویرایش کنید.
  3. در توضیحات، #agenda را اضافه کنید و رویداد را ذخیره کنید.
  4. ایمیل خود را برای اطلاع از اینکه سندی با شما به اشتراک گذاشته شده است، بررسی کنید، یا تقویم را رفرش کنید و دوباره روی رویداد کلیک کنید تا پیوند به سند دستور جلسه را ببینید.

همه شرکت‌کنندگان برای مشاهده دستور جلسه، ایمیل اطلاع‌رسانی دریافت می‌کنند. اسکریپت به شرکت‌کنندگان اجازه ویرایش می‌دهد، اما شما می‌توانید اسکریپت را ویرایش کنید تا مجوزهای سند دستور جلسه را برای شرکت‌کنندگان به‌روزرسانی کنید .

کد را مرور کنید

برای بررسی کد Apps Script برای این راهکار، روی مشاهده کد منبع در زیر کلیک کنید:

مشاهده کد منبع

کد.gs

راهکارها/اتوماسیون‌ها/برنامه‌ریز/کد.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();
}

اصلاحات

شما می‌توانید نمونه را تا جایی که می‌خواهید متناسب با نیازهایتان ویرایش کنید. در زیر چند تغییر اختیاری وجود دارد که می‌توانید اعمال کنید.

به‌روزرسانی مجوزهای سند دستور جلسه برای شرکت‌کنندگان

این اسکریپت به شرکت‌کنندگان اجازه ویرایش می‌دهد. اگر می‌خواهید مجوزها را فقط به مشاهده محدود کنید، متد addEditor با متد addViewer در بخش زیر از کد جایگزین کنید:

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

       newDoc.addEditor(guest.getEmail());

الگوی سند دستور کار را ویرایش کنید

برای به‌روزرسانی الگوی سند دستور جلسه، مراحل زیر را انجام دهید:

  1. بعد از اینکه اولین دستور کار خود را در یک رویداد تقویم ایجاد کردید، گوگل درایو را باز کنید.
  2. پوشه‌ای به نام Agenda Maker - App را باز کنید.
  3. سند Agenda TEMPLATE## را باز کنید و ویرایش‌های خود را انجام دهید.

مشارکت‌کنندگان

این نمونه توسط جرمی گلسنبرگ، مشاور مدیریت محصول و استراتژی پلتفرم، ایجاد شده است. جرمی را در توییتر با شناسه @jglassenberg پیدا کنید.

این نمونه توسط گوگل و با کمک متخصصان توسعه‌دهنده گوگل نگهداری می‌شود.

مراحل بعدی