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

wx

v0.0.36

Published

W(ei)X(in) -- (minimalist) WeChat Middleware for Express.js

Downloads

169

Readme

WeiXin

(minimalist) WeChat Middleware for Express.js

微信应用框架

wx是极简设计的微信(公共平台)应用参考级框架,而并非微信接口在node.js下的幂等映射。

安装

wx要求在线的**Redis**实例。默认情况下,wx尝试连接本地实例,您可以指定Redis连接。利用Rediswx具备:

  • 集群模式下自动管理微信令牌;
  • 浏览器端捕捉二维码扫描;
  • 等功能。

===

  1. npm install wx

  2. ☞ 登录**微信公众平台**
    ☞ 高级功能
    ☞ 开发模式,获取token

    *配置服务器时仅token必须。

  3. 服务器端

 app = express()    
 wx  = new require 'wx'
   token            : 'xxx-xx-xx'
   app_id           : 'xx-xxx'
   app_secret       : 'xxxxxxxxxxxx'
   encoding_aes_key : 'xxxxxx'
 app.use '/wx', wx
  1. 启动应用程序后,修改微信开发模式中服务器配置为:http://server.address/wx,且有与程序相一致的token

接受文本消息

通过wx.text注册文本消息处理流程:

探索几种根据用户发送文本,通过res.text被动回复的方式:

匹配正则表达式

wx.text /(.+)天气/, (req, res) ->
  res.text "#{req.params[1]},晴[太阳]"

接收文本常量

wx.text '你好', (req, res) ->
  res.text "#{req.user.nickname},么么哒"

接收任意文本

wx.text (req, res) ->
  res.text "#{req.content},喵呜~"

*wx按注册顺序匹配消息,最后注册接收任意文本句柄。

接受其他消息

图片

下面演示了通过wx.image接收用户发送图片,再以res.image被动回复相同图片的方式:

wx.img, (req, res) ->
  res.image req.media_id

可以通过wx.download下载图片,得到图片buffer:

wx.download req.media_id, (err, image) ->

*res.image亦接收图片文件路径,自动上传图片(为避免请求超时,建议预传图片,或先ok再发送客服图片消息)。

语音

下面演示了通过wx.voice接收用户发送图片,再以res.voice被动回复相同语音的方式:

wx.voice, (req, res) ->
  res.voice req.media_id

可以通过wx.download下载图片,得到语音buffer:

wx.download req.media_id, (err, voice) ->

*res.voice亦接收语音文件路径,自动上传语音(为避免请求超时,建议预传语音,或先ok再发送客服语音消息)。

视频

下面演示了通过wx.video接收用户发送图片,再以res.video被动回复视频文件的方式:

wx.video, (req, res) ->
  res.video
    title        : '视频标题'
    description  : '视频描述'
    video        : 'video.mp4'

地理位置

下面演示了通过wx.location接收用户发送的地理位置,通过req.labelreq.location_yreq.location_x获取地址、维度、经度的方式:

wx.location, (req, res) ->
  coordinate = req.location_x + ',' + req.location_y
  res.text "您在#{req.label or coordinate}"

链接

下面演示了通过wx.link接收用户发送链接,再通过req.titlereq.descriptionreq.url获取标题、描述与链接的方式:

wx.link, (req, res) ->
  res.text "《#{req.title}》一文发人深省…"

发送消息

文本

被动回复文本消息:

wx.text '文本', (req, res) ->
  res.text '北京,晴[太阳]'

5秒内无法应答时,先200,再通过req.user发送客服文本消息(避免微信服务器发起重试):

wx.text '文本', (req, res) ->
  res.ok()
    req.user.text '北京,晴[太阳]'

主动发送客服文本消息:

wx.user('xx_xxx').text('北京,晴[太阳]')

图片

被动回复图片消息:

使用res.image被动回复图片。既可指定本地文件路径,由wx自动上传图片;亦可直接传入有效的media_id,省略上传图片步骤。

wx.image, (req, res) ->
   res.image req.media_id

如需上传图片,建议先200,再通过req.user发送客服消息,以免因上传耗时超5秒导致重试。

wx.img, (req, res) ->
  res.ok()
    req.user.image 'image.jpg'

上传图片获取media_id方式为:

wx.upload 'image', 'image.jpg', (req, res) ->
  # res.media_id 是上传图片的 media_id

主动发送客服图片消息:

wx.user('xx_xxx').image('image.jpg')

语音

被动回复语音消息:

使用res.voice被动回复语音。既可指定本地文件路径,由wx自动上传语音;亦可直接传入有效的media_id,省略上传语音步骤。

wx.voice, (req, res) ->
   res.voice req.media_id

如需上传语音,建议先200,再通过req.user发送客服消息,以免因上传耗时超5秒导致重试。

wx.voice, (req, res) ->
  res.ok()
    req.user.image 'voice.amr'

上传图片获取media_id方式为:

wx.upload 'voice', 'voice.amr', (req, res) ->
  # res.media_id 是可以重用的语音 media_id

主动发送客服语音消息:

wx.user('xx_xxx').voice('image.jpg')

视频

被动发送视频消息:

使用res.video被动回复视频。既可指定本地文件路径,由wx自动上传语音;亦可直接传入有效的media_id,省略上传视频步骤。

wx.video, (req, res) ->
  res.video
    title        : '视频标题'
    description  : '视频描述'
    video        : 'video.mp4'

如需上传视频,建议先200,再通过req.user发送客服消息,以免因上传耗时超5秒导致重试。

wx.video, (req, res) ->
  res.ok()
    req.user.video ...

上传视频获取media_id方式为:

wx.upload 'video', 'video.mp4', (req, res) ->
  # res.media_id 是可以重用的视频 media_id

主动发送视频消息:

wx.user('xx_xxx').video ...

音乐

被动发送音乐消息:

需上传专辑图片时,先200,再通过req.user.music发送客服音乐消息(避免上传耗时超5秒,微信服务器发起重试):

wx.text '音乐', (req, res) ->
  music =
    title        : '音乐标题'
    description  : '音乐描述'
    music_url    : 'http://weixinjs.org/music.mp3'
    hq_music_url : 'http://weixinjs.org/music.mp3'
    thumb_media  : 'cover.jpg'
  res.music music

无客服消息权限,或已知专辑封面thumb_media_id时,可直接回复音乐:

wx.text '音乐', (req, res) ->
  res.music music

上传缩略图获取media_id方式为:

wx.upload 'thumb', 'cover.jpg', (req, res) ->
  # res.thumb_media_id 是可以重用的缩略图 thumb_media_id

主动发送视频消息: 请举一反三

图文

被动发送图文消息:

wx.text '图文', (req, res) ->
  news = [
    title       : '头条新闻标题'
    description : '头条新闻描述'
    pic_url     : ''
    url         : ''
  ,
    title       : '次条新闻标题'
    description : '次条新闻描述'
    pic_url     : ''
    url         : ''
  ]
  res.news news

亦可通过req.user发送客服新闻消息

wx.text '新闻', (req, res) ->
  res.ok()
  req.user.news news

主动发送图文消息: 举一反三

转客服

消息转多客服:

通过res.transfer方法,将消息转发到多客服:

wx.text /客服.*/, (req, res) ->
  res.transfer()

*公共平台开发者文档有更多关于多客服的开发者资料。在多客服网站下载客户端。

点击按钮

响应按钮点击,我们努力迫近最为自然的方式:
使用wx.click方法,指定被点击按钮名称,即可捕捉该按钮点击事件。

wx.click '点击按钮', (req, res) ->
   res.text "被#{req.user.nickname}点了一下[害羞]"

编辑按钮

编辑菜单是一种内容创意,应当由markdown来完成。使用wx,你可以立即预览菜单效果,无需关注更多。安装wx后,可以通过http://server.address/wx/admin地址进入管理界面.

通过以下Markdown格式的文件可以编辑并实时预览按钮。

+ 点击按钮 
+ [链接文档](http://mp.weixin.qq.com/wiki) 
+ 二级菜单
   - [链接跳转](http://github.com/baoshan/wx)
   - 拉取信息

扫描二维码登录

服务器端

通过wx.scan注册扫码处理流程*。响应句柄参数分别为:

  1. 浏览器请求,包含req.session会话、req.user微信用户、req.query二维码参数;
  2. 微信响应,可被动回复各种消息;
  3. 浏览器回调方法,可向浏览器发送任意数据。
wx.scan (req, res, desktop_callback) ->
  req.session.user = req.user
  res.text "#{req.user.nickname}从#{req.query.from}登录"
  desktop_callback req.user

标记语言*

    <script src="/wx/wx.js"></script>     
    <img id="登录二维码" src="/wx/qrcode?from=网页" />

浏览器端

$('#登录二维码').scan (user) -> 
  {headimgurl: src, nickname: title} = user
  $img = $ "<img src='#{src}' /><p>#{title}</p>"
  $(@).replaceWith($img)

*建议为所有二维码指定名称进行分类,见临时二维码与永久二维码部分。

临时二维码

指定名称,可为二维码分类。下面二维码名称为fruits

    <script src="/wx/wx.js"></script>     
    <img src="/wx/qrcode/fruits?name=cherry" />

*wx自动为被扫描的二维码增加scanned类名。

服务器端在wx.scan中指定二维码名称,注册该类二维码的处理流程。

wx.scan 'fruits', (req, res, desktop_callback) ->
  res.text "#{req.user.nickname}偷吃了#{req.query.name}"
  desktop_callback '吃一口'

永久二维码

*永久二维码图案稳定,永不过期,适于印刷品、广告等,实现来源统计用途。 名称在1100000间为永久二维码,[continuous]条码支持连续扫描:

服务器端

通过permanent名称注册永久二维码扫码处理流程,用req.params.scene_id获取编号。

wx.scan 'permanent', (req, res, callback) ->
  {nickname} = req.user
  {from} = req.query
  {scene_id} = req.params
  res.text "#{nickname}扫描#{from}编号#{scene_id}的永久二维码"
  callback req.user

浏览器端

通过scan方法,捕捉永久二维码扫描事件

$('#永久二维码').scan ({nickname: title, headimgurl: src}) ->
  $img = $("<img src='#{src}' title='#{title}' />")
  $('#div_headimgs').append($img)
  $img.load -> $(@).addClass('loaded')

关注与取消关注

关注

通过wx.subscribe注册关注事件。

wx.subscribe (req, res) ->
  nickname = req.user.nickname
  res.text "[礼物]欢迎#{nickname}关注微信应用框架!"

*当用户通过扫描二维码关注时,如已注册相应的二维码扫码处理流程,则交给该流程处理,不触发subscribe事件,仍可根据scan事件的req.eventsubscribe判断用户为通过扫码关注。

取消关注

通过wx.unsubscribe注册取消关注事件。

wx.unsubscribe (req, res) ->
  # 按具体需求进行处理。
  res.ok()

获取关注者列表

通过wx.subscribers方法,拉取关注者列表:

wx.subscribers (err, res) ->
  console.log res if res

获取到的关注者列表结构:

{
  "total" : 23000,
  "count" : 10000,
  "data"  : {"openid": ["OPENID1", ...]},
  "next_openid": "NEXT_OPENID"
}

亦可指定next_openid,拉取后续用户列表:

wx.subscribers next_openid, (err, res) ->

更多时候……

可以考虑用wx.populate_subscribers获取指定范围内关注者完整信息(分页显示关注用户、批量发送客服消息等)。

wx.populate_subscribers from, to, (err, res) ->
  {total, subscribers} = res if res

获取到的指定范围关注者完整信息结构:

{
  total       : 23000,
  subscribers : [{
    "subscribe"      : 1,
    "openid"         : "......",
    "nickname"       : "Band",
    "sex"            : 1,
    "language"       : "zh_CN",
    "city"           : "广州",
    "province"       : "广东",
    "country"        : "中国",
    "headimgurl"     : "http://wx.qlogo.cn/...",
    "subscribe_time" : 1382694957
  }, ...]
}

有限状态机

定义用户所处状态与各状态间跃迁条件,微信应用框架帮助您分解复杂业务,且毫不妥协研发体验:

wx.click '申办', (req, res) ->
  res.text '回复“固话”申办固话,回复“宽带”申办宽带。'
  req.user.state '申办'
  
wx.state('申办').text '固话', (req, res) ->
  req.text '正在为您申办固话业务,请提供认证照片。'
  req.user.state '认证'
  
wx.state('认证').image (req, res) ->
  req.text '已收到您提交的认证图片,请发送装机地址。'
  req.user.state '装机'
  
wx.state('装机').location (req, res) ->
  res.text "工程师正前往#{req.label}为您安装固话。"
  req.user.state null