코딩 수준: 초급
시간: 5분
프로젝트 유형: 커스텀 메뉴가 포함된 자동화
이벤트 기반 트리거
목표
- 솔루션의 기능을 이해합니다.
- 애플리케이션 내에서 Apps Script 서비스가 수행하는 작업을 이해
솔루션을 제공합니다
- 스크립트를 설정합니다.
- 스크립트를 실행합니다.
이 솔루션 정보
엔드 투 엔드 이벤트 등록 시스템을 만듭니다. 일정이 있는 경우
회의처럼, 회의를 위해 새 캘린더를 설정할 수 있습니다
가입 양식을 만들고 참석자에게 맞춤형 이메일을 자동으로 보낼 수 있습니다.
있습니다.
작동 방식
이 솔루션은 Google Sheets의 맞춤 메뉴를 사용하여 자동화된 스프레드시트를
이벤트 등록 시스템입니다. 스크립트가 회의로 캘린더를 만듭니다.
이벤트 목록을 표시합니다. 그런 다음 스크립트에서
양식이 있습니다. 참석자 이후
스크립트를 작성하면 스크립트가 참석자를 캘린더 일정에 추가하고
일정을 이메일로 보냅니다.
Apps Script 서비스
이 솔루션은 다음 서비스를 사용합니다.
- 스프레드시트 서비스: 스프레드시트 서비스인
이벤트 정보를 다른 서비스에 전송하는 것입니다.
- 캘린더 서비스:
새 캘린더를 만들고, 캘린더에 이벤트를 추가하고, 참석자를 추가
정보를 제공할 수 있습니다.
- 속성 서비스:
캘린더 서비스에서 만든 캘린더의 ID입니다. 사용자가
맞춤 회의 메뉴에서 회의 설정을 클릭한 후
속성 서비스는 이벤트 등록 시스템이 이미
캘린더 ID 속성이 있는지 확인하여 설정해야 합니다. 이렇게 하면
중복된 양식과 캘린더를 만들지 않습니다.
- Forms 서비스: 양식을 만듭니다.
스프레드시트의 정보를 바탕으로
세션.
- 스크립트 서비스: 실행되는 트리거를 만듭니다.
참석자가 양식을 작성할 때 표시됩니다.
- 문서 서비스: 일정을 가져옵니다.
참가자가 가입한 이벤트에 대한 정보와 참가자 목록을
이벤트를 새 문서에 추가합니다. 스크립트는 참석자에게
할 수 있습니다.
- 메일 서비스: 운항 일정 문서를 이메일로 전송합니다.
있습니다.
기본 요건
이 샘플을 사용하려면 다음과 같은 기본 요건이 필요합니다.
- Google 계정 (Google Workspace 계정은
관리자의 승인이 필요함)
- 인터넷에 액세스할 수 있는 웹브라우저
스크립트 설정
- 다음 버튼을 클릭하여 가입 생성
샘플 스프레드시트입니다. Apps Script
프로젝트가 스프레드시트에 첨부되어 있습니다.
사본 만들기
- 다자간 통화 > 설정을 클릭합니다.
컨퍼런스에 참여했습니다. 이 맞춤 메뉴의 페이지를 새로고침해야 할 수도 있습니다.
나타납니다.
메시지가 표시되면 스크립트를 승인합니다.
OAuth 동의 화면에 확인되지 않은 앱입니다.라는 경고가 표시되면,
고급 >을 선택하여 계속합니다.
{프로젝트 이름}(으)로 이동(안전하지 않음)
다자간 통화 > 설정을 클릭합니다.
컨퍼런스를 다시 진행해 보겠습니다.
스크립트 실행
- 도구 > 양식 관리를 클릭합니다.
> 실시간 양식으로 이동을 탭합니다.
- 양식을 작성하여 제출합니다.
- calendar.google.com으로 이동합니다.
- 왼쪽에서 Conference Calendar(회의 캘린더) 옆의 체크박스가 선택되어 있는지 확인합니다.
- 가입한 이벤트의 날짜로 이동하여 추가되었는지 확인하세요.
참석자로 초대합니다.
(선택사항) 솔루션 재설정
이 솔루션을 다시 사용해 보거나
이벤트 정보가 없는 경우 이전에 설정된 일부 항목을 재설정해야 합니다.
확인할 수 있습니다. 솔루션을 재설정하는 단계를 보려면
아래에서 솔루션을 재설정합니다.
솔루션 재설정
1단계: 저장된 스크립트 속성 재설정
스크립트를 두 번 이상 실행하려고 하면
회의가 이미 설정되어 있습니다. Google Drive에서 가입 양식을 찾아보세요.
이는 Conference Calendar가 생성되면 캘린더 ID가
스크립트 속성으로 저장됩니다. 스크립트가 실행되면
캘린더 ID 속성이 이미 존재하며 이 속성이 있으면 실행이 중지됩니다.
기존 캘린더 ID 속성을 삭제하려면 다음 단계를 따르세요.
- 스프레드시트에서 확장 프로그램을 클릭합니다.
> Apps Script를 클릭합니다.
- Apps Script 편집기의 다음에서
resetProperties
을 선택합니다.
함수 드롭다운 목록을 클릭하고 실행을 클릭합니다.
2단계: 회의 캘린더 삭제하기
스크립트가 실행될 때마다 새 캘린더가 생성됩니다.
생성된 원래 캘린더를 유지하려면 다음 단계를 따르세요.
- calendar.google.com으로 이동합니다.
- 회의 캘린더 옆의 회의 캘린더 옵션을 클릭합니다.
>
설정 및 공유:
- 설정 하단으로 스크롤하여 삭제를 클릭합니다.
이 스크립트는 양식을 실행할 때마다 양식 제출에 대한 트리거를 만듭니다. 받는사람
중복 이메일이 생성되는 여러 트리거 방지, 원본 이메일 삭제
있습니다. 다음 단계를 따르세요.
- 스프레드시트에서 확장 프로그램을 클릭합니다.
> Apps Script를 클릭합니다.
- Apps Script 프로젝트의 왼쪽에서 트리거를 클릭합니다.
입니다.
- 트리거 옆에 있는 더보기 를 클릭합니다.
> 트리거 삭제를 클릭합니다.
스크립트를 실행할 때마다 새 양식이 생성됩니다. 다음 단계를 따르세요.
스프레드시트에서 양식을 연결 해제하고 삭제합니다.
- 스프레드시트에서 설문지 응답 시트를 마우스 오른쪽 버튼으로 클릭하고
설문지 연결 해제 > 확인을 탭합니다.
- 양식 응답 시트를 다시 마우스 오른쪽 버튼으로 클릭하고 삭제를 클릭합니다.
> 확인을 탭합니다.
- forms.google.com으로 이동합니다.
- Conference Form을 마우스 오른쪽 버튼으로 클릭하고 Remove를 클릭합니다.
> 휴지통으로 이동을 탭합니다.
솔루션을 재설정한 후 자체 데이터를 추가하거나
스크립트를 다시 실행할 수 있습니다.
코드 검토
이 솔루션의 Apps Script 코드를 검토하려면 다음을 클릭합니다.
아래에서 소스 코드 보기:
소스 코드 보기
Code.gs
// 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_() {
let 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;
}
let ss = SpreadsheetApp.getActive();
let sheet = ss.getSheetByName('Conference Setup');
let range = sheet.getDataRange();
let 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) {
let cal = CalendarApp.createCalendar('Conference Calendar');
// Start at 1 to skip the header row.
for (let i = 1; i < values.length; i++) {
let session = values[i];
let title = session[0];
let start = joinDateAndTime_(session[1], session[2]);
let end = joinDateAndTime_(session[1], session[3]);
let options = {location: session[4], sendInvites: true};
let 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.
let 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) {
date = new Date(date);
date.setHours(time.getHours());
date.setMinutes(time.getMinutes());
return date;
}
/**
* 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.
let schedule = {};
// Start at 1 to skip the header row.
for (let i = 1; i < values.length; i++) {
let session = values[i];
let day = session[1].toLocaleDateString();
let 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.
let form = FormApp.create('Conference Form');
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
form.addTextItem().setTitle('Name').setRequired(true);
form.addTextItem().setTitle('Email').setRequired(true);
Object.keys(schedule).forEach(function(day) {
let header = form.addSectionHeaderItem().setTitle('Sessions for ' + day);
Object.keys(schedule[day]).forEach(function(time) {
let item = 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) {
let 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.
let response = [];
let values = SpreadsheetApp.getActive().getSheetByName('Conference Setup')
.getDataRange().getValues();
for (let i = 1; i < values.length; i++) {
let session = values[i];
let title = session[0];
let day = session[1].toLocaleDateString();
let time = session[2].toLocaleTimeString();
let 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) {
let id = ScriptProperties.getProperty('calId');
let 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) {
let doc = DocumentApp.create('Conference Itinerary for ' + user.name)
.addEditor(user.email);
let 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(){
let scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.deleteAllProperties();
}
참여자
이 샘플은 Google에서 Google Developer Experts의 도움을 받아 유지관리합니다.
다음 단계