apps2sd使用_如何使用带有顶部源代码的Google Apps脚本创建自动日历

apps2sd使用

在会议上讲话可能很难。 本教程旨在帮助您更好地管理“征集建议书”(CFP)和在会议上发表演讲的“行政管理”。

我主要谈论开放源代码工具或开放组织概念,我认为与他人共享非常重要。 如果您有兴趣发言,请查看本文中提到的一些会议,阅读此真棒资源 ,如果需要任何提示或帮助,请随时与我联系 。 这也可能有助于阅读一些针对组织者的重要技巧 ,因为它们可以帮助您更好地制定可以被接受的建议。

除了担任演讲者之外,我还是DevOpsDays KC的CFP审核委员会成员,所以我对CFP流程的主题策划方面有所了解。 专家提示:去年,我们发现有人在A / B上与我们一起测试他们的头衔,而我们的评级受到头衔的影响。 描述是相同的。

管理会议提交

我将参加技术行业内外的许多会议。 在精神上要保持很多。 我已经花了数周的时间来创建提案并使其正确无误,但是我将如何管理所有提交的提案? 如果每个人都使用papercall.io那就太好了 ,因为我会在那里跟踪它们。 但是,我们都知道永远不会有一个单一的标准。 有些会议有一个仪表板来跟踪您的提交,另一些则发送电子邮件,而另一些则什么也不做。 最后一个是最难追踪的。

因此,我决定从一个简单的Google Form自动生成的Sheet开始 。 在提交之后,我添加了我认为在不同阶段需要的信息类型。 我添加了事件名称,位置,开始和结束日期,CFP结束日期,事件和CFP URL,发言人通知日期以及我提交的演讲列表的条目。 我将在完成每个CFP时填写此内容。

这将要结束,但是我意识到,没有日历就很难跟踪全年的所有情况。 我的第一个想法是用JavaScript从头开始创建某些东西,但这只是我的开发人员。 在服从他之后,我决定可能有一种更简单的方法。

谷歌搜索开始了。 Zapier的教程中的SEO很好,因此我决定用它来将Google表格与Google日历关联 。 我制作了两个特殊的日历,一个用于跟踪未被接受的会议,另一个用于接受我的建议的日历。 我还创建了一个单独的工作表,因此我可以添加其他列,例如接受状态和接受哪些讨论。

一旦掌握了与Zapier的集成,它就非常容易。 我配置了一个复杂的Zap,它为流程的每个阶段创建了不同类型的日历事件,包括针对CFP结束日期的单独事件。 它运行的很好,然后我意识到我使用的是试用版,两周后一切都会消失。 不好! 这不是我的工作,所以我不想为我可以建造(写)的东西付钱。

因此,谷歌搜索再次开始。 我找到了Google Apps脚本 (GAS)以及一些Google Sheets和Calendar API库。 当我开始使用某些库时,我意识到要使身份验证正常工作将花费大量的精力,然后我必须在某个地方运行它。

即使GAS不是开源的,我还是决定使用它,并使我在此之上所做的一切完全开放和免费。 我首先导航到工作表,然后单击“ 工具” ,然后单击“ 脚本编辑器”。这将打开一个IDE ,可以开始使用。

Google Apps Scripts IDE

尽管有很多试验和错误,但是我最终还是得到了一个小的脚本,可以完成Zapier的所有工作。 对于我有限的需求,它也是完全免费的。 它每五分钟运行一次,并且完全幂等。 我也不必运行脚本-Google在我不知道其他任何地方的情况下执行了该脚本。

建立我的日历自动化

在开始之前,需要对这种自动化进行警告。 我对Google表格不满意,因此我不知道在更新“响应”表时如何更新结果表。 这意味着我必须输入规则并将当前单元格中的规则复制到任何需要填写的新单元格中。

另外,我建议您使用此Chrome扩展程序该扩展程序可让您将GitLab存储库用于脚本。 我在开发结束时就了解了它,然后立即使用它将完成的代码放入版本库中。 现在,您可以从我的存储库中派生代码,以将脚本从您控制的存储库中导入到GAS编辑器中。

现在,我将遍历代码,以便在展示最终产品之前更好地了解正在发生的事情以及原因。


   
   
function createTrigger() {
  ScriptApp.newTrigger('updateEvents')
      .timeBased()
      .everyMinutes(5)
      .create();
}

第一个函数创建一个调用updateEvents方法的触发器。 将此脚本设置为每五分钟运行一次,因为它是幂等的,所以很好。 注意不要以消除幂等性的方式来编辑脚本,这意味着您需要删除数百个事件。 好消息是,您可以快速删除日历上的所有事件,并在短短几分钟内恢复到幂等脚本以返回完全正常的状态。 您也可以撤消deleteEvent函数中的检查,并且每次脚本运行时,脚本都会为每个事件删除一个条目。 这帮助我在开发过程中慢慢走回一个错误。


   
   
// Deletes an event if it exists
function deleteEvent(event) {
  if (typeof event != 'undefined') {
    Logger.log("Deleting event %s", event.getTitle())
    event.deleteEvent()
  }
}

让我们跳过下一个函数,转到第三个函数 deleteEvent 。 此函数将CalendarEvent作为参数,检查它是否存在,然后删除它。 这只是一个小的帮助程序脚本,它使我的代码整理了很多。


   
   
// Get Sheet and both Calendars.
  var sheet = SpreadsheetApp.openByUrl("https://xxxxxx").getSheetByName("Results")
  var submittedCalendar = CalendarApp.getCalendarById("xxxxxxx")
  var acceptedCalendar = CalendarApp.getCalendarById("xxxxxx")

现在,让我们解决大功能 updateEvents 。 这执行所有逻辑。 首先,我需要在每个日历和正在使用的工作表中建立身份验证。 这是非常快速和容易的,并且在脚本的第一次执行中得到了处理。 您可以通过导航到工作表并从地址栏中获取URL来获取工作表URL。 您可以按照以下说明获取日历ID。 我建议不要使用任何名称,因为您以后可能想更改它而忘记更新引用。


   
   
  // Get data from Sheet
  var data = sheet.getDataRange().getValues()
 
  var events = []
 
  // This loop parses the data from the spreadsheet and adds it to an array
  for (var i = 1; i < data.length; i++) {
    // Skips blank rows
    if (data[i][0] == "") {
      break
    }
   
    // Gets the speaker notification date if one exists or sets it to the start date of the conference
    var speakerNotificationDate = new Date(data[i][4].getTime() + 2.88e7)
    if (data[i][5] != '') {
      speakerNotificationDate = new Date(data[i][5].getTime() + 2.88e7)
    }
   
    // Uses the first row, headers, as keys with the values being assigned to each. Then the object is pushed onto the array.
    var event = {}
    event[data[0][0]] = data[i][0]
    event[data[0][1]] = data[i][1]
    event[data[0][2]] = data[i][2]
    event[data[0][3]] = data[i][3]
    event[data[0][4]] = new Date(data[i][4].getTime() + 2.88e7) // Update the time to 8 a.m.
    event[data[0][5]] = speakerNotificationDate
    event[data[0][6]] = new Date(data[i][6].getTime() + 2.88e7) // Update the time to 8 a.m.
    event[data[0][7]] = new Date(data[i][7].getTime() + 7.2e7) // Update the time to 8 p.m.
    event[data[0][8]] = data[i][8]
    event[data[0][9]] = data[i][9]
    event[data[0][10]] = data[i][10]
    events.push(event)
  }

完成身份验证后,我将继续从工作表中获取所有数据。 脚本检查以确保存在事件名称 ; 如果不是,它将不会继续处理该行,并将转到下一个条目。 每一行被解析为对象是列标题和是正在处理从所述行中的单元格的值。 我对日期和空数据进行了一些清理,以确保脚本的其余部分正常运行。

我在活动如何显示在日历上时遇到了一些问题,我发现最好将开始时间设置为上午8点将结束时间设置为下午8点 。 避免使用0000小时似乎是解决我遇到的许多问题的理想选择。 该脚本还确保输入发言人通知日期,或者将日期设置为事件的开始日期。


   
   
if (events[i]["Accepted"] == "Yes") {
      if (typeof acceptedCalendar.getEvents(events[i]["Start date"], events[i]["End date"], {search: events[i]["Event Name"] + " - " + events[i]["Talks Accepted"]})[0] == 'undefined') {
        acceptedCalendar.createEvent(events[i]["Event Name"] + " - " + events[i]["Talks Accepted"], events[i]["Start date"], events[i]["End date"], {location: events[i]["Location"], description: "Event URL: " + events[i]["Event URL"] + "\n\nCFP URL: " + events[i]["CFP URL"] + "\n\nTalks Accepted: " + events[i]["Talks Accepted"]}).setColor(CalendarApp.EventColor.GREEN).addEmailReminder(40320).addPopupReminder(40320)
        Logger.log("Created accepted event on accepted calendar")
      }
     
      if (typeof submittedCalendar.getEvents(events[i]["Start date"], events[i]["End date"], {search: events[i]["Event Name"] + " - Accepted"})[0] == 'undefined') {
        submittedCalendar.createEvent(events[i]["Event Name"] + " - Accepted", events[i]["Start date"], events[i]["End date"], {location: events[i]["Location"], description: "Event URL: " + events[i]["Event URL"] + "\n\nCFP URL: " + events[i]["CFP URL"] + "\n\nTalks Accepted: " + events[i]["Talks Accepted"]}).setColor(CalendarApp.EventColor.GREEN)
        Logger.log("Created accepted event on submitted calendar")
      }
     
      deleteEvent(submittedCalendar.getEvents(events[i]["Start date"], events[i]["End date"], {search: events[i]["Event Name"] + " - Submitted"})[0])
      deleteEvent(submittedCalendar.getEvents(events[i]["Start date"], events[i]["End date"], {search: events[i]["Event Name"] + " - Rejected"})[0])
    }

然后,脚本循环遍历每个事件,以将其添加到适当的日历中。 您可以在上面看到添加和删除事件的示例。 如果会议已接受我的任何提交,则表中有一个名为“已接受”的属性,其中填充有单词“ 是”如果为true ,那么将创建两个日历事件 ,每个日历事件一个。

由于我有两个独立的日历,因此我可以轻松查看正在发言的所有会议。 对于“ 接受的日历” ,我首先在日历上搜索事件 ,然后从Google日历响应的数组中返回第一项。 我假设如果有一个事件,那就是我想要的事件。 我使用的是非常具体的搜索,其中包括接受的演讲,因此它应该只与事件匹配。 如果没有事件,那么我将创建一个包含所有相关信息的新事件 ,并确保颜色为绿色(因为这是“接受的日历”上事件的颜色)。 我也有在活动开始前四个星期设置的通知。 这可以帮助我确保演示文稿准备就绪,并且预订了我的所有旅行。

事件以完全相同的方式添加到“已提交的日历”中,但是,“-已接受”将添加到会议标题中,因为它位于包含许多其他类似事件的日历中。 然后,我删除标题中带有“-提交”“-拒绝”关键字的所有事件,因为不再需要它们。

如果Accepted 属性设置为No ,那么我在Submitted Calendar上创建一个拒绝事件 。 我还需要删除其他三个可能的日历条目 。 然后, 如果 “接受”列中还有其他值或没有任何值 ,我可以假定它已提交但尚未被接受或拒绝。 因此,我创建一个“-Submitted”事件删除任何可能的拒绝或接受事件


   
   
  if (typeof submittedCalendar.getEvents(events[i]["CFP end date"], events[i]["Start date"], {search: events[i]["Event Name"] + " - CFP"})[0] == 'undefined') {
      submittedCalendar.createAllDayEvent(events[i]["Event Name"] + " - CFP", events[i]["CFP end date"], {location: events[i]["Location"], description: "CFP End Date: " + events[i]["CFP end date"] + "\n\nSpeaker Notification Date: " + events[i]["Speaker notification date"] + "\n\nEvent URL: " + events[i]["Event URL"] + "\n\nCFP URL: " + events[i]["CFP URL"] + "\n\nTalks Submitted: " + events[i]["Talks Submitted"]}).setColor(CalendarApp.EventColor.YELLOW).addEmailReminder(10080).addPopupReminder(10080)
      Logger.log("Created CFP event")
    }

最后,我确保每个CFP都有一个条目 。 这是 CFP的发布结束日期创建的,颜色更改为黄色,并且通知设置为截止日期之前的7天。 尽管我可能已经提交了会议,但有时在我想更改提交或决定提交其他提案时会发生一些事情。 另外,我可以添加一个活动而无需提交任何演讲(尚未),因此将提醒我在CFP关闭之前提交。 目前,除非我在日历中手动删除该事件,否则在事件中添加其他发言不会更新该事件。 这是非常罕见的情况,因此我不太担心。

Google calendar of speaking engagements

将所有这些整合在一起不会花很长时间,而且我认为这确实可以帮助我更好地管理日程表。 这是我四月份的日历,到目前为止,有一个会议被接受,有几个正在等待CFP关闭。 此外,您可以看到Submitted有两种颜色(首先使用Zapier的工件)。 这表明搜索工作正常,并且仅在标题上匹配。 如果我想花时间在上面,可以更改它,但是它不会打扰我,也不会影响您。

如果您想对该项目做出任何贡献,请随时在GitLab上提交合并请求

撰写获奖方案

在过去的几年中,我已经在各种会议上发言。 第一年,我刚提出了针对每个事件定制的一堆随机提案,并尝试不重复任何提案。 这意味着我几乎没有申请任何东西,而基本上所有的人都拒绝了我。 我想我那年在一个会议上发言。

我认为那不是最佳选择。 我的建议都没有那么好,因为我不能花太多时间在其中任何一项上。 我也意识到这很像销售,因为我几乎都会被拒绝。 因此,我决定创建三个提案,为每个CFP稍作自定义,并在提案被接受后自定义实际演示。 根据每个会议的重点和时间限制,我全年都会更改演讲的内容,因此基本上我不会重复发表同一件事。

我想我在那年的10个会议上发言,包括全天DevOps,Jenkins World,All Things Open和LISA(列举一些较大的会议)。 我还推荐了许多小型会议,这些会议都有出色的组织者和社区,例如GlueCon,亚特兰大WeRISE,BSidesKC和RevolutionConf。 您可以通过我的网站查看幻灯片或观看视频

我只使用三个提案的策略使我能够参加更多会议,以找到最适合自己和会议组织者的方式。 效果很好,我大概参加了50个会议。 跟踪它们都没有发生。 我一直很担心自己会错过一封电子邮件,以免被接受或接受同时发生的两个会议。 幸运的是,我认为两者均未发生。

在2018年,我决定不去很多次旅行,所以我只在几次会议上发表了讲话,他们都是定制提交的,因为我没有参加太多会议。 我的录取率接近50%。

进入2019年,我计划展示更多内容,因此我需要一个策略。 我再次决定进行一小组讨论。 由于我在NAIC工作中积累了很多新知识,并通过大规模的技术和文化转型帮助该组织,因此今年将有七个提案。 我还希望以包括整个产品线以及如何将其用于资助转型的方式来谈论风险,这很方便,因为我的新职位是RSA Archer的首席架构师。


继续阅读

翻译自: https://opensource.com/article/19/1/automate-calendar

apps2sd使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值