微信公众平台向特定用户推送消息

简介: 最近研究微信公众平台,这里整理了一下向特定用户推送消息的思路 一、首先需要将微信的openid与系统用户绑定。 在用户关注公众平台的时候,回复一个链接,要求用户绑定,可以设计如下消息进行回复,(openid最好进行加密处理,后者还需要用这个字段绑定fakeid)。

最近研究微信公众平台,这里整理了一下向特定用户推送消息的思路

一、首先需要将微信的openid与系统用户绑定。

在用户关注公众平台的时候,回复一个链接,要求用户绑定,可以设计如下消息进行回复,(openid最好进行加密处理,后者还需要用这个字段绑定fakeid)。

欢迎关注有问必答平台,< a  href='http://myweixin123.duapp.com/bind.html?openid=@openid'>点击此处进行用户绑定</ a >!

在bind.html页面将openid与系统的usercode进行绑定,这个绑定过程非常简单,这里不详叙述。

二、将openid与fakeid进行绑定

微信公众平台是一回一答的模式;但是在微信公众平台后台,可以向特定用户进行消息发送。我们利用这个机制使用代码去模拟这个过程来实现消息推送。

首先需要模拟登录:

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Web;
using  System.Security.Cryptography;
using  System.Text;
using  System.Net;
using  System.IO;
using  System.Security.Authentication;
using  System.Security.Cryptography.X509Certificates;
/// <summary>
///WeiXinLogin 的摘要说明
/// </summary>
public  class  WeiXinLogin
{
    
     /// <summary>
     /// MD5 32位加密
     /// </summary>
     /// <param name="str"></param>
     /// <returns></returns>
     static  string  GetMd5Str32( string  str)
     {
         MD5CryptoServiceProvider md5Hasher = new  MD5CryptoServiceProvider();
         // Convert the input string to a byte array and compute the hash. 
         char [] temp = str.ToCharArray();
         byte [] buf = new  byte [temp.Length];
         for  ( int  i = 0; i < temp.Length; i++)
         {
             buf[i] = ( byte )temp[i];
         }
         byte [] data = md5Hasher.ComputeHash(buf);
         // Create a new Stringbuilder to collect the bytes 
         // and create a string. 
         StringBuilder sBuilder = new  StringBuilder();
         // Loop through each byte of the hashed data  
         // and format each one as a hexadecimal string. 
         for  ( int  i = 0; i < data.Length; i++)
         {
             sBuilder.Append(data[i].ToString( "x2" ));
         }
         // Return the hexadecimal string. 
         return  sBuilder.ToString();
     }
 
     public  static  bool  ExecLogin( string  name, string  pass)
     {
         bool  result = false ;
         string  password = GetMd5Str32(pass).ToUpper();
         string  padata = "username="  + name + "&pwd="  + password + "&imgcode=&f=json" ;
         string  url = "https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN " ;//请求登录的URL
         try
         {
             CookieContainer cc = new  CookieContainer(); //接收缓存
             byte [] byteArray = Encoding.UTF8.GetBytes(padata); // 转化
             HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create(url);  //新建一个WebRequest对象用来请求或者响应url
             ServicePointManager.CertificatePolicy = new  AcceptAllCertificatePolicy();
 
             webRequest2.CookieContainer = cc;                                      //保存cookie 
             webRequest2.Method = "POST" ;                                          //请求方式是POST
             webRequest2.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69 Safari/537.36" ;
             webRequest2.Referer = "https://mp.weixin.qq.com/" ;
             webRequest2.ContentType = "application/x-www-form-urlencoded" ;       //请求的内容格式为application/x-www-form-urlencoded
             webRequest2.ContentLength = byteArray.Length;
             Stream newStream = webRequest2.GetRequestStream();           //返回用于将数据写入 Internet 资源的 Stream。
             // Send the data.
             newStream.Write(byteArray, 0, byteArray.Length);    //写入参数
             newStream.Close();
             HttpWebResponse response2 = (HttpWebResponse)webRequest2.GetResponse();
             StreamReader sr2 = new  StreamReader(response2.GetResponseStream(), Encoding.Default);
             string  text2 = sr2.ReadToEnd();
 
             //此处用到了newtonsoft来序列化
             WeiXinRetInfo retinfo = Newtonsoft.Json.JsonConvert.DeserializeObject<WeiXinRetInfo>(text2);
             string  token = string .Empty;
             if  (retinfo.ErrMsg.Length > 0)
             {
                 token = retinfo.ErrMsg.Split( new  char [] { '&'  })[2].Split( new  char [] { '='  })[1].ToString(); //取得令牌
                 LoginInfo.LoginCookie = cc;
                 LoginInfo.CreateDate = DateTime.Now;
                 LoginInfo.Token = token;
                 result = true ;
             }
         }
         catch  (Exception ex)
         {
           
             throw  new  Exception(ex.StackTrace);
         }
         return  result;
     }
 
     public  static  class  LoginInfo
     {
         /// <summary>
         /// 登录后得到的令牌
         /// </summary>       
         public  static  string  Token { get ; set ; }
         /// <summary>
         /// 登录后得到的cookie
         /// </summary>
         public  static  CookieContainer LoginCookie { get ; set ; }
         /// <summary>
         /// 创建时间
         /// </summary>
         public  static  DateTime CreateDate { get ; set ; }
 
     }
     internal  class  AcceptAllCertificatePolicy : ICertificatePolicy
     {
         public  AcceptAllCertificatePolicy()
         {
         }
 
         public  bool  CheckValidationResult(ServicePoint sPoint,
            X509Certificate cert, WebRequest wRequest, int  certProb)
         {
             // Always accept 
             return  true ;
         }
    
}

获取fakeid

public  static  ArrayList SubscribeMP()
{
 
     try
     {
         CookieContainer cookie = null ;
         string  token = null ;
 
 
         cookie = WeiXinLogin.LoginInfo.LoginCookie; //取得cookie
         token = WeiXinLogin.LoginInfo.Token; //取得token
 
         /*获取用户信息的url,这里有几个参数给大家讲一下,1.token此参数为上面的token 2.pagesize此参数为每一页显示的记录条数
 
         3.pageid为当前的页数,4.groupid为微信公众平台的用户分组的组id,当然这也是我的猜想不一定正确*/
         string  Url = "https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&token="  + token + "&lang=zh_CN" ;
         HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create(Url);
         webRequest2.CookieContainer = cookie;
         webRequest2.ContentType = "text/html; charset=UTF-8" ;
         webRequest2.Method = "GET" ;
         webRequest2.UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1" ;
         webRequest2.ContentType = "application/x-www-form-urlencoded" ;
         HttpWebResponse response2 = (HttpWebResponse)webRequest2.GetResponse();
         StreamReader sr2 = new  StreamReader(response2.GetResponseStream(), Encoding.Default);
         string  text2 = sr2.ReadToEnd();
 
 
         MatchCollection mc;
 
         //由于此方法获取过来的信息是一个html网页所以此处使用了正则表达式,注意:(此正则表达式只是获取了fakeid的信息如果想获得一些其他的信息修改此处的正则表达式就可以了。)
         Regex r = new  Regex( "\"id\"\\:\\d+,\"nick_name\"" ); //定义一个Regex对象实例
         mc = r.Matches(text2);
         Int32 friendSum = mc.Count;          //好友总数
 
         string  fackID = "" ;
 
         ArrayList fackID1 = new  ArrayList();
 
         for  ( int  i = 0; i < friendSum; i++)
         {
             //"id":208989515,"nick_name"
             fackID = mc[i].Value.Replace( ",\"nick_name\"" , "" ).Split( new  char [] { ':'  })[1];
             fackID = fackID.Replace( "\"" , "" ).Trim();
             fackID1.Add(fackID);
         }
 
         return  fackID1;
 
 
 
     }
     catch  (Exception ex)
     {
         throw  new  Exception(ex.StackTrace);
     }
}

根据fakeid获取openid

复制代码
    public static string GetOpenidByFakeid(string fakeid)
    {
        try
        {
            CookieContainer cookie = null;
            string token = null;


            cookie = WeiXinLogin.LoginInfo.LoginCookie;//取得cookie
            token = WeiXinLogin.LoginInfo.Token;//取得token
            string Url = "https://mp.weixin.qq.com/cgi-bin/singlemsgpage?msgid=&source=&count=20&t=wxm-singlechat&fromfakeid=" + fakeid + "&token=" + token + "&lang=zh_CN";
            HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create(Url);
            webRequest2.CookieContainer = cookie;
            webRequest2.ContentType = "text/html; charset=UTF-8";
            webRequest2.Method = "GET";
            webRequest2.UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1";
            webRequest2.ContentType = "application/x-www-form-urlencoded";
            HttpWebResponse response2 = (HttpWebResponse)webRequest2.GetResponse();
            StreamReader sr2 = new StreamReader(response2.GetResponseStream(), Encoding.UTF8);
            string text2 = sr2.ReadToEnd();
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(text2);
            var str = doc.GetElementbyId("json-msgList").InnerHtml;
            JArray messages = JArray.Parse(str);
            foreach (var message in messages)
            {
                string strContent = HttpUtility.HtmlDecode(message["content"].ToString());
                Regex reg = new Regex(@"(?is)<a[^>]*?href=(['""\s]?)(?<href>[^'""\s]*)\1[^>]*?>");
                MatchCollection match = reg.Matches(strContent);
                var href = "";
                foreach (Match m in match)
                {
                    href = m.Groups["href"].Value;
                }

                var openid = GetUrlParamValue(href, "openid");
                if (!string.IsNullOrEmpty(openid))
                 return openid;

            }
            return "";
        }
        catch (Exception ex)
        {
            return "";
        }
  
    }
复制代码

 

由于之前有建立openid与usercode的关系,所以可以根据usercode找到openid,又可以根据openid找到fakeid。使用下面代码进行推送:

public  static  bool  SendMessage( string  Message, string  fakeid)
{
     bool  result = false ;
     CookieContainer cookie = null ;
     string  token = null ;
     cookie = WeiXinLogin.LoginInfo.LoginCookie; //取得cookie
     token =  WeiXinLogin.LoginInfo.Token; //取得token
 
     string  strMsg = System.Web.HttpUtility.UrlEncode(Message);  //对传递过来的信息进行url编码
     string  padate = "type=1&content="  + strMsg + "&error=false&tofakeid="  + fakeid + "&token="  + token + "&ajax=1" ;
     string  url = "https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response&lang=zh_CN" ;
 
     byte [] byteArray = Encoding.UTF8.GetBytes(padate); // 转化
 
     HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create(url);
 
     webRequest2.CookieContainer = cookie; //登录时得到的缓存
 
     webRequest2.Referer = "https://mp.weixin.qq.com/cgi-bin/singlemsgpage?token="  + token + "&fromfakeid="  + fakeid + "&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN" ;
 
     webRequest2.Method = "POST" ;
 
     webRequest2.UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1" ;
 
     webRequest2.ContentType = "application/x-www-form-urlencoded" ;
 
     webRequest2.ContentLength = byteArray.Length;
 
     Stream newStream = webRequest2.GetRequestStream();
 
     // Send the data.           
     newStream.Write(byteArray, 0, byteArray.Length);    //写入参数   
 
     newStream.Close();
 
     HttpWebResponse response2 = (HttpWebResponse)webRequest2.GetResponse();
 
     StreamReader sr2 = new  StreamReader(response2.GetResponseStream(), Encoding.Default);
 
     string  text2 = sr2.ReadToEnd();
     if  (text2.Contains( "ok" ))
     {
         result = true ;
     }
     return  result;
}

  

可以写一个长期运行的windows服务用于建立fakeid和openid的关系,这里不再详诉。




本文转自麒麟博客园博客,原文链接:http://www.cnblogs.com/zhuqil/p/3354640.html,如需转载请自行联系原作者

相关文章
|
监控 安全 机器人
通过GitHub Actions给微信公众测试号和钉钉群定时推送消息(Python)
通过GitHub Actions给微信公众测试号和钉钉群定时推送消息(Python)
238 0
|
JSON 运维 JavaScript
教你如何快速接入微信消息通知,使用消息推送服务,「传息」推送消息到个人微信
教你如何快速接入微信消息通知,使用消息推送服务,「传息」推送消息到个人微信
1818 0
|
7月前
|
jenkins Devops 机器人
【DevOps】(五)Jenkins构建给企业微信推送消息
【DevOps】(五)Jenkins构建给企业微信推送消息
282 1
|
6月前
|
程序员
程序员必知:微信报错40029微信模板推送消息报错问题
程序员必知:微信报错40029微信模板推送消息报错问题
237 0
|
7月前
|
人工智能 机器人 API
【Python+微信】【企业微信开发入坑指北】3. 如何利用企业微信API给微信群推送消息
【Python+微信】【企业微信开发入坑指北】3. 如何利用企业微信API给微信群推送消息
310 0
|
运维 机器人 Java
Springboot 整合 企业微信机器人助手推送消息
Springboot 整合 企业微信机器人助手推送消息
1161 0
Springboot 整合 企业微信机器人助手推送消息
|
JSON 开发者 数据格式
微信服务号通过客服接口主动给普通微信号推送消息
当用户主动发消息给公众号的时候(包括发送信息、点击自定义菜单、订阅事件、扫描二维码事件、支付成功事件、用户维权),微信将会把消息数据推送给开发者,开发者在一段时间内(目前修改为48小时)可以调用客服消息接口,通过POST一个JSON数据包来发送消息给普通用户,在48小时内不限制发送次数。此接口主要用于客服等有人工消息处理环节的功能,方便开发者为用户提供更加优质的服务。
523 0
微信服务号通过客服接口主动给普通微信号推送消息
|
XML 数据格式
记一次接收微信公众平台推送消息的实例
本章的内容来源是有朋友咨询怎么做微信公众号信息的收发消息功能,因此本着为社区做贡献的态度申请了个人公众号,然后尝试对接了一下接收公众号内容信息的流程;要说对接其实呢也算不上,因为个人账号只有简单的一些接收,被动回复等功能信息,不能群发和使用客服接口,所以本章主要分享的是怎么接受信息和被动发送回复信息...
1112 0
|
2月前
|
JSON 小程序 JavaScript
uni-app开发微信小程序的报错[渲染层错误]排查及解决
uni-app开发微信小程序的报错[渲染层错误]排查及解决
679 7