using Api.Framework; using Api.Framework.Enums; using Api.Framework.Model; using Api.Framework.SDK; using Api.Framework.Tools; using Chat.Framework.WXSdk; using Chat.Framework.WXSdk.Implement; using CsharpHttpHelper; using CsharpHttpHelper.Enum; using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Weixin.AccurateCircle.Entitys; using Weixin.AccurateCircle.Properties; namespace Weixin.AccurateCircle { public class MonitorThread : TimerTask { private string cache_key = "weixin_accurateCircle_cache_key"; public override void Run(object state, bool timedOut) { #region 定时清空采集的数据 if (!string.IsNullOrWhiteSpace(Class1.Config.AutoClearTaskTimes)) { if (Class1.Config.Auto_IsClear == SwitchType.开启) { try { if (DateTime.Now.AddSeconds(-3).ToString("HHmm") == DateTime.Parse(Class1.Config.AutoClearTaskTimes).ToString("HHmm")) { var session = ApiClient.GetSession(); session.Deleteable().ExecuteCommand(); } } catch (Exception ex) { EventClient.OnEvent(this, "定时清理异常" + ex.Message + "-" + ex.StackTrace); } } } #endregion #region try { #region 采集 if (Class1.Config.DownTime.AddMinutes(Class1.Config.DownInterval) < DateTime.Now) { Task.Run(() => { try { var url = string.IsNullOrWhiteSpace(Class1.Config.DownUrl) ? string.Empty : System.IO.Path.Combine(Class1.Config.DownUrl, "api", "circle", "gettask").Replace(@"\", "/"); if (string.IsNullOrWhiteSpace(url)) return; var html = string.Empty; HttpHelper http = new HttpHelper(); HttpItem item = new HttpItem() { URL = url, Method = "post", Postdata = $"taskid={Class1.Config.DownID}", Timeout = 100000, ReadWriteTimeout = 30000, UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)", ContentType = "application/x-www-form-urlencoded", Allowautoredirect = false }; var result = http.GetHtml(item); html = result.Html; if (!string.IsNullOrWhiteSpace(html)) { var dic = HttpExtend.JsonToDictionary(html); if (dic == null) throw new Exception($"请求采集失败! {html}"); if (dic.ContainsKey("Data")) { var data = dic["Data"] as Dictionary; if (data.ContainsKey("data")) { long maxId = 0;//获取最大的id var list = new List(); var _data = data["data"] as ArrayList; foreach (Dictionary temp in _data) { var datainfo = temp.ConvertToObj(); if (datainfo != null) { datainfo.state = StateType.未推广; datainfo.cur_time = DateTime.Now; list.Add(datainfo); if (maxId < datainfo.id) maxId = datainfo.id; } } var _session = ApiClient.GetSession(); _session.Saveable(list).ExecuteCommand(); Class1.Config.DownID = maxId; Class1.Config.DownTime = DateTime.Now; Util.Save(Class1.Config); } } } } catch (Exception ex) { EventClient.OnEvent(this, $"精准朋友圈采集异常:{ex.Message} - {ex.StackTrace}"); } }); } #endregion #region 发送 var session = ApiClient.GetSession(); var datainfos = session.Queryable().OrderBy(f => f.Sendtime, SqlSugar.OrderByType.Asc).Where(f => f.state == StateType.未推广).ToList(); datainfos = datainfos.Where(f => f.Sendtime.ToString("HHmm") == DateTime.Now.ToString("HHmm")).ToList(); foreach (var datainfo1 in datainfos) { if (datainfo1 != null) { var result = ApiClient.Cache.Get>(cache_key); if (result != null && result.Contains(datainfo1.id)) return; var task_time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + datainfo1.Sendtime.ToString(" HH:mm:ss")); var now = DateTime.Now; var dValue = (now - task_time).TotalMinutes; if (0 < dValue && dValue < 5) { if (result == null) result = new List(); result.Add(datainfo1.id); ApiClient.Cache.Set(cache_key, result, 5); var clients = Chat.Framework.ChatClient.WXClient; var tbAnalysis = new TBHelper.TbAnalysis(); var jsonData = "{\"data\":" + datainfo1.AdditionalPic + "}"; #region 用户设置的附加图片 StringBuilder strbImage = new StringBuilder(); var dicData = HttpExtend.JsonToDictionary(jsonData); if (dicData != null && dicData.ContainsKey("data")) { var arrFileName = dicData["data"] as ArrayList; HttpHelper http = new HttpHelper(); foreach (string fileName in arrFileName) { try { var image = Util.MapFile(fileName, @"Cache\image"); var url = string.IsNullOrWhiteSpace(Class1.Config.DownUrl) ? string.Empty : Path.Combine(Class1.Config.DownUrl, fileName).Replace(@"\", "/"); if (!string.IsNullOrWhiteSpace(url)) { HttpItem item = new HttpItem() { URL = url, Method = "get", IsToLower = false, Timeout = 100000, ReadWriteTimeout = 30000, UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)", ContentType = "text/html", Allowautoredirect = false, ResultType = ResultType.Byte }; var resule_ = http.GetHtml(item); var bytes = resule_.ResultByte; var flag = byteArrayToImage(bytes, image); strbImage.Append($"[图片={image}]"); } } catch (Exception ex) { } } } #endregion foreach (var client in clients.Values) { try { if (client.WeixinType == WeixinType.Grpc微信 && client.Status == WxStatus.在线) { if (!string.IsNullOrWhiteSpace(datainfo1.Data)) { StringBuilder strb = new StringBuilder(); strb.Append(datainfo1.Content); jsonData = "{\"data\":" + datainfo1.Data + "}"; dicData = HttpExtend.JsonToDictionary(jsonData); if (dicData != null && dicData.ContainsKey("data")) { var arr = dicData["data"] as ArrayList; foreach (Dictionary item in arr) { var baseInfo = new BaseInfo(); if (item.ContainsKey("Cps")) baseInfo.Cps = item["Cps"].ToString(); if (item.ContainsKey("ItemId")) baseInfo.ItemId = item["ItemId"].ToString(); if (item.ContainsKey("Price")) baseInfo.Price = double.Parse(item["Price"].ToString()); if (item.ContainsKey("ItemTitle")) baseInfo.ItemTitle = item["ItemTitle"].ToString(); if (item.ContainsKey("conupon_url")) baseInfo.conupon_url = item["conupon_url"].ToString(); if (item.ContainsKey("Notice")) baseInfo.Notice = item["Notice"].ToString(); if (item.ContainsKey("conupon_price")) baseInfo.conupon_price = double.Parse(item["conupon_price"].ToString()); if (item.ContainsKey("Images")) { var _images = new List(); var images = item["Images"] as ArrayList; foreach (string image in images) { _images.Add(image); } baseInfo.Images = _images; } if (baseInfo != null) { var robot = session.FindRobots().FirstOrDefault(f => f.name == client.WeixinHao && f.type == ChatType.微信); if (robot == null) continue; var adzones = session.FindAdzoneInfos().Where(f => !f.onoff && f.custom_type == Resources.SoftwareType && f.robot_id == robot.id); if (baseInfo.Cps == "淘宝") { #region 淘宝 try { var adzone = adzones.FirstOrDefault(f => f.alliance_id == (int)CpsType.阿里妈妈); if (adzone == null) continue; var member = CpsClient.Members.FirstOrDefault(f => f.cpstype == CpsType.阿里妈妈 && f.username == adzone.adzone_pid_cps_name); if (member != null) { var api = CpsClient.CreateAlimamaRequest(member); if (api == null) continue; var pict_url = (baseInfo.Images != null && baseInfo.Images.Count != 0) ? baseInfo.Images[0] : string.Empty; #region 获取淘口令 tkl var tkl = string.Empty; try { var _title = baseInfo.ItemTitle; var _pict_url = pict_url; tkl = tbAnalysis.FindTKL(baseInfo.conupon_url, _title, _pict_url, api); if (string.IsNullOrEmpty(tkl)) { for (int i = 0; i <= 3; i++) { tkl = tbAnalysis.FindTKL(baseInfo.conupon_url, _title, _pict_url, api); if (!string.IsNullOrEmpty(tkl)) break; Thread.Sleep(200); } } if (string.IsNullOrEmpty(tkl)) continue; } catch (Exception ex) { } #endregion var short_url = api.ComposeTbClick(baseInfo.ItemId, pict_url, tkl, baseInfo.conupon_url, true, (int)DwzType.官方短网址);//短连接 var image = ApiClient.GetQRImage(baseInfo.ItemTitle, baseInfo.Price.ToString(), baseInfo.conupon_price.ToString(), ((decimal)baseInfo.Price - (decimal)baseInfo.conupon_price).ToString(), pict_url, short_url, ApiClient.QrImageType.模板A, CpsType.阿里妈妈, baseInfo.Notice); //合成附带二维码等信息的宝贝图片 strb.Append($"[图片={image}]"); } } catch (Exception ex) { EventClient.OnEvent(this, $"精确朋友圈淘宝商品解析失败:{ex.Message} - {ex.StackTrace}"); } #endregion } else if (baseInfo.Cps == "京东") { #region 京东 try { var adzone = session.FindAdzoneInfos().FirstOrDefault(f => f.alliance_id == (int)CpsType.京东联盟 && f.custom_type == Resources.SoftwareType && f.robot_id == robot.id); if (adzone != null) { var member = CpsClient.Members.FirstOrDefault(f => f.cpstype == CpsType.京东联盟 && f.username == adzone.adzone_pid_cps_name); if (member != null) { var api = CpsClient.CreateJingdongRequest(member); if (api == null) { return; } var buyshorturl = string.Empty; //转连后的地址 Dictionary conversionlinkresult = null; //查询到的转换链接对象 var positionId = adzone.adzone_pid.Substring(adzone.adzone_pid.LastIndexOf("_") + 1); if (string.IsNullOrWhiteSpace(baseInfo.conupon_url)) { conversionlinkresult = api.SendJingdong("jd.union.open.promotion.byunionid.get", new { promotionCodeReq = new { materialId = $@"https://item.m.jd.com/product/{baseInfo.ItemId}.html", positionId = positionId, unionId = member.usernick } });//宝贝id 和 用户的目标推客的联盟id } else { try { conversionlinkresult = api.SendJingdong("jd.union.open.promotion.byunionid.get", new { promotionCodeReq = new { materialId = $@"https://item.m.jd.com/product/{baseInfo.ItemId}.html", positionId = positionId, unionId = member.usernick, couponUrl = baseInfo.conupon_url } }); } catch (Exception) { conversionlinkresult = api.SendJingdong("jd.union.open.promotion.byunionid.get", new { promotionCodeReq = new { materialId = $@"https://item.m.jd.com/product/{baseInfo.ItemId}.html", positionId = positionId, unionId = member.usernick } });//宝贝id 和 用户的目标推客的联盟id } } if (conversionlinkresult != null) { if (conversionlinkresult["code"].ToString() != "200") throw new Exception($"京东查询接口调用失败:{conversionlinkresult["message"].ToString()}");//抛出错误信息 if (conversionlinkresult.ContainsKey("data")) { var data = conversionlinkresult["data"] as Dictionary; if (data.ContainsKey("shortURL")) buyshorturl = data["shortURL"].ToString();//购买短连接 } if (string.IsNullOrWhiteSpace(buyshorturl)) continue;//京东转链失败,请稍后重试 } var goods_desc = string.IsNullOrWhiteSpace(baseInfo.Notice) ? string.Empty : baseInfo.Notice; var image = ApiClient.GetQRImage(baseInfo.ItemTitle, baseInfo.Price.ToString(), baseInfo.conupon_price.ToString(), ((decimal)baseInfo.Price - (decimal)baseInfo.conupon_price).ToString(), baseInfo.Images[0], buyshorturl, ApiClient.QrImageType.模板A, CpsType.京东联盟, baseInfo.Notice); //合成附带二维码等信息的宝贝图片 strb.Append($"[图片={image}]"); } } } catch (Exception ex) { EventClient.OnEvent(this, $"精确朋友圈京东商品解析失败:{ex.Message} - {ex.StackTrace}"); } #endregion } else if (baseInfo.Cps == "拼多多") { #region 拼多多 try { var adzone = session.FindAdzoneInfos().FirstOrDefault(f => f.alliance_id == (int)CpsType.多多进宝 && f.custom_type == Resources.SoftwareType && f.robot_id == robot.id); if (adzone != null) { var member = CpsClient.Members.FirstOrDefault(f => f.cpstype == CpsType.多多进宝 && f.username == adzone.adzone_pid_cps_name); if (member != null) { string param = $"fl_{robot.name}_{(int)ChatType.微信}_精准朋友圈推广"; var api = CpsClient.CreatePinduoduoRequest(member); if (api == null) { return; } try { var data = new { goods_id_list = $"[{baseInfo.ItemId}]" }; var obj = api.SendPinduoduo("pdd.ddk.goods.detail", data); if (obj == null) throw new Exception("创建拼多多API请求失败"); //解析商品,获取商品的信息 var goods_detail_response = obj["goods_detail_response"] as Dictionary; var goods_details = goods_detail_response["goods_details"] as ArrayList; //有查到返利提示 if (goods_details.Count != 0) { foreach (var _details in goods_details) { var details = _details as Dictionary; var _coupon_discount = double.Parse((details["coupon_discount"] ?? 0).ToString()); var coupon_discount = _coupon_discount == 0 ? 0 : Math.Round(_coupon_discount / 100.00, 2); //优惠券面额,单位为分 var pddHelper = new PDDHelper(); string _temp_param = $"fl_{robot.name}_{(int)ChatType.微信}_精准朋友圈推广"; //搜索成功有券的情况下 //if (_coupon_discount != 0) //{ var manyShoppingUrl = pddHelper.GetShoppingUrl(api, new { p_id = adzone.adzone_pid, custom_parameters = _temp_param, goods_id_list = $"[{baseInfo.ItemId}]", multi_group = true, generate_short_url = true, generate_weapp_webview = true, force_duo_id = true }); strb.Append($"[图片={ApiClient.GetQRImage(baseInfo.ItemTitle, baseInfo.Price.ToString(), coupon_discount.ToString(), ((decimal)baseInfo.Price - (decimal)coupon_discount).ToString(), baseInfo.Images[0], manyShoppingUrl, ApiClient.QrImageType.模板A, CpsType.多多进宝, baseInfo.Notice)}]"); //} } } } catch { } } } } catch (Exception ex) { EventClient.OnEvent(this, $"精确朋友圈拼多多商品解析失败:{ex.Message} - {ex.StackTrace}"); } #endregion } } } } strb.Append(strbImage.ToString()); EventClient.OnEvent(this, "定时任务:" + client.WeixinHao + ":准备发了"); var json = client.SendCircle(strb.ToString());//发送朋友圈的主内容 if (string.IsNullOrWhiteSpace(json)) EventClient.OnEvent(this, "定时任务:" + client.WeixinHao + ":发送失败"); else EventClient.OnEvent(this, "定时任务:" + client.WeixinHao + ":已经发了"); var reg = Regex.Match(json.Replace("", ""), @"(?\d{15,})");//获取返回的朋友圈id if (reg.Success) { var id = reg.Groups["id"].Value; if (!string.IsNullOrWhiteSpace(datainfo1.Comment)) client.SendCircleComment(client.User.Username, id, datainfo1.Comment); } datainfo1.state = StateType.已推广; session.Saveable(datainfo1).ExecuteCommand(); } } } catch (Exception ex) { EventClient.OnEvent(this, $"朋友圈工具 - 定时发送任务:{ex.Message},{ex.StackTrace}"); } } } } } #endregion } catch (Exception ex) { EventClient.OnEvent(this, $"{ex.Message} - {ex.StackTrace}"); } #endregion } /// /// 字节数组生成图片 /// /// 字节数组 /// 图片 private bool byteArrayToImage(byte[] Bytes, string fileName) { Stream ms = null; try { ms = new MemoryStream(Bytes); return StreamToFile(ms, fileName); } catch (Exception ex) { return false; } finally { if (ms != null) { ms.Close(); ms.Dispose(); } } } /// /// 将Stream写入文件 /// /// /// public bool StreamToFile(Stream stream, string path) { try { byte[] bytes = new byte[stream.Length]; // 把Stream转换成byte[] stream.Read(bytes, 0, bytes.Length); stream.Seek(0, SeekOrigin.Begin); // 设置当前流的位置为流的开始 FileStream fs = new FileStream(path, FileMode.Create); // 把byte[]写入文件 BinaryWriter bw = new BinaryWriter(fs); bw.Write(bytes); bw.Close(); fs.Close(); } catch (Exception) { return false; } return true; } } }