wechat_query_status
Check WeChat Official Account article publishing status and view statistics using message ID and account credentials.
Instructions
查询文章发布状态和统计数据
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| msgId | Yes | 消息ID | |
| appId | Yes | 微信公众号AppID | |
| appSecret | Yes | 微信公众号AppSecret |
Implementation Reference
- src/server.js:74-108 (registration)Registration of the wechat_query_status tool, including input schema definition and thin wrapper handler that delegates to WeChatStatus.queryserver.registerTool( "wechat_query_status", { description: "查询文章发布状态和统计数据", inputSchema: { msgId: z.string().describe("消息ID"), appId: z.string().describe("微信公众号AppID"), appSecret: z.string().describe("微信公众号AppSecret") } }, async (params) => { const { msgId, appId, appSecret } = params; logger.info(`Querying status for message: ${msgId}`); try { // 调用实际的查询逻辑 const result = await WeChatStatus.query({ msgId, appId, appSecret }); return result; } catch (error) { logger.error(`查询失败: ${error.message}`); return { content: [{ type: "text", text: `❌ 查询失败: ${error.message}` }], isError: true }; } } );
- src/tools/wechat-status.js:15-71 (handler)Core handler implementation for wechat_query_status: performs parameter validation, initializes WeChatAPI, queries publish status, formats detailed response with stats, handles errors.static async query(params) { const startTime = Date.now(); try { logger.info('开始查询状态', { msgId: params.msgId }); // 1. 参数验证 const validation = validateStatusParams(params); if (!validation.valid) { throw new Error(`参数验证失败: ${validation.errors.join(', ')}`); } const { msgId, appId, appSecret } = params; // 2. 初始化微信API logger.debug('初始化微信API'); const wechatAPI = new WeChatAPI(appId, appSecret); // 3. 查询发布状态 logger.debug('查询发布状态', { msgId }); const statusData = await wechatAPI.getPublishStatus(msgId); const executionTime = Date.now() - startTime; logger.info('状态查询成功', { msgId, status: statusData.publish_status, executionTime: `${executionTime}ms` }); // 4. 构建成功响应 const successMessage = this.buildStatusMessage(statusData, executionTime, msgId); return { content: [{ type: "text", text: successMessage }] }; } catch (error) { const executionTime = Date.now() - startTime; logger.error('状态查询失败', { msgId: params.msgId, error: error.message, executionTime: `${executionTime}ms`, stack: error.stack }); return { content: [{ type: "text", text: this.buildErrorMessage(error) }], isError: true }; } }
- src/services/WeChatAPI.js:392-479 (helper)Low-level helper that performs the actual HTTP request to WeChat API endpoint /cgi-bin/freepublish/get to retrieve publish status and article stats.async getPublishStatus(msgId) { logger.info('开始查询发布状态', { msgId, appId: this.appId }); // 检查是否为明确的测试模式(只有以test_开头的msgId才使用模拟数据) if (msgId && msgId.toString().startsWith('test_')) { logger.info('测试模式:返回模拟状态数据', { msgId }); return { errcode: 0, errmsg: 'ok', publish_status: 1, // 发布成功 article_detail: { count: 1, item: [{ article_id: msgId, title: '测试文章标题', author: '测试作者', digest: '这是一篇测试文章', content: '', content_source_url: '', url: `https://mp.weixin.qq.com/s/test_${msgId}`, publish_time: Math.floor(Date.now() / 1000), stat_info: { read_num: 0, // 测试模式不显示虚假阅读量 like_num: 0, comment_num: 0, share_num: 0 } }] } }; } // 对于真实的msgId,始终调用真实的微信API const accessToken = await this.getAccessToken(); logger.debug('获取到access_token,准备查询状态', { tokenLength: accessToken.length }); try { logger.debug('调用微信API查询发布状态', { msgId, api: 'freepublish/get' }); const response = await axios.post( `https://api.weixin.qq.com/cgi-bin/freepublish/get?access_token=${accessToken}`, { publish_id: msgId }, { timeout: 15000 } ); logger.debug('微信API响应', { errcode: response.data.errcode, errmsg: response.data.errmsg, hasArticleDetail: !!response.data.article_detail }); if (response.data.errcode === 0) { logger.info('状态查询成功', { msgId, status: response.data.publish_status, articleCount: response.data.article_detail?.count || 0 }); return response.data; } else { // 如果是文章不存在或权限问题,返回更友好的错误信息 if (response.data.errcode === 40007) { throw new Error(`文章不存在或已被删除 (错误码: ${response.data.errcode})`); } else if (response.data.errcode === 40001) { throw new Error(`access_token无效,请检查AppID和AppSecret (错误码: ${response.data.errcode})`); } else { throw new Error(`查询发布状态失败: ${response.data.errmsg} (错误码: ${response.data.errcode})`); } } } catch (error) { logger.error('状态查询失败', { msgId, error: error.message, isAxiosError: !!error.response }); if (error.response) { const errorData = error.response.data; throw new Error(`微信API调用失败: ${errorData.errmsg || error.message} (HTTP状态: ${error.response.status})`); } else if (error.code === 'ECONNABORTED') { throw new Error('请求超时,请检查网络连接后重试'); } else { throw new Error(`网络请求失败: ${error.message}`); } } }
- src/utils/validator.js:96-135 (schema)Runtime input schema validation for wechat_query_status parameters: checks required fields, formats, lengths for msgId, appId, appSecret.function validateStatusParams(params) { const errors = []; // 必需参数检查 if (!params.msgId || typeof params.msgId !== 'string' || params.msgId.trim() === '') { errors.push('msgId参数是必需的,且不能为空字符串'); } if (!params.appId || typeof params.appId !== 'string' || params.appId.trim() === '') { errors.push('appId参数是必需的,且不能为空字符串'); } if (!params.appSecret || typeof params.appSecret !== 'string' || params.appSecret.trim() === '') { errors.push('appSecret参数是必需的,且不能为空字符串'); } // 格式验证 if (params.msgId && !isValidMsgId(params.msgId)) { errors.push('msgId格式不正确,应该是数字字符串'); } // AppID格式验证 if (params.appId && !params.appId.startsWith('wx')) { errors.push('AppID格式错误,应该以"wx"开头'); } if (params.appId && params.appId.length !== 18) { errors.push('AppID长度应该为18个字符'); } // AppSecret格式验证 if (params.appSecret && params.appSecret.length !== 32) { errors.push('AppSecret长度应该为32个字符'); } return { valid: errors.length === 0, errors }; }
- src/server.js:77-82 (schema)Zod-based input schema definition for the tool registration, specifying required string parameters.description: "查询文章发布状态和统计数据", inputSchema: { msgId: z.string().describe("消息ID"), appId: z.string().describe("微信公众号AppID"), appSecret: z.string().describe("微信公众号AppSecret") }