前段时间开发了一款名为 信息墙 的插件,其中有一个模块的功能是对 halo 的瞬间插件的数据以及 memos 的数据进行了统一的同步,并且扩充了 memos 和瞬间的渲染内容,可以支持各大平台音乐以及哔哩哔哩视频和 MP4 视频。最近有使用的用户提了个 issue ,希望可以增加多人 Memos 内容同步以及标签分类功能,于是又回过头研究了下官方目前提供的 V1 系列 API。

GEThttps://domain.com/api/v1/memo/all
| 参数名称 | 参数类型 | 是否必须 | 参数传入方式 | 参数含义 |
|---|---|---|---|---|
| limit | integer | No | query | 限制条数 |
| offset | integer | No | query | 偏移量 |
[
{
"id": 30,
"name": "RwtGjxhwb6X5px6XtvAUUB",
"rowStatus": "NORMAL",
"creatorId": 3,
"createdTs": 1719142976,
"updatedTs": 1719142976,
"displayTs": 1719142976,
"content": "#说说\n\n测试用户发了一个说说",
"visibility": "PUBLIC",
"pinned": false,
"creatorName": "test",
"creatorUsername": "test",
"resourceList": [],
"relationList": []
},
{
"id": 29,
"name": "D6GordMjsRNe8scbFq4jgC",
"rowStatus": "NORMAL",
"creatorId": 1,
"createdTs": 1718709467,
"updatedTs": 1718709467,
"displayTs": 1718709467,
"content": "#感悟 #说说\n\n此刻的我们,也许经历着另外一种成长,仅以此共勉!",
"visibility": "PUBLIC",
"pinned": false,
"creatorName": "dreamChaser",
"creatorUsername": "dreamChaser",
"resourceList": [
{
"id": 22,
"name": "resources/22",
"uid": "U73Bmubs3AsQG7DvFBakxB",
"creatorId": 1,
"createdTs": 1718709429,
"updatedTs": 1718709468,
"filename": "gw.png",
"externalLink": "",
"type": "image/png",
"size": 47542
}
],
"relationList": []
},
{
"id": 27,
"name": "74cDGRaCYpPX9a3cgQCuHg",
"rowStatus": "NORMAL",
"creatorId": 1,
"createdTs": 1718171605,
"updatedTs": 1718171605,
"displayTs": 1718171605,
"content": "#备忘录\n系统注入的代码\n```html\n .post-content p{\n text-indent: 2em;\n } \n/*font-family: 'Aa唯独你是深情命题'; LXGW WenKai */\nbody, #post-content, .code-toolbar{\n font-family: \"Aa唯独你是深情命题\",PingFang SC,Hiragino Sans GB,Droid Sans Fallback,Microsoft YaHei,sans-serif !important;\n font-weight: 545;\n} \nbody {\ncursor: url(https://blog.wenjing.xin/upload/icon/mouse-new.png), default;\n} \n```",
"visibility": "PUBLIC",
"pinned": false,
"creatorName": "dreamChaser",
"creatorUsername": "dreamChaser",
"resourceList": [],
"relationList": []
}]
请求方式: GET
请求路径
https://domain.com/api/v1/memo/stats
请求头:无
请求参数:V0.22.1 版本需要至少下面中的一个参数,往前的版本可不需要如下参数,具体情况请自行测试
| 参数名称 | 参数类型 | 是否必须 | 参数传入方式 | 参数含义 |
|---|---|---|---|---|
| creatorId | integer | 可选参数 | query | 创建者ID |
| creatorUsername | string | 可选参数 | query | 创建者用户名 |
返回结果:时间戳列表
[
1718709467,
1718171605,
1718033655,
1718014123,
1717846085,
1717736035,
1717652332,
1717596945,
1717508307,
1716869221,
1716642917,
1716220249,
1716111586,
1716107585,
1716106994
]
请求方式 GET
请求路径
https://domain.com/api/v1/status
请求头:无
请求参数:无
请求结果:
{
"host": {
"id": 1,
"rowStatus": "",
"createdTs": 0,
"updatedTs": 0,
"username": "",
"role": "",
"email": "",
"nickname": "",
"avatarUrl": ""
},
"profile": {
"mode": "prod",
"version": "0.21.0"
},
"dbSize": 0,
"disablePasswordLogin": false,
"disablePublicMemos": false,
"maxUploadSizeMiB": 32,
"customizedProfile": {
"name": "dreamChaser的树洞",
"logoUrl": "https://dream-chaser.oss-cn-beijing.aliyuncs.com/halo-blog-save/other/iCopy_2024_05_03_13_34_54.png",
"description": "分享日常点滴!",
"locale": "zh-Hans",
"appearance": "system"
},
"storageServiceId": -1,
"localStoragePath": "assets/{timestamp}_{filename}",
"memoDisplayWithUpdatedTs": false
}
请求方式 GET
请求路径
https://domain.com/api/v1/tag
请求头:
Authorization: Bearer <Token>
# 例子
Authorization: Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6oiSldUIn0.eyJuYW1lIjoiIiwiaXNzIjoibWVtb3MiLCJzdWIiOiIzIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImV4cCI6NDg3Mjc0MjkyNSwiaWF0IjoxNzE5MTQyOTI1fQ.XSfl4omDbOTvwiKIymReaxMCXSP7i4B1GXhyiK1R8rk
请求参数:无
JavaScript结果
[
"说说"
]
请求方式:GET
请求路径
https://domain.com/api/v1/memo
请求头:如果没有携带任何过滤参数的情况下,请携带该 token
Authorization: Bearer <Token>
# 例子
Authorization: Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6oiSldUIn0.eyJuYW1lIjoiIiwiaXNzIjoibWVtb3MiLCJzdWIiOiIzIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImV4cCI6NDg3Mjc0MjkyNSwiaWF0IjoxNzE5MTQyOTI1fQ.XSfl4omDbOTvwiKIymReaxMCXSP7i4B1GXhyiK1R8rk
请求参数
| 参数名称 | 参数类型 | 是否必须 | 参数传入方式 | 参数含义 |
|---|---|---|---|---|
| creatorId | integer | 可选参数 | query | 创建者ID |
| creatorUsername | string | 可选参数 | query | 创建者用户名 |
| pinned | boolean | 可选参数 | query | 是否被固定 |
| tag | string | 可选参数 | query | 标签名称 |
| content | string | 可选参数 | query | memos内容 |
| limit | integer | 可选参数 | query | 限制的查询条数 |
| offset | integer | 可选参数 | query | 偏移量 |
返回结果
[
{
"id": 32,
"name": "8LWfp2sJcfeHarT6TggU6M",
"rowStatus": "NORMAL",
"creatorId": 3,
"createdTs": 1719143854,
"updatedTs": 1719143854,
"displayTs": 1719143854,
"content": "工作区内的 Memos",
"visibility": "PROTECTED",
"pinned": false,
"creatorName": "test",
"creatorUsername": "test",
"resourceList": [],
"relationList": []
}
{
"id": 30,
"name": "RwtGjxhwb6X5px6XtvAUUB",
"rowStatus": "NORMAL",
"creatorId": 3,
"createdTs": 1719142976,
"updatedTs": 1719142976,
"displayTs": 1719142976,
"content": "#说说\n\n测试用户发了一个说说",
"visibility": "PUBLIC",
"pinned": false,
"creatorName": "test",
"creatorUsername": "test",
"resourceList": [],
"relationList": []
}
]
需要注意的是:如果不携带任何请求参数,只加入请求头的 token 时,则会获取当前用户的所有 memos 内容,包括工作区和私有的 memos 内容!
请求方式: GET
请求路径:
https://domain.com/api/v1/resource
请求头
Authorization: Bearer <Token>
# 例子
Authorization: Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6oiSldUIn0.eyJuYW1lIjoiIiwiaXNzIjoibWVtb3MiLCJzdWIiOiIzIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2V0sImV4cCI6NDg3Mjc0MjkyNSwiaWF0IjoxNzE5MTQyOTI1fQ.XSfl4omDbOTvwiKIymReaxMCXSP7i4B1GXhyiK1R8rk
请求参数
| 参数名称 | 参数类型 | 是否必须 | 参数传入方式 | 参数含义 |
|---|---|---|---|---|
| limit | integer | 可选参数 | query | 查询数量 |
| offset | integer | 可选参数 | query | 偏移量 |
请求结果
[
{
"id": 22,
"name": "resources/22",
"uid": "U73Bmubs3AsQG7DvFBakxB",
"creatorId": 1,
"createdTs": 1718709429,
"updatedTs": 1718709468,
"filename": "gw.png",
"externalLink": "",
"type": "image/png",
"size": 47542
}
{
"id": 4,
"name": "resources/4",
"uid": "EFKgJ8QkxEJxUVxUo6UZdb",
"creatorId": 1,
"createdTs": 1716111576,
"updatedTs": 1716178958,
"filename": "飘雪.mp4",
"externalLink": "",
"type": "video/mp4",
"size": 6881783
}
]
一个基本的 memos 数据格式如下
{
"id": 29,
"name": "D6GordMjsRNe8scbFq4jgC",
"rowStatus": "NORMAL",
"creatorId": 1,
"createdTs": 1718709467,
"updatedTs": 1718709467,
"displayTs": 1718709467,
"content": "#感悟 #说说\n\n此刻的我们,也许经历着另外一种成长,仅以此共勉!",
"visibility": "PUBLIC",
"pinned": false,
"creatorName": "dreamChaser",
"creatorUsername": "dreamChaser",
"resourceList": [
{
"id": 22,
"name": "resources/22",
"uid": "U73Bmubs3AsQG7DvFBakxB",
"creatorId": 1,
"createdTs": 1718709429,
"updatedTs": 1718709468,
"filename": "gw.png",
"externalLink": "",
"type": "image/png",
"size": 47542
}
],
"relationList": []
},
如何根据得到的 resourceList 拼接出资源路径,格式如下:
https://domain.com/o/r/${resourceList[i].uid}
如果发布 memos 时,使用的资源是外部资源链接,则只需要 resourceList[i].externalLink 即可获取外部资源链接!
memos 默认请求到的内容标签格式直接是 #tag 形式的,和内容是混合在一起的,而且样式不怎么好看。
这时候就需要提取内容中的标签,对其进行重新渲染,如果使用正则表达式提取总是会发现匹配的不准确,可能是自己的正则有问题,所有采用曲线救国的方式,先获取所有的标签内容,再对获取的 memos 内容进行标签匹配,重新替换原内容的标签渲染样式。