node-wechat 微信實踐

jopen 9年前發布 | 24K 次閱讀 node-wechat

node-wechat

從去年開始微信開發越來越火了,體現在sdk和h5上(h5如果大家想聽,可以回復),這里就簡單介紹一下sdk開發

既然是noder,那肯定要用nodejs寫,不然會被鄙視的。

node-webot簡介

node-webot是老樸幾個人建的org,主要開發微信sdk相關的node modules

地址 https://github.com/node-webot/

  • wechat 微信公共平臺消息接口服務中間件
  • weixin-robot 微信公共帳號自動回復機器人 A Node.js robot for wechat.
  • wechat-oauth 授權
  • wechat-api Wechat API/主動調用API
  • </ul>

    wechat sdk開發常用包

    • wechat-oauth
    • wechat-api(菜單,消息回復等)
    • wx_jsapi_sign(js-sdk)
    • </ul>

      創建菜單

      wxapi.js

      var API = require('wechat-api');
      var config = require('config');

      var menu_config = config.get('wx.wx_menu'); var app_id = config.get('wx.app_id'); var app_secret = config.get('wx.app_secret');

      //配置 var api = new API(app_id, app_secret);

      //測試 function app(){ api.createMenu(menu_config, function(err, result){ console.log(result); }); }

      module.exports = app;</pre>

      把數據放到配置文件中

      config/default.json

      {
        "domain": "xxxxxxxx.com",
        "is_debug": true,
        "mongodb": {
          "host": "127.0.0.1",
          "port": "27017",
          "db": "node-webot"
        },
        "sms": {
          "host": "127.0.0.1",
          "port": "5001"
        },
        "wx": {
          "app_id": "wx04014b02asdsfdsfsf",
          "app_secret": "cc4c224b50fkjlksdafkldfsakljsdfk",
          "wx_menu": {
            "button": [
              {
                "name": "菜單",
                "sub_button": [
                  {
                    "type": "view",
                    "name": "資訊菜單",
                    "url": "http://ip:port/all"
                  }
                ]
              },
              {
                "name": "菜單2",
                "sub_button": [
                  {
                    "type": "view",
                    "name": "我的11",
                    "url": "http://ip:port/all"
                  }
                ]
              },
              {
                "name": "助理",
                "sub_button": [
                  {
                    "type": "view",
                    "name": "大學",
                    "url": "http://ip:port/all"
                  },
                  {
                    "type": "view",
                    "name": "社區",
                    "url": "http://ip:port/all"
                  }
                ]
              }
            ]
          }
        }
      }

      oauth

      使用微信的用戶,或者綁定微信賬號

      微信有一個唯一的id是openid,它是辨別的唯一標識。

      routes/weixin.js

      // 微信授權和回調
      var client = new OAuth(app_id, app_secret);

      // 主頁,主要是負責OAuth認真 router.get('/', function(req, res) { var url = client.getAuthorizeURL('http://' + domain + '/weixin/callback','','snsapi_userinfo'); res.redirect(url) })

      /**

      • 認證授權后回調函數 *
      • 根據openid判斷是否用戶已經存在
        • 如果是新用戶,注冊并綁定,然后跳轉到手機號驗證界面
        • 如果是老用戶,跳轉到主頁 */ router.get('/callback', function(req, res) { console.log('----weixin callback -----') var code = req.query.code;

        var User = req.model.UserModel;

        client.getAccessToken(code, function (err, result) { console.dir(err) console.dir(result) var accessToken = result.data.access_token; var openid = result.data.openid;

        console.log('token=' + accessToken); console.log('openid=' + openid);

        User.find_by_openid(openid, function(err, user){ console.log('微信回調后,User.find_by_openid(openid) 返回的user = ' + user) if(err || user == null){

         console.log('user is not exist.')
         client.getUser(openid, function (err, result) {
           console.log('use weixin api get user: '+ err)
           console.log(result)
           var oauth_user = result;
        
           var _user = new User(oauth_user);
           _user.username = oauth_user.nickname;
           _user.nickname = oauth_user.nickname;
        
           _user.save(function(err, user) {
             if (err) {
               console.log('User save error ....' + err);
             } else {
               console.log('User save sucess ....' + err);
               req.session.current_user = void 0;
               res.redirect('/user/' + user._id + '/verify');
             }
           });
        
         });
        

        }else{

         console.log('根據openid查詢,用戶已經存在')
         // if phone_number exist,go home page
         if(user.is_valid == true){
           req.session.current_user = user;
           res.redirect('/mobile')
         }else{
           //if phone_number exist,go to user detail page to fill it
           req.session.current_user = void 0;
           res.redirect('/users/' + user._id + '/verify');
         }
        

        } }); }); });</pre>

        上面的簡單介紹一下

        wx_jsapi_sign(nodejs)

        wx_jsapi_sign = wechat(微信) js-api signature implement.

        • 支持集群,將獲得的前面寫到cache.json里
        • 使用cache.json保存,比如用redis省事,更省內存
        • 足夠小巧,便于集成

        Install

        npm install --save wx_jsapi_sign

        Usage

        copy config file

        cp node_modules/wx_jsapi_sign/config.example.js config.js 

        change appId && appSecret

        then mount a route in app.js

        var signature = require('wx_jsapi_sign');
        var config = require('./config')();

      ....

      app.post('/getsignature', function(req, res){ var url = req.body.url; console.log(url); signature.getSignature(config)(url, function(error, result) { if (error) { res.json({ 'error': error }); } else { res.json(result); } }); });</pre>

      more usages seetest/public/test.html

      Test

      微信訪問網址http://yourserver.com:1342/test

      原作者博客

      http://blog.xinshangshangxin.com/2015/04/22/%E4%BD%BF%E7%94%A8nodejs-%E8%B8%A9%E5%9D%91%E5%BE%AE%E4%BF%A1JS-SDK%E8%AE%B0%E5%BD%95/

      我為什么要重寫這個模塊?

      微信簽名7200秒可以查看一次,所以就要考慮緩存問題

      • wx_jsapi_sign是一個開源項目,使用redis作為緩存,思路挺好,但依賴redis,還是有點重,沒必要
      • xinshangshangxin寫的模塊使用cache.json做緩存,然后把獲取的時間保存到配置文件里,每次請求只要讀取文件即可。這個思路非常好,依賴少,省內存,簡單,支持集群
      • </ul>

        那哥們寫的已經很不錯了,但是有幾個問題

        • 他不太了解如何寫通用模塊(復用程度比較低)
        • 代碼比較亂(抽取了配置,很好,但想art-template之類的都混在里面看的人頓時頭大)
        • 沒有發布到npm上
        • </ul>

          如果各位想了解是如何做的,請移步http://www.github.com/i5ting/wx_jsapi_sign

          • 依賴管理(區分模塊依賴的,還是開發階段依賴的)
          • npmjs.org上如何發布模塊
          • </ul>

            配置文件實際

            上面的微信的菜單,db連接,還是wx_jsapi_sign都是基于配置的,使用配置文件會有一些問題

            比如config.json作為配置文件,你需要在版本控制里放一個config.example.json,然后把config.json放到.gitinore里。

            然后每個使用的人,需要先拷貝一個config.example.json為config.json。

            這樣做的好處

            • 敏感信息不能提交上去
            • 部署服務器的時候,不會沖突(比如配置文件里有一個is_debug選項,服務器上必須是false,而開發階段是要用true的)
            • </ul>

              另外配置文件格式,推薦json和yaml,而不是js,不要在配置文件了寫邏輯,雖然沒問題,但實為陋習。

              糾正一下價值觀

              很多人都認為現在啥模塊都有了,隨便找一個用就可以了,但這種想法是危險的

              • 第一件事兒是思考,而不是想找一個隨便xx
              • 不要造重復的輪子,除非必要(先到github或相關網站上找對應模塊,要有可以修改對應模塊源碼的能力)
              • 反身而誠,樂莫大焉
              • </ul>

                全文完

                歡迎關注我的公眾號【node全棧】 

                來自:http://my.oschina.net/nodeonly/blog/476894

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!