消息推送接口说明¶
1. 请求方式¶
- 协议:HTTP
- 方法:POST
- Content-Type:application/json
2. 请求参数¶
服务端会接收到如下格式的 JSON:
{
"data": {
"id": "消息ID",
"chat_id": "对话ID",
"chat_title": "对话名称",
"content": "消息内容",
"timestamp": "消息时间"
},
"sign": "E9324CF02F95CB072B6DBCEA33E725C3"
}
字段说明¶
字段 | 类型 | 说明 |
---|---|---|
data.id | string | 消息唯一ID |
data.chat_id | string | 对话ID |
data.chat_title | string | 对话名称 |
data.content | string | 消息内容 |
data.timestamp | string | 消息时间戳 |
sign | string | 请求签名(大写MD5) |
3. 签名规则(如果需要)¶
3.1 生成规则¶
-
将
data
中的参数按照key=value
的形式组织,并 按字典序升序排序。 -
示例:
-
在末尾拼接接口密钥:
- 计算
MD5
值,并转为大写:
3.2 示例¶
假设传入参数为:
{
"id": "abc123",
"chat_id": "123",
"chat_title": "测试群",
"content": "你好",
"timestamp": "1724060800"
}
排序后:
拼接密钥(假设key=192006250b4c09247ec02f6a2d):
计算MD5并转大写:
最终推送给服务端时:
{
"data": {
"id": "abc123",
"chat_id": "123",
"chat_title": "测试群",
"content": "你好",
"timestamp": "1724060800"
},
"sign": "E9324CF02F95CB072B6DBCEA33E725C3"
}
4. 服务端校验逻辑¶
服务端接收到请求后,需要做以下几步:
- 解析
data
和sign
。 - 按签名规则重新生成本地
sign
。 -
比较请求中携带的
sign
与本地生成的sign
是否一致。 -
一致 → 验证通过,数据可信。
- 不一致 → 拒绝请求。
5. 响应格式¶
服务端返回示例:
字段 | 类型 | 说明 |
---|---|---|
code | int | 0 表示成功,其它表示失败 |
msg | string | 结果描述 |
服务端示例代码(Java、Python、PHP),都包含以下功能:
- 接收客户端推送的 JSON 请求;
- 从
data
提取参数,按规则生成签名; - 校验
sign
是否正确; - 返回结果。
Java (Spring Boot 示例)¶
import org.springframework.web.bind.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.security.MessageDigest;
import java.util.*;
@RestController
public class PushController {
private static final String KEY = "192006250b4c09247ec02f6a2d";
@PostMapping("/push")
public Map<String, Object> receivePush(@RequestBody Map<String, Object> body) {
Map<String, Object> response = new HashMap<>();
try {
Map<String, Object> data = (Map<String, Object>) body.get("data");
String clientSign = (String) body.get("sign");
// 生成本地签名
String localSign = generateSign(data);
if (localSign.equals(clientSign)) {
response.put("code", 0);
response.put("msg", "success");
} else {
response.put("code", 1);
response.put("msg", "invalid sign");
}
} catch (Exception e) {
response.put("code", -1);
response.put("msg", "error: " + e.getMessage());
}
return response;
}
private String generateSign(Map<String, Object> data) throws Exception {
List<String> keys = new ArrayList<>(data.keySet());
Collections.sort(keys);
StringBuilder sb = new StringBuilder();
for (String key : keys) {
sb.append(key).append("=").append(data.get(key)).append("&");
}
sb.append("key=").append(KEY);
return md5(sb.toString()).toUpperCase();
}
private String md5(String input) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(input.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte b : array) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
}
}
Python (Flask 示例)¶
from flask import Flask, request, jsonify
import hashlib
app = Flask(__name__)
KEY = "192006250b4c09247ec02f6a2d"
def generate_sign(data):
# 排序参数
items = sorted(data.items(), key=lambda x: x[0])
query = "&".join(f"{k}={v}" for k, v in items)
query = f"{query}&key={KEY}"
md5 = hashlib.md5()
md5.update(query.encode("utf-8"))
return md5.hexdigest().upper()
@app.route("/push", methods=["POST"])
def push():
try:
body = request.json
data = body.get("data", {})
client_sign = body.get("sign", "")
local_sign = generate_sign(data)
if local_sign == client_sign:
return jsonify({"code": 0, "msg": "success"})
else:
return jsonify({"code": 1, "msg": "invalid sign"})
except Exception as e:
return jsonify({"code": -1, "msg": f"error: {str(e)}"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
PHP 示例¶
<?php
$key = "192006250b4c09247ec02f6a2d";
function generateSign($data, $key) {
ksort($data); // 按字典序排序
$query = [];
foreach ($data as $k => $v) {
$query[] = $k . "=" . $v;
}
$queryStr = implode("&", $query) . "&key=" . $key;
return strtoupper(md5($queryStr));
}
header("Content-Type: application/json");
// 读取请求体
$body = json_decode(file_get_contents("php://input"), true);
$data = $body["data"] ?? [];
$clientSign = $body["sign"] ?? "";
$localSign = generateSign($data, $key);
if ($localSign === $clientSign) {
echo json_encode(["code" => 0, "msg" => "success"]);
} else {
echo json_encode(["code" => 1, "msg" => "invalid sign"]);
}