sails.jswechat

SailsJS - How can I handle WeChat requst in SailJS app


I had problem handling WeChat request in my Sails app. It took me lots of time figuring it out. So I just wanna record it here.

I'm using this this library.

The flow and solution will be provided in the answer.

Hope this would help, thanks.


Solution

  • First, you have to register an account in WeChat Public Platform.

    1. Log in and configure your server configuration. The URL will be the interface where you verify and handle WeChat message, and for the token, you can specify any string you like, which will be used to verify your server.

      For this URL, you have to define both GET and POST interface for it in your backend code. The GET interface is for verifying validation of your server, the POST will be used to handle the message from WeChat server. The verification snippet code in NodeJS should be like this:

       var array = [token, timestamp, nonce];
       array.sort();
      
       var tempStr = array.join('');
       const hashCode = crypto.createHash('sha1');
       var resultCode = hashCode.update(tempStr, 'utf8').digest('hex');
      
       if (resultCode === signature) {
           return cb(null, echostr);
       } else {
           return cb('mismatch', null);
       }
      

      token is what you specified in your WeChat Public Platform,timestamp and nonce are passed by WeChat as query string.

    2. Here comes the important part that adds the xml support for Sails.

      In config/http.js, replace bodyParse with xmlBodyParser and add following code:

    xmlBodyParser: function(req, res, next) {
      var xmlParser = require('express-xml-bodyparser')();
      var skipper = require('skipper')();
      if (req.headers && (req.headers['content-type'] == 'text/xml' || req.headers['content-type'] == 'application/xml')) {
        return xmlParser(req, res, next);
      }
      return skipper(req, res, next);
    }
    
    1. Add controller method for the configured URL, since I'm using this library, the code should be like this:
    onMessage: wechat(wechatConfig.oa.app, function (req, res, next) {
        var signature = req.query.signature,
            timestamp = req.query.timestamp,
            nonce = req.query.nonce;
        if (WeChatService.isFromOfficalAccount(signature, timestamp, nonce)) {
          return WeChatService.handle(req, res);
        } else {
          return res.forbidden("Validation failed!");
        }
    })
    

    All the request from WeChat will be handled by this wechat function. Inside the handle function, you can use the library's API to handle all the request from WeChat server. For the usage of this library, you can find in its documentation.