本文最后更新于 2024-06-25,文章内容可能已经过时。

一、前言

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

mw-issue.png

二、相关 API 调用

本文下面的API是基于memosV0.21.1进行测试的!

1、获取全部的公共可见的 memos

  • 请求方式 GET
  • 请求路径
https://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": []
    }]

2、获取 memos 的活动记录

  • 请求方式: 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
    ]
    

3、获取 memos 的系统信息

  • 请求方式 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
    }
    

4、获取所有标签列表

  • 请求方式 GET

  • 请求路径

    https://domain.com/api/v1/tag
    
  • 请求头:

    Authorization: Bearer <Token>
    # 例子
    Authorization: Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6oiSldUIn0.eyJuYW1lIjoiIiwiaXNzIjoibWVtb3MiLCJzdWIiOiIzIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImV4cCI6NDg3Mjc0MjkyNSwiaWF0IjoxNzE5MTQyOTI1fQ.XSfl4omDbOTvwiKIymReaxMCXSP7i4B1GXhyiK1R8rk
    
  • 请求参数:无

  • JavaScript结果

    [
        "说说"
    ]
    

5、根据过滤条件获取相应 memos

  • 请求方式: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 内容!

6、获取所有的上传资源

  • 请求方式: 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
      }
    ]
    
    

三、数据使用 tips

1、如何在获取的 memos 内容里得到媒体资源路径

一个基本的 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 即可获取外部资源链接!

2、标题替换方法

memos 默认请求到的内容标签格式直接是 #tag 形式的,和内容是混合在一起的,而且样式不怎么好看。

这时候就需要提取内容中的标签,对其进行重新渲染,如果使用正则表达式提取总是会发现匹配的不准确,可能是自己的正则有问题,所有采用曲线救国的方式,先获取所有的标签内容,再对获取的 memos 内容进行标签匹配,重新替换原内容的标签渲染样式。