* [规范](#规范) * [参数和返回值](#参数和返回值) * [鉴权](#鉴权) * [笔记本](#笔记本) * [列出笔记本](#列出笔记本) * [打开笔记本](#打开笔记本) * [关闭笔记本](#关闭笔记本) * [重命名笔记本](#重命名笔记本) * [创建笔记本](#创建笔记本) * [删除笔记本](#删除笔记本) * [获取笔记本配置](#获取笔记本配置) * [保存笔记本配置](#保存笔记本配置) * [文档](#文档) * [通过 Markdown 创建文档](#通过-markdown-创建文档) * [重命名文档](#重命名文档) * [删除文档](#删除文档) * [移动文档](#移动文档) * [根据路径获取人类可读路径](#根据路径获取人类可读路径) * [资源文件](#资源文件) * [上传资源文件](#上传资源文件) * [块操作](#块操作) * [插入块](#插入块) * [插入前置子块](#插入前置子块) * [插入后置子块](#插入后置子块) * [更新块](#更新块) * [删除块](#删除块) * [属性](#属性) * [设置块属性](#设置块属性) * [获取块属性](#获取块属性) * [SQL](#SQL) * [SQL 查询](#SQL-查询) * [模板](#模板) * [渲染模板](#渲染模板) * [导出](#导出) * [导出 Markdown 文本](#导出-markdown-文本) * [系统](#系统) * [获取启动进度](#获取启动进度) * [获取系统版本](#获取系统版本) * [获取系统当前时间](#获取系统当前时间) * [Webhook](#Webhook) --- ## 规范 ### 参数和返回值 * 端点:`http://127.0.0.1:6806` * 均是 POST 方法 * 需要带参的接口,参数为 JSON 字符串,放置到 body 里,标头 Content-Type 为 `application/json` * 返回值 ```json { "code": 0, "msg": "", "data": {} } ``` * `code`:非 0 为异常情况 * `msg`:正常情况下是空字符串,异常情况下会返回错误文案 * `data`:可能为 `{}`、`[]` 或者 `NULL`,根据不同接口而不同 ### 鉴权 在 设置 - 关于 里查看 API token,请求标头:`Authorization: Token xxx` ## 笔记本 ### 列出笔记本 * `/api/notebook/lsNotebooks` * 不带参 * 返回值 ```json { "code": 0, "msg": "", "data": { "notebooks": [ { "closed": false, "id": "20210817205410-2kvfpfn", "name": "测试笔记本" }, { "closed": true, "id": "20210831090520-7dvbdv0", "name": "测试笔记本2" } ] } } ``` ### 打开笔记本 * `/api/notebook/openNotebook` * 参数 ```json { "notebook": "20210831090520-7dvbdv0" } ``` * `notebook`:笔记本 ID * 返回值 ```json { "code": 0, "msg": "", "data": null } ``` ### 关闭笔记本 * `/api/notebook/closeNotebook` * 参数 ```json { "notebook": "20210831090520-7dvbdv0" } ``` * `notebook`:笔记本 ID * 返回值 ```json { "code": 0, "msg": "", "data": null } ``` ### 重命名笔记本 * `/api/notebook/renameNotebook` * 参数 ```json { "notebook": "20210831090520-7dvbdv0", "name": "笔记本的新名称" } ``` * `notebook`:笔记本 ID * 返回值 ```json { "code": 0, "msg": "", "data": null } ``` ### 创建笔记本 * `/api/notebook/createNotebook` * 参数 ```json { "name": "笔记本的名称" } ``` * 返回值 ```json { "code": 0, "msg": "", "data": null } ``` ### 删除笔记本 * `/api/notebook/removeNotebook` * 参数 ```json { "notebook": "20210831090520-7dvbdv0" } ``` * `notebook`:笔记本 ID * 返回值 ```json { "code": 0, "msg": "", "data": null } ``` ### 获取笔记本配置 * `/api/notebook/getNotebookConf` * 参数 ```json { "notebook": "20210817205410-2kvfpfn" } ``` * `notebook`:笔记本 ID * 返回值 ```json { "code": 0, "msg": "", "data": { "box": "20210817205410-2kvfpfn", "conf": { "name": "测试笔记本", "closed": false, "refCreateSavePath": "", "createDocNameTemplate": "", "dailyNoteSavePath": "/daily note/{{now | date \"2006/01\"}}/{{now | date \"2006-01-02\"}}", "dailyNoteTemplatePath": "" }, "name": "测试笔记本" } } ``` ### 保存笔记本配置 * `/api/notebook/setNotebookConf` * 参数 ```json { "notebook": "20210817205410-2kvfpfn", "conf": { "name": "测试笔记本", "closed": false, "refCreateSavePath": "", "createDocNameTemplate": "", "dailyNoteSavePath": "/daily note/{{now | date \"2006/01\"}}/{{now | date \"2006-01-02\"}}", "dailyNoteTemplatePath": "" } } ``` * `notebook`:笔记本 ID * 返回值 ```json { "code": 0, "msg": "", "data": { "name": "测试笔记本", "closed": false, "refCreateSavePath": "", "createDocNameTemplate": "", "dailyNoteSavePath": "/daily note/{{now | date \"2006/01\"}}/{{now | date \"2006-01-02\"}}", "dailyNoteTemplatePath": "" } } ``` ## 文档 ### 通过 Markdown 创建文档 * `/api/filetree/createDocWithMd` * 参数 ```json { "notebook": "20210817205410-2kvfpfn", "path": "/foo/bar", "markdown": "" } ``` * `notebook`:笔记本 ID * `path`:文档路径,需要以 / 开头,中间使用 / 分隔层级(这里的 path 对应数据库 hpath 字段) * `markdown`:GFM Markdown 内容 * 返回值 ```json { "code": 0, "msg": "", "data": "20210914223645-oj2vnx2" } ``` * `data`:创建好的文档 ID * 如果使用同一个 `path` 重复调用该接口,不会覆盖已有文档,而是新建随机数结尾的文档 ### 重命名文档 * `/api/filetree/renameDoc` * 参数 ```json { "notebook": "20210831090520-7dvbdv0", "path": "/20210902210113-0avi12f.sy", "title": "文档新标题" } ``` * `notebook`:笔记本 ID * `path`:文档路径 * 返回值 ```json { "code": 0, "msg": "", "data": null } ``` ### 删除文档 * `/api/filetree/removeDoc` * 参数 ```json { "notebook": "20210831090520-7dvbdv0", "path": "/20210902210113-0avi12f.sy" } ``` * `notebook`:笔记本 ID * `path`:文档路径 * 返回值 ```json { "code": 0, "msg": "", "data": null } ``` ### 移动文档 * `/api/filetree/moveDoc` * 参数 ```json { "fromNotebook": "20210831090520-7dvbdv0", "fromPath": "/20210917220056-yxtyl7i.sy", "toNotebook": "20210817205410-2kvfpfn", "toPath": "/" } ``` * `fromNotebook`:源笔记本 ID * `fromPath`:源路径 * `toNotebook`:目标笔记本 ID * `toPath`:目标路径 * 返回值 ```json { "code": 0, "msg": "", "data": null } ``` ### 根据路径获取人类可读路径 * `/api/filetree/getHPathByPath` * 参数 ```json { "notebook": "20210831090520-7dvbdv0", "path": "/20210917220500-sz588nq/20210917220056-yxtyl7i.sy" } ``` * `notebook`:笔记本 ID * `path`:路径 * 返回值 ```json { "code": 0, "msg": "", "data": "/foo/bar" } ``` ## 资源文件 ### 上传资源文件 * `/api/asset/upload` * 参数为 HTTP Multipart 表单 * `assetsDirPath`:资源文件存放的文件夹路径,实参有以下三种情况 1. `"/assets/"`:工作空间/data/assets 文件夹 2. `"/测试笔记本/assets/"`:测试笔记本下的 assets 文件夹 3. `"/测试笔记本/foo/assets/"`:测试笔记本下 foo 文件夹下的 assets 文件夹 建议用第一种,统一存放到工作空间资源文件夹下。 * `file[]`:上传的文件列表 * 返回值 ```json { "code": 0, "msg": "", "data": { "errFiles": [""], "succMap": { "foo.png": "assets/foo-20210719092549-9j5y79r.png" } } } ``` * `errFiles`:处理时遇到错误的文件名 * `succMap`:处理成功的文件,key 为上传时的文件名,value 为 assets/foo-id.png,用于将已有 Markdown 内容中的资源文件链接地址替换为上传后的地址 ## 块操作 ### 插入块 * `/api/block/insertBlock` * 参数 ```json { "dataType": "markdown", "data": "foo**bar**{: style=\"color: var(--b3-font-color8);\"}baz", "previousID": "20211229114650-vrek5x6" } ``` * `dataType`:待插入数据类型,值可选择 `markdown` 或者 `dom` * `data`:待插入的数据 * `previousID`:前一个块的 ID,用于锚定插入位置 * 返回值 ```json { "code": 0, "msg": "", "data": [ { "doOperations": [ { "action": "insert", "data": "
foobarbaz
", "id": "20211230115020-g02dfx0", "parentID": "", "previousID": "20211229114650-vrek5x6", "retData": null } ], "undoOperations": null } ] } ``` * `action.data`:新插入块生成的 DOM * `action.id`:新插入块的 ID ### 插入前置子块 * `/api/block/prependBlock` * 参数 ```json { "data": "foo**bar**{: style=\"color: var(--b3-font-color8);\"}baz", "dataType": "markdown", "parentID": "20220107173950-7f9m1nb" } ``` * `dataType`:待插入数据类型,值可选择 `markdown` 或者 `dom` * `data`:待插入的数据 * `parentID`:父块的 ID,用于锚定插入位置 * 返回值 ```json { "code": 0, "msg": "", "data": [ { "doOperations": [ { "action": "insert", "data": "
foobarbaz
", "id": "20220108003710-hm0x9sc", "parentID": "20220107173950-7f9m1nb", "previousID": "", "retData": null } ], "undoOperations": null } ] } ``` * `action.data`:新插入块生成的 DOM * `action.id`:新插入块的 ID ### 插入后置子块 * `/api/block/appendBlock` * 参数 ```json { "data": "foo**bar**{: style=\"color: var(--b3-font-color8);\"}baz", "dataType": "markdown", "parentID": "20220107173950-7f9m1nb" } ``` * `dataType`:待插入数据类型,值可选择 `markdown` 或者 `dom` * `data`:待插入的数据 * `parentID`:父块的 ID,用于锚定插入位置 * 返回值 ```json { "code": 0, "msg": "", "data": [ { "doOperations": [ { "action": "insert", "data": "
foobarbaz
", "id": "20220108003642-y2wmpcv", "parentID": "20220107173950-7f9m1nb", "previousID": "20220108003615-7rk41t1", "retData": null } ], "undoOperations": null } ] } ``` * `action.data`:新插入块生成的 DOM * `action.id`:新插入块的 ID ### 更新块 * `/api/block/updateBlock` * 参数 ```json { "dataType": "markdown", "data": "foobarbaz", "id": "20211230161520-querkps" } ``` * `dataType`:待更新数据类型,值可选择 `markdown` 或者 `dom` * `data`:待更新的数据 * `id`:待更新块 ID * 返回值 ```json { "code": 0, "msg": "", "data": [ { "doOperations": [ { "action": "update", "data": "
foobarbaz
", "id": "20211230161520-querkps", "parentID": "", "previousID": "", "retData": null } ], "undoOperations": null } ] } ``` * `action.data`:更新块生成的 DOM ### 删除块 * `/api/block/deleteBlock` * 参数 ```json { "id": "20211230161520-querkps" } ``` * `id`:待删除块 ID * 返回值 ```json { "code": 0, "msg": "", "data": [ { "doOperations": [ { "action": "delete", "data": null, "id": "20211230162439-vtm09qo", "parentID": "", "previousID": "", "retData": null } ], "undoOperations": null } ] } ``` ## 属性 ### 设置块属性 * `/api/attr/setBlockAttrs` * 参数 ```json { "id": "20210912214605-uhi5gco", "attrs": { "custom-attr1": "line1\nline2" } } ``` * `id`:块 ID * `attrs`:块属性,自定义属性必须以 `custom-` 作为前缀 * 返回值 ```json { "code": 0, "msg": "", "data": null } ``` ### 获取块属性 * `/api/attr/getBlockAttrs` * 参数 ```json { "id": "20210912214605-uhi5gco" } ``` * `id`:块 ID * 返回值 ```json { "code": 0, "msg": "", "data": { "custom-attr1": "line1\nline2", "id": "20210912214605-uhi5gco", "title": "PDF 标注双链演示", "type": "doc", "updated": "20210916120715" } } ``` ## SQL ### SQL 查询 * `/api/query/sql` * 参数 ```json { "stmt": "SELECT * FROM blocks WHERE content LIKE'%content%' LIMIT 7" } ``` * `stmt`:SQL 脚本 * 返回值 ```json { "code": 0, "msg": "", "data": [ { "列": "值" } ] } ``` ## 模板 ### 渲染模板 /template/render ## 导出 ### 导出 Markdown 文本 * `/api/export/exportMdContent` * 参数 ```json { "id": "" } ``` * `id`:要导出的文档块 ID * 返回值 ```json { "code": 0, "msg": "", "data": { "hPath": "/0 请从这里开始", "content": "## 🍫 内容块\n\n在思源中,唯一重要的核心概念是..." } } ``` * `hPath`:人类可读的路径 * `content`:Markdown 内容 ## 系统 ### 获取启动进度 * `/api/system/bootProgress` * 不带参 * 返回值 ```json { "code": 0, "msg": "", "data": { "details": "Finishing boot...", "progress": 100 } } ``` ### 获取系统版本 * `/api/system/version` * 不带参 * 返回值 ```json { "code": 0, "msg": "", "data": "1.3.5" } ``` ### 获取系统当前时间 * `/api/system/currentTime` * 不带参 * 返回值 ```json { "code": 0, "msg": "", "data": 1631850968131 } ``` * `data`: 精度为毫秒 ## Webhook TBD https://ld246.com/article/1627956688432