diff --git a/test_webhook.js b/test_webhook.js new file mode 100755 index 0000000..b2c4b5c --- /dev/null +++ b/test_webhook.js @@ -0,0 +1,85 @@ + +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 = `${timestamp}msg_${nonce}1000002`; + + 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 = ``; + + 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(); diff --git a/wecom-api.js b/wecom-api.js index 0dd9508..feab1ca 100755 --- a/wecom-api.js +++ b/wecom-api.js @@ -184,6 +184,10 @@ title: "AI Agent", desc: text, }, + card_action: { + type: "url", + url: "#", + }, }, }), });