API 接口文档 v1.2

概述

ACGBT API 提供了一套标准化的 RESTful 接口,供移动APP、第三方系统调用。

  • 基础URL: https://bj2.dmbt.site/api/v1
  • 数据格式: JSON
  • 字符编码: UTF-8

认证方式

方式一:API Key + Secret(推荐)

在请求头中传递认证信息:

X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-API-Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

方式二:签名验证(更安全)

适用于对安全性要求较高的场景:

X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Timestamp: 1700000000
X-Signature: hmac_sha256签名值

签名生成规则: signature = HMAC-SHA256(timestamp + api_key, api_secret)

通用响应格式

成功响应

{
    "code": 0,
    "message": "success",
    "data": { ... },
    "timestamp": 1700000000
}

错误码说明

错误码说明
0成功
400请求参数错误
401认证失败
403无权限访问
404资源不存在
429请求频率超限
500服务器内部错误

新增字段说明 v1.2

字段类型说明版本
imagesarray图片链接数组,JSON格式存储v1.1
image_layoutint图片排列方式:1=单图排列,2=双图排列,3=三图排列v1.1
resource_countint分类下的资源总数v1.1
authorstring发布者用户名v1.1
author_avatarstring发布者头像URLv1.1
message_typestring消息类型:system, activity, personalv1.2
is_readint消息已读状态:0=未读,1=已读v1.2

开放接口(无需认证)

1. 获取API信息

GET /api/v1

获取API版本和可用接口列表。

2. 获取资源列表

GET /api/v1/resources
参数类型必填说明
pageint页码,默认1
page_sizeint每页数量,默认20,最大100
category_idint分类ID筛选
order_bystring排序字段:created_at, downloads, seeders, title
order_dirstring排序方向:asc, desc

响应字段(新增):

字段类型说明
imagesarray图片链接数组 v1.1
image_layoutint图片排列方式 v1.1
authorstring发布者用户名 v1.1
author_avatarstring发布者头像URL v1.1

3. 获取资源详情

GET /api/v1/resources/{id}

获取单个资源的详细信息,包含下载链接、图片等。

响应字段(新增):

字段类型说明
imagesarray图片链接数组 v1.1
image_layoutint图片排列方式 v1.1
torrent_filestring种子文件路径
magnet_linkstring磁力链接
ipfs_cidstringIPFS CID
authorstring发布者用户名 v1.1
author_avatarstring发布者头像URL v1.1

4. 获取分类列表

GET /api/v1/categories

获取所有资源分类。

响应字段(新增):

字段类型说明
resource_countint该分类下的资源总数 v1.1
GET /api/v1/search
参数类型必填说明
qstring搜索关键词
pageint页码,默认1
page_sizeint每页数量,默认20

响应字段(新增):

字段类型说明
imagesarray图片链接数组 v1.1
image_layoutint图片排列方式 v1.1
authorstring发布者用户名 v1.1
author_avatarstring发布者头像URL v1.1

6. 获取资源评论 v1.1

GET /api/v1/resources/{id}/comments

获取指定资源的评论列表。

参数类型必填说明
pageint页码,默认1
page_sizeint每页数量,默认20,最大100

响应示例

{
    "code": 0,
    "message": "success",
    "data": {
        "items": [
            {
                "id": 1,
                "content": "评论内容",
                "parent_id": null,
                "created_at": "2024-01-01 12:00:00",
                "user_id": 1,
                "username": "用户名",
                "avatar": "https://example.com/avatar.jpg"
            }
        ],
        "pagination": { ... }
    }
}

需认证接口

7. 发布资源

POST /api/v1/publish

通过API发布新资源,需要 publish 权限。

请求体

{
    "title": "资源标题",
    "category_id": 1,
    "description": "资源简介",
    "images": [
        "https://example.com/image1.jpg",
        "https://example.com/image2.jpg"
    ],
    "image_layout": 2,
    "torrent_file": "/uploads/torrents/example.torrent",
    "magnet_link": "magnet:?xt=urn:btih:xxxxx",
    "ipfs_cid": "QmXyz...",
    "file_size": 5368709120
}
参数类型必填说明
titlestring资源标题
category_idint分类ID
descriptionstring资源简介,支持Markdown
imagesarray图片链接数组 v1.1
image_layoutint图片排列方式:1=单图,2=双图,3=三图 v1.1
torrent_filestring种子文件路径
magnet_linkstring磁力链接
ipfs_cidstringIPFS CID
file_sizeint文件大小(字节)

图片排列方式说明

说明显示效果
1单图排列每行一张图片,垂直排列
2双图排列每行两张图片,各占50%宽度
3三图排列每行三张图片,各占33.33%宽度

8. 发表评论 v1.1

POST /api/v1/comments

对资源发表评论,需要认证。

请求体

{
    "resource_id": 1,
    "parent_id": null,
    "content": "评论内容,最多1000字"
}
参数类型必填说明
resource_idint资源ID
parent_idint父评论ID,回复评论时传入
contentstring评论内容,最多1000字

9. 删除评论 v1.1

DELETE /api/v1/comments/{id}

删除自己的评论,需要认证。管理员可删除任何评论。

10. 获取用户资料 v1.1

GET /api/v1/user/profile

获取当前认证用户的资料信息,需要认证。

响应示例

{
    "code": 0,
    "message": "success",
    "data": {
        "id": 1,
        "username": "用户名",
        "email": "user@example.com",
        "avatar": "https://example.com/uploads/avatars/avatar_1_1234567890.jpg",
        "role": "user",
        "created_at": "2024-01-01 12:00:00"
    }
}

11. 更新头像(外链) v1.1

POST /api/v1/user/avatar

通过外链URL更新用户头像,需要认证。

请求体

{
    "avatar": "https://example.com/avatar.jpg"
}
参数类型必填说明
avatarstring头像图片URL地址

12. 上传头像 v1.1

POST /api/v1/user/avatar/upload

上传头像图片,需要认证。使用 multipart/form-data 格式。

参数类型必填说明
avatarfile头像图片文件(JPG/PNG/GIF/WebP,最大2MB)

响应示例

{
    "code": 0,
    "message": "头像上传成功",
    "data": {
        "avatar": "https://example.com/uploads/avatars/avatar_1_1234567890.jpg",
        "url": "/uploads/avatars/avatar_1_1234567890.jpg"
    }
}

13. 获取用户API密钥

GET /api/v1/user/keys

获取当前认证用户的所有API密钥。

14. 创建API密钥

POST /api/v1/user/keys

请求体

{
    "name": "我的新密钥",
    "permissions": ["read", "publish"],
    "rate_limit": 60
}
权限说明
read读取资源、分类等公开数据
publish发布资源
*全部权限
注意: api_secret 仅在创建时返回一次,请妥善保存!

15. 获取消息列表 v1.2

GET /api/v1/messages

获取当前用户的消息列表,包括个人消息和群发消息,需要认证。

参数类型必填说明
pageint页码,默认1
page_sizeint每页数量,默认20,最大100
typestring消息类型筛选:system, activity, personal

响应示例

{
    "code": 0,
    "message": "success",
    "data": {
        "items": [
            {
                "id": 1,
                "title": "消息标题",
                "content": "消息内容",
                "type": "system",
                "is_read": 0,
                "created_at": "2024-01-01 12:00:00"
            }
        ],
        "pagination": {
            "total": 100,
            "page": 1,
            "page_size": 20,
            "total_pages": 5
        }
    }
}

16. 获取未读消息数量 v1.2

GET /api/v1/messages/unread-count

获取当前用户的未读消息数量,需要认证。

响应示例

{
    "code": 0,
    "message": "success",
    "data": {
        "count": 5
    }
}

17. 获取消息详情 v1.2

GET /api/v1/messages/{id}

获取指定消息的详细内容,访问时自动标记为已读,需要认证。

响应示例

{
    "code": 0,
    "message": "success",
    "data": {
        "id": 1,
        "user_id": null,
        "title": "系统公告标题",
        "content": "消息详细内容...",
        "type": "system",
        "is_read": 1,
        "sender_id": 1,
        "created_at": "2024-01-01 12:00:00"
    }
}

18. 标记消息已读 v1.2

POST /api/v1/messages/{id}/read

将指定消息标记为已读,需要认证。

19. 全部标记已读 v1.2

POST /api/v1/messages/read-all

将当前用户的所有消息标记为已读,需要认证。

消息类型说明

类型说明
system系统消息,如系统公告、维护通知等
activity活动消息,如优惠活动、新功能上线等
personal个人消息,如审核结果、私信等

频率限制

  • 默认限制:60次/分钟
  • 超过限制将返回 429 错误
  • 可在管理后台或创建密钥时自定义限制

调用示例

cURL

# 获取资源列表
curl -X GET "https://bj2.dmbt.site/api/v1/resources?page=1&page_size=10"

# 获取分类列表
curl -X GET "https://bj2.dmbt.site/api/v1/categories"

# 发布资源(含图片)
curl -X POST "https://bj2.dmbt.site/api/v1/publish" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx" \
  -d '{
    "title": "测试资源",
    "category_id": 1,
    "description": "资源简介",
    "images": ["https://example.com/image1.jpg", "https://example.com/image2.jpg"],
    "image_layout": 2,
    "magnet_link": "magnet:?xt=urn:btih:xxxxx"
  }'

# 发表评论
curl -X POST "https://bj2.dmbt.site/api/v1/comments" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx" \
  -d '{"resource_id": 1, "content": "评论内容"}'

# 获取用户资料
curl -X GET "https://bj2.dmbt.site/api/v1/user/profile" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx"

# 更新头像(外链)
curl -X POST "https://bj2.dmbt.site/api/v1/user/avatar" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx" \
  -d '{"avatar": "https://example.com/my-avatar.jpg"}'

# 上传头像
curl -X POST "https://bj2.dmbt.site/api/v1/user/avatar/upload" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx" \
  -F "avatar=@/path/to/avatar.jpg"

# 获取消息列表
curl -X GET "https://bj2.dmbt.site/api/v1/messages?page=1&page_size=10" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx"

# 获取未读消息数量
curl -X GET "https://bj2.dmbt.site/api/v1/messages/unread-count" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx"

# 获取消息详情
curl -X GET "https://bj2.dmbt.site/api/v1/messages/1" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx"

# 标记消息已读
curl -X POST "https://bj2.dmbt.site/api/v1/messages/1/read" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx"

# 全部标记已读
curl -X POST "https://bj2.dmbt.site/api/v1/messages/read-all" \
  -H "X-API-Key: ak_xxx" \
  -H "X-API-Secret: xxx"

JavaScript

const apiUrl = 'https://bj2.dmbt.site/api/v1';

// 获取资源列表
fetch(`${apiUrl}/resources?page=1&page_size=10`)
    .then(res => res.json())
    .then(data => console.log(data));

// 发布资源(含图片)
fetch(`${apiUrl}/publish`, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    },
    body: JSON.stringify({
        title: '测试资源',
        category_id: 1,
        description: '资源简介',
        images: [
            'https://example.com/image1.jpg',
            'https://example.com/image2.jpg'
        ],
        image_layout: 2,
        magnet_link: 'magnet:?xt=urn:btih:xxxxx'
    })
})
    .then(res => res.json())
    .then(data => console.log(data));

// 发表评论
fetch(`${apiUrl}/comments`, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    },
    body: JSON.stringify({
        resource_id: 1,
        content: '评论内容'
    })
})
    .then(res => res.json())
    .then(data => console.log(data));

// 获取用户资料
fetch(`${apiUrl}/user/profile`, {
    headers: {
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    }
})
    .then(res => res.json())
    .then(data => console.log(data));

// 更新头像(外链)
fetch(`${apiUrl}/user/avatar`, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    },
    body: JSON.stringify({
        avatar: 'https://example.com/my-avatar.jpg'
    })
})
    .then(res => res.json())
    .then(data => console.log(data));

// 上传头像
const formData = new FormData();
formData.append('avatar', fileInput.files[0]);
fetch(`${apiUrl}/user/avatar/upload`, {
    method: 'POST',
    headers: {
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    },
    body: formData
})
    .then(res => res.json())
    .then(data => console.log(data));

// 获取消息列表
fetch(`${apiUrl}/messages?page=1&page_size=10`, {
    headers: {
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    }
})
    .then(res => res.json())
    .then(data => console.log(data));

// 获取未读消息数量
fetch(`${apiUrl}/messages/unread-count`, {
    headers: {
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    }
})
    .then(res => res.json())
    .then(data => console.log('未读消息:', data.data.count));

// 获取消息详情(访问时自动标记已读)
fetch(`${apiUrl}/messages/1`, {
    headers: {
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    }
})
    .then(res => res.json())
    .then(data => console.log(data));

// 标记消息已读
fetch(`${apiUrl}/messages/1/read`, {
    method: 'POST',
    headers: {
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    }
})
    .then(res => res.json())
    .then(data => console.log(data));

// 全部标记已读
fetch(`${apiUrl}/messages/read-all`, {
    method: 'POST',
    headers: {
        'X-API-Key': 'ak_xxx',
        'X-API-Secret': 'xxx'
    }
})
    .then(res => res.json())
    .then(data => console.log(data));

Python

import requests

api_url = 'https://bj2.dmbt.site/api/v1'
headers = {
    'Content-Type': 'application/json',
    'X-API-Key': 'ak_xxx',
    'X-API-Secret': 'xxx'
}

# 获取资源列表
response = requests.get(f'{api_url}/resources?page=1&page_size=10')
print(response.json())

# 发布资源(含图片)
payload = {
    'title': '测试资源',
    'category_id': 1,
    'description': '资源简介',
    'images': [
        'https://example.com/image1.jpg',
        'https://example.com/image2.jpg'
    ],
    'image_layout': 2,
    'magnet_link': 'magnet:?xt=urn:btih:xxxxx'
}
response = requests.post(f'{api_url}/publish', headers=headers, json=payload)
print(response.json())

# 发表评论
payload = {
    'resource_id': 1,
    'content': '评论内容'
}
response = requests.post(f'{api_url}/comments', headers=headers, json=payload)
print(response.json())

# 获取用户资料
response = requests.get(f'{api_url}/user/profile', headers=headers)
print(response.json())

# 更新头像(外链)
payload = {
    'avatar': 'https://example.com/my-avatar.jpg'
}
response = requests.post(f'{api_url}/user/avatar', headers=headers, json=payload)
print(response.json())

# 上传头像
files = {'avatar': open('/path/to/avatar.jpg', 'rb')}
response = requests.post(f'{api_url}/user/avatar/upload', 
    headers={'X-API-Key': 'ak_xxx', 'X-API-Secret': 'xxx'}, 
    files=files)
print(response.json())

# 获取消息列表
response = requests.get(f'{api_url}/messages?page=1&page_size=10', headers=headers)
print(response.json())

# 获取未读消息数量
response = requests.get(f'{api_url}/messages/unread-count', headers=headers)
print(f"未读消息: {response.json()['data']['count']}条")

# 获取消息详情(访问时自动标记已读)
response = requests.get(f'{api_url}/messages/1', headers=headers)
print(response.json())

# 标记消息已读
response = requests.post(f'{api_url}/messages/1/read', headers=headers)
print(response.json())

# 全部标记已读
response = requests.post(f'{api_url}/messages/read-all', headers=headers)
print(response.json())

更新日志

v1.2 (2024-04-25)

  • 新增消息中心API接口
  • 新增获取消息列表接口 GET /api/v1/messages
  • 新增获取未读消息数量接口 GET /api/v1/messages/unread-count
  • 新增获取消息详情接口 GET /api/v1/messages/{id}
  • 新增标记消息已读接口 POST /api/v1/messages/{id}/read
  • 新增全部标记已读接口 POST /api/v1/messages/read-all
  • 支持三种消息类型:system(系统消息)、activity(活动消息)、personal(个人消息)

v1.1 (2024-04-22)

  • 新增 images 字段:支持多图片链接数组
  • 新增 image_layout 字段:支持三种图片排列方式(单图/双图/三图)
  • 新增 authorauthor_avatar 字段:资源列表和详情显示发布者信息
  • 新增资源评论接口:获取评论、发表评论、删除评论
  • 新增用户资料接口:获取用户信息
  • 新增头像接口:支持外链头像和上传头像
  • 分类列表新增 resource_count 统计字段
  • 更新发布接口:支持图片和排列方式参数

v1.0 (2024-01-01)

  • 初始版本发布
  • 支持资源列表、详情、分类、搜索接口
  • 支持API Key认证发布资源
  • 支持用户自助管理API密钥