using Chat.Framework.PCRobotSDK.WechatEvents; using Chat.Framework.PCRobotSDK.WorkWechatEvents; using Chat.Framework.Utils; using Chat.Framework.WXSdk.Events; using Chat.Framework.WXSdk.HOOK; using CsharpHttpHelper; using Newtonsoft.Json; using PCRobot.Pack; using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; namespace Chat.Framework.WXSdk.Implement { /// /// 企业PC机器人 /// public class WXClientImpl_QYHOOK : WeixinBase { /// /// 上次心跳时间 /// public DateTime HeartBreakTime { get; internal set; } = DateTime.MinValue; /// /// 企业机器人 /// /// 企业账号 /// 企业昵称 /// 企业账号 public WXClientImpl_QYHOOK(string weixinhao, string usernick, long uin = -1) { WeixinType = WeixinType.QYHook微信; WeixinHao = weixinhao; User = new WeixinBaseUser(WeixinHao, usernick, uin); Friends = new Dictionary(); GroupMembers = new Dictionary(); HeartBreakTime = DateTime.Now; RequestContact(); base.ChangeStatus(WxStatus.在线); } //HeadPack_Hook headPack = null; public void Dispose() { if (this.User != null && this.User.Uin != 0 && this.User.Uin != -1) Grant.Framework.GrantClient.Get().LoginOut(this.User.Uin.ToString(), int.Parse(WXClientTool.auth_info[0])); } public override void ChangeStatus(WxStatus status, WXChangeStatus e = null, bool is_next = true) { if (status == WxStatus.已掉线 || status == WxStatus.已退出 || status == WxStatus.未登录 || status == WxStatus.登录失败) { if (this.User != null && this.User.Uin != 0 && this.User.Uin != -1) Grant.Framework.GrantClient.Get().LoginOut(this.User.Uin.ToString(), int.Parse(WXClientTool.auth_info[0])); } if (status == WxStatus.在线) { if (!Grant.Framework.GrantClient.Get().IsExistCustomers(User.Uin.ToString(), int.Parse(WXClientTool.auth_info[0]))) { try { if (User.Uin.ToString() != "0" && User.Uin.ToString() != "-1") Grant.Framework.GrantClient.Get().Login(User.Uin.ToString(), User.Nick, int.Parse(WXClientTool.auth_info[0]), WXClientTool.auth_info[1]); } catch (Exception ex) { var wx = ChatClient.WXClient.FirstOrDefault(f => f.Key == WeixinHao).Value; if (wx == null) ChatClient.UpdateWXClient(this); ChatClient.Events.OnEvent(new WXWriteLog(this) { Message = $"【{User.Uin}({User.Nick})】授权异常:" + $".{(WXClientTool.auth_info != null ? JsonConvert.SerializeObject(WXClientTool.auth_info) : string.Empty)}" }); status = WxStatus.登录失败; //LoginOut($"【{User.Username}({User.Nick})】{ex.Message}"); Dispose(); ChatClient.LoginOutWeixin(WeixinHao, $"【{User.Uin}({User.Nick})】{ex.Message}"); } } } else { LogHelper.GetSingleObj().Debug("", $"QY微信状态修改:{this.WeixinHao} - {status}"); ChatClient.LoginOutWeixin(WeixinHao); } base.ChangeStatus(status, e); } /// /// 退出消息 /// /// public override void LoginOut(string message) { //发送指令 强制退出易转发那边的微信 WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.closeWechat, message); try { LogHelper.GetSingleObj().Debug("", $"LoginOutQY带提示:{this.WeixinHao}"); } catch (Exception) { } } /// /// 退出登录 /// public override void LoginOut() { //发送指令 强制退出易转发那边的微信 WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.closeWechat); try { LogHelper.GetSingleObj().Debug("", $"LoginOutQY不带提示:{this.WeixinHao}"); } catch (Exception) { } } public override void ShowLogin() { throw new Exception("请在易转发,客户端执行登陆!"); } /// /// 获得好友或群组信息 /// public override Friend GetContact(string wxid, bool refresh = false) { lock (this.Friends) { try { if (refresh || !Friends.ContainsKey(wxid)) { var msg_id = GetWxidInfo(wxid); if (!string.IsNullOrEmpty(msg_id)) { var rst = ChatClient.PCRobotPool.PackHist.GetResult(msg_id).Result; if (rst != null) { //{"avatar":"http://wx.qlogo.cn/mmhead/GPyw0pGicibl4KQicb5bXGu2SibrykeGOH5IicK2d8LTfbA11zNB2A2SoKg/0","conversation_id":"S:1688853956558440_7881301364988874","corp_id":null,"desc":"","external_job":null,"nickname":"","position":"","realname":"","remark":"","sex":2,"user_id":"7881301364988874","username":"18","manager_wxid":null,"is_manager":0,"member_list":null} try { var contact = rst as WorkWechatContact; if (!string.IsNullOrWhiteSpace(contact.Message)) { var data = @"{""data"":" + contact.Message + "}"; var _result = HttpExtend.JsonToDictionary(data); if (_result != null) { var result = _result["data"] as Dictionary; var avatar = result["avatar"]?.ToString(); var username = result["username"]?.ToString(); var user_id = result["user_id"]?.ToString(); var sex = int.Parse(result["sex"]?.ToString()); var remark = result["remark"]?.ToString(); var manager_wxid = result["manager_wxid"]?.ToString(); Friends[user_id] = new Friend() { SmallHeadImgUrl = avatar, BigHeadImgUrl = avatar, City = string.Empty, Sex = sex, NickName = username, Remark = remark, UserName = user_id, Alias = user_id, ExtInfo = string.Empty, Province = string.Empty, ChatRoomOwner = manager_wxid, ChatroomVersion = string.Empty }; } } } catch (Exception ex) { this.WriteLog($"获取 Contact异常 :" + ex.Message + " - " + ex.StackTrace); } } } } if (Friends.ContainsKey(wxid)) return Friends[wxid]; else { var f = ChatClient.GetDBWechatFriend(wxid); if (f != null) Friends[wxid] = f; return f == null ? new Friend() { UserName = wxid, Alias = wxid } : f; } } catch (Exception ex) { this.WriteLog($"{ex.Message}"); } return new Friend() { UserName = wxid, Alias = wxid }; } } public Dictionary GroupMembers { get; private set; } /// /// 获取群成员信息 /// /// /// /// public override GroupMember GetMember(string groupid, string wxid) { try { if (!GroupMembers.ContainsKey(groupid) || GroupMembers[groupid].FirstOrDefault(f => f.Username == wxid) == null) { var msg_id = GetGroupWxidInfo(groupid, wxid); //GetGroupInfo(groupid); if (!string.IsNullOrEmpty(msg_id)) { var rst = ChatClient.PCRobotPool.PackHist.GetResult(msg_id).Result; if (rst != null) { //{"conversation_id":"R:10696053211008104","total":3,"friends":[{"avatar":"http://wx.qlogo.cn/mmhead/GPyw0pGicibl4KQicb5bXGu2SibrykeGOH5IicK2d8LTfbA11zNB2A2SoKg/0","conversation_id":"S:1688853956558440_7881301364988874","corp_id":null,"desc":"","external_job":null,"nickname":"18","position":"","realname":"","remark":"","sex":2,"user_id":"7881301364988874","username":null,"manager_wxid":"","is_manager":0,"member_list":""}]} try { var contact = rst as WorkWechatContact; if (!string.IsNullOrWhiteSpace(contact.Message)) { var data = @"{""data"":" + contact.Message + "}"; var _result = HttpExtend.JsonToDictionary(data); if (_result != null) { var result = _result["data"] as Dictionary; var conversation_id = result["conversation_id"]?.ToString(); var total = result["total"]?.ToString(); var friend = (result["friends"] as ArrayList)[0] as Dictionary; if (friend != null) { var avatar = friend["avatar"]?.ToString(); var nickname = friend["nickname"]?.ToString(); var remark = friend["remark"]?.ToString(); var sex = int.Parse(friend["sex"]?.ToString()); var user_id = friend["user_id"]?.ToString(); var manager_wxid = friend["manager_wxid"]?.ToString(); if (!GroupMembers.ContainsKey(conversation_id)) { GroupMembers.Add(conversation_id, new GroupMember[] { }); } var gm = GroupMembers[conversation_id].ToList(); if (gm.FirstOrDefault(f => f.Username == wxid) == null) { gm.Add(new GroupMember() { SmallHeadImgUrl = avatar, BigHeadImgUrl = avatar, Groupid = conversation_id, Username = wxid, NickName = nickname }); GroupMembers[conversation_id] = gm.ToArray(); } //Friends[user_id] = new Friend() { SmallHeadImgUrl = avatar, BigHeadImgUrl = avatar, City = string.Empty, Sex = sex, NickName = nickname, Remark = remark, UserName = user_id, Alias = user_id, ExtInfo = string.Empty, Province = string.Empty, ChatRoomOwner = manager_wxid, ChatroomVersion = string.Empty }; } } } } catch (Exception ex) { this.WriteLog($"获取 Member 异常 :" + ex.Message + " - " + ex.StackTrace); } } } } //if (!GroupMembers.ContainsKey(groupid)) return null; if (!GroupMembers.ContainsKey(groupid)) GroupMembers[groupid] = new GroupMember[] { new GroupMember() { Groupid = groupid, Username = wxid } }; else { var member = GroupMembers[groupid].FirstOrDefault(f => f.Username == wxid); if (member == null) { var gm = GroupMembers[groupid].ToList(); gm.Add(new GroupMember() { Groupid = groupid, Username = wxid }); GroupMembers[groupid] = gm.ToArray(); } } return GroupMembers[groupid].FirstOrDefault(f => f.Username == wxid); } catch (Exception ex) { this.WriteLog($"获取群信息:{ex.Message}"); } return new GroupMember() { Groupid = groupid, Username = wxid }; } /// /// 获取群成员信息 /// /// /// /// public override GroupMember GetMember(string groupid, string wxid, bool flush = false) { try { if (flush || !GroupMembers.ContainsKey(groupid) || GroupMembers[groupid].FirstOrDefault(f => f.Username == wxid) == null) { var msg_id = GetGroupWxidInfo(groupid, wxid, flush); //GetGroupInfo(groupid); if (!string.IsNullOrEmpty(msg_id)) { var rst = ChatClient.PCRobotPool.PackHist.GetResult(msg_id).Result; if (rst != null) { //{"conversation_id":"R:10696053211008104","total":3,"friends":[{"avatar":"http://wx.qlogo.cn/mmhead/GPyw0pGicibl4KQicb5bXGu2SibrykeGOH5IicK2d8LTfbA11zNB2A2SoKg/0","conversation_id":"S:1688853956558440_7881301364988874","corp_id":null,"desc":"","external_job":null,"nickname":"18","position":"","realname":"","remark":"","sex":2,"user_id":"7881301364988874","username":null,"manager_wxid":"","is_manager":0,"member_list":""}]} try { var contact = rst as WorkWechatContact; if (string.IsNullOrWhiteSpace(contact.Message)) return null; var data = @"{""data"":" + contact.Message + "}"; var _result = CsharpHttpHelper.HttpExtend.JsonToDictionary(data); if (_result == null) return null; var result = _result["data"] as Dictionary; var conversation_id = result["conversation_id"]?.ToString(); var total = result["total"]?.ToString(); var friend = (result["friends"] as ArrayList)[0] as Dictionary; if (friend != null) { var avatar = friend["avatar"]?.ToString(); var nickname = friend["nickname"]?.ToString(); var remark = friend["remark"]?.ToString(); var sex = int.Parse(friend["sex"]?.ToString()); var user_id = friend["user_id"]?.ToString(); var manager_wxid = friend["manager_wxid"]?.ToString(); if (!GroupMembers.ContainsKey(conversation_id)) { GroupMembers.Add(conversation_id, new GroupMember[] { }); } var gm = GroupMembers[conversation_id].ToList(); var info = gm.FirstOrDefault(f => f.Username == wxid); if (info != null) { gm.Remove(info); info = null; } if (info == null) { gm.Add(new GroupMember() { SmallHeadImgUrl = avatar, BigHeadImgUrl = avatar, Groupid = conversation_id, Username = wxid, NickName = nickname }); GroupMembers[conversation_id] = gm.ToArray(); } //Friends[user_id] = new Friend() { SmallHeadImgUrl = avatar, BigHeadImgUrl = avatar, City = string.Empty, Sex = sex, NickName = nickname, Remark = remark, UserName = user_id, Alias = user_id, ExtInfo = string.Empty, Province = string.Empty, ChatRoomOwner = manager_wxid, ChatroomVersion = string.Empty }; } } catch (Exception ex) { this.WriteLog($"获取 Member 异常 :" + ex.Message + " - " + ex.StackTrace); } } } } //if (!GroupMembers.ContainsKey(groupid)) return null; if (!GroupMembers.ContainsKey(groupid)) GroupMembers[groupid] = new GroupMember[] { new GroupMember() { Groupid = groupid, Username = wxid } }; var member = GroupMembers[groupid].FirstOrDefault(f => f.Username == wxid); return member; } catch (Exception ex) { this.WriteLog($"获取群信息:{ex.Message}"); } return null; } /// /// 创建群 /// /// public override string CreateChatRoom(string[] wxids) { try { if (wxids == null || wxids.Length == 0) return string.Empty; WechatPack pack = new WechatPack(this); var msg_id = pack.SendServer(PCRobotCMD.createRoom, string.Join(",", wxids)); if (!string.IsNullOrEmpty(msg_id)) { var rst = ChatClient.PCRobotPool.PackHist.GetResult(msg_id).Result; if (rst != null) { try { var createRoom = rst as CreateRoom; if (createRoom != null) return createRoom.GroupId; } catch (Exception ex) { this.WriteLog($"创建新群异常:" + ex.Message + " - " + ex.StackTrace); } } } } catch (Exception ex) { } return string.Empty; } #region xx /// /// 请求获取群信息 /// /// //private void GetGroupInfo(string groupid) //{ // try // { // lock (GroupMembers) // { // try // { // WechatPack send = new WechatPack(this); // send.SendServer(PCRobotCMD.getGroupMember, groupid); // } // catch (Exception ex) // { // this.WriteLog(ex.Message); // } // } // } // catch (Exception ex) // { // this.WriteLog($"请求群信息:{ex.Message}"); // } //} //private readonly object FriendsLock = new object(); //Action FriendsAction; // private void GetFriends(string friendsJson) // { // try // { // this.WriteLog($"GetFriends = {friendsJson}"); // lock (FriendsLock) // { // #region // var dic = HttpExtend.JsonToDictionary(friendsJson); // if (dic != null && dic.ContainsKey("data")) // { // var data = dic["data"] as System.Collections.ArrayList; // foreach (Dictionary item in data) // { // //var account = item["account"]?.ToString(); // //var avatar = item["avatar"]?.ToString(); // //var city = item["city"]?.ToString(); // //var country = item["country"]?.ToString(); // //var nickname = item["nickname"]?.ToString(); // //var province = item["province"]?.ToString(); // //var remark = item["remark"]?.ToString(); // //var sex = int.Parse(item["sex"]?.ToString()); // //var wxid = item["wxid"]?.ToString(); // var avatar = item["avatar"]?.ToString(); // var conversation_id = item["conversation_id"]?.ToString(); // var corp_id = item["corp_id"]?.ToString(); // var desc = item["desc"]?.ToString(); // var external_job = item["external_job"]?.ToString(); // var nickname = item["nickname"]?.ToString(); // var position = item["position"]?.ToString(); // var realname = item["realname"]?.ToString(); // var remark = item["remark"]?.ToString(); // var sex = int.Parse(item["sex"]?.ToString()); // var username = item["username"]?.ToString(); // var user_id = item["user_id"]?.ToString(); // var manager_wxid = item["manager_wxid"]?.ToString(); // var is_manager = int.Parse(item["is_manager"].ToString()); // Friends[user_id] = new Friend() { SmallHeadImgUrl = avatar, BigHeadImgUrl = avatar, City = string.Empty, Sex = sex, NickName = nickname, Remark = remark, UserName = user_id, Alias = user_id, ExtInfo = string.Empty, Province = string.Empty, ChatRoomOwner = manager_wxid, ChatroomVersion = string.Empty }; // #region 获取群详细信息 // if (user_id.Contains("R:")) // { // GetGroupInfo(user_id); // Thread.Sleep(5); // } // #endregion // } // } // #endregion // } // this.WriteLog($"GetFriends@ = {HttpHelper.ObjectToJson(Friends)}"); // } // catch (Exception ex) // { // this.WriteLog($@"获取成员失败:{ex.Message} - {ex.StackTrace} //friendsJson = {friendsJson}"); // } //} // private readonly object GroupMemberLock = new object(); // Action GroupMembersAction; // private void GetGroupMembers(string friendsJson) // { // try // { // this.WriteLog($"GetGroupMembers = {friendsJson}"); // lock (GroupMemberLock) // { // #region // var dic = HttpExtend.JsonToDictionary(friendsJson); // if (dic != null && dic.ContainsKey("data")) // { // var data = dic["data"] as Dictionary; // //var total_member = int.Parse(data["total_member"].ToString()); // var gId = data["conversation_id"].ToString(); // var list = data["member_list"] as ArrayList; // List groups = null; // if (GroupMembers.ContainsKey(gId)) // groups = GroupMembers[gId].ToList(); // else // groups = new List(); // foreach (Dictionary item in list) // { // //var account = item["account"]?.ToString(); // var avatar = item["avatar"]?.ToString(); // //var city = item["city"]?.ToString(); // //var country = item["country"]?.ToString(); // var nickname = item["nickname"]?.ToString(); // //var province = item["province"]?.ToString(); // var remark = item["remark"]?.ToString(); // var sex = int.Parse(item["sex"]?.ToString()); // var wxid = item["user_id"]?.ToString(); // if (groups.FirstOrDefault(f => f.Username == wxid) == null) // groups.Add(new GroupMember() { SmallHeadImgUrl = avatar, BigHeadImgUrl = avatar, Groupid = gId, Username = wxid, NickName = nickname }); // } // GroupMembers[gId] = groups.ToArray(); // } // #endregion // } // this.WriteLog($"GetGroupMembers@ = {HttpHelper.ObjectToJson(GroupMembers)}"); // } // catch (Exception ex) // { // this.WriteLog($@"获取群成员失败:{ex.Message} - {ex.StackTrace} //friendsJson = {friendsJson}"); // } // } #endregion /// /// 分析hook服务器过来的事件 /// /// public override void Receive(object obj) { var cmd = string.Empty; try { //LogHelper.GetSingleObj().Debug("", $"获取到解析后的数据_QY = {obj.GetType().Name},Uin:{this.User.Uin},{this.User.Nick}({this.WeixinHao})"); var events = ChatClient.Events; if (obj.GetType() == typeof(WorkWechatReceiveMsgEvents))//私聊和群聊消息 { var evt = obj as WorkWechatReceiveMsgEvents; cmd = evt.Data.Cmd.ToString(); //if (Friends.ContainsKey(evt.Data.FromUsername)) //{ // if (Friends[evt.Data.FromUsername].MsgType == 24 || Friends[evt.Data.FromUsername].MsgType == 8 || Friends[evt.Data.FromUsername].MsgType == 29)//公众号 // return; //} if (string.IsNullOrWhiteSpace(evt.Data.FromGroupid)) { if (Util.GetNoAnalysisConfig().Count == 0 || Util.GetNoAnalysisConfig().Contains("私消息")) { //bool is_phpone = false; Friend friend = null; friend = this.GetContact(evt.Data.FromUsername); if (!ChatClient.WXSdkConfig.MsgConvertToFriend && evt.Data.IsSend) { return; //if (evt.Data.IsSend == this.WeixinHao) //{ // is_phpone = true; //} //is_phpone = evt.Data.IsSend; } if (friend == null) { this.WriteLog(string.Format("获取用户{0}失败。", evt.Data.FromUsername)); return; } friend.NickName = Util.RemoveEmoji(friend.NickName); var eventobj = new WXReiceveFriendMsg(this, friend, evt.Data.FromMessage); eventobj.IsRobot = evt.Data.IsSend; events.OnEvent(eventobj); } } else { if (Util.GetNoAnalysisConfig().Count == 0 || Util.GetNoAnalysisConfig().Contains("群消息")) { var group = this.GetContact(evt.Data.FromGroupid); if (group == null) { this.WriteLog(string.Format("获取群{0}失败。", evt.Data.FromGroupid)); return; } GroupMember member = this.GetMember(evt.Data.FromGroupid, evt.Data.FromUsername); if (member == null) { this.WriteLog(string.Format("获取群{0}成员{1}信息失败。", evt.Data.FromGroupid, evt.Data.FromUsername)); return; } events.OnEvent(new WXReceiveGroupMsg(this, member, group, evt.Data.FromMessage)); return; } } } else if (obj.GetType() == typeof(WorkWechatApplyFriendEvents))//申请添加我为好友,需要审核 { if (Util.GetNoAnalysisConfig().Count == 0 || Util.GetNoAnalysisConfig().Contains("新申请")) { var evt = obj as WorkWechatApplyFriendEvents; cmd = evt.Data.Cmd.ToString(); events.OnEvent(new WXApplyFriend(this, evt.Data.NewFriendWxid, evt.Data.NewFriendNick, evt.Data.Message, evt.Data.OldFriendWxid, evt.Data.OldFriendNick, evt.Data.Token)); #region 这里给通过做准备,把用户信息保存起来 if (!Friends.ContainsKey(evt.Data.NewFriendWxid)) { var reg = Regex.Match(evt.Data.Token, @"smallheadimgurl==""(?<头像>[^""]*?)"""); var headIMG = string.Empty; if (reg.Success) headIMG = reg.Groups["头像"].Value; Friends[evt.Data.NewFriendWxid] = new Friend() { SmallHeadImgUrl = headIMG, BigHeadImgUrl = headIMG, City = string.Empty, Sex = 0, MsgType = 0, NickName = evt.Data.NewFriendNick, Remark = evt.Data.NewFriendNick, UserName = evt.Data.NewFriendWxid, Alias = evt.Data.NewFriendWxid, ExtInfo = string.Empty, Province = string.Empty, ChatRoomOwner = string.Empty, ChatroomVersion = string.Empty }; } #endregion } } else if (obj.GetType() == typeof(WorkWechatNewFriendEvents)) { if (Util.GetNoAnalysisConfig().Count == 0 || Util.GetNoAnalysisConfig().Contains("新好友")) { var evt = obj as WorkWechatNewFriendEvents; cmd = evt.Data.Cmd.ToString(); Friend friend = null; friend = this.GetContact(evt.Data.FromUserName);//这里很大概率获取不到用户的昵称,新用户 if (friend == null) { this.WriteLog(string.Format("获取用户{0}失败。", evt.Data.FromUserName)); return; } friend.NickName = Util.RemoveEmoji(friend.NickName); events.OnEvent(new WXNewFriend(this, friend)); } } else if (obj.GetType() == typeof(WorkWechatReicevePayEvents))//收到支付 { if (Util.GetNoAnalysisConfig().Count == 0 || Util.GetNoAnalysisConfig().Contains("转账")) { var evt = obj as WorkWechatReicevePayEvents; cmd = evt.Data.Cmd.ToString(); var friend = GetContact(evt.Data.FromUsername); if (friend != null) { friend.NickName = Util.RemoveEmoji(friend.NickName); var e = new WXReicevePay(this, friend, evt.Data.Invalidtime, evt.Data.Transferid, evt.Data.Money); events.OnEvent(e); } } } else if (obj.GetType() == typeof(WorkWechatNewMemerEvents))//新人入群 { if (Util.GetNoAnalysisConfig().Count == 0 || Util.GetNoAnalysisConfig().Contains("新群友")) { var evt = obj as WorkWechatNewMemerEvents; cmd = evt.Data.Cmd.ToString(); var group = GetContact(evt.Data.GroupId); if (group == null) return; events.OnEvent(new WXNewMemer(this) { Group = group, GroupId = evt.Data.GroupId, MemberNicks = evt.Data.MemberNick, SourceNick = Util.RemoveEmoji(evt.Data.SourceNick), SourceName = evt.Data.SourceName }); } } else if (obj.GetType() == typeof(WorkWechatContactListEvents))//获得通讯录列表 { //var evt = obj as WorkWechatContactListEvents; //cmd = evt.Data.Cmd.ToString(); //FriendsAction = GetFriends; //FriendsAction(evt.Data.Message); } else if (obj.GetType() == typeof(WorkWechatGroupMemberEvents))//获得群成员 { //var evt = obj as WorkWechatGroupMemberEvents; //cmd = evt.Data.Cmd.ToString(); //GroupMembersAction = GetGroupMembers; //GroupMembersAction(evt.Data.Message); } else if (obj.GetType() == typeof(WechatStatusEvents))//微信状态改变 { var evt = obj as WechatStatusEvents; cmd = evt.Cmd.ToString(); ChangeStatus(evt.Status == PCRobot.Pack.Status.在线 ? WxStatus.在线 : WxStatus.已退出); this.HeartBreakTime = DateTime.Now; } } catch (Exception ex) { this.WriteLog($"PC服务器消息处理异常:【{cmd}】- {ex.Message},{ex.StackTrace}"); } } /// /// 好友列表 /// public Dictionary Friends { get; private set; } public override List FindFriends() { try { var msg_id = RequestContact(); if (!string.IsNullOrEmpty(msg_id)) { var rst = ChatClient.PCRobotPool.PackHist.GetResult(msg_id).Result; if (rst != null) { try { var commonResult = rst as CommonResult; if (commonResult != null) { var data = commonResult.Data; return JsonConvert.DeserializeObject>(data); } } catch (Exception ex) { this.WriteLog($"获取企业外部通讯录用户异常:" + ex.Message + " - " + ex.StackTrace); } } } } catch (Exception ex) { } return null; } /// /// 请求获取联系人 /// /// public string RequestContact() { try { WechatPack pack = new WechatPack(this); return pack.SendServer(PCRobotCMD.getContact); } catch (Exception ex) { } return string.Empty; } /// /// 获取指定的用户 /// public string GetWxidInfo(string wxid) { try { WechatPack pack = new WechatPack(this); return pack.SendServer(PCRobotCMD.getWxidInfo, wxid); } catch (Exception ex) { } return string.Empty; } /// /// 获取指定的用户或群的信息 /// public string GetGroupWxidInfo(string groupId, string wxid) { try { WechatPack pack = new WechatPack(this); return pack.SendServer(PCRobotCMD.getGroupWxidInfo, wxid, WechatMsgType.图片, groupId); } catch (Exception ex) { } return string.Empty; } /// /// 获取指定的用户或群的信息 /// public string GetGroupWxidInfo(string groupId, string wxid, bool flush) { try { WechatPack pack = new WechatPack(this); //类型:图片表示不刷新,文件表示刷新 return pack.SendServer(PCRobotCMD.getGroupWxidInfo, wxid, flush ? WechatMsgType.文件 : WechatMsgType.图片, groupId); } catch (Exception ex) { } return string.Empty; } /// /// 领取转账 /// /// /// /// /// public override int TenPayTransferConfirm(string Invalidtime, string Transferid, string FromUsername) { WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.getPay, HttpHelper.ObjectToJson(new Dictionary() { { "Invalidtime", Invalidtime }, { "Transferid", Transferid } }), WechatMsgType.文本, FromUsername); return 0; } /// /// 发送卡片 /// /// /// public override void SendCard(string username, string friendwxid) { WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.sendCard, friendwxid, WechatMsgType.文本, username); } /// /// 邀请入群发送名片 和 AddChatRoomMember 功能一样 /// /// /// /// public override string InviteIntoGroup(string username, string groupId) { WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.inviteIntoGroup, groupId, WechatMsgType.文本, username); return string.Empty; } /// /// 邀请入群发送名片 和 AddChatRoomMember 功能一样 /// /// /// public override void AddChatRoomMember_40Down(string groupid, string members) { WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.inviteIntoGroup, groupid, WechatMsgType.文本, members); } /// /// 邀请入群发送名片 和 AddChatRoomMember_40Down 功能一样 /// /// /// public override void AddChatRoomMember(string groupid, string members) { AddChatRoomMember_40Down(groupid, members); } /// /// 删除群用户 /// /// /// /// public override string DeleteGroupMember(string username, string groupId) { WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.deleteGroupMember, username, WechatMsgType.文本, groupId); return string.Empty; } /// /// 发送图片 /// /// /// public override void SendImage(string username, string address) { try { byte[] ImangByte = null; string extension = Path.GetExtension(address); if (address.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)) { ImangByte = new System.Net.WebClient().DownloadData(address); byte[] imageHash = new MD5CryptoServiceProvider().ComputeHash(ImangByte); //图片哈希值 string StrimageHash = Util.HexToStr(imageHash); string FileName = StrimageHash + extension; string FilePath = Path.Combine(Util.MapPath("cache\\image", true), FileName); if (!File.Exists(FilePath)) { File.WriteAllBytes(FilePath, ImangByte); } if (File.Exists(FilePath)) address = FilePath; else throw new Exception("图片异常"); } WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.sendImg, address, WechatMsgType.图片, username); } catch (Exception ex) { this.WriteLog($"发送图片失败:{ex.Message} - {ex.StackTrace}"); } } public override void SendProgramMessage(string username, string ghid, string wxid, string name, string title, string enterpoint, string headimg, string image_key1, string image_key2, string image_key3, string image_size) { try { WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.sendProgramMessage, JsonConvert.SerializeObject(new { data = new { conversation_id = username, ghid = ghid, wxid = wxid, name = name, title = title, enterpoint = enterpoint, headimg = headimg, image_key1 = image_key1, image_key2 = image_key2, image_key3 = image_key3, image_size = image_size } }), WechatMsgType.文本, username); } catch (Exception ex) { this.WriteLog("SendProgramMessage ERROR:" + ex.Message); } } /// /// 发送消息 /// /// /// /// /// public override Task SendMessage(string _username, string _message, string _atUsername = "") { string username = _username; string content = _message; string atUsername = _atUsername; return Task.Run(() => { if (string.IsNullOrEmpty(content)) return true; content = content.Replace("\r\n", "\n").Trim().Replace("[时间]", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Replace("[机器人微信]", this.User.Username); var msgs = content.Split(new string[] { "[分段]" }, StringSplitOptions.RemoveEmptyEntries); try { foreach (var msg in msgs) { var m = msg.Replace("\r\n", "\n").Trim(); if (string.IsNullOrEmpty(m)) continue; var message = m.RandomMess(); message = message.Contains("[随机表情]") ? message.Replace("[随机表情]", WXClientImpl_IPAD.FindRandomExpression()) : message; //if (message.StartsWith("[延迟=")) //{ // var reg = Regex.Match(message, @"\[延迟=(\d+)\]"); // if (reg.Success) // { // message = Regex.Replace(message, @"\[延迟=(\d+)\]", "").Trim(); // // this.WriteLog($"需要延迟{reg.Groups[1].Value}秒,再发送:{message}"); // Thread.Sleep(int.Parse(reg.Groups[1].Value) * 1000); // } //} message = DelayMess(message); ChatClient.Events.OnEvent(new WXSendMessage(this, message, username)); WechatPack pack = new WechatPack(this); //发送XML消息 if (message.ToLower().Trim().StartsWith("")) { //if (!message.ToLower().Contains("")) if (true) { message = $@"{WeixinHao}0{msg/*.Replace("&", "&")*/}1Window wechat"; pack.SendServer(PCRobotCMD.sendTxt, message, WechatMsgType.文本, username); } else { /* {"data":{"content_type":78,"conversation_id":"S:1688852952419302_1688853086316483","enterpoint":"pages/index.html","ghid":"gh_0ed5d82fd775@app","headimg":"http://mmbiz.qpic.cn/mmbiz_png/R5xk2bJZhgSL24GXicQ24b8h7zwWKY9Eia4Pl4RJibFml6k2icWj8H7rbFmiaiakt7wPwx7vUgrKic62PBZpdTTwdsJ2g/640?wx_fmt=png&wxfrom=200","image_key1":"3069020102046230600201000204b84e8be602030f4243020412cf9b24020460df2504042439643136386638302d303661652d343136322d386438342d6265643138623961356665620201000203024ef0041083bf4e722024dbcfc797cfaa1e97ac090201010201000400","image_key2":"13e72cff06014d4e9d392fd059228092","image_key3":"83bf4e722024dbcfc797cfaa1e97ac09","image_size":151279,"is_pc":0,"local_id":"18","name":"通信行程卡","receiver":"1688853086316483","send_time":"1625236741","sender":"1688852952419302","sender_name":"滴滴滴","server_id":"1000455","title":"通信行程卡","wxid":"wx8f446acf8c4a85f5"},"type":11066} */ SendProgramMessage(username, "gh_0ed5d82fd775@app", "wx8f446acf8c4a85f5", "兑换助兑换助兑换助", "兑换助兑换助", "pages/11111111111111", "http://mmbiz.qpic.cn/mmbiz_png/R5xk2bJZhgSL24GXicQ24b8h7zwWKY9Eia4Pl4RJibFml6k2icWj8H7rbFmiaiakt7wPwx7vUgrKic62PBZpdTTwdsJ2g/640?wx_fmt=png&wxfrom=200", "3069020102046230600201000204b84e8be602030f4243020412cf9b24020460df2504042439643136386638302d303661652d343136322d386438342d6265643138623961356665620201000203024ef0041083bf4e722024dbcfc797cfaa1e97ac090201010201000400", "13e72cff06014d4e9d392fd059228092", "83bf4e722024dbcfc797cfaa1e97ac09", "151279"); } continue; } //发送图片消息 var matchs = Regex.Matches(message, @"\[图片\=([^\]]+)\]", RegexOptions.IgnoreCase); foreach (Match match in matchs) { var imageBase = string.Empty; var image = match.Groups[1].Value; if (!image.ToLower().Trim().StartsWith("http")) { if (File.Exists(image)) { double size = new FileInfo(image).Length; if (size > 1024 * 512) { try { var img = Util.ReadImageFile(image); var bitmap = Util.PercentImage(img, img.Width); var _image = image + Path.GetExtension(image);//压缩图片的地址 if (Util.YaSuo(bitmap, _image)) { imageBase = Util.FileToBase64(_image); } } catch (Exception ex) { LogHelper.GetSingleObj().Error("", $"QY图片压缩异常:{ex.Message} - {ex.StackTrace}"); imageBase = Util.FileToBase64(image); } } else imageBase = Util.FileToBase64(image); } } else imageBase = image; SendImage(username, imageBase); } message = Regex.Replace(message, @"\[图片\=([^\]]+)\]", ""); message = DelayMess(message); //发送语音消息 //matchs = Regex.Matches(message, @"\[语音\=([^\]]+)\]", RegexOptions.IgnoreCase); //foreach (Match item in matchs) //{ //SendVoice(username, item.Groups[1].Value);//PC不能发送语音 //} message = Regex.Replace(message, @"\[语音\=([^\]]+)\]", ""); message = DelayMess(message); matchs = Regex.Matches(message, @"\[视频\=([^\]]+)\]", RegexOptions.IgnoreCase); foreach (Match item in matchs) { //var video = Util.StrToHex(item.Groups[1].Value); //if (video != null) //{ // var video_json = Encoding.UTF8.GetString(video); // var video_data = CsharpHttpHelper.HttpExtend.JsonToDictionary(video_json); // if (video_data != null) // { // SendCDNInfo(username, video_data["cdnurl"].ToString(), video_data["aeskey"].ToString(), CDNType.发送视频); // } //} var filePath = item.Groups[1].Value; if (!Regex.IsMatch(filePath, @"^[c-zC-Z]:\\")) continue; //if (File.Exists(filePath)) //{ //var base64 = Util.FileToBase64(filePath); pack.SendServer(PCRobotCMD.sendVideo, filePath, WechatMsgType.视频, username); //} } message = Regex.Replace(message, @"\[视频\=([^\]]+)\]", ""); message = DelayMess(message); matchs = Regex.Matches(message, @"\[卡片\=([^\]]+)\]", RegexOptions.IgnoreCase); foreach (Match item in matchs) { SendCard(username, item.Groups[1].Value == "自己" ? User.Username : item.Groups[1].Value); } message = Regex.Replace(message, @"\[卡片\=([^\]]+)\]", ""); message = DelayMess(message); if (string.IsNullOrWhiteSpace(message)) continue; if (message.StartsWith("\r\n")) message = message.Substring("\r\n".Length); if (message.StartsWith("\n")) message = message.Substring("\n".Length); //pack.SendServer(PCRobotCMD.sendTxt, message, WechatMsgType.文本, username); pack.SetNextData(new ServerWechatMsg() { Cmd = PCRobotCMD.sendTxt, ToMessage = message, ToMessageType = WechatMsgType.文件, ToUsername = username }); RunSendMessageQueue(pack); } return true; } catch (Exception ex) { this.WriteLog("SendMessage ERROR:" + ex.Message); return false; } }); } #region 消息发送速度处理 /// /// 需要发送的消息队列 /// private ConcurrentQueue SendMessageQueue { get; set; } = new ConcurrentQueue(); private object lock_sendmessage = new object(); private bool lock_sendmessage_ing = false; private int fragmentCount = 0; private DateTime fragmentTime = DateTime.MinValue; private Random random = new Random(); private void RunSendMessageQueue(WechatPack sendPack) { SendMessageQueue.Enqueue(sendPack); if (lock_sendmessage_ing) return; lock (lock_sendmessage) { if (lock_sendmessage_ing) return; lock_sendmessage_ing = true; ThreadPool.QueueUserWorkItem(x => { try { WechatPack pack = null; while (SendMessageQueue.TryDequeue(out pack)) { if (this.Status == WxStatus.在线) { pack.SendNextData(); #region 消息防止频繁,休眠操作 if (ChatClient.MessFrequentSleepTime != 0) { fragmentCount++; var totalSeconds = (DateTime.Now - fragmentTime).TotalSeconds;//上次休眠的时间差 bool rest = totalSeconds > 10; if (fragmentCount >= 10 && totalSeconds <= 10) { rest = true; Thread.Sleep(ChatClient.MessFrequentSleepTime * 1000); } if (rest) { fragmentCount = 1; fragmentTime = DateTime.Now; } else Thread.Sleep(60); } else Thread.Sleep(60); #endregion } } } catch (Exception) { } finally { lock_sendmessage_ing = false; } }); } } #endregion /// /// 同意添加我为好友 /// /// /// public override string AgreeAddMe(string token) { WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.agreeFriend, token, WechatMsgType.文本, string.Empty); return string.Empty; } /// /// 删除好友 /// /// /// public override string DeleteFriend(string username) { WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.deleteFriend, username, WechatMsgType.文本, string.Empty); return string.Empty; } /// /// 修改用户信息 /// /// /// /// public override void EditContacts(string username, EditContactsType type, string remark = "") { Task.Run(() => { for (int i = 0; i < 3; i++) { if (type == EditContactsType.备注) { WechatPack pack = new WechatPack(this); pack.SendServer(PCRobotCMD.editContacts, remark, WechatMsgType.文本, username); Thread.Sleep(500); } //else if (type == EditContactsType.置顶 || type == EditContactsType.取消置顶) //{ // WechatPack pack = new WechatPack(this); // pack.SendServer(PCRobotCMD.stateOpt, type == EditContactsType.置顶 ? "1" : "0", WechatMsgType.文本, username); //} //else // throw new Exception("本协议不支持该操作"); } }); } /// /// 消息延迟 /// /// public string DelayMess(string message) { try { message = message.Trim(); if (message.StartsWith("[延迟=")) { var reg = Regex.Match(message, @"\[延迟=(\d+)\]"); if (reg.Success) { message = Regex.Replace(message, @"\[延迟=(\d+)\]", "").Trim(); // this.WriteLog($"需要延迟{reg.Groups[1].Value}秒,再发送:{message}"); Thread.Sleep(int.Parse(reg.Groups[1].Value) * 1000); } } } catch (Exception ex) { } return message; } } }