Создайте запись на сеансы на конференции

Уровень владения программированием : начинающий
Продолжительность : 5 минут
Тип проекта : Автоматизация с использованием пользовательского меню и триггера, срабатывающего по событию.

Цели

  • Поймите, для чего предназначено это решение.
  • Разберитесь, что делают службы Apps Script в рамках данного решения.
  • Настройте скрипт.
  • Запустите скрипт.

Об этом решении

Создайте комплексную систему регистрации на мероприятия. Если у вас приближается мероприятие, например, конференция, вы можете создать новый календарь для конференционных сессий, разработать форму регистрации и автоматически отправлять участникам по электронной почте персонализированные маршруты.

Информация из таблиц переносится в формы и календарь.

Как это работает

Данное решение использует пользовательское меню в Google Sheets для реализации автоматизированной системы регистрации на мероприятия. Скрипт создает календарь с мероприятиями конференции, перечисленными в электронной таблице Sheets. Затем скрипт создает форму со списком мероприятий, на которые могут зарегистрироваться участники. После заполнения формы участники добавляются в календарь и отправляют им по электронной почте расписание мероприятий.

Сервисы Apps Script

Данное решение использует следующие сервисы:

  • Сервис электронных таблиц – предоставляет информацию о мероприятии другим сервисам.
  • Календарный сервис — создает новый календарь для мероприятия, добавляет мероприятия в календарь и добавляет участников к мероприятиям, на которые они зарегистрировались.
  • Служба свойств — хранит идентификатор календаря, созданного службой календаря. Когда пользователь нажимает кнопку «Настроить конференцию» в пользовательском меню «Конференция» , служба свойств проверяет, настроена ли уже система регистрации на мероприятие, проверяя наличие свойства ID календаря. Это помогает избежать создания дубликатов форм и календарей.
  • Сервис создания форм – создает форму на основе информации из электронной таблицы, позволяющую участникам записываться на сессии.
  • Сервис скриптов — создает триггер, который срабатывает, когда участник заполняет форму.
  • Сервис документов — получает информацию о мероприятиях, на которые зарегистрировался участник, и добавляет список мероприятий в новый документ. Скрипт предоставляет участнику разрешение на редактирование документа.
  • Почтовая служба – отправляет участнику документ с программой поездки по электронной почте.

Предварительные требования

Для использования этого примера необходимы следующие условия:

  • Для работы потребуется учетная запись Google (для учетных записей Google Workspace может потребоваться подтверждение администратора).
  • Веб-браузер с доступом в интернет.

Настройте скрипт

  1. Нажмите следующую кнопку, чтобы создать копию таблицы «Создание списка участников сессий на конференции» . Проект Apps Script для этого решения прикреплен к таблице.
    Сделать копию
  2. Нажмите «Конференция» > «Настроить конференцию» . Возможно, потребуется обновить страницу, чтобы появилось это пользовательское меню.
  3. При появлении запроса авторизуйте скрипт. Если на экране согласия OAuth отобразится предупреждение « Это приложение не проверено» , продолжите, выбрав «Дополнительно» > «Перейти к {Название проекта} (небезопасно)» .

  4. Нажмите «Конференция» > «Настроить конференцию заново».

Запустите скрипт

  1. Нажмите «Инструменты» > «Управление формой» > «Перейти к работающей форме» .
  2. Заполните и отправьте форму.
  3. Перейдите на calendar.google.com .
  4. Слева убедитесь, что установлен флажок рядом с пунктом «Календарь конференций» .
  5. Перейдите к датам мероприятий, на которые вы зарегистрировались, и убедитесь, что вас добавили в список участников.

(Необязательно) Сбросить решение

Если вы хотите повторить попытку или настроить решение для использования собственной информации о событиях, вам необходимо сбросить некоторые параметры, которые были установлены при первом запуске скрипта. Чтобы просмотреть шаги по сбросу решения, нажмите «Сбросить решение» ниже:

Сбросить решение

Шаг 1: Сбросьте свойства сохраненного скрипта.

Если вы попытаетесь запустить скрипт более одного раза, появится сообщение: «Ваша конференция уже создана. Найдите форму регистрации в Google Drive!» Это происходит потому, что после создания календаря конференции идентификатор календаря сохраняется как свойство скрипта. При запуске скрипт проверяет, существует ли уже свойство идентификатора календаря, и останавливается, если оно существует.

Чтобы удалить существующее свойство ID календаря, выполните следующие действия:

  1. В электронной таблице нажмите «Расширения» > «Apps Script» .
  2. В редакторе Apps Script выберите функцию resetProperties из выпадающего списка и нажмите «Выполнить» .

Шаг 2: Удалите календарь конференции.

При каждом запуске скрипта создаётся новый календарь. Если вы не хотите сохранять исходный созданный календарь, выполните следующие действия:

  1. Перейдите на calendar.google.com .
  2. Рядом с пунктом «Календарь конференций» нажмите «Параметры календаря конференций». > Настройки и общий доступ .
  3. Прокрутите страницу настроек до конца и нажмите «Удалить» .

Шаг 3: Удалите триггер отправки формы.

Скрипт создает триггер для отправки форм при каждом запуске. Чтобы избежать множественных триггеров, приводящих к дублированию электронных писем, удалите исходный триггер. Выполните следующие действия:

  1. В электронной таблице нажмите «Расширения» > «Apps Script» .
  2. В проекте Apps Script слева нажмите «Триггеры» . .
  3. Рядом с кнопкой нажмите «Подробнее». > Удалить триггер .

При каждом запуске скрипта создается новая форма. Выполните следующие действия, чтобы отвязать форму от электронной таблицы и удалить ее:

  1. В электронной таблице щелкните правой кнопкой мыши лист «Ответы на форму» и выберите «Отменить связь формы» > «ОК» .
  2. Снова щелкните правой кнопкой мыши по листу «Ответы на форму» и выберите «Удалить» > «ОК» .
  3. Перейдите на сайт forms.google.com .
  4. Щелкните правой кнопкой мыши по форме конференции и выберите «Удалить» > «Переместить в корзину» .

После сброса настроек решения вы можете добавить свои собственные данные или продолжить использовать примерные данные и снова запустить скрипт.

Просмотрите код

Чтобы просмотреть код Apps Script для этого решения, нажмите «Просмотреть исходный код» ниже:

Просмотреть исходный код

Code.gs

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

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

/**
 * Inserts a custom menu when the spreadsheet opens.
 */
function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu("Conference")
    .addItem("Set up conference", "setUpConference_")
    .addToUi();
}

/**
 * Uses the conference data in the spreadsheet to create
 * Google Calendar events, a Google Form, and a trigger that allows the script
 * to react to form responses.
 */
function setUpConference_() {
  const scriptProperties = PropertiesService.getScriptProperties();
  if (scriptProperties.getProperty("calId")) {
    Browser.msgBox(
      "Your conference is already set up. Look in Google Drive for your" +
        " sign-up form!",
    );
    return;
  }
  const ss = SpreadsheetApp.getActive();
  const sheet = ss.getSheetByName("Conference Setup");
  const range = sheet.getDataRange();
  const values = range.getValues();
  setUpCalendar_(values, range);
  setUpForm_(ss, values);
  ScriptApp.newTrigger("onFormSubmit")
    .forSpreadsheet(ss)
    .onFormSubmit()
    .create();
}

/**
 * Creates a Google Calendar with events for each conference session in the
 * spreadsheet, then writes the event IDs to the spreadsheet for future use.
 * @param {Array<string[]>} values Cell values for the spreadsheet range.
 * @param {Range} range A spreadsheet range that contains conference data.
 */
function setUpCalendar_(values, range) {
  const cal = CalendarApp.createCalendar("Conference Calendar");
  // Start at 1 to skip the header row.
  for (let i = 1; i < values.length; i++) {
    const session = values[i];
    const title = session[0];
    const start = joinDateAndTime_(session[1], session[2]);
    const end = joinDateAndTime_(session[1], session[3]);
    const options = { location: session[4], sendInvites: true };
    const event = cal
      .createEvent(title, start, end, options)
      .setGuestsCanSeeGuests(false);
    session[5] = event.getId();
  }
  range.setValues(values);

  // Stores the ID for the Calendar, which is needed to retrieve events by ID.
  const scriptProperties = PropertiesService.getScriptProperties();
  scriptProperties.setProperty("calId", cal.getId());
}

/**
 * Creates a single Date object from separate date and time cells.
 *
 * @param {Date} date A Date object from which to extract the date.
 * @param {Date} time A Date object from which to extract the time.
 * @return {Date} A Date object representing the combined date and time.
 */
function joinDateAndTime_(date_, time) {
  const processedDate = new Date(date_);
  processedDate.setHours(time.getHours());
  processedDate.setMinutes(time.getMinutes());
  return processedDate;
}

/**
 * Creates a Google Form that allows respondents to select which conference
 * sessions they would like to attend, grouped by date and start time in the
 * caller's time zone.
 *
 * @param {Spreadsheet} ss The spreadsheet that contains the conference data.
 * @param {Array<String[]>} values Cell values for the spreadsheet range.
 */
function setUpForm_(ss, values) {
  // Group the sessions by date and time so that they can be passed to the form.
  const schedule = {};
  // Start at 1 to skip the header row.
  for (let i = 1; i < values.length; i++) {
    const session = values[i];
    const day = session[1].toLocaleDateString();
    const time = session[2].toLocaleTimeString();
    if (!schedule[day]) {
      schedule[day] = {};
    }
    if (!schedule[day][time]) {
      schedule[day][time] = [];
    }
    schedule[day][time].push(session[0]);
  }

  // Creates the form and adds a multiple-choice question for each timeslot.
  const form = FormApp.create("Conference Form");
  form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
  form.addTextItem().setTitle("Name").setRequired(true);
  form.addTextItem().setTitle("Email").setRequired(true);
  for (const day of Object.keys(schedule)) {
    form.addSectionHeaderItem().setTitle(`Sessions for ${day}`);
    for (const time of Object.keys(schedule[day])) {
      form
        .addMultipleChoiceItem()
        .setTitle(`${time} ${day}`)
        .setChoiceValues(schedule[day][time]);
    }
  }
}

/**
 * Sends out calendar invitations and a
 * personalized Google Docs itinerary after a user responds to the form.
 *
 * @param {Object} e The event parameter for form submission to a spreadsheet;
 *     see https://developers.google.com/apps-script/understanding_events
 */
function onFormSubmit(e) {
  const user = {
    name: e.namedValues.Name[0],
    email: e.namedValues.Email[0],
  };

  // Grab the session data again so that we can match it to the user's choices.
  const response = [];
  const values = SpreadsheetApp.getActive()
    .getSheetByName("Conference Setup")
    .getDataRange()
    .getValues();
  for (let i = 1; i < values.length; i++) {
    const session = values[i];
    const title = session[0];
    const day = session[1].toLocaleDateString();
    const time = session[2].toLocaleTimeString();
    const timeslot = `${time} ${day}`;

    // For every selection in the response, find the matching timeslot and title
    // in the spreadsheet and add the session data to the response array.
    if (e.namedValues[timeslot] && e.namedValues[timeslot] === title) {
      response.push(session);
    }
  }
  sendInvites_(user, response);
  sendDoc_(user, response);
}

/**
 * Add the user as a guest for every session he or she selected.
 * @param {object} user An object that contains the user's name and email.
 * @param {Array<String[]>} response An array of data for the user's session choices.
 */
function sendInvites_(user, response) {
  const id = ScriptProperties.getProperty("calId");
  const cal = CalendarApp.getCalendarById(id);
  for (let i = 0; i < response.length; i++) {
    cal.getEventSeriesById(response[i][5]).addGuest(user.email);
  }
}

/**
 * Creates and shares a personalized Google Doc that shows the user's itinerary.
 * @param {object} user An object that contains the user's name and email.
 * @param {Array<string[]>} response An array of data for the user's session choices.
 */
function sendDoc_(user, response) {
  const doc = DocumentApp.create(
    `Conference Itinerary for ${user.name}`,
  ).addEditor(user.email);
  const body = doc.getBody();
  let table = [["Session", "Date", "Time", "Location"]];
  for (let i = 0; i < response.length; i++) {
    table.push([
      response[i][0],
      response[i][1].toLocaleDateString(),
      response[i][2].toLocaleTimeString(),
      response[i][4],
    ]);
  }
  body
    .insertParagraph(0, doc.getName())
    .setHeading(DocumentApp.ParagraphHeading.HEADING1);
  table = body.appendTable(table);
  table.getRow(0).editAsText().setBold(true);
  doc.saveAndClose();

  // Emails a link to the Doc as well as a PDF copy.
  MailApp.sendEmail({
    to: user.email,
    subject: doc.getName(),
    body: `Thanks for registering! Here's your itinerary: ${doc.getUrl()}`,
    attachments: doc.getAs(MimeType.PDF),
  });
}

/**
 * Removes the calId script property so that the 'setUpConference_()' can be run again.
 */
function resetProperties() {
  const scriptProperties = PropertiesService.getScriptProperties();
  scriptProperties.deleteAllProperties();
}

Авторы

Данный пример поддерживается компанией Google при содействии экспертов-разработчиков Google.

Следующие шаги