[英]Server-side function does not want to run
I'm building a sidebar for Google Sheets using Apps Script, it is a tool to import data from Google Calendar.我正在使用 Apps Script 为 Google Sheets 构建一个侧边栏,它是一个从 Google Calendar 导入数据的工具。 The script is not that complicated:
脚本并不复杂:
1. I have a file Code.gs in charge of creating a custom menu and rendering the sidebar 1. 我有一个文件 Code.gs 负责创建自定义菜单和渲染侧边栏
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Custom Menu')
.addItem('Show sidebar', 'showSidebar')
.addToUi();
}
function showSidebar() {
var html = HtmlService.createTemplateFromFile('index').evaluate()
.setTitle('Extract data from calendar')
.setWidth(300);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showSidebar(html);
}
function include(filename){
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
2. Index.html: the content of the sidebar 2.Index.html:侧边栏的内容
<!DOCTYPE html>
<html>
<head>
</head>
<body style="margin: 10px;">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<div class="row">
<form class="col s12">
<!-- CHOOSE CALENDAR ROW -->
<div class="row">
<div class="input-field col s12">
<select id='calendar'>
<? var calendars = CalendarApp.getAllOwnedCalendars();
calendars.forEach((calendar) => { ?>
<option value="<?= calendar.getId() ?>"><?= calendar.getName() ?></option>
<? }) ?>
</select>
<label>Calendar</label>
</div>
</div>
<!-- START TIME ROW -->
<div class="row">
<div class="input-field col s12">
<input placeholder="Start date" id="startDate" type="date" class="validate">
<label for="startDate">Start date</label>
</div>
</div>
<!-- END TIME ROW -->
<div class="row">
<div class="input-field col s12">
<input placeholder="End date" id="endDate" type="date" class="validate">
<label for="endDate">End Date</label>
</div>
</div>
<!-- INCLUDE HEADER -->
<div class="row">
<label>
<input type="checkbox" class="filled-in" checked="checked" id="includeHeader" />
<span>Include Header</span>
</label>
</div>
<!-- EXTRACT BUTTON -->
<div class="row">
<button class="btn waves-effect waves-light" id="extractBtn">EXTRACT</button>
</div>
</form>
</div>
<?!= include('index-js') ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems, {});
});
</script>
</body>
</html>
3. index-js.html: add an event to the extract button and call the server-side function 3. index-js.html:给解压按钮添加事件,调用服务端function
<script>
var extractBtn = document.getElementById('extractBtn');
extractBtn.addEventListener('click', function(e) {
e.preventDefault();
var calendarId = document.getElementById('calendar').value;
var startDate = new Date(document.getElementById('startDate').value);
var endDate = new Date(document.getElementById('endDate').value);
var includeHeader = document.getElementById('includeHeader').checked;
if(startDate.getTime() < endDate.getTime()) {
e.target.textContent = 'Extracting...';
google.script.run.withSuccessHandler(extractCompleted).writeData(calendarId, startDate, endDate, includeHeader);
} else {
M.toast({html: "Please enter an end date starting after the selected start date"});
}
});
function extractCompleted(){
M.toast({html: 'Extract completed'});
extractBtn.textContent = 'Extract';
}
</script>
4. extractCalendar.gs in charge of getting the data and adding it to the Google sheet 4. extractCalendar.gs 负责获取数据并将其添加到 Google sheet
function extractCalendar(calendarId, startDate, endDate) {
var calendar = CalendarApp.getCalendarById(calendarId);
var events = calendar.getEvents(startDate, endDate);
// Initialize variables that will hold information
var rows = [];
events.forEach((event) => {
// Get basic information
var eventTitle = event.getTitle();
var startTime = event.getStartTime();
var endTime = event.getEndTime();
var description = event.getDescription();
var isRecurring = event.isRecurringEvent();
// Get the guest list
var guests = event.getGuestList();
var emailsParticipantsArray = [];
var emailsParticipants = '';
// Add each guest email to the array
guests.forEach(guest => emailsParticipantsArray.push(guest.getEmail()));
// Convert the array to a string
emailsParticipants = emailsParticipantsArray.join(',');
rows.push([eventTitle, startTime, endTime, emailsParticipants, description, isRecurring]);
}
);
return rows;
}
function writeData(calendarId, startDate, endDate, includeHeader=True){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var rows = extractCalendar(calendarId, startDate, endDate);
var numRows = rows.length;
var lastRow = sheet.getLastRow();
(includeHeader) && rows.unshift(['Title', 'Start Date', 'End Date', 'Participants Email', 'Description', 'Recurring']);
sheet.getRange(lastRow + 1, 1, numRows, 6).setValues(rows);
}
The line below does not run and generate the error message: Uncaught TypeError: Failed due to illegal value in property: 12769757186-mae_html_user_bin_i18n_mae_html_user.js:61下面的行不运行并生成错误消息:未捕获的类型错误:由于属性中的非法值而失败:12769757186-mae_html_user_bin_i18n_mae_html_user.js:61
google.script.run.withSuccessHandler(extractCompleted).writeData(calendarId, startDate, endDate, includeHeader);
What's happening right here, why is the server-side function not running?这里发生了什么,为什么服务器端 function 没有运行?
Thank you for your help !谢谢您的帮助 !
Parameters and Return Values 参数和返回值
You can pass year,month and day or the date in a standard string format and use the Date() constructor to recreate the date.您可以传递标准字符串格式的年、月和日或日期,并使用 Date() 构造函数重新创建日期。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.