yszl-mcp
Version:
Scenic Area Tourist Flow Query Server with official MCP SDK
111 lines (96 loc) • 3 kB
JavaScript
/**
* 实时游客流量查询工具
*/
import crypto from 'crypto';
import axios from 'axios';
export class TouristFlowTool {
constructor() {
this.apiUrl = process.env.API_URL;
this.account = process.env.ACCOUNT;
this.appSecret = process.env.APP_SECRET;
}
/**
* 生成API请求签名
* @param {Object} params - 请求参数
* @returns {string} - MD5签名
*/
generateSignature(params) {
// 按照参数名称排序
const sortedParams = Object.keys(params).sort().reduce(
(result, key) => {
result[key] = params[key];
return result;
},
{}
);
// 构建签名字符串:按顺序拼接参数值,用分号分隔
let signStr = '';
for (const key in sortedParams) {
signStr += sortedParams[key] + ';';
}
signStr += this.appSecret;
console.log('签名字符串:', signStr);
// 返回MD5哈希
return crypto.createHash('md5').update(signStr).digest('hex').toUpperCase();
}
/**
* 执行工具查询实时游客流量
* @param {Object} params - 查询参数
* @param {string} params.scenicId - 景区ID
* @returns {Promise<Object>} - 实时流量数据
*/
async execute(params) {
try {
// 验证必填参数
if (!params.scenicId) {
throw new Error('缺少必填参数: scenicId');
}
// 准备请求参数
const requestParams = {
account: this.account,
ts: Date.now().toString(),
code: params.scenicId
};
// 生成签名
const sign = this.generateSignature(requestParams);
// 构建请求数据
const requestData = {
...requestParams,
sign
};
// 发送API请求
const response = await axios.post(`${this.apiUrl}/v3/realtime/tl/tourist`, requestData);
console.log('API响应:', JSON.stringify({
status: response.status,
data: response.data,
request: {
url: response.config.url,
method: response.config.method,
data: JSON.stringify(response.config.data)
}
}, null, 2));
// 检查API响应
if (response.data.code !== 200) {
throw new Error(`API错误: ${response.data.message || '未知错误'} (code: ${response.data.code})`);
}
// 返回实时流量数据
return response.data.data;
} catch (error) {
const errorDetails = {
message: error.message,
response: error.response?.data,
status: error.response?.status,
statusText: error.response?.statusText,
params,
config: {
url: error.config?.url,
method: error.config?.method,
data: error.config?.data ? JSON.stringify(error.config.data) : undefined
}
};
console.error('实时游客流量查询出错:', JSON.stringify(errorDetails, null, 2));
throw new Error(`API调用失败: ${error.message}`);
}
}
}
export default TouristFlowTool;