LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# WebQQ协议群发机器人(一)

admin
2016年12月23日 18:55 本文热度 5775

原创性申明

本文地址 http://blog.csdn.net/zhujunxxxxx/article/details/38931287 转载的话请注明出处!

之前我也写过一篇使用Python来实现的一个版本 点击打开链接

前言

现在我用c#语言改写过后也放出源码来让大家学习,希望大家喜欢,不懂的相互交流,

目前我实现的一些功能包括  第一次登录  二次登陆 获取群信息  获取群好友 发送群消息 发送消息给好友

先给出一些webqq的一些参数吧

 如果有人需要源码可以联系我 qq: 10588690,但是不是无偿提供,请大家理解。

协议分析

psessionid 这个是在第二次登录的时候在 cookie中的一个重要的值,在后面获取群信息,获取好友信息等 都要用到这个参数

vfwebqq 这个同上

ptwebqq 同上

hash  这个参数是后面发送群消息和好友消息需要用到的,以前版本没有 后面加上了

先给出腾讯密码加密算法  这部分我是用我以前python版本的 比较懒这部分没有转为c#版本的

[python] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #md5  
  2.     def PCMd5(self,s):  
  3.         h=hashlib.md5()  
  4.         h.update(s)  
  5.         return h.hexdigest()  
  6.     #16 to cgar  
  7.     def hex2asc(self,s):  
  8.         _str="".join(s.split(r''\x''))  
  9.         length=len(_str)  
  10.         data=''''  
  11.         for i in range(0,length,2):  
  12.             data+=chr(int(_str[i:i+2],16))  
  13.         return data  
  14.     #the password encrypt  v1 is checkcode  
  15.     def PasswordSecret(self,password,v1,v2,md5=True):  
  16.         if md5==True:  
  17.             password=self.PCMd5(password).upper()  
  18.         length=len(password)  
  19.         temp=''''  
  20.         for i in range(0,length,2):  
  21.             temp+=r''\x''+password[i:i+2]  
  22.         return self.PCMd5(self.PCMd5(self.hex2asc(temp)+self.hex2asc(v2)).upper()+v1).upper()  


Hash算法

然后给的是hash算法

 

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /// <summary>  
  2.         /// 获取hash值的算法  
  3.         /// </summary>  
  4.         /// <param name="b"></param>  
  5.         /// <param name="j"></param>  
  6.         /// <returns></returns>  
  7.         public string Hash(string b, string j)  
  8.         {  
  9.             string a = j + "password error";  
  10.             string i = "";  
  11.             List<int> E = new List<int>();  
  12.             while(true)  
  13.             {  
  14.                 if (i.Length <= a.Length)  
  15.                 {  
  16.                     i += b;  
  17.                     if (i.Length == a.Length)  
  18.                     {  
  19.                         break;  
  20.                     }  
  21.                 }  
  22.                 else  
  23.                 {  
  24.                     i = i.Substring(0, a.Length);  
  25.                     break;  
  26.                 }  
  27.   
  28.             }  
  29.             for (int c = 0; c < i.Length; c++)  
  30.             {  
  31.                 int tmp = (char)i[c] ^ (char)a[c];  
  32.                 E.Add(tmp);  
  33.             }  
  34.             string[] seed = {"0""1""2""3""4""5""6""7""8""9""A""B""C""D""E""F"};  
  35.             i = "";  
  36.             for (int c = 0; c < E.Count; c++)  
  37.             {  
  38.                 i += seed[E[c] >> 4 & 15];  
  39.                 i += seed[E[c] & 15];  
  40.             }  
  41.   
  42.             return i;  
  43.         }  


这个函数的参数是 第一个是你的qq号 第二个是ptwebqq 之前一直以为是vfwebqq 结果一直出错

 这两个函数都是正确的,网上很多的方法已经失效了

是否需要验证码

首先在登录时,你必须检查是否需要输入验证码 这个函数的返回值是一个字符串

ptui_checkVC(''0'',''!NTZ'',''\x00\x00\x00\x00\x22\x79\x9f\x0d'', ''ef0e577a40249cc2b77dc9f266a3a4141a987d06a8f3ae39117183f1ff0491720e1f6f498a9a038f032d99f8622ea628'');

第一个参数是0 表示不需要输入参数,第二个参数是一个验证码 后面用来加密密码的

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //检查是否需要 验证码  
  2.         public bool check()  
  3.         {  
  4.             string url = "https://ssl.ptlogin2.qq.com/check?uin={$uin}&appid=1003903&js_ver=10092&js_type=0&login_sig=K5F0E8woS74td4sRIqKiSHmH6B2RYYP467z2r*6YWaH4wc7vE*4G*X7V2kGP9s1*&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&r=0.2689784204121679";  
  5.             url = url.Replace("{$uin}"this.qq);  
  6.             HttpItem item = new HttpItem()  
  7.             {  
  8.                 URL = url,//URL     必需项      
  9.                 Encoding = System.Text.Encoding.GetEncoding("utf-8"),//URL     可选项 默认为Get     
  10.                 Method = "get",//URL     可选项 默认为Get     
  11.                 IsToLower = false,//得到的HTML代码是否转成小写     可选项默认转小写     
  12.                 Timeout = 100000,//连接超时时间     可选项默认为100000      
  13.                 ReadWriteTimeout = 30000,//写入Post数据超时时间     可选项默认为30000     
  14.                 UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0",//用户的浏览器类型,版本,操作系统     可选项有默认值     
  15.                 ContentType = "application/x-www-form-urlencoded",//返回类型    可选项有默认值     
  16.                 ResultType = ResultType.String,  
  17.             };  
  18.             HttpResult result = http.GetHtml(item);  
  19.             Regex reg = new Regex(@"ptui_checkVC(.),(.),(.),(.);");  
  20.             Match m = reg.Match(result.Html);  
  21.             string[] ret = new string[m.Groups.Count];  
  22.             for (int i = 0; i < m.Groups.Count; i++)  
  23.             {  
  24.                 ret[i] = m.Groups[i].Value;  
  25.             }  
  26.             this.checkv2 = ret[3];  
  27.             if (ret[1] == "0")  
  28.             {  
  29.                 this.checkcode = ret[2];  
  30.                 this.session = ret[4];  
  31.                 return false;  
  32.             }  
  33.             else  
  34.                 return true;  
  35.         }  


 一次登录

接下来是我们第一次登录

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public bool Login()  
  2.         {  
  3.             string url = "https://ssl.ptlogin2.qq.com/login?u={$uin}&p={$pwd}&verifycode={$verify}&webqq_type=10&remember_uin=1&login2qq=0&aid=1003903&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html%3Flogin2qq%3D0%26webqq_type%3D10&h=1&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=2-9-33854&mibao_css=m_webqq&t=1&g=1&js_type=0&js_ver=10092&login_sig=K5F0E8woS74td4sRIqKiSHmH6B2RYYP467z2r*6YWaH4wc7vE*4G*X7V2kGP9s1*&pt_uistyle=5&pt_vcode_v1=0&pt_verifysession_v1={$session}";  
  4.             url=url.Replace("{$uin}",this.qq);  
  5.             url=url.Replace("{$verify}",this.checkcode);  
  6.             string pwd = encrypt.Encrypt_Password(this.qq,this.password,this.checkcode);  
  7.             url=url.Replace("{$pwd}",pwd);  
  8.             url = url.Replace("{$session}"this.session);  
  9.             HttpItem item = new HttpItem()  
  10.             {  
  11.                 URL = url,  
  12.                 Encoding = System.Text.Encoding.GetEncoding("utf-8"),    
  13.                 Method = "get",  
  14.                 IsToLower = false,  
  15.                 Timeout = 100000,   
  16.                 Referer="https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=5&mibao_css=m_webqq&appid=1003903&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20140612002",  
  17.                 Host="d.web2.qq.com",  
  18.                 UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0",//用户的浏览器类型,版本,操作系统     可选项有默认值     
  19.                 ContentType = "application/x-www-form-urlencoded",  
  20.                 ResultType = ResultType.String  
  21.             };  
  22.             HttpResult result = http.GetHtml(item);  
  23.   
  24.             foreach (Cookie c in result.CookieCollection)  
  25.             {  
  26.                 if (c.Name == "ptwebqq")  
  27.                     this.ptwebqq = c.Value;  
  28.             }  
  29.             this.hash= Hash(this.qq, this.ptwebqq);  
  30.   
  31.             Regex reg = new Regex(@"ptuiCB(.),(.),(.),(.),(.),\s(.);");  
  32.             Match m = reg.Match(result.Html);  
  33.             string[] ret = new string[m.Groups.Count];  
  34.             for (int i = 0; i < m.Groups.Count; i++)  
  35.             {  
  36.                 ret[i] = m.Groups[i].Value;  
  37.             }  
  38.             if (ret[1] == "0")  
  39.             {  
  40.                 this.proxyurl = ret[3];  
  41.                 return true;  
  42.             }  
  43.             else  
  44.                 return false;  
  45.               
  46.         }  


第一次登录后会返回 return ptuiCB(''0'',''0'',''http://ptlogin4.web2.qq.com/check_sig?pttype=1&uin=578395917&service=login&nodirect=0&ptsig=uV34Xt9XM3e2oQ3wuub8LIBIGsIIZATjiz-cqSVHJ5o_&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html%3Flogin2qq%3D0%26webqq_type%3D10&f_url=&ptlang=2052&ptredirect=100&aid=1003903&daid=164&j_later=0&low_login_hour=0&regmaster=0&pt_login_type=1&pt_aid=0&pt_aaid=0&pt_light=0'',''0'',''登录成功!'', ''你的名字'');

如果第一个参数不是0的话 表示有错,如果像这样的话就表示成功了

返回结果中的那个ur链接我们用get方式打开它,这个步骤是为了获取一个关键的cookie值 p_skey 这个是第二次登录的时候有用

 二次登陆

接下来是我们二次登录了

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public void Login2()  
  2.         {  
  3.               
  4.             Dictionary<string, Object> r = new Dictionary<string, Object>();  
  5.             r.Add("status""online");  
  6.             r.Add("ptwebqq"this.ptwebqq);  
  7.             r.Add("passwd_sig""");  
  8.             r.Add("clientid"this.clientid.ToString());  
  9.             r.Add("psessionid"null);  
  10.             Dictionary<string, Object> data = new Dictionary<string, Object>();  
  11.             data.Add("r", JsonConvert.SerializeObject(r));  
  12.             data.Add("clientid"this.clientid);  
  13.             data.Add("psessionid""null");  
  14.             string postdata = Tool.MakePostData(data);  
  15.               
  16.             //string postdata="r=%7B%22status%22%3A%22online%22%2C%22ptwebqq%22%3A%22{$ptwebqq}%22%2C%22passwd_sig%22%3A%22%22%2C%22clientid%22%3A%22{$clientid}%22%2C%22psessionid%22%3Anull%7D&clientid={$clientid}&psessionid=null";  
  17.             //postdata=postdata.Replace("{$ptwebqq}",this.ptwebqq);  
  18.             //postdata = postdata.Replace("{$clientid}", this.clientid);  
  19.             HttpItem item = new HttpItem()  
  20.             {  
  21.                 URL = "http://d.web2.qq.com/channel/login2",//URL     必需项       
  22.                 Method = "POST",//URL     可选项 默认为Get  
  23.                 IsToLower = false,//得到的HTML代码是否转成小写     可选项默认转小写  
  24.                 Timeout = 100000,//连接超时时间     可选项默认为100000      
  25.                 Postdata=postdata,  
  26.                 Host=HOST[0],  
  27.                 Referer=REFERER[0],  
  28.                 UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36",//用户的浏览器类型,版本,操作系统     可选项有默认值     
  29.                 ContentType = "application/x-www-form-urlencoded",//返回类型    可选项有默认值  
  30.                 Accept="*/*",  
  31.                 ResultType = ResultType.String  
  32.             };  
  33.             HttpResult result = http.GetHtml(item);  
  34.             JObject obj = (JObject)JsonConvert.DeserializeObject(result.Html);  
  35.             this.vfwebqq= obj["result"]["vfwebqq"].ToString();  
  36.             this.psessionid = obj["result"]["psessionid"].ToString();  
  37.   
  38.         }  


这个步骤很重要,获取很多有用的cookie值,上面提到的那些就要用一个变量保存下来,以便后面使用

获取群列表

下面我们就要拉去我们的群组信息了

这个返回结果是一个json格式的,我们需要序列化为json对象,把里面的群相关信息存起来

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /// <summary>  
  2.         /// 获取群列表  
  3.         /// </summary>  
  4.         public void GetGroupNameList()  
  5.         {  
  6.               
  7.             Dictionary<string, Object> r = new Dictionary<string, Object>();  
  8.             r.Add("hash"this.hash);  
  9.             r.Add("vfwebqq"this.vfwebqq);  
  10.             Dictionary<string, Object> data = new Dictionary<string, Object>();  
  11.             data.Add("r", JsonConvert.SerializeObject(r));  
  12.             string postdata = Tool.MakePostData(data);  
  13.               
  14.             //string postdata = "r=%7B%22hash%22%3A%22{$hash}%22%2C%22vfwebqq%22%3A%22{$vfwebqq}%22%7D";  
  15.             //postdata = postdata.Replace("{$hash}", this.hash);  
  16.             //postdata = postdata.Replace("{$vfwebqq}", this.vfwebqq);  
  17.             HttpItem item = new HttpItem()  
  18.             {  
  19.                 URL = "http://s.web2.qq.com/api/get_group_name_list_mask2",  
  20.                 Method = "POST",  
  21.                 IsToLower = false,  
  22.                 Timeout = 100000,  
  23.                 Postdata = postdata,  
  24.                 Host = HOST[1],  
  25.                 Referer = REFERER[1],  
  26.                 UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36",//用户的浏览器类型,版本,操作系统     可选项有默认值     
  27.                 ContentType = "application/x-www-form-urlencoded",  
  28.                 ResultType = ResultType.String  
  29.             };  
  30.             HttpResult result = http.GetHtml(item);  
  31.             JObject ret = (JObject)JsonConvert.DeserializeObject(result.Html);  
  32.             JObject retjson = (JObject)ret["result"];  
  33.             foreach (JToken jk in retjson["gnamelist"])//获取群信息用 code  发送群信息用 gid  
  34.             {  
  35.                 this.grouplist.Add(jk["gid"].ToString()+":"+jk["code"].ToString(), jk["name"].ToString());  
  36.             }  
  37.   
  38.         }  


每个群 有个gid 和code  name  其中获取群成员的使用code 而向群发送消息的时候用的是gid 这部分一定要注意 我花了很多时间才发现自己的错误

 群信息

获取某个群的群成员信息 参数就是上面提到的code 不要用错了哦

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /// <summary>  
  2.         /// 根据群code得到群信息  
  3.         /// </summary>  
  4.         /// <param name="gcode"></param>  
  5.         public void GetGroupInfo(string gcode)  
  6.         {  
  7.             string url = "http://s.web2.qq.com/api/get_group_info_ext2?gcode={$gcode}&cb=undefined&vfwebqq={$vfwebqq}&t=1409316979595";  
  8.             url=url.Replace("{$vfwebqq}",this.vfwebqq);  
  9.             url = url.Replace("{$gcode}", gcode);  
  10.   
  11.             HttpItem item = new HttpItem()  
  12.             {  
  13.                 URL = url,  
  14.                 Encoding = System.Text.Encoding.GetEncoding("utf-8"),   
  15.                 Method = "get",  
  16.                 IsToLower = false,    
  17.                 Timeout = 100000,   
  18.                 ReadWriteTimeout = 30000,  
  19.                 Host=HOST[1],  
  20.                 Referer=REFERER[1],  
  21.                 UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0",//用户的浏览器类型,版本,操作系统     可选项有默认值     
  22.                 ContentType = "application/x-www-form-urlencoded",   
  23.                 ResultType = ResultType.String,  
  24.             };  
  25.             HttpResult result = http.GetHtml(item);  
  26.             JObject ret = (JObject)JsonConvert.DeserializeObject(result.Html);  
  27.             JObject retjson = (JObject)ret["result"];  
  28.             foreach (JToken jk in retjson["cards"])  
  29.             {  
  30.                 this.groupinfo.Add(jk["muin"].ToString(), jk["card"].ToString());  
  31.             }  
  32.         }  

发送群消息

下面是向群里面发送消息  这个用的就是刚才说的 gid 也不要用错了

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public void SendGroupMsg(long groupid,string msg)  
  2.         {  
  3.             string style="\"{content}\"";  
  4.             string temp="";  
  5.             temp += style.Replace("{content}", msg) + ",";  
  6.             temp = temp.Substring(0, temp.Length - 1);  
  7.             Random rd = new Random();  
  8.             int msg_id = (rd.Next(100000) + 100000);  
  9.             string content="[{$msg},\"\",[\"font\",{\"name\":\"宋体\",\"size\":\"10\",\"style\":[0,0,0],\"color\":\"000000\"}]]";  
  10.             content = content.Replace("{$msg}", temp);  
  11.               
  12.             Dictionary<string, Object> r = new Dictionary<string, Object>();  
  13.             r.Add("group_uin", groupid);  
  14.             r.Add("content", content);  
  15.             r.Add("msg_id", msg_id);  
  16.             r.Add("clientid"this.clientid);  
  17.             r.Add("psessionid",this.psessionid);  
  18.             Dictionary<string, Object> data = new Dictionary<string, Object>();  
  19.             data.Add("r", JsonConvert.SerializeObject(r));  
  20.             data.Add("clientid"this.clientid);  
  21.             data.Add("psessionid"this.psessionid);  
  22.             string postdata = Tool.MakePostData(data);  
  23.               
  24.             HttpItem item = new HttpItem()  
  25.             {  
  26.                 URL = "http://d.web2.qq.com/channel/send_qun_msg2",  
  27.                 Accept="*/*",  
  28.                 Method = "POST",  
  29.                 IsToLower = false,  
  30.                 KeepAlive=true,  
  31.                 Timeout = 100000,  
  32.                 Postdata = postdata,  
  33.                 Host = HOST[0],  
  34.                 Referer = REFERER[0],  
  35.                 UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2041.4 Safari/537.36",  
  36.                 ContentType = "application/x-www-form-urlencoded",  
  37.                 ResultType = ResultType.String  
  38.             };  
  39.             HttpResult result = http.GetHtml(item);  
  40.             JObject ret = (JObject)JsonConvert.DeserializeObject(result.Html);  
  41.               
  42.             //string html = HttpHelper2.GetHtml("http://d.web2.qq.com/channel/send_qun_msg2", postdata,HttpHelper.cookies);  
  43.   
  44.         }  


接下来还有 获取好友信息和 向好友发送消息...

这一部分我放在下一篇将    头昏啊!sorry!

 

该文章在 2016/12/23 18:55:57 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved