如果我在网上搜索“带有 Google 日历的 Notion API”之类的内容,我只会找到与 Automate.io 或 Zappier 相关的解决方案。
有没有办法使用这些强大的 API 将 Notion 与 Google 日历集成,而不依赖于这些站点?我可以使用哪种编程语言来做到这一点?我需要一个服务器来定期运行程序吗?
PS:在 YT 上我发现了一些 Python 的东西,但我找不到使用这些工具的完整指南
如果我在网上搜索“带有 Google 日历的 Notion API”之类的内容,我只会找到与 Automate.io 或 Zappier 相关的解决方案。
有没有办法使用这些强大的 API 将 Notion 与 Google 日历集成,而不依赖于这些站点?我可以使用哪种编程语言来做到这一点?我需要一个服务器来定期运行程序吗?
PS:在 YT 上我发现了一些 Python 的东西,但我找不到使用这些工具的完整指南
我可以使用哪种编程语言来做到这一点?
您可以轻松地使用Google App Script和Notion API来实现这一点。Google 应用脚本的语法基于 javascript(尽管不支持某些 ES6 功能)。使用CalendarApp,您几乎可以控制 Google 日历上的所有内容。
我需要一个服务器来定期运行程序吗?
不,你不需要。在 Google App Script 中,您可以添加时间驱动的触发器以使其自动启动。
在这种情况下,我将根据“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
anddatabase_id
作为事件的唯一标识符。并且需要区分deadline是包含时间还是只包含日期。
这里有两个变量需要处理:
const calendar = CalendarApp.getCalendarById("your calendar id");
const onlyDateRegex = /(\d{4})-(\d{2})-(\d{2})\b/;
const dateTimeRegex = /(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})\.(\d{3})\+(\d{2})\:(\d{2})\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);
}
这里继续第一步的主要功能。
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);
}
}
我不是专业的 javascript 或 Google App Script 工程师,这些代码可能还需要改进,希望对你有用。