带有 Google 日历的 Notion API
Posted
技术标签:
【中文标题】带有 Google 日历的 Notion API【英文标题】:Notion APIs with Google Calendar 【发布时间】:2021-08-17 12:22:08 【问题描述】:如果我在网上搜索“Notion API with Google Calendar”之类的内容,我只会找到与 Automate.io 或 Zappier 相关的解决方案。
有没有办法使用这些强大的 API 将 Notion 与 Google 日历集成,不依赖这些网站? 我可以使用哪种编程语言来做到这一点?我需要一个服务器来定期运行程序吗?
PS:在 YT 上我找到了一些 Python 工具,但我找不到使用这些工具的完整指南
【问题讨论】:
【参考方案1】:我可以使用哪种编程语言来做到这一点?
您可以轻松地使用Google App Script 和Notion API 来实现此目的。 Google 应用脚本的语法基于 javascript(尽管不支持某些 ES6 功能)。使用CalendarApp,您几乎可以控制 Google 日历上的所有内容。
我需要一个服务器来定期运行程序吗?
不,你不需要。在 Google App Script 中,您可以添加 time-driven triggers 让它自动启动。
这是一个将概念同步到日历的简单示例:
使用 UrlFetchApp 将查询发布到您的 Notion 数据库
在这种情况下,我将根据 'DeadLine' 属性设置事件的日期。所以我附加了一个过滤器来排除空值。
function main()
let data =
"filter":
"property": "DeadLine",
"date":
"is_not_empty": true
;
let options =
'method': 'post',
'contentType': 'application/json',
'headers':
Authorization: 'Bearer ' + 'your integration token',
'Notion-Version': '2021-05-13',
'Content-Type': 'application/json',
,
'payload': JSON.stringify(data)
;
let response = UrlFetchApp.fetch('https://api.notion.com/v1/databases/your_database_id/query', options);
response = JSON.parse(response.getContentText());
//other code
创建一个新的日历事件
page
是 response.results
数组之一。这里我们使用page.id
和database_id
作为事件的唯一标识。并且需要区分deadline是包含时间还是只包含日期。
这里有两个变量需要处理:
是否有结束日期 有时间或只有日期const calendar = CalendarApp.getCalendarById("your calendar id");
const onlyDateRegex = /(\d4)-(\d2)-(\d2)\b/;
const dateTimeRegex = /(\d4)-(\d2)-(\d2)T(\d2)\:(\d2)\:(\d2)\.(\d3)\+(\d2)\:(\d2)\b/;
function create(page)
let deadLine = page.properties.DeadLine;
let title = "";
page.properties.Name.title.forEach((rich_text) =>
title += rich_text.plain_text;
)
let pageId = page.id + " in database " + page.parent.database_id;
let startDate = deadLine.date.start;
let endDate = deadLine.date.end;
let startDateObj = new Date(startDate);
let endDateObj = new Date(endDate);
let evnet;
Logger.log("Create page " + title);
if (deadLine.date.end !== null)
if (onlyDateRegex.test(startDate))
evnet = calendar.createAllDayEvent(title, startDateObj, endDateObj);
if (dateTimeRegex.test(startDate))
evnet = calendar.createEvent(title, startDateObj, endDateObj);
else
if (onlyDateRegex.test(startDate))
evnet = calendar.createAllDayEvent(title, startDateObj);
if (dateTimeRegex.test(startDate))
evnet = calendar.createEvent(title, startDateObj, startDateObj);
evnet.setDescription(pageId);
然后我们可以使用描述中的id来搜索已经同步的页面
这里继续第一步的main函数。
function main()
//other code
response = JSON.parse(response.getContentText());
for (let i = 0; i < response.results.length; i++)
let pageId = response.results[i].id + " in database " + response.results[i].parent.database_id;
let event = search(pageId);
if (event === null) create(response.results[i]);
else update(event, response.results[i]);
function search(str)
let events = calendar.getEvents(new Date("1970-1-1"), new Date("2100-1-1"),
search: str
);
if (events.length > 1) throw new Error("uuid duplicate in search");
if (events.length === 0) return null;
return events[0];
如果没有找到结果,则创建一个新事件,否则,尝试更新它。
更新事件的做法与创建事件时几乎相同
function update(event, page)
let deadLine = page.properties.DeadLine;
let title = "";
page.properties.Name.title.forEach((rich_text) =>
title += rich_text.plain_text;
)
Logger.log("Update page " + title);
let startDate = deadLine.date.start;
let endDate = deadLine.date.end;
let startDateObj = new Date(startDate);
let endDateObj = new Date(endDate);
if (deadLine.date.end !== null)
if (onlyDateRegex.test(startDate))
startDateObj.setHours(0, 0, 0, 0);
endDateObj.setHours(0, 0, 0, 0);
if (event.isAllDayEvent())
if ((event.getAllDayStartDate().getTime() !== startDateObj.getTime()) ||
(event.getAllDayEndDate().getTime() !== endDateObj.getTime()))
Logger.log("update allDayStartDate " + event.getAllDayStartDate() + " to " + startDateObj);
Logger.log("update allDayEndDate " + event.getAllDayEndDate() + " to " + endDateObj);
event.setAllDayDates(startDateObj, endDateObj);
else event.setAllDayDates(startDateObj, endDateObj);
if (dateTimeRegex.test(startDate))
if (event.isAllDayEvent())
Logger.log("change to dateTime, start: " + startDateObj + " end: " + endDateObj);
event.setTime(startDateObj, endDateObj);
else
if ((event.getStartTime().getTime() !== startDateObj.getTime()) ||
(event.getEndTime().getTime() !== endDateObj.getTime()))
Logger.log("update dateTime, start: " + startDateObj + " end: " + endDateObj);
event.setTime(startDateObj, endDateObj);
else
if (onlyDateRegex.test(startDate))
startDateObj.setHours(0, 0, 0, 0);
if (event.isAllDayEvent())
if ((event.getAllDayStartDate().getTime() !== startDateObj.getTime()) ||
(event.getAllDayEndDate().getTime() !== startDateObj.getTime()))
Logger.log("update allOneDayDate " + event.getAllDayStartDate() + " to " + startDateObj);
event.setAllDayDate(startDateObj);
else
Logger.log("change to allOneDayDate: " + startDateObj);
event.setAllDayDates(startDateObj);
if (dateTimeRegex.test(startDate))
if (event.isAllDayEvent())
Logger.log("change to dateTime: " + startDateObj);
event.setTime(startDateObj, startDateObj);
else
if (event.getStartTime().getTime() !== startDateObj.getTime())
Logger.log("update dateTime: " + startDateObj);
event.setTime(startDateObj, startDateObj);
if (event.getTitle() !== title)
Logger.log("update title: \"" + event.getTitle() + "\" to " + title);
event.setTitle(title);
Full example code
我不是专业的 javascript 或 Google App Script 工程师,这些代码可能还需要改进,希望对你有用。
【讨论】:
以上是关于带有 Google 日历的 Notion API的主要内容,如果未能解决你的问题,请参考以下文章
带有 Google 日历 API(时隙)React/NodeJS 的预约系统