上一章已经讲过如何用node.js发送微信消息了,,这一章为大家深入一点研究微信公众平台的机制.上一章的链接:http://cnodejs.org/topic/510889e9df9e9fcc58b69afe 首先我们要获取这个发送微信人的信息,当你用控制台查看微信的接口你会发现,要有一个Fakeid,那么我们首要要获取Fakeid,其他就好办了.首先我们先获取登录人的这个fakeid,防止后面还会用的.看了一下微信公众平台的所有api接口,,没有发现,那么我们只能去它的用户页面去拿,代码如下:
getFakeId: (options, fn) ->
request
.get('http://mp.weixin.qq.com/cgi-bin/userinfopage?t=wxm-setting&lang=zh_CN#')
.set('Cookie', options.cookie)
.end (res) ->
//这里是你的fakeid
//在拿到的结果里,实际上是一个页面的所有数据,那么我们只能用正则去匹配到所需的fakeid数据,下面是完整的代码:
getFakeId: (options, fn) ->
request
.get('http://mp.weixin.qq.com/cgi-bin/userinfopage?t=wxm-setting&lang=zh_CN#')
.set('Cookie', options.cookie)
.end (res) ->
fakeid = res.text.match(/FakeID : "(\d+)"/)[1]
fn null, fakeid
到了这一步,其实还没有成功,因为我们还没有拿到发送人的fakeid,不然怎么发微信消息给好友呢?于是,我们要去微信公众平台的用户管理页面拿到你所有的好友的fakeid,代码如下:
getFriendPage: (req, fn) ->
[@login](/user/login) (err, cookie)->
request
.get('http://mp.weixin.qq.com/cgi-bin/contactmanagepage?t=wxm-friend&lang=zh_CN&pagesize=&pageidx=0&type=0&groupid=0')
.set('Cookie', cookie)
.end (res) ->
//在这里res.text已经是用户管理页面的html代码了,但是并不会出来,一番查找后,发现是因为它里面的js在我们这里用是有跨域的问题的,知道问题就好办了,查找html它里面设置了document.domain:`document.domain = document.location.hostname.match(/[^\.]+\.com/)[0];`结果在控制台的输出是qq.com,看到这里,就证明我的判断是没有错误的.正则替换掉里面的hostname就ok了.完整代码如下:
getFriendPage: (req, fn) ->
[@login](/user/login) (err, cookie)->
request
.get('http://mp.weixin.qq.com/cgi-bin/contactmanagepage?t=wxm-friend&lang=zh_CN&pagesize=&pageidx=0&type=0&groupid=0')
.set('Cookie', cookie)
.end (res) ->
rs = res.text.replace(/document.location.hostname.match.*\[0\]/g, '"'+req.host+'"')
fn null, res.text
在这里,大家已经能拿到所有好友的fakeid了,但是不能用jsdom或者cheerio去拿,因为是整个页面加载后才出现好友的html的,至于解决方法我是用phantom.js解决的,具体代码我就不贴了,因为要涉及到安装什么的.因为研究微信公众平台时间也就几天,如果有更好的方法获取好友的fakeid请在下面留言. 到这一步,在这里已经拿到了fakeid了,我们可以去拿到这个微信好友的相关信息,在微信公众平台中,找到了如下接口,以下是代码:
getInfo: (fakeid, fn) ->
[@login](/user/login) (err, cookie) ->
request
.post(’http://mp.weixin.qq.com/cgi-bin/getcontactinfo?t=ajax-getcontactinfo&fakeid=‘+fakeid)
.type('form')
.set('Cookie', cookie)
.end (res) ->
fn null, JSON.parse res.text
调用代码打印以下结果:
{
FakeId: "xxxx",
NickName: "岳蒙",
ReMarkName: "",
Username: "xxxx",
Signature: "",
Country: "中国",
Province: "江西",
City: "南昌",
Sex: "1",
GroupID: "0",
Groups: [
{
GroupId: "0",
GroupName: "未分组"
},
{
GroupId: "1",
GroupName: "黑名单"
},
{
GroupId: "2",
GroupName: "星标组"
}
]
}
当然群发的话也挺简单的,我已经做好了就不发了,大家可以贴出自己的代码,互相讨论下. 微信发送到这里已经讲完,后面我会为大家准备一个node.js+express的OAuth2的一个认证流程的代码出来/
发布完不能编辑?这… 如果大家想获取微信的头像的话,其实有点复杂,因为是远程图片,而且要附带cookie上去,为了怕新手碰壁,以下贴出代码:下面的__basename其实是我定义的全局变量,放在index.js或者app.js都可以
global.__basename = __dirname
getAvatar: (options, fn) ->
@login (err, cookie) ->
request
.get('mp.weixin.qq.com/cgi-bin/getheadimg?fakeid=' + options.takeid)
.set('Cookie', cookie)
.end (res) ->
f = fs.createWriteStream(__basename + '/public/avatar/'+options.takeid+'.jpg',
flags: "w"
encoding: "binary"
)
res.on "data", (data) ->
f.write data
options.res.write data
res.on "end", (data) ->
f.end()
options.res.end()
取好友fakeId.
var pattern = /\"fakeId\" : \"(\d+)\"/gi;
var fakes = typeof res.text === 'undefined' ? [] : pattern.exec(res.text);
for (var i = 1; i < fakes.length; i++) {
console.log(fakes[i]);
}`
取自己fakeid
var pattern = /FakeID : \"(\d+)\"/gi;
var FakeID = typeof res.text === 'undefined' ? undefined : pattern.exec(res.text)[1];
其实可以直接用拿到它的好友列表的json数据的,qq微信公众平台的用户管理的html代码中有这样一段:
所以…getFriendPage方法改成如下就可以顺利拿到这个数据了:
getFriendPage: (req, fn) ->
page = req.query.page or 0
@login (err, cookie)->
request
.get('http://mp.weixin.qq.com/cgi-bin/contactmanagepage?t=wxm-friend&lang=zh_CN&pagesize=&pageidx='+page+'&type=0&groupid=0')
.set('Cookie', cookie)
.end (res) ->
rs = res.text.replace(/document.location.hostname.match.*\[0\]/g, '"'+req.host+'"')
pattern = /<script id="json-friendList" .*>([\s\S]*?)<\/script>/
results = rs.match(/<script id="json-friendList" .*>([\s\S]*?)<\/script>/)[1]
fn null, results
嗯这是昨晚写的一段方法, cookieAgent(request, response).toString()
存储了代理的cookies, 获得的数据填充在request.wechat
里.
获取朋友列表:
var getFriendsList = function (request, response, next) {
var url = 'http://mp.weixin.qq.com/cgi-bin/contactmanagepage?t=wxm-friend&pagesize=&groupid=100';
var cb = function (res) {
var pattern = /<script id="json-friendList" type="json\/text">([\s\S]*)<\/script><script type="text\/javascript">/;
var fakes = [];
try {
fakes = JSON.parse(pattern.exec(res.text)[1]);
} catch (e) {
console.error(e);
}
request.wechat.fakes = fakes;
next();
};
superagent.get(url).set('Cookie', cookieAgent(request, response).toString()).end(cb);
};
补全好友信息:
var entry = function (request, response, next) {
var ep = new EventProxy();
var getInfo = function (index, fake) {
var url = 'http://mp.weixin.qq.com/cgi-bin/getcontactinfo?t=ajax-getcontactinfo&fakeid=' + fake.fakeId;
var cb = function (res) {
request.wechat.fakes[index] = JSON.parse(res.text);
ep.emit('getInfo');
};
superagent.get(url).set('Cookie', cookieAgent(request, response).toString()).end(cb);
};
ep.after('getInfo', request.wechat.fakes.length, function () {
// console.log(request.wechat.fakes);
next();
});
for (var i in request.wechat.fakes) {
getInfo(i, request.wechat.fakes[i]);
}
};
另外今天微信登录的post表单改了.
var postData = {
username: loginData.user,
pwd: md5(loginData.password.substr(0, 16)),
imgcode: loginData.verify,
register: 0,
f: 'json'
};
我用php模仿上传封面图片也碰到了document.domain问题,但是不知道怎么解决: 抓取正确的返回如下:
<script>
document.domain = location.hostname.match(/[^.]?.[^.]?$/); var url = window.location.href, type = url.match(/[?&]type=([^&])/), formId = url.match(/[?&]formId=([^&])/);
type = type[1] || 0; formId = formId[1]; top.W.upload.suc("上传成功", type, formId, ‘10000017’);
</script>但是我用PHP模拟上传了之后返回:
<script>
document.domain = location.hostname.match(/[^.]?.[^.]?$/); var url = window.location.href, type = url.match(/[?&]type=([^&])/), formId = url.match(/[?&]formId=([^&])/);
type = type[1] || 0; formId = formId[1]; top.W.upload.err("上传文件失败", type, formId);
</script>请问如何解决domain这个问题呢?
其实你要正则匹配拿回来的数据,
#node.js:
res.text.replace(/document.location.hostname.match.*\[0\]/g, '"'+req.host+'"')
#php
preg_replace('/document.location.hostname.match.*\[0\]/g/','"'.$_SERVER['HTTP_HOST'].'"', results)
其实你主要是为了拿下面的10000017也就是封面图片的id,正则拿就好了. top.W.upload.suc("上传成功", type, formId, ‘10000017’);
#node.js:
res.text.replace(/document.location.hostname.match.*[0]/g, ‘"’+req.host+’"’)
#php
preg_replace('/document.location.hostname.match.*[0]/g/’,’"’.$_SERVER[‘HTTP_HOST’].’"’, results)
#node.js:
res.text.replace(/document.location.hostname.match.*[0]/g, ‘"’+req.host+’"’)
#php
preg_replace('/document.location.hostname.match.*[0]/g/’,’"’.$_SERVER[‘HTTP_HOST’].’"’, results)`
php版的图片上传是否可以, 我在模拟上传的时候也遇到了这问题. 我的提示如下:
<script> document.domain = location.hostname.match(/[^\.]*?\.[^\.]*?$/); var url = window.location.href, type = url.match(/[\?&]type=([^&]*)/), formId = url.match(/[\?&]formId=([^&]*)/);type = type[1] || 0; formId = formId[1]; top.W.upload.err("上传的素材格式不正确", type, formId);
</script>--------------------------- 如果已解决能否分享一下. 邮箱:[email protected]
我也碰到php版的图片上传是否可以, 我在模拟上传的时候也遇到了这问题. 我的提示如下:
<script> document.domain = location.hostname.match(/[^\.]*?\.[^\.]*?$/); var url = window.location.href, type = url.match(/[\?&]type=([^&]*)/), formId = url.match(/[\?&]formId=([^&]*)/); type = type[1] || 0; formId = formId[1]; top.W.upload.err("上传的素材格式不正确", type, formId); </script>能否解决,麻烦指导下,谢谢!
感谢楼主,正为获取fakeid着急呢,我用的php,模拟登陆获取用户信息页面但是返回的字符串到
<script type="text/javascript">WXM.Conf = {};
WXM.Conf.protocol = (function(){
if(location.host.indexOf("dev")<0 && location.host.indexOf("991") < 0){
return 'https';
}
return 'http';
})();
下面的代码就输出不了,所以也就不用preg_replace了,请问楼主是为什么呢?参数都带上了
我用php想获取用户的头像,代码是这样写的。但是微信用户的图片一点就是下载的,显示不出来,跟一般的好像不一样。那我这样获取URL的方法是不是不对啊。我刚开始学代码,能不能麻烦楼主也写下php怎么保存头像啊。非常感谢啊。我正在做一个东西,但是卡在保存图像这很长时间了。您写的东西给了我很大的帮助,谢谢。 $headimg="https://mp.weixin.qq.com/cgi-bin/getheadimg?token=".$this->_token."&fakeid=".$match[1]; echo $headimg; //创建新图片的名称 $filename=date(“YmdHis”).".jpg"; //建立抓取图片类 $f = new SaeFetchurl(); //抓取图片 $res = $f->fetch($headimg); //如果抓取到图片 if($f->errno() == 0) { //新建存储类 $s = new SaeStorage(); //写入图片 $s->write( ‘sth’ , $filename , $res ); }
@ym1623 你好!我想请问下,目前用C#的话,是否可以实现将图片POST到微信公众平台服务器上面 我试了很长时间都是上传文件失败! 可以将你那边所配置头和参数发一份给我吗? mail:[email protected] 非常感谢!
先运行运行npm install 命令,然后运行http://服务地址:端口/wx/login 或者 修改routers/test/test.coffee的第九行和第十行,把第八行的post修改为get,即能通过get的方式在浏览器中直接运行你的脚本
你可以用snoopy或者curl就可以了,,你可以多看看我的第一篇文章:http://cnodejs.org/topic/510889e9df9e9fcc58b69afe 还有我的github源码:https://github.com/ym1623/node_wx