📖 概述
旧聊小程序商店提供开放的 RESTful API,允许第三方 App 接入小程序的上传、浏览、下载功能。
所有接口均基于 HTTP,返回 application/json 格式数据(下载接口除外)。
🌐 基础信息
API 地址: https://app.524090.xyz/api.php
请求格式: multipart/form-data(上传) / query string(其他)
响应格式: JSON(下载接口返回文件流)
编码: UTF-8
CORS: 已启用 (*)
💡 提示: 将 https://app.524090.xyz/api.php 中的域名替换为你实际部署的地址。
📤 通用响应格式
所有 JSON 接口遵循统一的响应结构:
{
"success": true, // 是否成功 (boolean)
"error": "错误信息", // 仅失败时存在 (string)
"...": "其他业务数据" // 成功时的业务数据
}
🔧 接口列表
| 接口 |
方法 |
说明 |
公开 |
| action=list |
GET |
获取所有小程序列表 |
✅ |
| action=get |
GET |
获取单个小程序详情 |
✅ |
| action=upload |
POST |
上传小程序包 |
✅ |
| action=download |
GET |
下载小程序 CIP 文件 |
✅ |
| action=delete |
POST |
删除小程序 |
❌ 仅后台 |
1. 获取小程序列表
GET https://app.524090.xyz/api.php?action=list
请求参数
无
响应示例
{
"success": true,
"apps": [
{
"id": "hello_world",
"name": "Hello World",
"description": "第一个小程序",
"version": 1,
"icon_url": "cips/hello_world/assets/icon.png",
"enabled": true,
"uploaded_at": "2026-07-29 12:00:00"
}
]
}
字段说明
| 字段 | 类型 | 说明 |
| id | string | 应用唯一标识 (小写字母/数字/下划线/短横线, 1-64字符) |
| name | string | 应用名称 |
| description | string | 应用描述 |
| version | int | 版本号 |
| icon_url | string|null | 图标地址 (相对路径或完整 URL) |
| enabled | boolean | 是否启用 |
| uploaded_at | string | 上传时间 |
调用示例 (JavaScript)
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://app.524090.xyz/api.php?action=list');
xhr.onload = function() {
var res = JSON.parse(xhr.responseText);
if (res.success) {
console.log(res.apps); // 小程序数组
}
};
xhr.send();
调用示例 (Java)
URL url = new URL("https://app.524090.xyz/api.php?action=list");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
InputStream is = conn.getInputStream();
// 使用 JSON 库解析响应
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
System.out.println(sb.toString());
2. 获取小程序详情
GET https://app.524090.xyz/api.php?action=get&id={应用ID}
请求参数
| 参数 | 类型 | 必填 | 说明 |
| action | string | 必填 | 固定值 get |
| id | string | 必填 | 应用 ID |
响应示例
{
"success": true,
"manifest": {
"id": "hello_world",
"name": "Hello World",
"description": "第一个小程序",
"version": 1,
"icon_url": "assets/icon.png",
"enabled": true,
"order": 0,
"permissions": ["network"],
"allowed_hosts": ["example.com"]
},
"lua": "-- main.lua source code",
"assets": {
"assets/icon.png": "cips/hello_world/assets/icon.png",
"assets/screenshot.png": "cips/hello_world/assets/screenshot.png"
}
}
字段说明
| 字段 | 类型 | 说明 |
| manifest | object | 应用元数据 (即 manifest.json 内容) |
| lua | string | main.lua 源代码 (无则空字符串) |
| assets | object | 资源文件映射: {包内路径: 访问URL} |
3. 上传小程序
POST https://app.524090.xyz/api.php?action=upload
请求参数
| 参数 | 类型 | 必填 | 说明 |
| action | string | 必填 | 固定值 upload |
| file | file | 必填 | CIP/ZIP 文件 (multipart 上传) |
上传限制
| 限制项 | 值 |
| 文件格式 | .cip / .zip |
| 文件大小 | 最大 10 MB |
| 解压后大小 | 最大 40 MB |
| 文件数量 | 最多 128 个 |
| 资源扩展名 | png, jpg, jpeg, webp, gif, json, txt, md |
成功响应
{
"success": true,
"message": "小程序 Hello World 上传成功",
"id": "hello_world"
}
失败响应示例
{
"success": false,
"error": "压缩包中未找到 manifest.json"
}
调用示例 (JavaScript)
var formData = new FormData();
formData.append('file', fileInput.files[0]);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://app.524090.xyz/api.php?action=upload');
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var pct = Math.round(e.loaded / e.total * 100);
console.log('上传进度: ' + pct + '%');
}
};
xhr.onload = function() {
var res = JSON.parse(xhr.responseText);
if (res.success) {
console.log('上传成功, ID: ' + res.id);
} else {
console.log('上传失败: ' + res.error);
}
};
xhr.send(formData);
调用示例 (Java - Android)
// 使用 OkHttp 库
File file = new File("/sdcard/app.cip");
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(),
RequestBody.create(file, MediaType.parse("application/zip")))
.build();
Request request = new Request.Builder()
.url("https://app.524090.xyz/api.php?action=upload")
.post(body)
.build();
Response response = client.newCall(request).execute();
String json = response.body().string();
// 解析 JSON 获取结果
4. 下载小程序
GET https://app.524090.xyz/api.php?action=download&id={应用ID}
请求参数
| 参数 | 类型 | 必填 | 说明 |
| action | string | 必填 | 固定值 download |
| id | string | 必填 | 应用 ID |
响应
成功时返回文件流(非 JSON),HTTP 头如下:
Content-Type: application/zip
Content-Disposition: attachment; filename="hello_world.cip"
Content-Length: 102400
失败时返回 JSON:
{"success": false, "error": "小程序不存在"}
调用示例 (Java - Android 下载并保存)
URL url = new URL("https://app.524090.xyz/api.php?action=download&id=hello_world");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
if (conn.getResponseCode() == 200) {
InputStream is = conn.getInputStream();
File outputFile = new File("/sdcard/download/hello_world.cip");
FileOutputStream fos = new FileOutputStream(outputFile);
byte[] buffer = new byte[4096];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
is.close();
System.out.println("下载完成: " + outputFile.getAbsolutePath());
} else {
// 读取错误 JSON
InputStream es = conn.getErrorStream();
// 解析错误信息
}
📝 manifest.json 规范
每个 CIP/ZIP 包必须在根目录包含 manifest.json 文件,格式如下:
{
"id": "hello_world", // 必填, 唯一标识, [a-z0-9_-]{1,64}
"name": "Hello World", // 必填, 应用名称, 最多40字
"description": "一个示例小程序", // 选填, 描述, 最多200字
"version": 1, // 选填, 版本号, 默认1
"icon_url": "assets/icon.png", // 选填, 图标路径(包内)或完整URL
"enabled": true, // 选填, 是否启用, 默认true
"order": 0, // 选填, 排序值, 越小越靠前
"permissions": [ // 选填, 权限列表
"network",
"storage"
],
"allowed_hosts": [ // 选填, 允许访问的主机
"api.example.com"
]
}
字段说明
| 字段 | 类型 | 必填 | 说明 |
| id | string | 必填 | 唯一标识,仅小写字母/数字/下划线/短横线,1-64字符 |
| name | string | 必填 | 应用名称 |
| description | string | 选填 | 应用描述 |
| version | int | 选填 | 版本号,默认 1 |
| icon_url | string | 选填 | 图标路径。包内路径以 assets/ 开头,或完整 http(s) URL |
| enabled | boolean | 选填 | 是否启用,默认 true |
| order | int | 选填 | 排序值,越小越靠前,默认 0 |
| permissions | string[] | 选填 | 权限列表 |
| allowed_hosts | string[] | 选填 | 允许访问的主机域名列表 |
📦 CIP 包结构
my_app.cip (或 .zip)
├── manifest.json // 必填, 应用元数据
├── main.lua // 选填, 小程序界面逻辑
└── assets/ // 选填, 资源目录
├── icon.png // 图标
├── screenshot.png // 截图
└── ...
⚠ 注意:
1. 压缩包不能包含绝对路径 (以 / 开头)
2. 不能包含 .. 路径穿越
3. 不能包含反斜杠路径
4. 资源文件仅支持: png, jpg, jpeg, webp, gif, json, txt, md
💡 main.lua 界面 DSL
main.lua 使用类 Lua 语法描述小程序界面,支持以下控件:
| 控件 | 说明 |
| ui.text | 文本标签,支持 text/size/color/center/margin |
| ui.button | 按钮,支持 text/id/margin |
| ui.image | 图片,支持 url/height/id/margin |
| ui.input | 输入框,支持 hint/text/input_type/max_length/single_line |
| ui.checkbox | 复选框,支持 text/checked/id |
| ui.spacer | 间距,支持 height |
| ui.list | 列表容器 |
示例
-- main.lua 示例
title = "我的小程序"
ui.text {
text = "欢迎来到旧聊!",
size = 18,
color = "#A4C639",
center = true
}
ui.button {
id = "btn_ok",
text = "确定"
}
ui.image {
id = "img_logo",
url = "assets/icon.png",
height = 64
}
ui.input {
id = "input_name",
hint = "请输入名称",
single_line = true,
max_length = 20
}
❌ 常见错误
| 错误信息 | 原因 | 解决方法 |
| 未知操作 | action 参数缺失或错误 | 检查 action 参数值 |
| 请使用 POST | 上传/删除使用了 GET | 改用 POST 方法 |
| 未收到文件 | 上传时缺少 file 字段 | 检查 multipart 表单 |
| 只支持 .cip 或 .zip | 文件扩展名不正确 | 使用 .cip 或 .zip 格式 |
| 文件超过 XX MB 限制 | 文件太大 | 压缩文件后再上传 |
| 无法打开压缩包 | ZIP 文件损坏 | 重新打包 |
| 压缩包中未找到 manifest.json | 缺少清单文件 | 在包根目录添加 manifest.json |
| manifest.json 格式错误或缺少必需字段 | JSON 格式错误或缺 id/name | 检查 JSON 格式和字段 |
| 应用 ID 格式非法 | ID 不符合 [a-z0-9_-]{1,64} | 使用合法的 ID |
| 压缩包包含非法路径 | 含 ../ 或 \ 或绝对路径 | 使用相对路径 |
| 文件数量超过 128 个限制 | 包内文件太多 | 精简文件 |
| 解压后大小超过 40 MB 限制 | 解压后太大 | 压缩资源文件 |
| 非法 ID | ID 参数缺失或格式错误 | 传入合法的 ID |
| 小程序不存在 | ID 不存在 | 先调用 list 获取可用 ID |
📄 版本历史
| 版本 | 日期 | 变更 |
| v1.0 | 2026-07-29 | 初始版本,支持 list/get/upload/download 接口 |