邀请客人参加"快速添加" Google日历活动

时间:2014-08-16 07:10:10

标签: google-apps-script google-calendar-api

我正在尝试改进Google日历中“快速添加”功能的功能。快速添加功能通常可以通过转到Google Calendar并点击红色“创建”按钮旁边的向下箭头来访问(参见图片:http://s2.postimg.org/95zxshivt/calendar_screenshot.png)。

我想要实现的功能是允许用户使用“快速添加”框中输入的关键字邀请访客加入新创建的日历活动。例如,如果用户使用“快速添加”框通过输入文本Eat pizza tomorrow at 3pm with michelle@gmail.com and john@gmail.com来添加活动,则Google日历会在第二天的下午3点添加标题为Eat pizza with michelle@gmail.com and john@gmail.com的新活动,就像它应该。 我想更进一步让Google同时向新创建的活动发送两个日历邀请:一个用于michelle@gmail.com,另一个用于john@gmail.com

感谢您对此主题的建议。我想了解最好的方法是什么:

  • 使用带有Google Apps脚本的触发器来捕获用户添加日历事件的时间。触发器将访问事件的标题,挑选标题中的任何电子邮件地址,并向新创建的事件发送邀请到每个电子邮件地址。

  • 使用Chrome 扩展程序,让用户通过点击Chrome浏览器中的扩展程序图标,输入他们通常会在“快速添加”框中输入的字符串。扩展程序将从用户输入的内容中选择电子邮件地址,在用户的输入上使用createEventFromDescription(description)来创建事件,然后向新创建的事件发送邀请到每个电子邮件地址

请让我知道你的想法。我非常感谢你的想法。

1 个答案:

答案 0 :(得分:1)

您可能知道,没有与日历Ui创建事件相关联的触发源。

你确实有两种可能性:

  • 使用专用的Ui(镀铬扩展程序或独立的webapp)对事件进行编码,该Ui会负责发送邀请,但这可能不符合您所描述的“扩展quickAdd功能的功能”的初始要求
  • 找到一种方法来检测事件创建并自动从其内容发送邀请。

使用定时器触发器监视您的日历并检测任何新事件(通过将存储在某处的列表与实际日历内容进行比较),最后一种可能性是完全可行的。

我为不同的目的制作了这样的应用程序并且效果很好但是你应该注意一些困难。

在scriptProperties中存储事件时(它可能是最好的去处),您可以使用有限的存储空间,因此您必须知道可以处理多少事件。

添加详细信息或纠正拼写错误等事件的任何更改都会重新触发邀请过程并再次发送邀请。虽然这可以避免,但它会非常复杂。

当脚本在事件结束后立即运行时,比较会检测到更改,因为缺少一个事件(来自脚本pov),因此它可以发送邮件来取消事件(如果您选择实现该功能的话)但我想这是“必须拥有的”)。处理这种情况可能有点棘手......(将事件结束时间与触发器触发脚本的实际时间进行比较,可能是几毫秒; - 。)。

除了这些困难之外,一般的想法如下:

  • 创建一个定时器触发器,每小时左右运行一次
  • 将此日历中的每个事件存储在脚本属性中(或最终存储在电子表格中),从当前日期开始并在几天后结束(不要太远,因为发送邀请对于接下来发生的事件没有意义年)
  • 将列表与日历内容进行比较
  • 抓取每个“新”事件并从描述中提取电子邮件地址(例如使用正则表达式或字符串操作)
  • 发送邀请(这是简单的部分)

此工作流程有效但在比较和电子邮件检测中可能有点脆弱。


修改

因为这是一个有趣的主题(恕我直言),我认为我可以有效地使用(现在我在我的日历UI中切换到英语;-D)我写了一个代码来实现它......

我将代码嵌入电子表格中,以简化我拥有的许多日历中的处理和事件存储。

此电子表格为viewable here,如果您复制了该电子表格,则可以运行该代码。

我设置了一个定时器触发器,每小时运行autoCheckAllCal功能,它似乎没有任何问题。

告诉我你的想法。

完整代码转载如下,它从日历中获取数据,检查事件是否包含访客,如果没有,则检查标题是否有任何有效的电子邮件地址(一个或多个)并自动发送邀请。

我使用正则表达式从标题字符串中提取电子邮件(此正则表达式是从an answer on SO借用的,因为我对此不够好!)

注意:为myOnOpen设置onOpen触发器(因为使用SS服务进行全局变量声明)

// update the ID below to your copy ID and run the Callist() function to get the calendars ID on first sheet.
//set up an onOpen trigger for the myOnOpen function
var ss = SpreadsheetApp.openById('1xDOaoSl3HbkS95cj8Jl-82rdiui7G0sFz96PIO6iVF4');// this spreadsheet
var calNamesSheet = ss.getSheetByName('calNames');
var calList = calNamesSheet.getDataRange().getValues();

function MyOnOpen() {
  var menuEntries = [ {name: "Lauch autoTest", functionName: "autoCheckAllCals"},
                      {name: "delete created sheets", functionName: "delsheets"}
                     ];
  ss.addMenu("Tracking utilities",menuEntries);//
}

function autoCheckAllCals(){
  var today =  new Date(); // now
  var startDate = new Date(today.setHours(0,0,0,0));// today @ 0 AM
  var endDate = new Date(new Date(startDate).setDate(startDate.getDate()+7)); // adjust time frame to read here = 7 days
  for(var nn=0;nn<calList.length;nn++){
    var logArray = new Array();
    logArray.push(['Calendar + Title','Description','Start','End','Location','Creators','Date Created','Duration','Guests']);
    var calName = calList[nn][0];
    var calId = calList[nn][1];   
    var Calendar = CalendarApp.getCalendarById(calId);
    var events = Calendar.getEvents(startDate , endDate);
    if (events[0]) {
      for (var i = 0; i < events.length; i++) {
        var row = new Array();
        row.push(calName +' : '+events[i].getTitle());
        row.push(events[i].getDescription());      
        row.push(Utilities.formatDate(events[i].getStartTime(), Session.getScriptTimeZone(), "MMM-dd-yy")+' @ ' +Utilities.formatDate(events[i].getStartTime(), Session.getScriptTimeZone(), "HH:mm"));
        row.push(Utilities.formatDate(events[i].getEndTime(), Session.getScriptTimeZone(), "MMM-dd-yy")+' @ ' +Utilities.formatDate(events[i].getEndTime(), Session.getScriptTimeZone(), "HH:mm"));
        row.push(events[i].getLocation());      
        row.push(events[i].getCreators().join());
        row.push('on '+Utilities.formatDate(events[i].getLastUpdated(), Session.getScriptTimeZone(), "MMM-dd-yyyy"));
        row.push(((events[i].getEndTime() - events[i].getStartTime()) / 3600000)+' hours');//duration
        var inviteList = checkInvites(events[i]);
        if (inviteList.length==0){ // if guests were found in checkInvites() then don't read it from event since checkInvites() added them to the cal but this event is not yet updated
          var list = events[i].getGuestList();
          for(n=0;n<list.length;++n){inviteList.push(list[n].getEmail())};
        }else{
          for(var n in inviteList){
            events[i].addGuest(inviteList[n]);
          }
        }
        row.push(inviteList.join(', '));
        logArray.push(row);
      }
    }    
//    Logger.log(logArray);
    if(logArray.length==0){continue};
    try{
      var sheetToWrite = ss.insertSheet(calName,ss.getNumSheets());// create sheet if doesn't exist
    }catch(err){
      var sheetToWrite = ss.getSheetByName(calName);// else open it
      }
    sheetToWrite.getRange(1,1,logArray.length,logArray[0].length).setValues(logArray).setHorizontalAlignment('left'); // enhance formating
    sheetToWrite.getRange(1,1,1,logArray[0].length).setBackground('#EEA').setBorder(true,true,true,true,true,true).setHorizontalAlignment('left').setFontSize(12);
    for(var w in logArray[0]){
      sheetToWrite.setColumnWidth(Number(w)+1,180);
    }
  }
}

function checkInvites(event){
  var email = []
  var title = event.getTitle();
  if(title.indexOf('@')==-1){return email};
  email = title.match(/([\w-\.]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4})/g);
  Logger.log('email var = '+email);
  return email;
}

function delsheets(){
  var numbofsheet = ss.getNumSheets();// check how many sheets in the spreadsheet
  for (var pa=numbofsheet-1;pa>0;pa--){ 
    ss.setActiveSheet(ss.getSheets()[pa]);
    if(ss.getSheets()[pa].getSheetName()!='calNames'){
      ss.deleteActiveSheet(); // delete sheets begining with the last one
      Utilities.sleep(400);
    }
  }
  SpreadsheetApp.flush();
}

// This small function is to get the list of calendar names & Ids that you have access to, please edit the calNames sheet to keep only the ones you want to monitor (without empty rows).
function Callist(){
  calNamesSheet.getDataRange().clearContent();                      
  var list = new Array();
  var store = new Array();
  list = CalendarApp.getAllCalendars()
  for (n=0;n<list.length;++n){
    var name = list[n].getName() ;                     
    var id = list[n].getId() ;                     
    store.push( [name,id])
  }        
  calNamesSheet.getRange(1,1,store.length,store[0].length).setValues(store);  
}

// Serge insas - 08-2014