Exemple #1
0
        public void SyncCheck(IWeChatLoginClient weChatLoginClient)
        {
            //检测程序是否退出
            if (_Logout)
            {
                SystemInfo.IsLogin = false;

                LogHelper.Default.LogDay("微信离线,消息同步线程退出");
                LogHelper.Default.LogPrint("微信离线,消息同步线程退出", 3);
                return;
            }

            //更新同步消息时间
            _LastSyncCheckTime = DateTime.Now;

            //同步检查是否有新消息
            var resultSyncCheckResponse = _WeChatHttpClient.SyncCheck(weChatLoginClient.LoginResponse, weChatLoginClient.SyncKey.ToString());

            if (!resultSyncCheckResponse.Success)
            {
                //同步消息异常,直接进入下个循环
                //LogHelper.Default.LogPrint("", 3);
                Task.Run(() => SyncCheck(weChatLoginClient));
            }
            else
            {
                //同步消息结果解析
                SyncCheckResponseParser(resultSyncCheckResponse.Data, weChatLoginClient);

                //进入下一个循环接收消息
                Task.Run(() => SyncCheck(weChatLoginClient));
            }
        }
Exemple #2
0
        /*constructor*/
        public WeChatMessageClinet(IWeChatHttpClient weChatHttpClient, IWeChatContactClient weChatContactClient, IWeChatLoginClient weChatLoginClient)
        {
            _WeChatHttpClient    = weChatHttpClient;
            _WeChatContactClient = weChatContactClient;
            _WeChatLoginClient   = weChatLoginClient;

            Init();
        }
Exemple #3
0
 public WeChatEngine(
     ILogger <WeChatEngine> logger,
     ILoggerFactory loggerFactory,
     IWeChatLoginClient weChatClient)
 {
     _logger        = logger;
     _loggerFactory = loggerFactory;
     _weChatClient  = weChatClient;
 }
Exemple #4
0
        private void DownloadAudio(string msgId, IWeChatLoginClient weChatLoginClient)
        {
            var result = _WeChatHttpClient.FetchAudioMessage(msgId, weChatLoginClient.LoginResponse);

            if (result.Success)
            {
                var fullFileName = SystemInfo.WechatImagePath + msgId + ".mp3";
                File.WriteAllBytes(fullFileName, result.GetData());
                LogHelper.Default.LogPrint($"语音下载完成", 2);
            }
        }
Exemple #5
0
        private void DownloadImage(string msgId, string type, IWeChatLoginClient weChatLoginClient, string ext = ".jpg")
        {
            var result = _WeChatHttpClient.FetchImageMessage(msgId, type, weChatLoginClient.LoginResponse);

            if (result.Success)
            {
                var fullFileName = SystemInfo.WechatImagePath + msgId + ext;
                File.WriteAllBytes(fullFileName, result.GetData());
                LogHelper.Default.LogPrint($"图片下载完成", 2);
            }
        }
Exemple #6
0
        /*private method*/
        private void Init()
        {
            if (_Cookie == null)
            {
                _Cookie = new CookieContainer();
            }
            if (_HttpClient == null)
            {
                _HttpClient = new HttpClient(new HttpClientHandler()
                {
                    UseCookies = true, CookieContainer = _Cookie
                });
            }
            if (_WeChatHttpClient == null)
            {
                _WeChatHttpClient = new WeChatHttpClient(_HttpClient);
            }
            if (_WeChatContactClient == null)
            {
                _WeChatContactClient = new WeChatContactClient(_WeChatHttpClient);
            }
            if (_WeChatLoginClient == null)
            {
                _WeChatLoginClient = new WeChatLoginClient(_WeChatHttpClient, _WeChatContactClient);
            }
            if (_WeChatMessageClient == null)
            {
                _WeChatMessageClient = new WeChatMessageClinet(_WeChatHttpClient, _WeChatContactClient, _WeChatLoginClient);
            }


            if (!Directory.Exists(SystemInfo.WechatImagePath))
            {
                Directory.CreateDirectory(SystemInfo.WechatImagePath);
                LogHelper.Default.LogPrint($"微信图片文件夹创建成功", 2);
            }
        }
Exemple #7
0
        private void SyncCheckResponseParser(SyncCheckResponse syncCheckResponse, IWeChatLoginClient weChatLoginClient)
        {
            try
            {
                if (syncCheckResponse.RetCode == "0")
                {
                    if (syncCheckResponse.Selector == "0")
                    {
                        //没有任何消息
                        LogHelper.Default.LogPrint($"没有新消息,空循环", 1);
                    }
                    else if (syncCheckResponse.Selector == "2")
                    {
                        LogHelper.Default.LogPrint("接收到新消息", 2);

                        //拉取消息
                        var resultFetchMessageResponse = _WeChatHttpClient.FetchMessage(weChatLoginClient.LoginResponse, weChatLoginClient.SyncKey);
                        if (resultFetchMessageResponse.Success)
                        {
                            //更新synckey
                            weChatLoginClient.SyncKey = resultFetchMessageResponse.Data.SyncKey;

                            //提取消息
                            GetMessages(resultFetchMessageResponse.Data, weChatLoginClient);
                        }
                        else
                        {
                            LogHelper.Default.LogDay("消息拉取失败");
                            LogHelper.Default.LogPrint("消息拉取失败", 3);
                        }
                    }
                    else if (syncCheckResponse.Selector == "4")
                    {
                        LogHelper.Default.LogPrint("通讯列表更新", 3);

                        //拉取通讯录更新消息
                        var resultFetchMessageResponse = _WeChatHttpClient.FetchMessage(weChatLoginClient.LoginResponse, weChatLoginClient.SyncKey);
                        if (resultFetchMessageResponse.Success)
                        {
                            //更新synckey
                            weChatLoginClient.SyncKey = resultFetchMessageResponse.Data.SyncKey;

                            //提取通讯录更新消息
                            GetMessages(resultFetchMessageResponse.Data, weChatLoginClient);
                        }
                        else
                        {
                            LogHelper.Default.LogDay("通讯列表更新消息拉取失败");
                            LogHelper.Default.LogPrint("通讯列表更新消息拉取失败", 3);
                        }
                    }
                    else if (syncCheckResponse.Selector == "6")
                    {
                        LogHelper.Default.LogDay("0-6:暂停5S");
                        LogHelper.Default.LogPrint("0-6:暂停5S", 1);
                        Task.Delay(5000).Wait();
                    }
                    else if (syncCheckResponse.Selector == "7")
                    {
                        LogHelper.Default.LogDay("0-7:暂停5S");
                        LogHelper.Default.LogPrint("0-7:暂停5S", 1);
                        Task.Delay(5000).Wait();
                    }
                    else
                    {
                        LogHelper.Default.LogDay($"未知情况,RetCode={syncCheckResponse.RetCode},Selector={syncCheckResponse.Selector}");
                        LogHelper.Default.LogPrint($"未知情况,RetCode={syncCheckResponse.RetCode},Selector={syncCheckResponse.Selector}", 3);
                    }

                    _LogoutTimes = 0;
                }
                else if (syncCheckResponse.RetCode == "1101")
                {
                    _LogoutTimes++;
                    if (_LogoutTimes > _LogoutTimesLimit)
                    {
                        _Logout = true;
                    }

                    LogHelper.Default.LogDay($"从微信客户端上登出,{_LogoutTimes}/{_LogoutTimesLimit}");
                    LogHelper.Default.LogPrint($"从微信客户端上登出,{_LogoutTimes}/{_LogoutTimesLimit}", 3);
                }
                else
                {
                    LogHelper.Default.LogDay($"未解析的同步消息,RetCode={syncCheckResponse.RetCode},Selector={syncCheckResponse.Selector}");
                    LogHelper.Default.LogPrint($"未解析的同步消息,RetCode={syncCheckResponse.RetCode},Selector={syncCheckResponse.Selector}", 3);
                    Task.Delay(5000).Wait();
                }
            }
            catch (Exception ex)
            {
                LogHelper.Default.LogDay($"消息类型解析异常,{ex}");
                LogHelper.Default.LogPrint($"消息类型解析异常,{ex.Message}", 4);
            }
        }
Exemple #8
0
        private void DownloadFile(string msgId, string sender, string mediaid, string fileName, string encryfilename, IWeChatLoginClient weChatLoginClient)
        {
            var result = _WeChatHttpClient.FetchFileMessage(sender, mediaid, encryfilename, weChatLoginClient.LoginResponse);

            if (result.Success)
            {
                var fullFileName = SystemInfo.WechatImagePath + msgId + fileName;
                File.WriteAllBytes(fullFileName, result.GetData());
                LogHelper.Default.LogPrint($"文件下载完成", 2);
            }
        }
Exemple #9
0
        private void GetMessages(FetchMessageResponse fetchMessageResponse, IWeChatLoginClient weChatLoginClient)
        {
            try
            {
                LogHelper.Default.LogPrint($"当前接收消息条数:{fetchMessageResponse.AddMsgCount}", 2);

                if (fetchMessageResponse.AddMsgList != null && fetchMessageResponse.AddMsgList.Count > 0)
                {
                    //消息解析
                    foreach (var v in fetchMessageResponse.AddMsgList)
                    {
                        var fromUserName = v.FromUserName;
                        var toUserName   = v.ToUserName;
                        var fromNickName = _WeChatContactClient.AllMemberList?.Where(x => x.UserName == fromUserName).Select(x => x.NickName).FirstOrDefault();
                        var toNickName   = _WeChatContactClient.AllMemberList?.Where(x => x.UserName == toUserName).Select(x => x.NickName).FirstOrDefault();

                        if (v.MsgType == 1 && v.ImgStatus == 1 && v.Status == 3)
                        {
                            //文字【确认】
                            //腾讯新闻检测规则(?<=;name[^\[]+)\[CDATA\[[^\]]+]](?=\S+/name)
                            //腾讯新闻列表提取规则(?<=;title[^\[]+)\[CDATA\[[^\]]+]](?=\S+/title)
                            var name = Regex.Match(v.Content, "(?<=;name[^\\[]+)\\[CDATA\\[[^\\]]+]](?=\\S+/name)").ToString();
                            if (!string.IsNullOrEmpty(name))
                            {
                                var itemList = new List <string>();
                                var mas      = Regex.Matches(v.Content, "(?<=;title[^\\[]+)\\[CDATA\\[[^\\]]+]](?=\\S+/title)");
                                foreach (Match ma in mas)
                                {
                                    itemList.Add(ma.ToString());
                                }
                                LogHelper.Default.LogPrint($"{name}\r\n{string.Join("\r\n", itemList)}");
                            }
                            else
                            {
                                LogHelper.Default.LogPrint($"文本消息[{fromNickName}==>{toNickName}]:{v.Content}", 2);
                            }
                        }
                        else if (v.MsgType == 3 && v.ImgStatus == 2 && v.Status == 3)
                        {
                            //图片【确认】
                            LogHelper.Default.LogPrint($"图片[{fromNickName}==>{toNickName}]:MsgId={v.MsgId}", 2);
                            DownloadImage(v.MsgId, "big", weChatLoginClient, ".jpg");
                        }
                        else if (v.MsgType == 34 && v.ImgStatus == 1 && v.Status == 3)
                        {
                            //语音消息【确认】
                            LogHelper.Default.LogPrint($"语音[{fromNickName}==>{toNickName}]", 2);

                            //语音下载
                            DownloadAudio(v.MsgId, weChatLoginClient);
                        }
                        else if (v.MsgType == 43 && v.ImgStatus == 1 && v.Status == 3)
                        {
                            //小视频【确定】
                            LogHelper.Default.LogPrint($"小视频[{fromNickName}==>{toNickName}]", 2);

                            //视频略缩图下载
                            DownloadImage(v.MsgId, "slave", weChatLoginClient, ".jpg");

                            //小视频下载
                            DownloadVideo(v.MsgId, weChatLoginClient);
                        }
                        else if (v.MsgType == 47 && v.ImgStatus == 2 && v.Status == 3)
                        {
                            //动画【确认】
                            //动画类型提取 1:系统内置 2:可以使GIF
                            var type = Regex.Match(v.Content, "(?<=type=\")[^\"]+").ToString().Trim();
                            if (type == "1")
                            {
                                var ma = Regex.Match(v.Content, "gameext type=\"([^\"]+)\"\\s+content=\"([^\"]+)");
                                LogHelper.Default.LogPrint($"内置动画[{fromNickName}==>{toNickName}]:MsgId={v.MsgId},gameext type={ma.Groups[1]},content={ma.Groups[2]}", 2);
                                DownloadImage(v.MsgId, "big", weChatLoginClient, ".jpg");
                            }
                            else if (type == "2")
                            {
                                LogHelper.Default.LogPrint($"GIF图片[{fromNickName}==>{toNickName}]:MsgId={v.MsgId}", 2);
                                DownloadImage(v.MsgId, "big", weChatLoginClient, ".gif");
                            }
                            else if (v.HasProductId == 1)
                            {
                                LogHelper.Default.LogDay($"只能在手机查看的表情[{fromNickName}==>{toNickName}]:MsgId={v.MsgId}");
                            }
                            else
                            {
                                LogHelper.Default.LogDay($"未知图片[{fromNickName}==>{toNickName}]:MsgId={v.MsgId}");
                                LogHelper.Default.LogPrint($"未知图片[{fromNickName}==>{toNickName}]:MsgId={v.MsgId}", 2);
                            }
                        }
                        else if (v.MsgType == 49 && v.ImgStatus == 1 && v.Status == 3)
                        {
                            if (v.AppMsgType == 6)
                            {
                                //文件接收
                                var fileName = v.FileName;
                                LogHelper.Default.LogPrint($"接收文件[{fromNickName}==>{toNickName}]:{fileName}", 2);

                                //文件下载
                                DownloadFile(v.MsgId, toUserName, v.MediaId, v.FileName, v.EncryFileName, weChatLoginClient);
                            }
                            else if (v.AppMsgType == 2000)
                            {
                                //微信转账
                                var fileName = v.FileName;
                                var desc     = Regex.Match(v.Content, "(?<=;des[^\\[]+)\\[CDATA\\[[^\\]]+]](?=\\S+/des)").ToString();
                                LogHelper.Default.LogPrint($"{fileName}[{fromNickName}==>{toNickName}]:{desc}", 2);
                            }
                            else
                            {
                                LogHelper.Default.LogDay($"49-1-3内置类型未解析,{JsonConvert.SerializeObject(v)}");
                                LogHelper.Default.LogPrint($"49-1-3内置类型未解析,{JsonConvert.SerializeObject(v)}", 3);
                            }


                            ////订阅号消息【确认】
                            //var stepCountType = Regex.Match(v.Content, "\\[CDATA\\[夺得\\d+月\\d+日排行榜冠军\\]\\]").ToString();
                            //if (!string.IsNullOrEmpty(stepCountType))
                            //{
                            //    //微信运动
                            //    LogHelper.Default.LogDay($"微信运动订阅号消息[{fromNickName}==>{toNickName}]");
                            //    LogHelper.Default.LogPrint($"微信运动订阅号消息[{fromNickName}==>{toNickName}]", 2);
                            //}
                            //else
                            //{

                            //    //(?<=;title[^\[]+)\[CDATA\[[^\]]+]](?=\S+/title)
                            //    var mas = Regex.Matches(v.Content, "(?<=;title[^\\[]+)\\[CDATA\\[[^\\]]+]](?=\\S+/title)");
                            //    if(mas.Count==1)
                            //    {
                            //        //转账消息,也有可能是别的
                            //        //消息识别规则(?<=;des[^\[]+)\[CDATA\[[^\]]+]](?=\S+/des)
                            //        var desc = Regex.Match(v.Content, "(?<=;des[^\\[]+)\\[CDATA\\[[^\\]]+]](?=\\S+/des)").ToString();
                            //        LogHelper.Default.LogDay($"[{fromNickName}==>{toNickName}]:title={mas[0].ToString()},des={desc}");
                            //        LogHelper.Default.LogPrint($"[{fromNickName}==>{toNickName}]:title={mas[0].ToString()},des={desc}", 2);
                            //    }
                            //    else
                            //    {
                            //        //普通订阅号消息
                            //        var itemList = new List<string>();
                            //        foreach (Match ma in mas)
                            //        {
                            //            itemList.Add(ma.ToString());
                            //        }

                            //        LogHelper.Default.LogDay($"订阅号消息[{fromNickName}==>{toNickName}]\r\n{string.Join("\r\n", itemList)}");
                            //        LogHelper.Default.LogPrint($"订阅号消息[{fromNickName}==>{toNickName}]\r\n{string.Join("\r\n", itemList)}", 2);
                            //    }
                            //}
                        }
                        else if (v.MsgType == 49 && v.ImgStatus == 2 && v.Status == 3)
                        {
                            //群内的新闻链接【确定】
                            var title = Regex.Match(v.Content, "(?<=title)\\S+(?=/title)").ToString().Replace("&gt;", "");
                            var url   = Regex.Match(v.Content, "(?<=url)\\S+(?=/url)").ToString().Replace("&gt;", "");
                            LogHelper.Default.LogPrint($"外链消息[{fromNickName}==>{toNickName}]\r\n" +
                                                       $"title={title}\r\n" +
                                                       $"url={url}", 2);
                        }
                        else if (v.MsgType == 51 && v.ImgStatus == 1 && v.Status == 3)
                        {
                            //跟通信列表有关系,单个联系人更新或者群列表同志【确认】
                            if (v.StatusNotifyUserNameArray != null && v.StatusNotifyUserNameArray.Length > 1)
                            {
                                LogHelper.Default.LogDay("消息解析过程中,遇到微信群列表通知,进行群列表获取");
                                LogHelper.Default.LogPrint("消息解析过程中,遇到微信群列表通知,进行群列表获取", 2);
                                GetBatchContacts(v.StatusNotifyUserNameArray);
                            }
                            else
                            {
                                //LogHelper.Default.LogDay($"通信列表更新,[{fromNickName}==>{toNickName}]:{JsonConvert.SerializeObject(fetchMessageResponse)}");
                                LogHelper.Default.LogPrint($"通信列表更新[{fromNickName}==>{toNickName}]", 2);
                            }
                        }
                        else if (v.MsgType == 10000 && v.ImgStatus == 1 && v.Status == 3)
                        {
                            //收到红包【确定】
                            LogHelper.Default.LogPrint($"[{fromNickName}==>{toNickName}]:{v.Content}", 2);
                        }
                        else if (v.MsgType == 10000 && v.ImgStatus == 1 && v.Status == 4)
                        {
                            //群内邀请通知【确定】
                            LogHelper.Default.LogPrint($"群内邀请通知[{fromNickName}==>{toNickName}]:{v.Content}", 2);
                        }
                        else if (v.MsgType == 10002 && v.ImgStatus == 1 && v.Status == 4)
                        {
                            //消息撤回【确认】
                            var oldMgId = Regex.Match(v.Content, "(?<=;oldmsgid[^\\d]+)\\d+(?=[^\\d+]+oldmsg)").ToString();
                            var msgId   = Regex.Match(v.Content, "(?<=;msgid[^\\d]+)\\d+(?=[^\\d+]+msg)").ToString();
                            var msg     = Regex.Match(v.Content, "\\[[^\\]]+]]").ToString();
                            LogHelper.Default.LogPrint($"消息撤回[{fromNickName}==>{toNickName}]:{msg},oldMsgId={oldMgId},msgId={msgId}", 2);
                        }
                        else
                        {
                            LogHelper.Default.LogDay($"未解析类型消息:{v.MsgType}-{v.ImgStatus}-{v.Status}-{v.Content}");
                            LogHelper.Default.LogPrint($"未解析类型消息:{v.MsgType}-{v.ImgStatus}-{v.Status}-{v.Content}", 3);
                        }
                    }

                    _NullCyclelingSyncCheckTimes = 0;
                }
                else if (fetchMessageResponse.ModContactCount > 0)
                {
                    //通信列表更新消息解析
                    foreach (var v in fetchMessageResponse.ModContactList)
                    {
                        LogHelper.Default.LogDay($"通信列表更新,NickName={v.NickName},UserName={v.UserName},City={v.City},Signature={v.Signature}");
                        LogHelper.Default.LogPrint($"通信列表更新,NickName={v.NickName},UserName={v.UserName},City={v.City},Signature={v.Signature}", 2);
                    }

                    _NullCyclelingSyncCheckTimes = 0;
                }
                else
                {
                    //LogHelper.Default.LogDay($"接收到空的消息体,{JsonConvert.SerializeObject(fetchMessageResponse)}");
                    //LogHelper.Default.LogPrint($"接收到空的消息体,{JsonConvert.SerializeObject(fetchMessageResponse)}", 3);
                    LogHelper.Default.LogDay($"接收到空的消息体");
                    LogHelper.Default.LogPrint($"接收到空的消息体", 3);

                    //高频率空循环延时检测
                    _NullCyclelingSyncCheckTimes++;
                    if (_NullCyclelingSyncCheckTimes >= __NullCyclelingSyncCheckTimesLimit)
                    {
                        _NullCyclelingSyncCheckTimes = 0;
                        Task.Delay(5000).Wait();
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Default.LogDay($"消息解析异常,{ex}");
                LogHelper.Default.LogPrint($"消息解析异常,{ex.Message}", 4);
            }
        }