Node微信開發

魯鵬發表於2016-04-29
  • 微信公眾賬號實踐
    做一些針對微信的開發嘗試,學習ing...

    微信開發之開發者認證

今天閒之無聊,拿出閒置好久的微信公眾賬號,做了一下開發者驗證。

伺服器:家中Mac
語言/平臺: JavaScript/Node

看了一下,微信公眾賬號的伺服器必須要是在80埠,這一點對於使用花生殼服務的我來說實在是太方便了,通過殼域名80埠指向內網主機9090埠(隨便一個都行)就行了,然後在內網主機上通過Node寫一個簡單的HTTP伺服器,監聽9090埠,微信後臺訪問殼域名,一切就準備就緒了。接下來就是二十幾行的一段程式碼就OK了。

var http = require('http');
var sha1 = require('sha1');    // 需要提前通過npm安裝sha1模組
var util = require('util');
var url = require('url');
var qs = require('querystring');
http.createServer(function(req,res){
    var pathname = url.parse(req.url).pathname;
    if (pathname == '/weixin'){    // 指定一個訪問路徑
        var query = url.parse(req.url,true).query;  // 獲取微信伺服器傳過來的引數
        var signature = query.signature;
        var timestamp = query.timestamp;
        var nonce = query.nonce;
        var echostr = query.echostr;
        var token = 'pengloo53';     // 微信後臺填寫的token值
        var array = new Array (token,timestamp,nonce);
        array.sort();
        var arraystring = array.join('');
        arraystring = sha1(arraystring);
        if (arraystring == signature){  // 值一樣,說明確實是從微信伺服器發過來的請求
            console.log("驗證成功!");
            res.writeHeader(200,{"Content-Type":"text/html"});
            res.end(echostr);  // 原樣返回echostr字串給微信伺服器
            return true; 
        }else{
            return false;
        }
    }
}).listen(9090);   // 監聽9090埠
console.log("正在驗證..."); 

完事了,驗證成功,編輯模式下的自動回覆以及自定義選單都不能用了,乖乖的交錢進行微信認證,然後進行開發吧!

微信開發之todo-list小應用

週末在家,做了一個小的開發,家裡一臺還能湊合的Mac mini做伺服器,用起久未使用的微信公眾賬號,連線上微信公眾賬號伺服器,做一個「代辦事項」的小應用,也就是常說的todo-list應用。

根據目前學習進度以及未認證公眾賬號的介面許可權,做出下列簡要的需求:

  1. 僅利用公眾賬號接收訊息以及自動回覆介面實現;
  2. 簡單todo-list需求:增加事項、刪除事項以及展示事項列表功能;
  3. 簡單檔案儲存,儲存不同使用者的事項列表;

簡單需求確定,那就可以動手實現了。

1. 微信公眾賬號的設定

首先需要有一臺能使用80埠的伺服器,這裡我使用的家裡的Mac電腦,內網穿透以及80埠等問題就不多說了,可以看這裡以及看這裡。之前還是有一些知識儲備的。

設定微信公眾賬號伺服器配置,將伺服器與微信公眾賬號服務進行對接,有一個簡單的驗證過程,上面一篇文章已經介紹過了。

2. todo-list應用開發

為什麼最近總是跟todo-list程式幹上了呢?因為todo-list程式邏輯清晰,“增刪改查”符合應用程式中一套基本的RESTful原則。更加方便學習理解以及練習。

這裡使用的是Node進行開發,同時使用了wechat模組,它對微信公眾賬號獲取資訊以及傳送資訊做了一個封裝,簡化開發流程,而不用再去寫獲取以及解析XML資訊以及傳送XML資訊的一些程式碼。所以這裡關注的重點是todo-list應用的一些邏輯,如何新增事項,儲存事項,刪除事項。

部分程式碼如下:

...
var message = req.weixin;  // 獲取使用者傳送的資訊物件
var username = message.FromUserName;
var Content = (typeof(message.Content) == 'undefined')?'try again.':message.Content;
console.log(username + ": " + Content);
var filePath = '/.tasks/.' + username;
var file = path.join(process.cwd(), filePath);
var content = '';
// 根據使用者訊息中前幾個字元來判斷對應的指令(增,刪,查)
if(Content.substring(0,2) == 'ls'){
  list(file, function(replys){  // 檢視列表方法
    res.reply(replys);
  });
}else if(Content.substring(0,3) == 'add'){
  content = Content.substring(3).trim();
  add(file,content);  // 新增事項方法
}else if(Content.substring(0,3) == 'del'){
  content = Content.substring(3).trim();
  var delId = parseInt(content);
  delData(file, delId);  // 刪除事項方法
}else{
  res.reply("『代辦事項』小應用,用法: 輸入add Message新增一條代辦事項;輸入`add message1 message2`新增多條待辦事項;輸入`del id`刪除指定事項;輸入`ls`檢視所有代辦事項 ");
}
...

從這段簡單的程式碼上就可以看出,通過add可以新增代辦事項;通過del可以刪除對應的事項;通過ls就可以檢視代辦事項列表了。

詳細的程式碼可以點選這裡檢視,現在可以關注一下這個公眾賬號體驗一下效果。如果有Bug或者伺服器無法響應,請見諒(有可能電腦睡眠了或者其他...)。

轉載儲存:微信 | LP's Blog

微信開發之showshow小程式

由於公司無法使用微信,網盤等一些雲類同步軟體,就算只是想將手機上一段文字亦或是一個圖片上傳到電腦端也只能是通過郵件的方式來傳送,當比較頻繁的時候一會一封郵件還是比較麻煩,想要一個簡單直觀的方法滿足這個小需求。於是就想到通過微信公眾平臺來實現,將一段文字或者圖片通過微信公眾賬號上傳,最後通過電腦訪問,簡單寫了個雛形,如下圖:

實現了簡單功能:

  1. 向公眾賬號傳送文字以及圖片,返回訪問連結;
  2. 圖片直接下載到本地儲存,以時間戳命名圖片;
  3. 資料通過JSON檔案的儲存方式儲存,可以檢視近期所有傳送的文字或圖片;

功能比較簡單,全部程式碼130+行。基本沒有什麼前臺,通過拼接字串的方式寫的HTML;也基本沒有什麼後臺,整體使用的是expressWeb框架,微信互動使用的wechat模組;下載圖片使用的download模組。

這裡先簡單介紹一下實現的細節,首先,以/根目錄接受微信的資訊,如下程式碼:

app.use('/', wechat(config, function(req,res,next){
  var message = req.weixin;
  console.log(message);
  var FromUserName = message.FromUserName;
  var CreateTime = new Date().getTime();
  var file = path.join(process.cwd(), '/.data/.', FromUserName);
  var data = {};

  // 每一條資訊儲存時間,欄位為CreateTime
  data.CreateTime = CreateTime;

  switch (message.MsgType){
    case 'text':
      var Content = message.Content;
      data.text = Content;  // 當為文字內容的時候,儲存text欄位
      storeData(file,data,function(result){
        if(result == 'success'){
          res.reply("請在瀏覽器中訪問:http://pengloo53.eicp.net/user/" + FromUserName);
        }else{
          res.reply(result);
        }
      });
      break;
    case 'image':
      var PicUrl = message.PicUrl;
      var picName = new Date().getTime() + '.png';
      var imagePath = path.join(process.cwd(), '/.data/dist/' , picName);
      data.image = picName; // 當為圖片內容的時候,儲存image欄位(時間戳命名)
      downloadPic(PicUrl, imagePath ,function(result){
        if(result == 'success'){
          storeData(file,data,function(result){
            if(result == 'success'){
              res.reply("圖片上傳成功,請在瀏覽器中訪問:http://pengloo53.eicp.net/user/" +     FromUserName);
            }else{
              res.reply(result);
            }
          })
        }
      });
      break;
    default:
      res.reply('歡迎使用showshow小工具,請輸入文字或是圖片!');
  }
}));

這裡只是實現了text以及image的微信訊息型別,也就是隻接受並處理文字資訊以及圖片資訊;每一條訊息為一個物件,通過鍵值對來儲存資料,一個CreateTime,一個textimage;每一個訊息當做一個物件push到資料陣列中儲存,最終以JSON的方式儲存到檔案中,每一個使用者對應一個資料檔案,代替資料庫的功能。實現程式碼如下:

// 初始化資料
function initData(file,callback){
  fs.stat(file, function(err){
    if (err){
      callback([]);
    }else{
      var content = [];
      fs.readFile(file,'utf8',function(err,result){
        if(err){
          callback([]);
        }
        content = JSON.parse(result.toString() || []);
        callback(content);
      });
    }
  });
}

// 插入新的資料,儲存到本地
function storeData(file, data, callback){
  initData(file,function(result){
    result.push(data);
    fs.writeFile(file, JSON.stringify(result), function(err){
      if(err){
        callback(err);
      }else{
        callback('success');
        console.log('store success.');
      }
    });
  })
}

最後瀏覽器以GET請求獲取資訊,以達到資料傳輸到PC端的目的。定義一個GET路由,指定路徑為/user/:id,id即為微信使用者的Open ID;

app.get('/user/:id', function(req,res,next){
  var pathname = url.parse(req.url).pathname;
  var match = pathname.match(/^\/user\/(.+)/);
  if (match){
    var username = match[1];
    var file = path.join(process.cwd(), '/.data/' , username);
    var pageContent = '';
    initData(file,function(result){
      for(var i = result.length -1 ; i >= 0 ; i--){
        var dateDisplay = new Date(result[i].CreateTime * 1);
        var text = result[i].text;
        var image = result[i].image;
        pageContent += '<h2>' + dateDisplay.toLocaleString() + '</h2>';
        if(text){
          pageContent += '<p>' + text + '</p>';
        }else{
          pageContent += '<p><a href="/'+ result[i].image +'"><img src="/'+ result[i].image +'"     width="600px"></a></p>';
        }
        pageContent += '<hr/>';
      }
      res.send(pageContent);
    });
  }
});

以倒序的方式顯示訊息,最終顯示如上圖,頁面比較簡單,後續想通過jade模板引擎寫個漂亮的前臺頁面。

原始碼:Node_note/showshow.js,寫得不好請指正。

現在可以關注一下這個公眾賬號體驗一下效果。如果有Bug或者伺服器無法響應,請見諒(家裡Mac mini擔當的伺服器,或許已經不在提供服務)。

相關文章