const crypto = require('crypto');
const axios = require('axios');
class WecomCrypto {
constructor(token, encodingAesKey) {
this.token = token;
const aesKey = Buffer.from(encodingAesKey + '=', 'base64');
if (aesKey.length !== 32) {
throw new Error('Invalid encodingAesKey');
}
this.key = aesKey;
this.iv = aesKey.slice(0, 16);
}
getSignature(timestamp, nonce, encrypt) {
const sorted = [this.token, timestamp, nonce, encrypt].sort().join('');
const sha1 = crypto.createHash('sha1');
sha1.update(sorted);
return sha1.digest('hex');
}
encrypt(text) {
const randomBytes = crypto.randomBytes(16);
const textBytes = Buffer.from(text);
const textLengthBytes = Buffer.alloc(4);
textLengthBytes.writeUInt32BE(textBytes.length, 0);
const corpId = "ww0da105afdbf73b04"; // Hardcoded from your config
const corpIdBytes = Buffer.from(corpId);
const buffer = Buffer.concat([randomBytes, textLengthBytes, textBytes, corpIdBytes]);
const cipher = crypto.createCipheriv('aes-256-cbc', this.key, this.iv);
cipher.setAutoPadding(false);
// PKCS#7 padding
const blockSize = 32;
const padding = blockSize - (buffer.length % blockSize);
const paddingBytes = Buffer.alloc(padding, padding);
const finalBuffer = Buffer.concat([buffer, paddingBytes]);
const encrypted = Buffer.concat([cipher.update(finalBuffer), cipher.final()]);
return encrypted.toString('base64');
}
}
async function sendTestRequest() {
const token = "NC73HfvnFUgz";
const encodingAesKey = "YsZhCtNwguf7jGFKo1GSaraYekbm28tFWaqzH4vItGV";
const corpId = "ww0da105afdbf73b04";
const user = "test_user_from_script";
const wecomCrypto = new WecomCrypto(token, encodingAesKey);
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = Math.random().toString(36).substring(2);
const plainXml = `<xml><ToUserName><![CDATA[${corpId}]]></ToUserName><FromUserName><![CDATA[${user}]]></FromUserName><CreateTime>${timestamp}</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[Hello from test script]]></Content><MsgId>msg_${nonce}</MsgId><AgentID>1000002</AgentID></xml>`;
const encryptedMsg = wecomCrypto.encrypt(plainXml);
const signature = wecomCrypto.getSignature(timestamp, nonce, encryptedMsg);
const url = `http://127.0.0.1:18789/webhooks/wecom/self_build_app?msg_signature=${signature}×tamp=${timestamp}&nonce=${nonce}`;
const postBody = `<xml><ToUserName><![CDATA[${corpId}]]></ToUserName><Encrypt><![CDATA[${encryptedMsg}]]></Encrypt></xml>`;
console.log("Sending request to:", url);
try {
const response = await axios.post(url, postBody, {
headers: { 'Content-Type': 'application/xml' }
});
console.log("Response Status:", response.status);
console.log("Response Body:", response.data);
} catch (error) {
console.error("Error sending request:", error.message);
if (error.response) {
console.error("Error Response Status:", error.response.status);
console.error("Error Response Body:", error.response.data);
}
}
}
sendTestRequest();