消息推送接口說明¶
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"]);
}