前言
本潜水员记得最开始看到 Notion 即将发布 API 的新闻就是在少数派,后来又看到有大佬发了一篇用 API 辅助记账的 应用文章。很是兴奋,但苦于门槛较高一直在等方便一些的体验文章。
直到现在 API 功能已正式发布,但是仍没见新文,心痒难耐,索性直接研究了一下。踩了一些坑,同时深感测试之麻烦。要复制来去扒 ID,看报错内容,摸索对象类型,折腾下来不禁头大了半圈。
所以一气之下用 Python 撸了两个工具,顺便写上使用教程和心得,希望可以帮大家在测试 API 的时候惬意些。
本文前半部分比较繁琐,但是很推荐看完,可以参考目录跳转。
原计划用快捷指令完成这些功能,但是作者的设备目前都是 beta 版系统,快捷指令编辑的时候频出 bug 与 UI 错误。最后甚至用钟大的 JSBox 使快捷指令跳转执行 JavaScript 代码才可以成功添加记录。所以快捷指令版 Notion 助手要等正式版系统发布之后再更新了(或者有意帮忙的大佬也可以私信讨论)。
如果觉得 Python 门槛太高,可以多点赞,大家需求高的话我就封成 exe 文件再发出来(嘿嘿)。
简单介绍
拿个人最常用的吃药记录举例,最近在吃褪黑素和咖啡因片。那么我很想知道药效如何、多长时间起作用,就可以在记录时写入时间和净含量,再用 Notion 自动计算出经过的时间和服用量等数据。
![](https://cdnfile.sspai.com/2021/08/06/a30b60719a414679aa494465947d4864.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
不得不说这种小公式使用起来真的是很舒服,而且日常使用比 Excel 更美观易读,但是需要每次吃药都打开 Notion 手动选择数据记录下来。当然可以使用模板自动填充大部分数据,但仍需要打开 Notion 才能操作,并且还需要选择日期。如果能用手机上的快捷指令一键添加就好了。
Notion API 当然就可以实现这个功能。首先我们需要创建一个机器人,然后将机器人添加到需要进行操作的页面中,很简单,大佬的帖子 写的很详细了。
但是后续的流程操作实在繁琐,以 Python 举例:(非常推荐看完下面正常方法再看辅助代码的使用教程,这样您就理解我了)
POST —— 提交数据给 Notion 的方式
如果想在某个表格里添加一项记录,你需要如下 POST 代码将数据提交给 Notion 以及一个格式正确的消息体(后面会说怎么制作)
# 在 Python 中使用 requests 模块的功能进行 GET 或 POST 操作
NotionData = requests.request(
# POST 提交,GET 拉取
"POST",
# API 链接,不同操作类型的 API 链接不同,例如这个就是数据库 databases 的 API 链接
"https://api.notion.com/v1/databases",
# 读取消息体,消息体需要另行编辑,后文再说
json = body,
# 消息头,内有必要信息
headers={
# 设置机器人令牌,即 Notion 的机器人码
"Authorization": "secret_kWWY0dlOI7E0nRSZbNmvxADpgFjtOD876J4W0HBn5bj",
# 设置 Notion 版本,目前不用改
"Notion-Version": "2021-05-13"
},
)
消息体的格式与所需数据
好的,在上面的步骤中,你要根据需求自行更改三项内容:API 链接、消息体、机器人令牌。其中API 链接和机器人令牌都是易得的,消息体怎么做呢?这就比较麻烦了,看下面代码:
# 消息体的变量 body,你还记得他吗?上面的代码里就引用了它~
body = {
# 父级信息(即你要创建的页面的上一级页面)
"parent": {
# 父级页面类型,如果我们想在服药记录的数据库中增加一条记录,那么新纪录是什么类型呢?
# 答对了!是页面类型,我们创建的是记录,它展开后是一条页面,所以输入 page_id
"type": "page_id",
# 注意,下面的 "page_id" 项仍需要根据你的创建项目类型变化
# 所需要提供的 ID 就是父级页面的 ID,需要手动在链接中进行复制
"page_id": "bbae1170539f40fea03d0d07eb5a8b60"
},
# 属性项,在这里决定新记录的属性是什么,这里我用服药记录举例
"properties":{
# 真正的属性项里有更多参数,但是很多参数都可以被忽略,Notion 会自动补全
# 此处已经由作者处理完毕,目前有自动处理代码正在编写当中
"数量": {
"select": {
"name": "2"
}},
"药名": {
"select": {
"name": "咖啡因片"
}},
"单份含量": {
"select": {
"name": "200mg"
}},
"服药日期": {
"date": {
# 日期可以用其他函数自动填写
"start": "2021-08-03T05:32:00.000+08:00"}}}
}
GET —— 让我们从 Notion 中拉取数据吧!
很好,在这部分代码中,我们需要补充:父级页面类型、父级页面 ID、编写不同的属性项
那这些神奇的数据我们需要如何获取呢?请看下面的 GET 代码,我们将用它从 Notion 上拉取页面信息~
首先我们要先在数据库中创建一条记录,然后将它的数据拉取,就可以得到最全面的数据及属性项格式了。
# 通过 Notion API 拉取数据
NotionData = requests.request(
# POST 提交,GET 拉取
"GET",
# API 链接,不同操作类型的 API 链接不同
# 在前文由于我们要创建的是数据库中的记录即页面,因此在这里我们拉取的也是页面类型 pages
# 后面需要指明所拉取的页面 ID
"https://api.notion.com/v1/pages/532b676181db4c13b43e1203cc69e693",
# 前文已介绍过
headers={
"Authorization": "secret_kWWY0dlOI7E0nRSZbNmvxADpgFjtOD876J4W0HBn5bj",
"Notion-Version": "2021-05-13"
},
)
# 一切顺利的话,我们将拉取如下数据
# {"object":"page","id":"532b6761-81db-4c13-b43e-1203cc69e693","created_time":"2021-08-05T06:56:00.000Z","last_edited_time":"2021-08-05T10:43:00.000Z","parent":{"type":"database_id","database_id":"bbae1170-539f-40fe-a03d-0d07eb5a8b60"},"archived":false,"properties":{"数量":{"id":">dRE","type":"select","select":{"id":"03be4654-3ae8-4a71-bc3e-5d8d0f24456c","name":"4","color":"pink"}},"类别":{"id":"D`Yd","type":"select","select":{"id":"620209f6-fa99-4944-8797-5b44c9e3015d","name":"咖啡因片","color":"brown"}},"hours":{"id":"OFoK","type":"formula","formula":{"type":"string","string":"62"}},"单份含量":{"id":"TIc^","type":"select","select":{"id":"4b10b0a8-7d6e-4ff3-8cbf-737596504795","name":"200mg","color":"brown"}},"褪黑素数量":{"id":"W;[>","type":"formula","formula":{"type":"number","number":0}},"服药日期":{"id":"iahF","type":"date","date":{"start":"2021-08-03T05:32:00.000+08:00","end":null}},"minutes":{"id":"jUE[","type":"formula","formula":{"type":"string","string":"3757"}},"days":{"id":"msql","type":"formula","formula":{"type":"string","string":"2"}},"摄入量":{"id":"nyGz","type":"formula","formula":{"type":"string","string":"800mg"}},"已过时间":{"id":"v{wq","type":"formula","formula":{"type":"string","string":"已过 2 天 14 小时"}},"喝咖啡数量":{"id":"{Ah>","type":"formula","formula":{"type":"number","number":4}},"记录名":{"id":"title","type":"title","title":[]}},"url":"https://www.notion.so/532b676181db4c13b43e1203cc69e693"}
我们可以将数据复制到 JSON 在线解析网站 中,可以得到如下视图。
可以发现右侧还有很多 id、type 等属性项,这些都可以后期去掉,只留下前文消息体那样的格式即可。同时右侧也展示了父级页面的类型和 ID,好方便啊(no)。
![](https://cdnfile.sspai.com/2021/08/06/4dc302003abe6a994af99cc2ad19b494.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
好啦!然后我们写好消息体,再从此处向前文回溯到 POST 提交数据,即可完成仅这个表格的仅一类记录的提交测试流程。
代码功能及介绍
好的,让我们休息一下。不要再想前面的流程了,现在可以用更简单的方法完成上述操作。
本模块主要简略的展示代码功能和操作方式,具体的实现思路以后有机会再更新。
简单的前置条件
需要安装 Python ,真的不难,可以参考该安装教程。
再安装 requests 模块以便进行 GET 和 POST 操作,只需要在终端中输入 'pip install requests' 即可。
作者在使用 VS Code 搓代码与运行,如果你只安装了 Python 怎么办呢?可以右键 .py 文件选择 'edit with IDLE' 后打开。然后根据下文内容修改关键变量后点击上方 “Run” 即可运行。
如果这个也有点难,那你可以选择等待鸽子作者可能会推出的 exe 版 Notion 助手(但是不可能有 UI)。
![](https://cdnfile.sspai.com/2021/08/06/75c1431651429a81bbf2c2b94f467b3a.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
![](https://cdnfile.sspai.com/2021/08/06/e2123319bbff4771734bece8f78bb7e5.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
GET 代码功能及使用介绍
- 直接粘贴待测试页面的链接即可,不需要扒 ID
- 选择待测试页面类型更方便
- 自定义参数的修改流程及位置集中化
- 直接输出当前页面类型、父级页面类型、父级页面 ID
- 可更直观的输出不同类型的报错提示
我们只需要把待检测链接粘贴进来,然后选择好复制该页面链接时的页面类型,再将机器人令牌粘贴过来就可以点击运行。
![](https://cdnfile.sspai.com/2021/08/06/6a3d7009da5cc79e673c7a0bd9a1c256.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
上图为自定义参数的修改处,可以仅靠修改数字改变待测 ID,省时省力。
![](https://cdnfile.sspai.com/2021/08/06/6fd4e56cf540615b60edc5ca2aeb8c5b.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
粘贴链接后,选择测试类型运行后的输出结果,直接告诉用户页面类型和 ID,省时省力。
![](https://cdnfile.sspai.com/2021/08/06/68d3c2db1365f868a35f665419bdfbd8.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
修改待测 ID 后输出的报错,省时省力。
这样就极大地减少了工作量,并且可以直接复制父级 ID 给 POST 界面。
POST 代码功能及使用介绍
- 直接粘贴父级页面 ID 即可
- 更方便的选择操作类型及父页面类型
- 和 GET 代码一样可以方便的自定义参数
- 不需要编辑消息体中的 parent 父级信息(属性项仍需要编辑)
- 页面创建成功后提供直达链接
- 可更直观的输出不同类型的报错提示
![](https://cdnfile.sspai.com/2021/08/06/9ff8b8929d3cd818fc8e3fbadea13ebd.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
和 GET 代码一样,轻松选择类型~
![](https://cdnfile.sspai.com/2021/08/06/4018f31e31c3a57b4bf1e86f69968261.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
添加成功~
输出直达链接更方便我们找到新增的页面。
![](https://cdnfile.sspai.com/2021/08/06/1ac0b262d0a499e71a812cbce680e90f.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
![](https://cdnfile.sspai.com/2021/08/06/de99c5be684fecab985427cf396a7ab0.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
测试一下吧!
本文最早就是 在 Notion 上完成 的,同时也预备了一个 测试页面 给各位。
里面有两个表格,第一个表格的内容已经内置在代码中了,直接点击即可添加一条记录。第二个表格则需要大家修改一下属性项以及其他参数,供练手用,各位加油。
代码下载地址:Notion 助手(阿里云盘)
![](https://cdnfile.sspai.com/2021/08/06/d3222feb16edcabc0b2a3167eadd13e4.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
部分细节与 todo list
下面是几个可能有人想修改或解封的模块,作者在 Python 方面实属菜鸡,有些模块感觉还可以更简单。注释已经尽量写得详细了。
原计划当做练习作业尽量写写实现思路,但是字儿太多,以后更新新模块后发一篇吧。
GET 代码文件中被封存的 Block 类型
![](https://cdnfile.sspai.com/2021/08/06/9a0d3755160a4b7260b90787eaea44ae.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
这个类型已被封存,因为我觉得这个功能不太常用,而且通过 API 添加新 block 记录也未免太过麻烦,直接去掉注释的用处也不是很大,有这个需求可以留个评论讨论一下。
GET 代码文件中输出信息及报错的模块(POST 代码文件中同理)
![](https://cdnfile.sspai.com/2021/08/06/dc7bb7afc51298aecfe5e91b36738254.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
如果发现了新的错误代码或其他提示信息,可以在 「# 报错消息对照表」里添加错误代码及修改信息文本。
彩蛋:简易消息体制作助手
![](https://cdnfile.sspai.com/2021/08/06/afcb6c0644b35563360b38100594f61c.png?imageView2/2/w/1120/q/40/interlace/1/ignore-error/1)
目前输出的属性项已可以直接使用了,目前的小目标就是可以直接将父级页面信息与属性项拼接制作成一个消息体,我们只需要修改关键数值即可完成一份消息体的创建。
做到了这一步其实就可以将 GET 中获得的父级信息和属性项直接通过此代码制作成消息体,再打包成一个 POST 文件输出供人修改。
但是作者比较懒,随缘更新吧~