wechat.js•6.03 kB
import axios from 'axios';
export class WeChatService {
constructor(config) {
this.webhookUrl = config.webhookUrl;
this.corpId = config.corpId;
this.corpSecret = config.corpSecret;
this.agentId = config.agentId;
this.accessToken = null;
this.tokenExpireTime = null;
}
/**
* 发送消息到企业微信
* @param {string} message - 消息内容
* @param {string} messageType - 消息类型:'text' 或 'markdown'
* @returns {Promise<Object>} 发送结果
*/
async sendMessage(message, messageType = 'text') {
try {
// 优先使用Webhook方式(更简单)
if (this.webhookUrl) {
return await this.sendWebhookMessage(message, messageType);
}
// 使用企业微信API方式
if (this.corpId && this.corpSecret && this.agentId) {
return await this.sendApiMessage(message, messageType);
}
throw new Error('未配置企业微信发送方式,请设置WECHAT_WEBHOOK_URL或完整的企业微信API配置');
} catch (error) {
console.error('发送企业微信消息失败:', error.message);
return {
success: false,
message: `发送失败: ${error.message}`,
};
}
}
/**
* 通过Webhook发送消息(推荐方式)
*/
async sendWebhookMessage(message, messageType) {
try {
let payload;
if (messageType === 'markdown') {
payload = {
msgtype: 'markdown',
markdown: {
content: message,
},
};
} else {
payload = {
msgtype: 'text',
text: {
content: message,
},
};
}
const response = await axios.post(this.webhookUrl, payload, {
headers: {
'Content-Type': 'application/json',
},
});
if (response.data.errcode === 0) {
return {
success: true,
message: '消息发送成功',
data: response.data,
};
} else {
throw new Error(`企业微信返回错误: ${response.data.errmsg}`);
}
} catch (error) {
throw new Error(`Webhook发送失败: ${error.message}`);
}
}
/**
* 通过企业微信API发送消息
*/
async sendApiMessage(message, messageType) {
try {
// 获取访问令牌
const token = await this.getAccessToken();
let payload;
if (messageType === 'markdown') {
payload = {
touser: '@all', // 发送给所有人,也可以指定具体用户
msgtype: 'markdown',
agentid: this.agentId,
markdown: {
content: message,
},
};
} else {
payload = {
touser: '@all',
msgtype: 'text',
agentid: this.agentId,
text: {
content: message,
},
};
}
const response = await axios.post(
`https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${token}`,
payload,
{
headers: {
'Content-Type': 'application/json',
},
}
);
if (response.data.errcode === 0) {
return {
success: true,
message: '消息发送成功',
data: response.data,
};
} else {
throw new Error(`企业微信API返回错误: ${response.data.errmsg}`);
}
} catch (error) {
throw new Error(`API发送失败: ${error.message}`);
}
}
/**
* 获取企业微信访问令牌
*/
async getAccessToken() {
try {
// 检查token是否还有效
if (this.accessToken && this.tokenExpireTime && Date.now() < this.tokenExpireTime) {
return this.accessToken;
}
const response = await axios.get(
'https://qyapi.weixin.qq.com/cgi-bin/gettoken',
{
params: {
corpid: this.corpId,
corpsecret: this.corpSecret,
},
}
);
if (response.data.errcode === 0) {
this.accessToken = response.data.access_token;
// 提前5分钟过期
this.tokenExpireTime = Date.now() + (response.data.expires_in - 300) * 1000;
return this.accessToken;
} else {
throw new Error(`获取访问令牌失败: ${response.data.errmsg}`);
}
} catch (error) {
throw new Error(`获取访问令牌失败: ${error.message}`);
}
}
/**
* 测试企业微信连接
*/
async testConnection() {
try {
if (this.webhookUrl) {
// 测试Webhook
const result = await this.sendWebhookMessage('测试消息 - MCP工具连接正常', 'text');
return result;
} else if (this.corpId && this.corpSecret && this.agentId) {
// 测试API
const token = await this.getAccessToken();
return {
success: true,
message: '企业微信API连接成功',
token: token.substring(0, 10) + '...',
};
} else {
return {
success: false,
message: '未配置企业微信参数',
};
}
} catch (error) {
return {
success: false,
message: `连接测试失败: ${error.message}`,
};
}
}
/**
* 发送富文本消息(支持更多格式)
*/
async sendRichMessage(title, content, items = []) {
try {
let message = `# ${title}\n\n${content}\n\n`;
if (items.length > 0) {
items.forEach((item, index) => {
message += `${index + 1}. **${item.title}**\n`;
if (item.description) {
message += ` ${item.description}\n`;
}
if (item.url) {
message += ` [查看详情](${item.url})\n`;
}
message += '\n';
});
}
return await this.sendMessage(message, 'markdown');
} catch (error) {
return {
success: false,
message: `发送富文本消息失败: ${error.message}`,
};
}
}
}