CNode

Node.js 发送微信下(原创)

Yym1623发布于13 年前最后回复13 年前61 回复51482 浏览0 收藏

上一章已经讲过如何用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的一个认证流程的代码出来/

查看回复

回复 (63)

Z
zhihuzeye#1·13 年前

取好友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];
Y
ym1623#2·13 年前
引用 zhihuzeye取好友fakeId. var pattern = /\"fakeId\" : \"(\d+)\"/gi; var fakes = typeof res.text === 'undefined'...

嗯,很好,遗憾的就是知道微信号或者qq号不能search到fakeid,现在也只能局限于自己的微信好友或者朋友圈了

Y
ym1623#3·13 年前
引用 JacksonTian可以编辑的吧

谢谢提醒,总算找到了,但是位置和图标我感觉不明显,要是能调调那是最好不过的了.

Z
zrhhust#4·13 年前

大侠上面的代码使用的什么语言?我试了js和php都不像,只好自己用js重写一把了

Y
ym1623#5·13 年前
引用 zrhhust大侠上面的代码使用的什么语言?我试了js和php都不像,只好自己用js重写一把了

node.js啊,我用的是coffeescript的语法,你可以在index.js中写require('coffee-script');就能用了

Z
zrhhust#6·13 年前

完整的可运行的code能否给我发一份,我的邮箱如下: zrhhust@gmail.com

L
llb2004#7·13 年前

我用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');

但是我用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);

请问如何解决domain这个问题呢?

Y
ym1623#9·13 年前
引用 llb2004我用php模仿上传封面图片也碰到了document.domain问题,但是不知道怎么解决: 抓取正确的返回如下: <script document.domain = location.host...

其实你要正则匹配拿回来的数据,

#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');

L
letian#10·13 年前

完整的代码能否也给我分享下,我用php试了半天没搞出来就放弃了。看了你这个, 我有来劲了, 想参考你这个改成php的。 呵呵·~ 邮箱:273097817@qq.com 先谢谢了~~~~

O
oliver#11·13 年前

最近学习node.js,真心渴望一个demo,楼主分享一个吧,谢谢! oujianlin1990@126.com

T
tangtaorong86#12·13 年前

楼主能不能把源码发我一份?邮箱:553072209@qq.com,跪谢!!

M
magicbrighter#13·13 年前

楼主分享一下吧,谢谢!
magicbrighter@gmail.com 其实可以和公众平台的机器人结合起来实现更多交互

Y
ym1623#14·13 年前

nodejs发送微信代码我已经放入到我的github中,需要的到该地址下载 https://github.com/ym1623/node_wx

Y
yutingzhao1991#15·13 年前

赞! 不过觉得这只是一个技术性的临时解决方案,最后微信团队肯定是要将发送微信的标准接口制定出来。 不过作为geek怎么能够忍耐等待官方的接口!!!再赞

W
wlpphper#16·13 年前
引用 llb2004我用php模仿上传封面图片也碰到了document.domain问题,但是不知道怎么解决: 抓取正确的返回如下: <script document.domain = location.host...

php版的图片上传是否可以, 我在模拟上传的时候也遇到了这问题. 我的提示如下:

--------------------------- 如果已解决能否分享一下.  邮箱:1060314286@qq.com

W
wh521t#17·13 年前

楼主你好,我刚接触这一块,能发一份给我这个初学者研究研究吗? 664075573@qq.com

R
realeyes#20·13 年前

楼主辛苦了,请发给我一份完整代码吧,我的邮箱是:168177867@qq.com,谢谢!

W
wdy3674172#21·13 年前

@ym1623 你好!我想请问下,目前用C#的话,是否可以实现将图片POST到微信公众平台服务器上面 我试了很长时间都是上传文件失败! 可以将你那边所配置头和参数发一份给我吗? mail:wdy3674172@163.com 非常感谢!

J
j60017268#22·13 年前

兄弟们拿到demo,也传一份给我,非常感谢: mail:j60017268@gmail.com

I
iamroody#23·13 年前

现在貌似又被堵塞了,我现在使用的是php的版本来做的,希望 @ym1623 给确认一下还能继续发不?

H
hawkc#25·13 年前

我是node初学,你用coffee写的,看的好困难,请问怎么运行你的代码呢?node index.js能运行,怎么用呢?

Y
ym1623#26·13 年前

已经更新了github修复了登录bug

地址:https://github.com/ym1623/node_wx

Y
ym1623#27·13 年前
引用 hawkc我是node初学,你用coffee写的,看的好困难,请问怎么运行你的代码呢?node index.js能运行,怎么用呢?

先运行运行npm install 命令,然后运行http://服务地址:端口/wx/login 或者 修改routers/test/test.coffee的第九行和第十行,把第八行的post修改为get,即能通过get的方式在浏览器中直接运行你的脚本

T
tonyidni#28·13 年前

你好 ,完全看不懂啊 我是弄php的 请问在么部署到php上怎么弄?

T
tonyidni#29·13 年前

能否整个PHP 可以运行的(win环境的),小弟不懂node.js 或是你教我怎么整 QQ:742345550@qq.com

Y
ym1623#30·13 年前

发布完不能编辑?这... 如果大家想获取微信的头像的话,其实有点复杂,因为是远程图片,而且要附带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()
Y
ym1623#31·13 年前
引用 zhihuzeye取好友fakeId. var pattern = /\"fakeId\" : \"(\d+)\"/gi; var fakes = typeof res.text === 'undefined'...

其实可以直接用拿到它的好友列表的json数据的,qq微信公众平台的用户管理的html代码中有这样一段: enter image description here

所以...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
Z
zhihuzeye#32·13 年前
引用 zhihuzeye取好友fakeId. var pattern = /\"fakeId\" : \"(\d+)\"/gi; var fakes = typeof res.text === 'undefined'...

嗯这是昨晚写的一段方法, 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'
  };
Y
ym1623#33·13 年前
引用 zhihuzeye取好友fakeId. var pattern = /\"fakeId\" : \"(\d+)\"/gi; var fakes = typeof res.text === 'undefined'...

@zhihuzeye 谢谢提醒,今天早上我看了一下,现在要进行实名认证了,这两天我认证下在看看之前的接口是否存在问题.

Y
ym1623#34·13 年前
引用 zhihuzeye取好友fakeId. var pattern = /\"fakeId\" : \"(\d+)\"/gi; var fakes = typeof res.text === 'undefined'...

@zhihuzeye 实名认证后除了login有所改动,其他接口工作一切正常

K
kongwu#35·13 年前

不错!

J
JacksonTian#36·13 年前

可以编辑的吧

W
wppept#37·13 年前

这么好的项目,上到github上维护吧。

1
1330222#38·13 年前

这种获取fakeid的方法只能是唯一一个用户的情况下,多人关注的时候,怎么获取呢?

Y
yellowbig#40·13 年前

楼主的开源精神值得学习,能不能发我一份呢?dahwang@126.com

Y
ym1623#41·13 年前

现在每次发送都需模拟登录,我已经改成了一次登录后就可以了,然后掉用发送接口即可,避免重复登录,增加了接口的稳定性,可靠性.现在需要此功能的人越来越多,这段时间我会将它放在我的github中.

C
cassano#42·13 年前

lz 用的什么编辑器,这个配色方案 怎么弄?

M
marzoom#43·13 年前
#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)

M
marzoom#44·13 年前
#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)`

A
aven86#45·13 年前

楼主的开源精神值得学习,能不能发一份我呢?aven86@163.com

Y
ym1623#46·13 年前
引用 cassanolz 用的什么编辑器,这个配色方案 怎么弄?

这个是次编辑器回复的markdown语法,我个人用的编辑器是e和sublime

1
105333972#47·13 年前

高手,你写的很漂亮,能否把源码发我一份,研究研究

1
105333972#48·13 年前
S
surefond#49·13 年前
引用 llb2004我用php模仿上传封面图片也碰到了document.domain问题,但是不知道怎么解决: 抓取正确的返回如下: <script document.domain = location.host...

@ym1623 我几乎完全模拟了在web上传文件的行为,包括头,post参数,和files。但是依然返回“上传文件失败”,请教有什么别的注意点么?

S
surefond#50·13 年前
引用 llb2004我用php模仿上传封面图片也碰到了document.domain问题,但是不知道怎么解决: 抓取正确的返回如下: <script document.domain = location.host...

@ym1623 或者方便可以给我一份你测试成功的上传文件的php代码么,不需要完整,主要是头和参数配置。156208621@qq.com。thx。

L
laoflch#51·13 年前

我也碰到php版的图片上传是否可以, 我在模拟上传的时候也遇到了这问题. 我的提示如下:

能否解决,麻烦指导下,谢谢!

W
wechat#53·13 年前

感谢楼主,正为获取fakeid着急呢,我用的php,模拟登陆获取用户信息页面但是返回的字符串到

T
timmit#54·13 年前
引用 ym1623发布完不能编辑?这... 如果大家想获取微信的头像的话,其实有点复杂,因为是远程图片,而且要附带cookie上去,为了怕新手碰壁,以下贴出代码:下面的 basename其实是我定义的全局变量,...

我用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 ); }

Y
ym1623#56·13 年前
引用 wdy3674172@ym1623 你好!我想请问下,目前用C 的话,是否可以实现将图片POST到微信公众平台服务器上面 我试了很长时间都是上传文件失败! 可以将你那边所配置头和参数发一份给我吗? mail:wd...

现在这段时间不知道微信平台是否有变,因为有很多人都对这个功能很感兴趣,这段时间我会找个时间把这个功能推到github中,

Y
ym1623#57·13 年前
引用 ym1623发布完不能编辑?这... 如果大家想获取微信的头像的话,其实有点复杂,因为是远程图片,而且要附带cookie上去,为了怕新手碰壁,以下贴出代码:下面的 basename其实是我定义的全局变量,...

@timmit 你用的是新浪云里面的lib吧,php的话还没做这个代码,nodejs的代码已经公布了,你在处理流的过程是要一点一点写的,然后成功的时候把头像保持至服务器,我现在是这么做的

C
coolicer#58·13 年前

真心没怎么关注coffee,你这样写看得好辛苦。

T
timmit#59·13 年前
T
timmit#60·13 年前

现在获取 fakeid 和获取用户信息的链接地址是不是,我自己找了很长时间也不试不出来哪个是,请问换成什么了呀???????????????、

Y
ysheaven#61·13 年前

初学node,完全一头雾水,求教怎么运行啊

O
oluul#63·13 年前

又是coffescript ,很头痛

参与回复
登录后即可参与回复。登录