在我们公司电子表格中的受文档约束的Google Appscript中,我创建了一个脚本,可将电子表格行转换为Google日历约会。虽然我们都有权编辑日历和更改共享权限,但该功能对我来说效果不错,但我的同事却没有,而我的同事证明他可以通过calendar.google.com在日历上创建约会。
他在运行脚本时收到以下错误消息:
function createAppointments() {
var CAL = 'companyname.com_1v033gttnxe2r3eakd8t9sduqg@group.calendar.google.com';
for(/*each row in spreadsheet*/)
{
if(/*needs appointment*/)
{
var object = {/*...STUFF...*/};
var coworker = 'coworker@companyname.com';
var timeArgs = {start: /*UTC Formatted time*/, end: /*UTC Formatted time*/}
if(/*All the data checks out*/{
var summary = 'Name of appointment'
var notes = 'Stuff to put in the body of the calendar appointment';
var location = '123 Happy Trail, Monterrey, TX 12345'
//BUILD GOOGLE CALENDAR OBJECT
var event = {
"summary": summary,
"description": notes,
"start": {
"dateTime": timeArgs.start,
"timeZone": TZ
},
"end": {
"dateTime": timeArgs.end,
"timeZone": TZ
},
"guestsCanInviteOthers": true,
"reminders": {
"useDefault": true
},
"location": location
//,"attendees": []
};
event.attendees = [{coworker@companyname.com, displayName: 'coworker name'}];
//CREATE CALENDAR IN GOOGLE CALENDAR OF CONST CAL
Calendar.Events.insert(event, CAL, {sendNotifications: true, supportsAttachments:true});
} else{/*Tell user to fix data*/}
}
}
第204行对应命令:
<!DOCTYPE html><html><head><link rel="shortcut icon" href="//ssl.gstatic.com/docs/script/images/favicon.ico"><title>Error</title><style type="text/css">body {background-color: #fff; margin: 0; padding: 0;}.errorMessage {font-family: Arial,sans-serif; font-size: 12pt; font-weight: bold; line-height: 150%; padding-top: 25px;}</style></head><body style="margin:20px"><div><img alt="Google Apps Script" src="//ssl.gstatic.com/docs/script/images/logo.png"></div><div style="text-align:center;font-family:monospace;margin:50px auto 0;max-width:600px">Object does not allow properties to be added or changed.</div></body></html>
如果他拥有日历的编辑权限,为什么禁止这样做? Google Apps脚本中的日历服务是否存在问题?更重要的是,我将CAL变量更改为我个人创建的日历,并以相同的权限分享给他。他可以很好地编辑那个日历。
这是函数的伪代码
function convertURItoObject(url){
url = url.replace(/\+/g,' ')
url = decodeURIComponent(url)
var parts = url.split("&");
var paramsObj = {};
parts.forEach(function(item){
var keyAndValue = item.split("=");
paramsObj[keyAndValue[0]] = keyAndValue[1]
})
return paramsObj; // here's your object
}
function doPost(e) {
var data = e.postData.contents;
data = convertURItoObject(data);
var CAL = data.cal;
var event = JSON.parse(data.event);
var key = data.key;
var start = new Date(event.start.dateTime);
if(ACCEPTEDPROJECTS.indexOf(key) > -1)
{
try{
var calendar = CalendarApp.getCalendarById(CAL);
calendar.createEvent(event.summary, new Date(event.start.dateTime), new Date(event.end.dateTime), {description: event.description, location: event.location, guests: event.guests, sendInvites: true});}
/*try {Calendar.Events.insert(event, CAL, {sendNotifications: true, supportsAttachments:true});} Same error when I use this command*/
catch(fail){return ContentService.createTextOutput(JSON.stringify(fail));}
e.postData.result = 'pass';
return ContentService.createTextOutput(JSON.stringify(e));
}
else {
return ContentService.createTextOutput('Execution not authorized from this source. See CONFIG of target project for details.');
}
}
非常感谢!
2009年12月29日更新:
我试过根据Jason Allshorn和Crazy Ivan调整应用程序。到目前为止,感谢您的帮助!有趣的是,我使用高级日历服务和CalendarApp遇到了相同的响应。
错误如下所示:
{{1}}
或者,通过html编辑器解析之后:
这甚至意味着什么?我启用了高级服务,并且脚本可以从任何人运行。有什么想法吗?
我在测试运行calendarApp / Advanced Calendar事件创建命令后测试错误后确认了。
这是我的代码导致我走得这么远:
{{1}}
答案 0 :(得分:1)
您的脚本正在使用Advanced Google Services,特别是Calendar
。阅读&#34;启用高级服务&#34;;每个人都必须按照这些步骤来使用脚本。
或者(在我看来,这是一个更好的解决方案),重写脚本以便它使用标准的CalendarApp
服务。它还允许您create an event,然后您可以add various reminders参加该活动。
答案 1 :(得分:1)
我方的解决方案是将日历事件创建功能从您的电子表格绑定脚本抽象到一个单独的独立应用程序脚本,该脚本以您的名义和您的权限运行。
然后从工作表绑定脚本调用独立脚本,其中包含PUT请求,其中包含更新日历所需的信息。这样,任何使用你的工作表插件的人都可以更新压延器而不会有任何混乱的权限。
表单绑定脚本可能如下所示:
function updateCalander(){
var data = {
'event': EVENT,
};
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : data
};
var secondScriptID = 'STANDALONE_SCRIPT_ID'
var response = UrlFetchApp.fetch("https://script.google.com/macros/s/" + secondScriptID + "/exec", options);
Logger.log(response) // Expected to see sent data sent back
然后你的独立脚本看起来像这样:
function convertURItoObject(url){
url = url.replace(/\+/g,' ')
url = decodeURIComponent(url)
var parts = url.split("&");
var paramsObj = {};
parts.forEach(function(item){
var keyAndValue = item.split("=");
paramsObj[keyAndValue[0]] = keyAndValue[1]
})
return paramsObj; // here's your object
}
function doPost(e) {
var CAL = 'companyname.com_1v033gttnxe2r3eakd8t9sduqg@group.calendar.google.com';
var data = e.postData.contents;
data = convertURItoObject(data)
var event = data.event;
try {
Calendar.Events.insert(event, CAL, {sendNotifications: true, supportsAttachments:true});
}
catch(e){
Logger.log(e)
}
return ContentService.createTextOutput(JSON.stringify(e));
}
请注意,需要将独立脚本设置为任何人都可以访问,并且当您对代码进行更新时,请务必重新发布代码。如果您不重新发布对独立脚本的调用,则不会使用最新代码。
答案 2 :(得分:0)
这是一个延迟回复,但感谢所有推荐使用POST方法的人。事实证明,正确的方法是使用URLFetchApp并传递脚本的项目密钥来授权日历访问(我相信你只需要确保执行脚本的人有权编辑实际的日历)
以下基本上是如何以功能方式完成的:
//GCALENDAR is th e unique ID of the project int it's URL when the script is open for editing
//PROJECTKEY is the unique ID of the project, found in the Project Properties Menu under FILE.
//CREATE CALENDAR IN GOOGLE CALENDAR OF CONST CAL
var data = {
'event': JSON.stringify(event),
'cal': CAL,
'key': PROJECTKEY
};
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : data,
'muteHttpExceptions': true
};
var answer = UrlFetchApp.fetch("https://script.google.com/macros/s/" + GCALENDAR + "/exec", options).getContentText();
Logger.log(answer);
&#13;