/// <summary> /// 获取关注信息。 /// </summary> /// <param name="startDate">起始日期。</param> /// <param name="endDate">结束日期。</param> /// <returns>关注信息数组。</returns> public AttentionInfo[] GetAttentions(DateTime startDate, DateTime endDate) { //得到AppId和插件Token。 var info = GetAppIdAndPluginToken(); var appId = info.Key; var pluginToken = info.Value; //关注数据请求Url。 var url = string.Format( "https://mta.qq.com/mta/wechat/ctr_user_summary/get_table_data/?start_date={0}&end_date={1}&need_compare=0&start_compare_date=&end_compare_date=&app_id=&source_list=-1&source_show=35%2C3%2C43%2C17%2C0&appid={2}&pluginid=luopan&token={3}&from=&devtype=2&time_type=day&ajax=1", startDate.ToString("yyyy-MM-dd"), endDate.ToString("yyyy-MM-dd"), appId, pluginToken); using (var client = new LastingWebClient(_cookieContainer)) { var data = client.DownloadData(url); var json = Encoding.UTF8.GetString(data); var weiXinAttention = new JavaScriptSerializer().Deserialize <WeiXinAttentionInfo>(json); return((weiXinAttention == null || weiXinAttention.Data == null) ? new AttentionInfo[0] : weiXinAttention.Data.Select(i => new AttentionInfo { CancelUser = i.GetCancelUser(), CumulateUser = i.GetCumulateUser(), Date = i.RefDate, NewUser = i.GetNewUser(), NetUser = i.GetNewUser(), }).ToArray()); } }
/// <summary> /// 用户微信用户信息。 /// </summary> /// <returns>用户信息。</returns> public UserInfo GetUserInfo() { using (var client = new LastingWebClient(_cookieContainer)) { var html = Encoding.UTF8.GetString(client.DownloadData( string.Format( "https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&token={0}&lang=zh_CN", LoginResult.Token))); var document = new HtmlDocument(); document.LoadHtml(html); var offset = 0; var type = GetMetaContent(document, 4); switch (type) { case "服务号": offset = 0; break; default: offset = 1; break; } var user = new UserInfo { Picture = new Lazy <byte[]>(() => { using (var c = new LastingWebClient(_cookieContainer)) { return(c.DownloadData( document.DocumentNode.CssSelect(".avatar").FirstOrDefault().GetAttributeValue("src").Insert(0, "https://mp.weixin.qq.com"))); } }), Name = GetMetaContent(document, 2), LoginEmail = GetMetaContent(document, 10 - offset), OriginalId = GetMetaContent(document, 11 - offset), UserName = GetMetaContent(document, 3), Type = type, AuthenticateStatus = GetMetaContent(document, 6), Body = GetMetaContent(document, 9 - offset), Area = GetMetaContent(document, 8 - offset), Description = GetMetaContent(document, 5), QrCode = new Lazy <byte[]>(() => { using (var c = new LastingWebClient(_cookieContainer)) { return(c.DownloadData( document.DocumentNode.CssSelect(".verifyInfo").FirstOrDefault().GetAttributeValue("href").Insert(0, "https://mp.weixin.qq.com"))); } }) }; return(user); } }
/// <summary> /// 设置编辑或者开发者模式。 /// </summary> /// <param name="type">类型,1代表编辑模式,2代表开发者模式。</param> /// <param name="enable">是否开启对应的模式。</param> private bool SetEditOrDevelopMode(int type, bool enable) { using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("ContentType", "application/x-www-form-urlencoded"); client.Headers.Add("Referer", "https://mp.weixin.qq.com/"); var data = client.UploadData("https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN", "POST", Encoding.UTF8.GetBytes(string.Format("flag={0}&type={1}&token={2}", enable ? 1 : 0, type, LoginResult.Token))); var json = Encoding.UTF8.GetString(data); return(json.StartsWith("{\"base_resp\":{\"ret\":0,\"err_msg\":\"ok\"}")); } }
/// <summary> /// 设置OAuth回调域名。 /// </summary> /// <param name="domain"></param> /// <returns></returns> public bool SetOAuthDomain(string domain) { using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("Referer", "https://mp.weixin.qq.com/"); var data = client.UploadData("https://mp.weixin.qq.com/merchant/myservice?action=set_oauth_domain&f=json", Encoding.UTF8.GetBytes( string.Format("token={0}&lang=zh_CN&f=json&ajax=1&random=0.18229547117417194&domain={1}", _loginResult.Token, domain))); var content = Encoding.UTF8.GetString(data); return(content.Contains("ok")); } }
private KeyValuePair <string, string> GetAppIdAndPluginToken() { using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("Referer", string.Format("https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token={0}", _loginResult.Token)); var url = string.Format( "https://mp.weixin.qq.com/misc/pluginloginpage?action=stat_user_summary&pluginid=luopan&t=statistics/index&token={0}&lang=zh_CN", _loginResult.Token); var html = Encoding.UTF8.GetString(client.DownloadData(url)); var appId = GetJsonValue(html, "appid : '"); var pluginToken = GetJsonValue(html, "pluginToken : '"); return(new KeyValuePair <string, string>(appId, pluginToken)); } }
/// <summary> /// 登录微信。 /// </summary> /// <param name="userName">用户名称。</param> /// <param name="password">用户密码。</param> /// <returns>登录结果。</returns> public LoginResult Login(string userName, string password) { _isLogin = true; _cookieContainer = new CookieContainer(); using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("Referer", "https://mp.weixin.qq.com/"); client.Headers.Add("ContentType", "application/x-www-form-urlencoded"); var data = client.UploadData("https://mp.weixin.qq.com/cgi-bin/login", "POST", Encoding.UTF8.GetBytes("username="******"&pwd=" + Md5Hash(password) + "&imgcode=&f=json")); var token = GetToken(Encoding.UTF8.GetString(data)); return _loginResult = string.IsNullOrWhiteSpace(token) ? null : new LoginResult { Token = token }; } }
/// <summary> /// 登录微信。 /// </summary> /// <param name="userName">用户名称。</param> /// <param name="password">用户密码。</param> /// <returns>登录结果。</returns> public LoginResult Login(string userName, string password) { _isLogin = true; _cookieContainer = new CookieContainer(); using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("Referer", "https://mp.weixin.qq.com/"); client.Headers.Add("ContentType", "application/x-www-form-urlencoded"); var data = client.UploadData("https://mp.weixin.qq.com/cgi-bin/login", "POST", Encoding.UTF8.GetBytes("username="******"&pwd=" + Md5Hash(password) + "&imgcode=&f=json")); var token = GetToken(Encoding.UTF8.GetString(data)); return(_loginResult = string.IsNullOrWhiteSpace(token) ? null : new LoginResult { Token = token }); } }
/// <summary> /// 设置开发者接口信息(会自动开启开发者模式)。 /// </summary> /// <param name="url">Url地址。</param> /// <param name="token">令牌。</param> /// <param name="aeskey">EncodingAESKey。</param> /// <param name="encryptMode">加密模式。</param> /// <returns>是否更新成功。</returns> public bool SetDevelopInterface(string url, string token, string aeskey, EncryptMode encryptMode) { //开启开发者模式。 if (!SetDevelopMode(true)) { throw new WeiXinWebApiException("更新开发者接口信息失败,因为开启开发者模式失败。"); } using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("Referer", "https://mp.weixin.qq.com/"); client.Headers.Add("ContentType", "application/x-www-form-urlencoded"); var data = client.UploadData( string.Format("https://mp.weixin.qq.com/advanced/callbackprofile?t=ajax-response&token={0}&lang=zh_CN", LoginResult.Token), "POST", Encoding.UTF8.GetBytes(string.Format("url={0}&callback_token={1}&encoding_aeskey={2}&callback_encrypt_mode={3}", HttpUtility.UrlEncode(url), token, aeskey, (int)encryptMode))); var json = Encoding.UTF8.GetString(data); return(json.Contains("\"err_msg\":\"ok\"")); } }
/// <summary> /// 获取开发者凭据。 /// </summary> /// <returns>如果具有开发者凭据则返回否则返回null。</returns> public DevelopCredential GetDevelopCredential() { using (var client = new LastingWebClient(_cookieContainer)) { var url = string.Format( "https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token={0}&lang=zh_CN", _loginResult.Token); var html = Encoding.UTF8.GetString(client.DownloadData(url)); var document = new HtmlDocument(); document.LoadHtml(html); var items = document.DocumentNode.CssSelect(".developer_info_item").ToArray(); if (items.Count() < 4) { return(null); } var item = items.First(); var controls = item.CssSelect(".frm_controls").ToArray(); string appSecret; using (var reader = new StringReader(controls.Last().InnerText.Trim())) appSecret = reader.ReadLine(); if (!string.IsNullOrWhiteSpace(appSecret)) { var index = appSecret.Trim().IndexOf(" ", StringComparison.Ordinal); if (index != -1) { appSecret = appSecret.Substring(0, index); } } return(new DevelopCredential { AppId = controls.First().InnerText.Trim(), AppSecret = appSecret }); } }
/// <summary> /// 用户微信用户信息。 /// </summary> /// <returns>用户信息。</returns> public UserInfo GetUserInfo() { using (var client = new LastingWebClient(_cookieContainer)) { var html = Encoding.UTF8.GetString(client.DownloadData( string.Format( "https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&token={0}&lang=zh_CN", LoginResult.Token))); var document = new HtmlDocument(); document.LoadHtml(html); var offset = 0; var type = GetMetaContent(document, 4); switch (type) { case "服务号": offset = 0; break; default: offset = 1; break; } var user = new UserInfo { Picture = new Lazy<byte[]>(() => { using (var c = new LastingWebClient(_cookieContainer)) { return c.DownloadData( document.DocumentNode.CssSelect(".avatar").FirstOrDefault().GetAttributeValue("src").Insert(0, "https://mp.weixin.qq.com")); } }), Name = GetMetaContent(document, 2), LoginEmail = GetMetaContent(document, 10 - offset), OriginalId = GetMetaContent(document, 11 - offset), UserName = GetMetaContent(document, 3), Type = type, AuthenticateStatus = GetMetaContent(document, 6), Body = GetMetaContent(document, 9 - offset), Area = GetMetaContent(document, 8 - offset), Description = GetMetaContent(document, 5), QrCode = new Lazy<byte[]>(() => { using (var c = new LastingWebClient(_cookieContainer)) { return c.DownloadData( document.DocumentNode.CssSelect(".verifyInfo").FirstOrDefault().GetAttributeValue("href").Insert(0, "https://mp.weixin.qq.com")); } }) }; return user; } }
/// <summary> /// 设置编辑或者开发者模式。 /// </summary> /// <param name="type">类型,1代表编辑模式,2代表开发者模式。</param> /// <param name="enable">是否开启对应的模式。</param> private bool SetEditOrDevelopMode(int type, bool enable) { using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("ContentType", "application/x-www-form-urlencoded"); client.Headers.Add("Referer", "https://mp.weixin.qq.com/"); var data = client.UploadData("https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN", "POST", Encoding.UTF8.GetBytes(string.Format("flag={0}&type={1}&token={2}", enable ? 1 : 0, type, LoginResult.Token))); var json = Encoding.UTF8.GetString(data); return json.StartsWith("{\"base_resp\":{\"ret\":0,\"err_msg\":\"ok\"}"); } }
private KeyValuePair<string, string> GetAppIdAndPluginToken() { using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("Referer", string.Format("https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token={0}", _loginResult.Token)); var url = string.Format( "https://mp.weixin.qq.com/misc/pluginloginpage?action=stat_user_summary&pluginid=luopan&t=statistics/index&token={0}&lang=zh_CN", _loginResult.Token); var html = Encoding.UTF8.GetString(client.DownloadData(url)); var appId = GetJsonValue(html, "appid : '"); var pluginToken = GetJsonValue(html, "pluginToken : '"); return new KeyValuePair<string, string>(appId, pluginToken); } }
/// <summary> /// 设置OAuth回调域名。 /// </summary> /// <param name="domain"></param> /// <returns></returns> public bool SetOAuthDomain(string domain) { using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("Referer", "https://mp.weixin.qq.com/"); var data = client.UploadData("https://mp.weixin.qq.com/merchant/myservice?action=set_oauth_domain&f=json", Encoding.UTF8.GetBytes( string.Format("token={0}&lang=zh_CN&f=json&ajax=1&random=0.18229547117417194&domain={1}", _loginResult.Token, domain))); var content = Encoding.UTF8.GetString(data); return content.Contains("ok"); } }
/// <summary> /// 获取关注信息。 /// </summary> /// <param name="startDate">起始日期。</param> /// <param name="endDate">结束日期。</param> /// <returns>关注信息数组。</returns> public AttentionInfo[] GetAttentions(DateTime startDate, DateTime endDate) { //得到AppId和插件Token。 var info = GetAppIdAndPluginToken(); var appId = info.Key; var pluginToken = info.Value; //关注数据请求Url。 var url = string.Format( "https://mta.qq.com/mta/wechat/ctr_user_summary/get_table_data/?start_date={0}&end_date={1}&need_compare=0&start_compare_date=&end_compare_date=&app_id=&source_list=-1&source_show=35%2C3%2C43%2C17%2C0&appid={2}&pluginid=luopan&token={3}&from=&devtype=2&time_type=day&ajax=1", startDate.ToString("yyyy-MM-dd"), endDate.ToString("yyyy-MM-dd"), appId, pluginToken); using (var client = new LastingWebClient(_cookieContainer)) { var data = client.DownloadData(url); var json = Encoding.UTF8.GetString(data); var weiXinAttention = new JavaScriptSerializer().Deserialize<WeiXinAttentionInfo>(json); return (weiXinAttention == null || weiXinAttention.Data == null) ? new AttentionInfo[0] : weiXinAttention.Data.Select(i => new AttentionInfo { CancelUser = i.GetCancelUser(), CumulateUser = i.GetCumulateUser(), Date = i.RefDate, NewUser = i.GetNewUser(), NetUser = i.GetNewUser(), }).ToArray(); } }
/// <summary> /// 获取开发者凭据。 /// </summary> /// <returns>如果具有开发者凭据则返回否则返回null。</returns> public DevelopCredential GetDevelopCredential() { using (var client = new LastingWebClient(_cookieContainer)) { var url = string.Format( "https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token={0}&lang=zh_CN", _loginResult.Token); var html = Encoding.UTF8.GetString(client.DownloadData(url)); var document = new HtmlDocument(); document.LoadHtml(html); var items = document.DocumentNode.CssSelect(".developer_info_item").ToArray(); if (items.Count() < 4) return null; var item = items.First(); var controls = item.CssSelect(".frm_controls").ToArray(); string appSecret; using (var reader = new StringReader(controls.Last().InnerText.Trim())) appSecret = reader.ReadLine(); if (!string.IsNullOrWhiteSpace(appSecret)) { var index = appSecret.Trim().IndexOf(" ", StringComparison.Ordinal); if (index != -1) { appSecret = appSecret.Substring(0, index); } } return new DevelopCredential { AppId = controls.First().InnerText.Trim(), AppSecret = appSecret }; } }
/// <summary> /// 设置开发者接口信息(会自动开启开发者模式)。 /// </summary> /// <param name="url">Url地址。</param> /// <param name="token">令牌。</param> /// <param name="aeskey">EncodingAESKey。</param> /// <param name="encryptMode">加密模式。</param> /// <returns>是否更新成功。</returns> public bool SetDevelopInterface(string url, string token, string aeskey, EncryptMode encryptMode) { //开启开发者模式。 if (!SetDevelopMode(true)) throw new WeiXinWebApiException("更新开发者接口信息失败,因为开启开发者模式失败。"); using (var client = new LastingWebClient(_cookieContainer)) { client.Headers.Add("Referer", "https://mp.weixin.qq.com/"); client.Headers.Add("ContentType", "application/x-www-form-urlencoded"); var data = client.UploadData( string.Format("https://mp.weixin.qq.com/advanced/callbackprofile?t=ajax-response&token={0}&lang=zh_CN", LoginResult.Token), "POST", Encoding.UTF8.GetBytes(string.Format("url={0}&callback_token={1}&encoding_aeskey={2}&callback_encrypt_mode={3}", HttpUtility.UrlEncode(url), token, aeskey, (int)encryptMode))); var json = Encoding.UTF8.GetString(data); return json.Contains("\"err_msg\":\"ok\""); } }