
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
express-wx
Advanced tools
Express Router for building Wechat Offical Account Message Server easily, supporting loading request (message) handlers dynamically. 快速构建微信公众号消息后端,支持动态加载请求处理逻辑代码。
Express-WX is an Express Router used for building Wechat (an instant messaging software, especially popular in China) Offical Account Message Server easily, supporting loading request (message) handlers dynamically.
Express-WX是一个动态的微信后端组件。它的主体是一个Express的Router,可以像一般的Router一样注册在app的某一个请求路径下。
按照下述示例,构建Express的app对象,并在其上use我们的WXRouter类的实例,设置好token,部署到服务器上。
之后在微信公众平台的开发——基本配置里填入该请求路径对应的url并填入上面设置的token,即可完成服务器搭建。
Express-WX最独特、最令人称赞一点是采用了动态路由架构。只需要在一个指定的文件夹里面放置您的含有消息处理逻辑的.js文件,这个文件就会在运行时被自动加载并调用其中的消息处理逻辑,完成您的需求。
如果想新增、修改或删除处理逻辑,只需要直接对含有上述处理逻辑的文件进行增删改。所有对文件的增删改会实时的应用到程序当中,完全不需要重启应用的麻烦!
此外,您也不用担心会有性能问题。本组件的动态加载处理函数的原理是基于FileWatcher的,即监听目录内的文件变化、仅当文件产生变化时才会调用相关逻辑动态加载处理函数。因此对于每一次单独的请求,没有任何动态加载的额外开销!
安装:
npm install express-wx --save
您的项目目录结构,应该大致如下图所示:
project
│
├───handlers
│ ├───helloworld.js (helloworld.ts)
│ └───time.js (time.ts)
│
├───app.js
│
└───package.json
注:动态加载不会识别ts文件,因此如果您用Typescript语言,您需要自行用tsc等工具把ts编译为js。
app.js示例:
var Express = require("express")
var Express_WX = require("express-wx")
// 构造Express的实例
var app = Express()
// 构造一个WXRouter的实例(使用express-wx包的WXRouter(config)函数,需要传入config)
var wxRouter = Express_WX.WXRouter({
// config中只有appInfo是必填的,appInfo只有token字段是必填的。
// 如果对更多的config配置感兴趣,请阅读WXRouterConfig接口上的注释(见bld/config.d.ts文件)
appInfo: {
token: "someToken" // 您需要保证在微信公众平台设置的Token和这里设置的Token一致
},
debugToken: "test"
})
// 把wxRouter对象注册到app上
app.use("/", wxRouter)
app.listen(8080) // 监听8080端口
接下来,您就可以撰写自己的请求处理逻辑的.js文件,并把它们放进handlers目录中。为您提供两个handler的示例供参考:
handlers/helloworld.ts示例:(注意需要先编译为js才可使用)
import {TextWXMessage, WXHandler} from "express-wx";
// 向WXHandler(fn)函数传入一个参数,参数的形式即为标准的express的(req, res, next)形式。
// 事实上您不使用WXHandler函数,而是直接提供一个普通函数也是可以的;但特别是当您使用TypeScript时还是强烈建议使用WXHandler,
// 因为这样可以获得更充分的类型提示。
export default WXHandler((req, res, next) => {
// req是WXRequest类型的对象,它除了具有一般的express请求对象的接口以外,还额外有wxRouter属性(即当前WXRouter的实例,
// 您可以从中获得公众号信息),
// 和wx属性(类型为WXMessage,您可以从中获得用户发来的消息。)
// WXMessage有很多种可能的类型、比如文本消息TextMessage类型;其上的text方法即是用户发来的消息文本。
// 下面的语句把收到的消息打印出来。
console.log("收到消息:" + (req.wx as TextWXMessage).text)
//使用res.wx(WXMessage)方法可以回复消息给用户
// 特殊的为了方便,回复文字内容时可以直接使用更简便的res.wxText(string)。
// 下面的语句向用户回复消息"Hello World"。
res.wxText("Hello World")
})
handlers/time.ts示例:(注意需要先编译为js才可使用)
import {TextWXMessage, WXHandler} from "express-wx";
import * as moment from "moment"
// 这个处理逻辑用于在用户发送的文本带有“时间”两字时,向用户回复当前的时间。
var handler = WXHandler((req, res, next) => {
if (req.wx instanceof TextWXMessage && req.wx.text.indexOf("时间") !== -1) {
// 仅当收到的消息是文本消息且文本内容中含有“时间”二字时
// 返回当前日期和时间的格式化字符串,使用moment库
res.wxText(moment(new Date()).format('YYYY-MM-DD HH:mm:ss'))
}
else next() // 否则,则本函数不处理此消息,调用next函数交给后续的人处理。。
})
// 设置一下优先级
// 因为我们有另一个回复一切请求的hellowrorld.js,如果helloworld比这个函数先被调用就无法实现回复当前时间的功能了。
// 一个handler在没有特殊设置的情况下默认优先级为0,因此我们要把上面这个handler的优先级设置为一个大于0的数
handler.priority = 10
export default handler
虽然本程序已经对微信的API进行了尽量简洁、对人友好的封装,但仍然建议您可以阅读一下微信公众平台的官方文档,这样有利于更好的使用本软件实现您的功能。
通过在WXRouter的构造函数传入config,可以实现更多的功能。
请看这里查看更多的配置项参考。
import {WXRouter, WXAPIUserProvider} from "express-wx";
app.use(WXRouter({
appInfo: {/*...*/},
userProvider: WXAPIUserProvider()
}))
import {WXRouter, FileOrConsoleLogger, MongoDBLogger} from "express-wx";
app.use(WXRouter({
appInfo: {/*...*/},
logger: new FileOrConsoleLogger("logs/log.txt"), // 不传参则为记录到控制台,传参则为记录到指定路径的文件
messageLogger: new MongoDBLogger("mongodb://localhost:27017/testApp", "testApp") // 记录收到的消息的内容到指定MongoDB的"testApp"collection
}))
import {WXRouter, TextWXMessage} from "express-wx";
let wxRouter = WXRouter({
appInfo: {/*...*/},
})
wxRouter.sendCustomMessage("openId", new TextWXMessage("Hello World")) // 发送客服消息
wxRouter.sendCustomTypingStatus("openId", true) // 下发输入状态
console.log(await wxRouter.getAllTemplates()) // 获取所有的添加到公众号的模版信息
await wxRouter.sendTemplateMessage("openId", "template_id", {xxx: "Hello", yyy: {value: "World", "color": "#FF0000"}}, {url: "http://xxx"}) // 发送模版消息
import {WXRouter, TextWXMessage} from "express-wx";
let wxRouter = WXRouter({
appInfo: {/*...*/},
enableJSAPI: true
})
wxRouter.signJSAPI({url: "http://xxx"}) // 内含signature、appid、timestamp、noncestr等字段,直接发回给前端用作wx.config的参数即可。
欢迎提出Issue反馈问题、建议、意见,欢迎发起Pull Request完善本程序。
由于项目尚处于初期阶段,对现有代码的测试尚不完善,因此暂不强制要求您的实现新特性的PR应当编写对新特性的测试。(当然,现有的数量有限的基础测试还是需要通过的,这个会由CI自动完成)
It is very welcomed to raise Issues and/or make Pull Requests. Though English document is not supplied at this time, please feel free to use English in Issues and Pull Requests.
特别感谢Rika的帮助和合作。
本项目的代码中使用了很多她的代码,包括:
以下是计划在未来逐步实现的功能(按顺序)。欢迎提交Pull Request!
考虑到即使是个人开发者也已经能十分容易的实现https的现状,微信自带的消息加解密功能暂无支持计划。
FAQs
Express Router for building Wechat Offical Account Message Server easily, supporting loading request (message) handlers dynamically. 快速构建微信公众号消息后端,支持动态加载请求处理逻辑代码。
The npm package express-wx receives a total of 1 weekly downloads. As such, express-wx popularity was classified as not popular.
We found that express-wx demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.