nodejs微信开发接入指南

微信二次开发已经很火热,php、C#、java、python等关于微信后台开发案例也是比较多。但是关于nodejs开发微信的案例比较少。博主在百度上找到案例也是只字片言,关于接入微信的文章也是各类各样。博主尝试过各种失败,最后才接入微信。所谓万事开始难,博主在文章会贴出自己失败的例子,以及后续也会推出在微信开发中遇到的错误。

  • 申请微信公众号

    • 个人开发者只能申请未认证的订阅号,未认证的订阅号可以使用的微信API接口有限;所以个人开发者申请成功订阅号成功后,可以直接申请免费的测试号,测试号提供的API接口比较多,方便开发进行测试开发,测试号的使用时限是一年,一年过后会被释放。关于注册公众号的流程,开发者可以自己根据腾讯官方的提示进行填写。
  • 申请测试号

    • 个人性的订阅号很多接口是不能用的;个人的订阅号也不能认证。所以为了体验微信公众号的开发的最好方法就是申请测试号了。测试号提供了很多API接口,方便我们进行测试。登录个人订阅号以后,在微信开发者文档里面有申请测试号的入口。申请测试号很简单,直接用管理员的微信扫一扫就可以直接注册到测试号了。
  • 登录到的测试页面如下所示:

    • APPID以及APPsecret都是微信提供的,这连个值到时候是用来调用获取access_token的,而access_token是用来取得微信一些API接口的使用的口令;至于下面的url是第三方服务器地址(主要是微信服务器把用户提交的信息转发给的服务器处理地址,博主买了阿里云ECS,没有注册域名,你们可以直接填http://192.168.x.x/deal; 这个公网ip是阿里云提供的,后面的/deal是自己定义对的处理路由);后面token是用来验证消息是否来自微信服务器,自定义,例如weixin。
测试号的页面
  • 第一步进行链接认证,即是配置第三方服务器和微信服务器的链接;按照上面一步填写好之后,直接提交;提交的过程中,微信服务器将会以get的方式发送nonce(随机数),singnature(加密后签名),timestamp(时间戳),echostr给第三方服务器。加密算法(首先将nonce、timestamp、token字典序排序,然后再转换成字符串,最后用sha1加密,最后得到signature;我们实际就是验证signature是否与第三方算出来的加密签名相等);代码如下所示:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var xmlParse=require('xml2js').parseString;
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var sha1=require('sha1');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);
app.get('/validate',(req,res,next)=>{
    let token='wechat';
    let signature=req.query.signature;
    let timestamp=req.query.timestamp;
    let echostr=req.query.echostr;
    let nonce=req.query.nonce;
    let oriArray=new Array();
    oriArray.push(nonce);
    oriArray.push(timestamp);
    oriArray.push(token);
    let original=oriArray.sort().join('');
    let combineStr=sha1(original);
    if(signature==combineStr){
        res.send(echostr);
    }else{
        console.log('error');
    }
    next();
});
app.post('/validate',(req,res,next)=>{
    var data='';
    req.on('data',(chunk)=>{
        data+=chunk;
    });
    req.on('end',()=>{
        // console.log(data);
        xmlParse(data,(err,result)=>{
            console.log(result);
            
            if(result.xml.MsgType=='image'){
                let str= '<xml><ToUserName><![CDATA['+result.xml.FromUserName+']]></ToUserName><FromUserName><![CDATA['+result.xml.ToUserName+']]></FromUserName><CreateTime>'+new Date().getTime()+'</CreateTime><MsgType><![CDATA['+'image'+']]></MsgType><Image><MediaId><![CDATA['+result.xml.MediaId+']]></MediaId></Image></xml>';
                res.send(str);
            }
            if(result.xml.MsgType=='text'){
                let responseMSg='欢迎关注聊天小喵;小喵智能已经下线,其他接口在开发中。。。喵喵喵';
                let str='<xml><ToUserName><![CDATA['+result.xml.FromUserName+']]></ToUserName><FromUserName><![CDATA['+result.xml.ToUserName+']]></FromUserName><CreateTime>'+new Date().getTime()+'</CreateTime><MsgType><![CDATA['+'text'+']]></MsgType><Content><![CDATA['+responseMSg+']]></Content></xml>';
                res.send(str);  
                
            }
            if(result.xml.MsgType=='voice'){
                // let requestMsg=result.xml.Recognition;
                let str='<xml><ToUserName><![CDATA['+result.xml.FromUserName+']]></ToUserName><FromUserName><![CDATA['+result.xml.ToUserName+']]></FromUserName><CreateTime>'+new Date().getTime()+'</CreateTime><MsgType><![CDATA['+'voice'+']]></MsgType><Voice><MediaId><![CDATA['+result.xml.MediaId+']]></MediaId></Voice></xml>';
                res.send(str);
            }
            if(result.xml.MsgType=='video'){
                // console.log(result.xml.MediaId);
                let str='<xml><ToUserName><![CDATA['+result.xml.FromUserName+']]></ToUserName><FromUserName><![CDATA['+result.xml.ToUserName+']]></FromUserName><CreateTime>'+new Date().getTime()+'</CreateTime><MsgType><![CDATA['+'video'+']]></MsgType><Video><MediaId><![CDATA['+result.xml.MediaId+']]></MediaId><Title><![CDATA['+'hello'+']]></Title><Description><![CDATA['+'hello world'+']]></Description></Video></xml>';
                res.send(str);
            }

        });
    });

});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});


module.exports = app;
  • 运行上述代码,然后按下提交按钮,验证配置是否正确;很多时候都会是提交失败,这个时候可以继续按提交按钮,如果出现4-5次都提交失败,那很有可能是代码出错,可以检查代码;如果第一次提交出错,有可能是网络原因延迟导致失败,所以继续提交。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容