node-webot / wechat-enterprise Goto Github PK
View Code? Open in Web Editor NEW微信公众平台企业号版本
License: Other
微信公众平台企业号版本
License: Other
modejs 并发发送模板消息,发现接受到了30条模板消息,但是记录的mesgid却有重复的
我们在wechat那个库中也提交了这样的一个issue,不知道wechat-enterprise中是否也可以修改,可以设置前置cryptor,前置token的,谢谢!
希望可以解决
s1:服务端和通过公众号发消息的用户之间的session
和
s2:服务端和浏览器端之间的session
互通
可以在 事件推送的时候就保存用户状态到s2
http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8
功能主要在lib/api_common.js
中
微信企业号的某个agent在access_token 过期之后,就没调用setToken方法。 access_token 是存在redis 里的, 设置的两小时过期。
下面是错误log。
[2018-01-10 10:55:23]10.0.1.94
content: [2018-01-10 10:55:23.577] [INFO] app - begin e93f55ba-9a6c-4738-a668-8bc7a475534d POST /message/send ::ffff:10.0.1.93
body: {"to":{"touser":"3"},"agentid":"agentid","message":{"msgtype":"text","text":{"content":"xxx"},"safe":"0"}}
[2018-01-10 10:55:23]10.0.1.94content: [2018-01-10 10:55:23.580] [INFO] app - get access token by redis: token = null
|[2018-01-10 10:55:23]10.0.1.94content: [2018-01-10 10:55:23.796] [ERROR] app - wechatAPI response error: method=send, error=invalid credential, hint: [1515552923_6_1c32f77d5bb48e4e928ca8e9c257f188], more info at https://open.work.weixin.qq.com/devtool/query?e=40001 code=40001
[2018-01-10 10:55:23]10.0.1.94content: [2018-01-10 10:55:23.797] [INFO] app - end e93f55ba-9a6c-4738-a668-8bc7a475534d POST /message/send - 500 - 220.157 ms
class WechatApi{
constructor({corpId, secret, agentid}){
this.api = new API(corpId, secret, agentid,
(cb) => this._getToken(agentid).then( token=> cb(null, token)).catch( err => cb(err, null) ),
(token, cb) => this._setToken(agentid, token).then( token=> cb && cb(null, token)))
}
_getToken(agentid) {
// 取redis里token
return redis.client('get', accessTokenPrefix+agentid)
.then( token=>{
logger.info(` get access token by redis: token =`, token)
return JSON.parse(token)
})
}
_setToken(agentid, token) {
logger.info(` set access token: token = `, token)
// 经过expire时间后过期
redis.client('set', accessTokenPrefix+agentid, JSON.stringify(token), 'EX', expire)
return Promise.resolve(token)
}
}
http://node-webot.github.io/wechat-enterprise/api.html#api_api_common
The API property deprecated, Use require("wechat-api") instead
然后更换成wechat-api
同样报错不能使用
var API = require('wechat-api');
var api = new API('wx*****', '******', '6');
api.getLatestToken(function(err,token){
console.log(err,token);
});
不是说 “无需尝试处理access token”吗? (http://doxmate.cool/node-webot/wechat-enterprise/Getting%20start.html#index_调用API);
但我调用api.send的时候还是会报 { [WeChatAPIError: access_token expired] name: 'WeChatAPIError', code: 42001 }的错误
现在依赖的可是0.0.2版本。
而实际上都进化到0.0.8版本了!
企业号 扫一扫 推送的事件中
二维码内容
message.ScanCodeInfo.ScanResult
把 二维码 中的参数 分隔符 & 给过滤没了。。
比如 http://www.xxx.com?id=ddd&aaa=bbb
会变成 http://www.xxx.com?id=dddaaa=bbb
encodingAESKey 这个如果写错的话,程序会崩溃。
是不是应该在callback里面捕获一下?
例如,当从微信的企业号后台copy过来的时候,万一不小心漏了一个字母,或者多复制了一些东西进来,就会提示
Error: encodingAESKey invalid at new WXBizMsgCrypt (/Users/nick/Develope/SVN/gisiclouds/node_modules/wechat-enterprise/lib/msg_crypto.js:56:11) at Handler.middlewarify (/Users/nick/Develope/SVN/gisiclouds/node_modules/wechat-enterprise/lib/wechat-enterprise.js:284:18) at middleware (/Users/nick/Develope/SVN/gisiclouds/node_modules/wechat-enterprise/lib/wechat-enterprise.js:393:21) ... ...
I want to use Sourcegraph for wechat-enterprise code search, browsing, and usage examples. Can an admin enable Sourcegraph for this repository? Just go to https://sourcegraph.com/github.com/node-webot/wechat-enterprise. (It should only take 30 seconds.)
Thank you!
The access token will expire after 2 hours and I will get 42001 "Access Token Expire" error when calling the getUserByCode().
ticket: 'kgt8ON7yVITDhtdwci0qeS9V0piZrVpzp2WAiIVVZ9tn15-IbBwGja1V3YjrAuCo0ik-PeO7UPJjWN1fVC2Q2Q',
url: http://qy.wql2015.cn:8889/kqqd/qd
{ debug: undefined,
appId: 'wx246c9cba234c2e15',
timestamp: '1496644307',
nonceStr: 'oc3w34onfz74bm6',
signature: '349b0e534ca1cdd9e34c393e47aaeb7a4875a372',
jsApiList: [ 'onMenuShareTimeline', 'onMenuShareAppMessage', 'getLocation' ] }
这个在android正常,但ios上报::invalid signature。
http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8
lib/api_department.js
中
微信企业号最近开放了第三方授权功能,是否有计划增加这个功能?
I want to use Sourcegraph for wechat-enterprise code search, browsing, and usage examples. Can an admin enable Sourcegraph for this repository? Just go to https://sourcegraph.com/github.com/node-webot/wechat-enterprise. (It should only take 30 seconds.)
Thank you!
koa1, koa-route
app.use(function*(next){
if(this.request.path === '/weixin'){
wechat(config, wechat.text(msg, req, res, next){
console.log("msg" + msg);//这里一直没打印(我在微信端发了文字了),
})
}else{
yield next;
}
}
http://qydev.weixin.qq.com/wiki/index.php?title=%E5%9B%9E%E8%B0%83%E6%A8%A1%E5%BC%8F
功能主要在lib/wechat-enterprise.js中
封装了一个co发送一条模板消息的方法,然后co 调用并发,但是却不能接受到所有的模板消息,微信用户接受模板消息有限制吗?
1:封装方法
function* cosendfc(prepareid){
let API = require('wechat-api');
let api = new API(defaultAppid, defaultsecrut, function (callback) {
// 传入一个获取全局token的方法
client.hget(hash_currTickets,defaultAppid, function(err, ret){
if(err){
return callback('[90]hget error. err=' + err);
}
// return callback(null,JSON.parse(ret));
var currACTicket = JSON.parse(ret);
if (currACTicket !== undefined && currACTicket !== null && currACTicket !== '') {
return callback(null,currACTicket);
}else{
return callback(null,{
access_token: '',
expire_time: 0
});
}
});
}, function (token, callback) {
// 请将token存储到全局,跨进程、跨机器级别的全局,比如写到数据库、redis等
client.hset(hash_currTickets, defaultAppid, JSON.stringify(token), function(err, ret){
if(err){
return callback('[109]hset error. err=' + err);
}
return callback(null);
});
});
var sendinfo = '';
let statu = Promise.resolve(new Promise(
(resolve,reject) => client.hget(store_prepare,prepareid,(err, res) => err ? reject(err) : resolve(res))
));
let length = Promise.resolve(new Promise(
(resolve,reject) => client.llen(prepareid,(err, res) => err ? reject(err) : resolve(res))
));
let lpopcontent = Promise.resolve(new Promise(
(resolve,reject) => client.lpop(prepareid,(err, res) => err ? reject(err) : resolve(res))
));
sendinfo = JSON.parse(lpopcontent);
console.log(sendinfo);
let openid = sendinfo.openid;
let templateId = sendinfo.templateId;
let data = sendinfo.data;
let url = sendinfo.url;
let uid = sendinfo.uid;
data.first.value = Math.floor(Math.random() * 10000 + 1);//测试的代码,上线需注释
data.keyword1.value = Math.floor(Math.random() * 10000 + 1);//测试的代码,上线需注释
let sendtesult = Promise.resolve(new Promise(
(resolve,reject) => api.sendTemplate(openid,templateId,url,data,(err, res) => err ? resolve(err) : resolve(res))
));
return sendtesult;
}
2:co并发处理
co(function* () {
var rs = yield [
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
//10
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
cosendfc(prepareid),
//20
];
return rs;
}).then(function (value) {
console.log(value);
return callback(null,value);
});
1:封装的发送模板消息的方法
采用request.post 发送模板消息 request.post(url,{ json: { touser:openid,template_id:templateId,url:url,data:data } },function (error, response, body){});
function sendmessage (prepareid,sendsuccess,sendfail,callback){
async.waterfall([
//start
function(callback){
client.hget(store_prepare,prepareid,function(err,res){
if(err || res==null){
return callback('[135]获取list状态失败');
}
// console.log(res);
return callback(null,res);
});
},
function(status,callback){
if(status==0){
return callback('[140]list处于暂停状态');
}else{
client.llen(prepareid,function(err,length){
if(err){
return callback('[144]获取list长度失败');
}
return callback(null,length);
});
}
},
function(length,callback){
// console.log(length);
if(length<=0){
return callback('[153]list已为空');
}else{
client.lpop(prepareid,function(err,templateinfo){
if(err || templateinfo==null){
return callback('[157]获取list数据失败');
}
// console.log(templateinfo);
return callback(null,templateinfo);
});
}
},
function(templateinfo,callback){
client.hget('currwxtickets',defaultAppid,function(err,ret){
if(err){
return callback('[4579]'+err);
}
var ret = JSON.parse(ret);
var get_access_token = ret.accessToken;
return callback(null,templateinfo,get_access_token);
});
},
function(templateinfo,get_access_token,callback){
var sendinfo = JSON.parse(templateinfo);
var openid = sendinfo.openid;
var templateId = sendinfo.templateId;
var data = sendinfo.data;
var url = sendinfo.url;
var uid = sendinfo.uid;
data.first.value = Math.floor(Math.random() * 10000 + 1);//测试的代码,上线需注释
data.keyword1.value = Math.floor(Math.random() * 10000 + 1);//测试的代码,上线需注释
var request = require('request');
url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='+get_access_token;
request.post(
url,
{ json: { touser: openid,template_id:templateId,url:url,data:data } },
function (error, response, body) {
//console.log(error);
//console.log(response);
if (!error && response.statusCode == 200) {
store.result = response.body;
var store_string = JSON.stringify(store);
return callback(null,1,store_string);
}else{
}
}
);
2:async.parallel调用方法并发发送模板消息,但是最后有时候只能接受到10几条数据
async.parallel([
function(callback){
sendmessage(prepareid,sendsuccess,sendfail,callback);
},
function(callback){
sendmessage(prepareid,sendsuccess,sendfail,callback);
},
function(callback){
sendmessage(prepareid,sendsuccess,sendfail,callback);
},
function(callback){
sendmessage(prepareid,sendsuccess,sendfail,callback);
},
function(callback){
sendmessage(prepareid,sendsuccess,sendfail,callback);
},
function(callback){
sendmessage(prepareid,sendsuccess,sendfail,callback);
},
function(callback){
sendmessage(prepareid,sendsuccess,sendfail,callback);
},
function(callback){
sendmessage(prepareid,sendsuccess,sendfail,callback);
},
function(callback){
sendmessage(prepareid,sendsuccess,sendfail,callback);
},
//20
],function(err,res){
//返回结果,就不贴代码了
})
http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%B6%88%E6%81%AF
lib/wechat-enterprise.js
lib/api_media.js
这个基本不用怎么开发,需要核对和测试。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.