npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

wxmsgcrypt

v1.0.6

Published

企业微信加解密库 nodejs

Downloads

13

Readme

安装

yarn add wxmsgcryptnpm i wxmsgcrypt

用法(亲测可用)

参考下述代码,打开将本地 3000端口,代理出去,即可 测试

参考示例

// 以下代码在 example 中
const express = require('express');
const server = express();
const bodyParser = require("body-parser");
const port = 3000;
server.use(bodyParser.urlencoded({
    extended: true
}));

// 假设你的 token 和 key 为如下的值
const config = {
    corpId: '*******', // 你的企业ID, 公众号不用,但是解密的思路一样的稍微改下代码,参见 /WXMsgCrypt/pkcs7****.js 第 69 行.
    token: '***********', // token
    aes_key: '**********Ahwyr3' // key值
}

// 引入加解密库
const WXBizMsgCrypt = require('./../index');

// 实例化加解密库

const wxBizMsgCrypt = new WXBizMsgCrypt(config.token, config.aes_key, config.corpId); // 会自动解构

server.get('/', (req, res) => {
    res.send('Hello World!')
})

// GET 请求主要用来验证 url 的,这里只演示企业微信的用法,微信公众号只需要将 明文返回即可,如果需要验证则逻辑和如下相同
server.get('/server', (req, res) => {
    /** 拿到 query 的值并解构如下
     *  msg_signature: '4b1999109ff2a628509b7edcaa460a07bb0f8675',
        timestamp: '1593083194',
        nonce: '1593678893',
        echostr: '7t5l6jS0mub7H/H+SX3sYTmHp8ONrNB9uVKcrVW38XYUIH9YovC0/AILhmtzB9KZoB3whKAM9Iw0FAz5RGU1nw=='
     */
    const { msg_signature, timestamp, nonce, echostr } = req.query;

    const replyEchostrMsg = wxBizMsgCrypt.VerifyURL(msg_signature, timestamp, nonce, echostr); // 会将密文 echostr 解密出来,在返回企业欸新即可

    res.send(replyEchostrMsg)
})

// 验证URL成功后,企业微信端会以POST的形式,将加密消息发送给我们的服务端
server.post('/server', (req, res) => {

    let data = '';//添加接收变量
    req.setEncoding('utf8');

    req.on('data', function (chunk) { //接收 数据包
        data += chunk;
    });
    req.on('end', function () { // 接受完以后
        // 解密的时候,同样需要拿到 以下 query 参数,不过此时没有了echostr
        const { msg_signature, timestamp, nonce } = req.query;
        // 将接收完的 data 数据包,进行解密
        let recivedMsg = wxBizMsgCrypt.DecryptMsg(msg_signature, timestamp, nonce, data);
        /**
         * 拿到的对象如下,为了保证通用性,并没有对原始格式进行改变,只是转为对象形式
         * 
         * {
            ToUserName: 'a****0', // 成员UserID
            FromUserName: '******', // CorpID
            CreateTime: 1593084439, // 消息创建时间(整型)
            MsgType: 'text', // 消息类型,很明显这个是文本的形式
            Content: '测试一下', // 这个就是我们回复的内容
            MsgId: 241693613, // 消息ID 可以排重
            AgentID: 1***1*5 // 是哪个应用发来的
            }
         */
        // console.log(recivedMsg);
        // res.send(data); // 可以将其原封不动返回去,因为总得返回点什么

        // 假设不论企业微信发个我们什么,我们都回复一样的,仅仅为了测试而已
        // 构建消息体
        const testXmlData = MessageHandle.textXml({
            toUser: '*****', // 员工号?或者账号就是 userid
            fromUser: config.corpId, // 此处固定为 企业CorpID
            content: '测试一下' // 我们要发送的内容
        })
        // 加密消息体
        let sendReplyMsg = wxBizMsgCrypt.EncryptMsg(testXmlData);
        
        res.send(sendReplyMsg);
    });
})

server.listen(port, () => console.log(`Example app listening on port ${port}!`))

/**
 * @description: 为了演示,我们构建一个明文的文本消息结构
 * @param {type} 
 * @return: 
 */
class MessageHandle {
    static textXml({ toUser, fromUser, content }) {
        const sTimeStamp = parseInt(new Date().valueOf() / 1000);
        return {
            sReplyMsg: `<xml><ToUserName><![CDATA[${toUser}]]></ToUserName><FromUserName><![CDATA[${fromUser}]]></FromUserName><CreateTime>${sTimeStamp}</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[${content}]]></Content></xml>`,
            sTimeStamp
        }
    }
}

参考链接

本插件参考的大量的示例,并非原创,算是搬运工吧,截至 2020年6月25日 一直用着不错,于是单独抽离形成一个插件. 大概有以下的文章,太多了记不清了: