微信网页版接口,通过抓包工具抓取得到,比较详细,部分参数可能发生改变
public class initWeChatLogin { static string uuid = ""; static string successUrl = "";//登录成功后返回的路径 static string skey = ""; static string wxsid = ""; static string wxuin = ""; static string pass_ticket = ""; static string isgrayscale = ""; static string DeviceID = ""; public static JObject BaseResponse;//联系人字符串 static string MsgID = ""; public static string webwx_data_ticket = ""; public initWeChatLogin() { uuid = ""; successUrl = ""; skey = ""; wxsid = ""; wxuin = ""; pass_ticket = ""; isgrayscale = ""; DeviceID = ""; BaseResponse = null; MsgID = ""; webwx_data_ticket = ""; } /// <summary> /// 获取登录二维码 /// </summary> /// <returns></returns> public static Bitmap GetLoginQrcode() { Bitmap loginQrcode = null; try { long Timestamps = Common.ConvertDateTimeToInt(DateTime.Now); //得到uuid string LoginJson_1 = Common.doGet("https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=" + Timestamps); uuid = LoginJson_1.Substring(LoginJson_1.IndexOf("window.QRLogin.uuid =") + "window.QRLogin.uuid =".Length); uuid = uuid.Replace("\"", ""); uuid = uuid.Replace(";", "").Trim(); //得到登录的二维码 loginQrcode = (Bitmap)Image.FromStream(WebRequest.Create(("https://login.weixin.qq.com/qrcode/" + uuid).Trim()).GetResponse().GetResponseStream()); } catch (Exception ex) { Common.ErrorLog(ex, "GetLoginQrcode"); } return loginQrcode; } /// <summary> /// 获取登录成功后的路径 /// </summary> /// <returns></returns> public static string GetLoginSuccessUrl() { string url = ""; int random = new Random().Next(100000000, 999999999); long Timestamps = Common.ConvertDateTimeToInt(DateTime.Now); string json = Common.doGet("https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=" + uuid + "&tip=0&r=" + random + "&_=" + Timestamps); if (string.IsNullOrEmpty(json)) { json = Common.doGet("https://login.wx2.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=" + uuid + "&tip=0&r=" + random + "&_=" + Timestamps); } var code = json.Substring(json.IndexOf("window.code=") + "window.code=".Length, 3); if (code.Trim() == "200") { if (json.IndexOf("https") != -1) { url = json.Substring(json.IndexOf("redirect_uri=") + "redirect_uri=".Length); url = url.Replace("\"", ""); url = url.Replace(";", "").Trim(); successUrl = url; } } return url; } /// <summary> /// 获取微信用户信息 /// </summary> public static void GetWeChatUserInfo() { string json = Common.HttpPostGetCookie(successUrl + "&fun=new&version=v2",""); if (Common.GetXmlConfig("ret", json) == "0") { skey = Common.GetXmlConfig("skey", json); wxsid = Common.GetXmlConfig("wxsid", json); wxuin = Common.GetXmlConfig("wxuin", json); pass_ticket = Common.GetXmlConfig("pass_ticket", json); isgrayscale = Common.GetXmlConfig("isgrayscale", json); } else { MessageBox.Show(Common.GetXmlConfig("message", json)); } } /// <summary> /// 初始化微信获取联系人信息 /// </summary> /// <returns></returns> public static string webwxinit() { int random = new Random().Next(100000000, 999999999); string parment = ""; Dictionary<string, object> BaseRequest = new Dictionary<string, object>(); BaseRequest.Add("Uin", wxuin); BaseRequest.Add("Sid", wxsid); BaseRequest.Add("Skey", skey); DeviceID = "e" + (random.ToString() + (new Random().Next(10000, 99999).ToString())); BaseRequest.Add("DeviceID", DeviceID); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("BaseRequest", BaseRequest); parment = Newtonsoft.Json.JsonConvert.SerializeObject(dic); string json = Common.PostMoths("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=" + random + "&pass_ticket=" + pass_ticket, parment); BaseResponse = JObject.Parse(json); if (BaseResponse["BaseResponse"]["Ret"].ToString() != "0") { json = Common.PostMoths("https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=" + random + "&pass_ticket=" + pass_ticket, parment); BaseResponse = JObject.Parse(json); } return json; } /// <summary> /// 开启消息通知状态 /// </summary> /// <returns></returns> public static void webwxstatusnotify() { int random = new Random().Next(100000000, 999999999); string parment = ""; Dictionary<string, object> BaseRequest = new Dictionary<string, object>(); BaseRequest.Add("Uin", wxuin); BaseRequest.Add("Sid", wxsid); BaseRequest.Add("Skey", skey); DeviceID = "e" + (random.ToString() + (new Random().Next(10000, 99999).ToString())); BaseRequest.Add("DeviceID", DeviceID); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("BaseRequest", BaseRequest); dic.Add("ClientMsgId", Common.ConvertDateTimeToInt(DateTime.Now)); dic.Add("Code", 3); dic.Add("FromUserName", BaseResponse["User"]["UserName"].ToString()); dic.Add("ToUserName", BaseResponse["User"]["UserName"].ToString()); parment = Newtonsoft.Json.JsonConvert.SerializeObject(dic); string json = Common.PostMoths("https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify?lang=zh_CN&pass_ticket=" + pass_ticket, parment); JObject obj = JObject.Parse(json); if (obj["BaseResponse"]["Ret"].ToString() != "0") { json = Common.PostMoths("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify?lang=zh_CN&pass_ticket=" + pass_ticket, parment); obj = JObject.Parse(json); } MsgID = obj["MsgID"].ToString(); } ///// <summary> ///// 请求群组列表 ///// </summary> //public static void webwxbatchgetcontact() //{ // int random = new Random().Next(100000000, 999999999); // string parment = ""; // Dictionary<string, object> BaseRequest = new Dictionary<string, object>(); // BaseRequest.Add("Uin", wxuin); // BaseRequest.Add("Sid", wxsid); // BaseRequest.Add("Skey", skey); // DeviceID = "e" + (random.ToString() + (new Random().Next(10000, 99999).ToString())); // BaseRequest.Add("DeviceID", DeviceID); // Dictionary<string, object> dic = new Dictionary<string, object>(); // dic.Add("BaseRequest", BaseRequest); // string json = Common.PostMoths("https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact?type=ex&r=" + random + "&lang=zh_CN&pass_ticket="+pass_ticket, parment); //} static string webwxsyncparment = ""; public static JObject webwxsyncsObj; /// <summary> /// 获取消息 /// </summary> public static webwxsync webwxsyncs() { //if (string.IsNullOrEmpty(webwxsyncparment)) //{ int random = new Random().Next(100000000, 999999999); Dictionary<string, object> BaseRequest = new Dictionary<string, object>(); BaseRequest.Add("Uin", wxuin); BaseRequest.Add("Sid", wxsid); BaseRequest.Add("Skey", skey); DeviceID = "e" + (random.ToString() + (new Random().Next(10000, 99999).ToString())); BaseRequest.Add("DeviceID", DeviceID); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("BaseRequest", BaseRequest); dic.Add("SyncKey", BaseResponse["SyncKey"]); webwxsyncparment = Newtonsoft.Json.JsonConvert.SerializeObject(dic); // } string json = Common.PostMoths("https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=" + wxsid + "&skey=" + skey + "&lang=zh_CN&pass_ticket=" + pass_ticket, webwxsyncparment); webwxsyncsObj = JObject.Parse(json); if (webwxsyncsObj["BaseResponse"]["Ret"].ToString() != "0") { json = Common.PostMoths("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=" + wxsid + "&skey=" + skey + "&lang=zh_CN&pass_ticket=" + pass_ticket, webwxsyncparment); webwxsyncsObj = JObject.Parse(json); } return JsonConvert.DeserializeObject<webwxsync>(json); } /// <summary> /// 发消息 /// </summary> /// <param name="ToUserName"></param> /// <param name="Msg"></param> /// <param name="Types">消息类型</param> public static void webwxsendmsg(string ToUserName, string Msg) { try { bool fig = false; string parment = ""; int random = new Random().Next(100000000, 999999999); Dictionary<string, object> BaseRequest = new Dictionary<string, object>(); BaseRequest.Add("Uin", wxuin); BaseRequest.Add("Sid", wxsid); BaseRequest.Add("Skey", skey); DeviceID = "e" + (random.ToString() + (new Random().Next(10000, 99999).ToString())); BaseRequest.Add("DeviceID", DeviceID); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("BaseRequest", BaseRequest); var msgId = Common.ConvertDateTimeToInt(DateTime.Now).ToString() + (new Random().Next(1000, 9999).ToString()); Dictionary<string, object> dicMsg = new Dictionary<string, object>(); dicMsg.Add("ClientMsgId", msgId); dicMsg.Add("Content", Msg); dicMsg.Add("FromUserName", BaseResponse["User"]["UserName"].ToString()); dicMsg.Add("LocalID", msgId); dicMsg.Add("ToUserName", ToUserName); dicMsg.Add("Type", 1); dic.Add("Msg", dicMsg); dic.Add("Scene", 0); parment = Newtonsoft.Json.JsonConvert.SerializeObject(dic); string json = Common.PostMoths("https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket=" + pass_ticket, parment); var obj = JObject.Parse(json); if (obj["BaseResponse"]["Ret"].ToString() != "0") { json = Common.PostMoths("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket=" + pass_ticket, parment); obj = JObject.Parse(json); fig = true; } else { fig = true; } } catch (Exception ex) { if (ex.Message.IndexOf("操作超时") != -1) { webwxsendmsg(ToUserName, Msg); } } } /// <summary> /// 发送图片 /// </summary> /// <param name="ToUserName">接收人</param> /// <param name="MediaId">图片ID</param> /// <returns></returns> public static bool webwxsendemoticon(string ToUserName, string MediaId) { bool fig = false; string parment = ""; int random = new Random().Next(100000000, 999999999); Dictionary<string, object> BaseRequest = new Dictionary<string, object>(); BaseRequest.Add("Uin", wxuin); BaseRequest.Add("Sid", wxsid); BaseRequest.Add("Skey", skey); DeviceID = "e" + (random.ToString() + (new Random().Next(10000, 99999).ToString())); BaseRequest.Add("DeviceID", DeviceID); var msgId = Common.ConvertDateTimeToInt(DateTime.Now).ToString() + (new Random().Next(10000, 99999).ToString()); Dictionary<string, object> dicMsg = new Dictionary<string, object>(); dicMsg.Add("ClientMsgId", msgId); dicMsg.Add("Content", ""); dicMsg.Add("FromUserName", BaseResponse["User"]["UserName"].ToString()); dicMsg.Add("LocalID", msgId); dicMsg.Add("MediaId", MediaId); dicMsg.Add("ToUserName", ToUserName); dicMsg.Add("Type", 3); Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("BaseRequest", BaseRequest); dic.Add("Msg", dicMsg); dic.Add("Scene", 0); parment = Newtonsoft.Json.JsonConvert.SerializeObject(dic); string json = Common.PostMoths("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&lang=zh_CN&pass_ticket=" + pass_ticket, parment); var obj = JObject.Parse(json); if (obj["BaseResponse"]["Ret"].ToString() != "0") { json = Common.PostMoths("https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&lang=zh_CN&pass_ticket=" + pass_ticket, parment); obj = JObject.Parse(json); fig = true; } else { fig = true; } return fig; } /// <summary> /// 检查微信状态 /// </summary> public static JObject synccheck() { int random = new Random().Next(100000000, 999999999); DeviceID = "e" + (random.ToString() + (new Random().Next(100000, 999999).ToString())); StringBuilder sb = new StringBuilder(); for (var i = 0; i < BaseResponse["SyncKey"]["List"].Count(); i++) { var item = BaseResponse["SyncKey"]["List"][i]; sb.Append(item["Key"].ToString() + "_" + item["Val"] + "|"); } string syncKey = (sb.ToString().Substring(0, sb.ToString().Length - 1)); StringBuilder parment = new StringBuilder(); parment.Append("?r=" + Common.ConvertDateTimeToInt(DateTime.Now)); parment.Append("&skey=" + HttpUtility.UrlEncode(skey)); parment.Append("&sid=" + wxsid); parment.Append("&uin=" + wxuin); parment.Append("&deviceid=" + DeviceID); parment.Append("&synckey=" + HttpUtility.UrlEncode(syncKey).ToUpper()); parment.Append("&_=" + Common.ConvertDateTimeToInt(DateTime.Now)); string json = Common.doGet("https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck" + parment.ToString()); json = json.Replace("window.synccheck", ""); json = json.Replace("=", ""); return JObject.Parse(json); } public static JObject contactObj; /// <summary> /// 返回群信息 /// </summary> /// <param name="ToUserName">群ID</param> /// <returns></returns> public static void webwxbatchgetcontact(string ToUserName, string AddUserName = "") { if (!string.IsNullOrEmpty(ToUserName)) { Dictionary<string, object> dicParment = new Dictionary<string, object>(); int random = new Random().Next(100000000, 999999999); Dictionary<string, object> BaseRequest = new Dictionary<string, object>(); BaseRequest.Add("Uin", wxuin); BaseRequest.Add("Sid", wxsid); BaseRequest.Add("Skey", skey); DeviceID = "e" + (random.ToString() + (new Random().Next(10000, 99999).ToString())); BaseRequest.Add("DeviceID", DeviceID); List<object> list = new List<object>(); //根据群找寻对应的群成员信息 for (var i = 0; i < BaseResponse["ContactList"].Count(); i++) { var item = BaseResponse["ContactList"][i]; if (item["UserName"].ToString().IndexOf(ToUserName) != -1) { if(!string.IsNullOrEmpty(AddUserName)) { JObject obj = JObject.Parse("{\"Uin\":0,\"UserName\":\""+AddUserName+"\",\"NickName\":\"\",\"AttrStatus\":0,\"PYInitial\":\"\",\"PYQuanPin\":\"\",\"RemarkPYInitial\":\"\",\"RemarkPYQuanPin\":\"\",\"MemberStatus\":0,\"DisplayName\":\"\",\"KeyWord\":\"\"}"); item["MemberList"].Last.AddAfterSelf(obj); } for (var j = 0; j < item["MemberList"].Count(); j++) { Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("EncryChatRoomId", ToUserName); dic.Add("UserName", item["MemberList"][j]["UserName"].ToString()); list.Add(dic); } break; } } dicParment.Add("BaseRequest", BaseRequest); dicParment.Add("Count", list.Count); dicParment.Add("List", list); string parment = Newtonsoft.Json.JsonConvert.SerializeObject(dicParment); string json = Common.PostMoths("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact?type=ex&r=" + Common.ConvertDateTimeToInt(DateTime.Now) + "&pass_ticket=" + pass_ticket, parment); contactObj = JObject.Parse(json); if (contactObj["BaseResponse"]["Ret"].ToString() != "0") { json = Common.PostMoths("https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact?type=ex&r=" + Common.ConvertDateTimeToInt(DateTime.Now) + "&pass_ticket=" + pass_ticket, parment); contactObj = JObject.Parse(json); } } else { contactObj = null; } } /// <summary> /// 图片上传类 /// </summary> /// <param name="fileUrl"></param> /// <param name="from"></param> /// <returns></returns> public static string WxUploadImage(string fileUrl, string from) { byte[] img = Common.GetFileData(fileUrl); try { var ClientMediaId = Common.ConvertDateTimeToInt(DateTime.Now).ToString() + (new Random().Next(1000, 9999).ToString()); #region 变量 string BoundStr = "-----------------------------143021075525875";//根据抓包生成 StringBuilder UploadBuf = new StringBuilder(); #endregion #region 头部数据 UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"id\"\r\n"); UploadBuf.Append("\r\n"); UploadBuf.Append("WU_FILE_0\r\n"); UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"name\"\r\n"); UploadBuf.Append("\r\n"); UploadBuf.Append("untitled1.jpg\r\n"); UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"type\"\r\n"); UploadBuf.Append("\r\n"); UploadBuf.Append("image/jpeg\r\n"); UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"lastModifiedDate\"\r\n"); UploadBuf.Append("\r\n"); UploadBuf.Append("Sat Apr 22 2017 15:59:04 GMT+0800 (中国标准时间)\r\n"); UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"size\"\r\n"); UploadBuf.Append("\r\n"); UploadBuf.Append(img.Length + "\r\n"); UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"mediatype\"\r\n"); UploadBuf.Append("\r\n"); UploadBuf.Append("pic\r\n"); UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"uploadmediarequest\"\r\n"); UploadBuf.Append("\r\n"); UploadBuf.Append("{\"UploadType\":2,\"BaseRequest\":{\"Uin\":" + wxuin + ",\"Sid\":\"" + wxsid + "\",\"Skey\":\"" +skey + "\""); UploadBuf.Append(",\"DeviceID\":\"e995465833539115\"},\"ClientMediaId\":" + ClientMediaId + ",\"TotalLen\":" + img.Length + ",\"StartPos\":0,\"DataLen\""); UploadBuf.Append(":" + img.Length + ",\"MediaType\":4,\"FromUserName\":\"" + BaseResponse["User"]["UserName"].ToString() + "\",\"ToUserName\":\"" + from + "\",\"FileMd5\""); UploadBuf.Append(":\"" + GetMD5Hash(img) + "\"}\r\n"); UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"webwx_data_ticket\"\r\n"); UploadBuf.Append("\r\n"); UploadBuf.Append(webwx_data_ticket + "\r\n"); UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"pass_ticket\"\r\n"); UploadBuf.Append("\r\n"); UploadBuf.Append(pass_ticket + "\r\n"); UploadBuf.Append(BoundStr + "\r\n"); UploadBuf.Append("Content-Disposition: form-data; name=\"filename\"; filename=\"untitled1.jpg\"\r\n"); UploadBuf.Append("Content-Type: image/jpeg\r\n"); UploadBuf.Append("\r\n"); byte[] HeadBytes = Encoding.ASCII.GetBytes(UploadBuf.ToString()); #endregion #region 图片数据 byte[] PicBytes = img; #endregion #region 尾部数据 UploadBuf.Clear(); UploadBuf.Append("\r\n" + BoundStr + "--"); UploadBuf.Append("\r\n"); byte[] TailBytes = Encoding.ASCII.GetBytes(UploadBuf.ToString()); #endregion #region 数组拼接 byte[] UploadBuffers = null; UploadBuffers = ComposeArrays(HeadBytes, PicBytes); UploadBuffers = ComposeArrays(UploadBuffers, TailBytes); #endregion Console.WriteLine("------------------------------------调试cookie"); Console.WriteLine(""); #region 上传 HttpHelper Http = new HttpHelper(); HttpItem item = null; HttpResult result = null; item = new HttpItem() { URL = "https://file.wx2.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json", Method = "POST", Accept = "/", Referer = " https://wx.qq.com/", ContentType = " multipart/form-data; boundary=" + BoundStr.Substring(2), PostDataType = PostDataType.Byte, PostEncoding = Encoding.UTF8, PostdataByte = UploadBuffers }; item.Header.Add("Origin", " https://wx.qq.com"); result = Http.GetHtml(item); #endregion JObject json = JObject.Parse(result.Html); if (json["BaseResponse"]["Ret"].ToString() == "0") { return json["MediaId"].ToString(); } else { item = new HttpItem() { URL = "https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json", Method = "POST", Accept = "/", Referer = " https://wx.qq.com/", ContentType = " multipart/form-data; boundary=" + BoundStr.Substring(2), PostDataType = PostDataType.Byte, PostEncoding = Encoding.UTF8, PostdataByte = UploadBuffers }; item.Header.Add("Origin", " https://wx.qq.com"); result = Http.GetHtml(item); json = JObject.Parse(result.Html); if (json["BaseResponse"]["Ret"].ToString() == "0") { return json["MediaId"].ToString(); } else { return ""; } } } catch { return null; } } #region 数组组合 public static byte[] ComposeArrays(byte[] Array1, byte[] Array2) { byte[] Temp = new byte[Array1.Length + Array2.Length]; Array1.CopyTo(Temp, 0); Array2.CopyTo(Temp, Array1.Length); return Temp; } #endregion /// <summary> /// 计算字符串MD5 /// </summary> /// <param name="bytedata"></param> /// <returns></returns> public static string GetMD5Hash(byte[] bytedata) { try { System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(bytedata); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } catch (Exception ex) { throw new Exception("GetMD5Hash() fail,error:" + ex.Message); } } }
HttpHelper 和HttpResult为http帮助类可见我另外一篇文章
https://blog.csdn.net/weixin_39349390/article/details/90041280
如有问题也可以加QQ群讨论:
技术群 710217654