public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
 {
     /*
         {
             "result": [
                 {
                     "client_type": 1,
                     "status": "online",
                     "uin": 3017767504
                 }
             ],
             "retcode": 0
         }
     */
     var json = response.ResponseString.ToJToken();
     if (json["retcode"].ToString() == "0")
     {
         var result = json["result"].ToObject<FriendOnlineInfo[]>();
         foreach (var info in result)
         {
             Store.FriendDic.GetAndDo(info.Uin, friend => Mapper.Map(info, friend));
         }
         return NotifyActionEventAsync(ActionEventType.EvtOK);
     }
     else
     {
         throw new QQException(QQErrorCode.ResponseError, response.ResponseString);
     }
 }
예제 #2
0
 private static void ReadHeader(HttpResponseMessage response, HttpResponseItem responseItem)
 {
     foreach (var header in response.Headers)
     {
         responseItem.Headers[header.Key] = header.Value.ToList();
     }
 }
예제 #3
0
        public override Task<ActionEvent> HandleResponse(HttpResponseItem responseItem)
        {
            /*
                {
                    "BaseResponse": {
                        "Ret": 0,
                        "ErrMsg": ""
                    },
                    "MsgID": "5895072760632094896"
                }
            */
            var str = responseItem.ResponseString;
            if (!str.IsNullOrEmpty())
            {
                var json = JObject.Parse(str);
                if (json["BaseResponse"]["Ret"].ToString() == "0")
                {
                    return NotifyActionEventAsync(ActionEventType.EvtOK);
                }
                else
                {
                    throw new WeChatException(WeChatErrorCode.ResponseError, json["BaseResponse"]["ErrMsg"].ToString());
                }

            }
            throw WeChatException.CreateException(WeChatErrorCode.ResponseError);
        }
 public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
 {
     /*
         {
             "retcode": 0,
             "result": {
                 "dnamelist": [
                     {
                         "name": "月光双刀、Test、月光借口、月光双",
                         "did": 522140442
                     }
                 ]
             }
         }
      */
     var json = response.ResponseString.ToJToken();
     if (json["retcode"].ToString() == "0")
     {
         var result = json["result"];
         var list = result["dnamelist"].ToObject<List<QQDiscussion>>();
         list.ForEach(Store.AddDiscussion);
         return NotifyActionEventAsync(ActionEventType.EvtOK);
     }
     else
     {
         throw new QQException(QQErrorCode.ResponseError, response.ResponseString);
     }
 }
예제 #5
0
        public override Task<ActionEvent> HandleResponse(HttpResponseItem responseItem)
        {
            var str = responseItem.ResponseString;
            var match = _regCode.Match(str);
            if (match.Success)
            {
                var code = match.Groups[1].Value;
                var result = EnumHelper.ParseFromStrNum<WatiForLoginResult>(code);
                switch (result)
                {
                    case WatiForLoginResult.Success:
                        {
                            var m = _regUrl.Match(str);
                            if (m.Success)
                            {
                                Session.LoginUrl = $"{m.Groups[1].Value}&fun=new&version=v2";
                                Session.BaseUrl = Session.LoginUrl.Substring(0, Session.LoginUrl.LastIndexOf("/", StringComparison.OrdinalIgnoreCase));
                            }
                            break;
                        }

                    case WatiForLoginResult.ScanCode:
                        _tip = 0;
                        break;

                    case WatiForLoginResult.QRCodeInvalid:
                        break;
                }
                return NotifyActionEventAsync(ActionEventType.EvtOK, result);
            }
            throw WeChatException.CreateException(WeChatErrorCode.ResponseError);
        }
예제 #6
0
 public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
 {
     var json = response.ResponseString.ToJToken();
     var retcode = json["retcode"].ToInt();
     switch (retcode)
     {
         case 0: return HandlePollMsg(json["result"]);
     }
     throw new QQException(QQErrorCode.ResponseError, response.ResponseString);
 }
예제 #7
0
 public override Task<ActionEvent> HandleResponse(HttpResponseItem responseItem)
 {
     var str = responseItem.ResponseString;
     var match = _reg.Match(str);
     if (match.Success && match.Groups.Count > 2 && match.Groups[1].Value == "200")
     {
         Session.Uuid = match.Groups[2].Value;
         return NotifyActionEventAsync(ActionEventType.EvtOK);
     }
     return NotifyErrorEventAsync(WeChatErrorCode.ResponseError);
 }
예제 #8
0
 public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
 {
     var json = response.ResponseString.ToJToken();
     if (json["BaseResponse"]["Ret"].ToString() == "0")
     {
         return NotifyActionEventAsync(ActionEventType.EvtOK);
     }
     else
     {
         throw new WeChatException(WeChatErrorCode.ResponseError, response.ResponseString);
     }
 }
예제 #9
0
 public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
 {
     var json = response.ResponseString.ToJToken();
     if (json["retcode"].ToString() == "0")
     {
         HandleResult(json);
         return NotifyActionEventAsync(ActionEventType.EvtOK);
     }
     else
     {
         throw new QQException(QQErrorCode.ResponseError, response.ResponseString);
     }
 }
예제 #10
0
 public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
 {
     /*
         {
             retcode: 0,
             result: {
                 birthday: {
                     month: 11,
                     year: 1990,
                     day: 14
                 },
                 face: 252,
                 phone: "83544376",
                 occupation: "计算机/互联网/IT",
                 allow: 1,
                 college: "北京师大附中",
                 uin: 89009143,
                 blood: 2,
                 constel: 12,
                 lnick: "努力去香港",
                 vfwebqq: "7454728c49b49db8eba34dad1df1704bffab25ce52f037516fed029e05a681473d01af3d85172a96",
                 homepage: "http://tieba.baidu.com/f?kw=%C0%EE%BE%AD",
                 vip_info: 7,
                 city: "西城",
                 country: "中国",
                 personal: "",
                 shengxiao: 7,
                 nick: "月光双刀",
                 email: "*****@*****.**",
                 province: "北京",
                 account: 89009143,
                 gender: "male",
                 mobile: "152********"
             }
         }
      */
     var json = response.ResponseString.ToJToken();
     if (json["retcode"].ToString() == "0")
     {
         var info = json["result"].ToObject<SelfInfo>();
         info.MapTo(Session.User);
         return NotifyActionEventAsync(ActionEventType.EvtOK);
     }
     else
     {
         throw new QQException(QQErrorCode.ResponseError, response.ResponseString);
     }
 }
예제 #11
0
 public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
 {
     var str = response.ResponseString;
     var m = _reg.Match(str);
     if (m.Success)
     {
         var ret = m.Groups[1].Value;
         switch (ret)
         {
             case "0": return NotifyActionEventAsync(ActionEventType.EvtOK, new CheckQRCodeArgs(QRCodeStatus.OK, m.Groups[3].Value));
             case "66": return NotifyActionEventAsync(ActionEventType.EvtOK, new CheckQRCodeArgs(QRCodeStatus.Valid, m.Groups[5].Value));
             case "67": return NotifyActionEventAsync(ActionEventType.EvtOK, new CheckQRCodeArgs(QRCodeStatus.Auth, m.Groups[5].Value));
             case "65": return NotifyActionEventAsync(ActionEventType.EvtOK, new CheckQRCodeArgs(QRCodeStatus.Invalid, m.Groups[5].Value));
         }
     }
     return NotifyErrorEventAsync(QQErrorCode.ResponseError);
 }
예제 #12
0
 public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
 {
     var str = response.ResponseString;
     var json = JObject.Parse(str);
     if (json["BaseResponse"]["Ret"].ToString() == "0")
     {
         Session.SyncKey = json["SyncCheckKey"];
         var list = json["AddMsgList"].ToObject<List<Message>>();
         var newMsgs = list.Where(m => m.MsgType != MessageType.GetContact).ToList();
         newMsgs.ForEach(m =>
         {
             m.FromUser = Store.ContactMemberDic.GetOrDefault(m.FromUserName);
         });
         return NotifyActionEventAsync(ActionEventType.EvtOK, newMsgs);
     }
     throw WeChatException.CreateException(WeChatErrorCode.ResponseError);
 }
예제 #13
0
        private static async Task ReadContentAsync(HttpResponseMessage response, HttpResponseItem responseItem)
        {
            switch (responseItem.RequestItem.ResultType)
            {
                case HttpResultType.String:
                    responseItem.ResponseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                    break;

                case HttpResultType.Byte:
                    responseItem.ResponseBytes = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
                    break;

                case HttpResultType.Stream:
                    responseItem.ResponseStream = new MemoryStream(await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false));
                    break;
            }
            foreach (var header in response.Content.Headers)
            {
                responseItem.Headers[header.Key] = header.Value.ToList();
            }
        }
예제 #14
0
        public override Task<ActionEvent> HandleResponse(HttpResponseItem responseItem)
        {
            var str = responseItem.ResponseString;
            if (!str.IsNullOrEmpty())
            {
                var json = JObject.Parse(str);
                if (json["BaseResponse"]["Ret"].ToString() == "0")
                {
                    var list = json["ContactList"].ToObject<List<ContactMember>>();
                    foreach (var item in list)
                    {
                        Store.ContactMemberDic[item.UserName] = item;
                    }
                    return NotifyActionEventAsync(ActionEventType.EvtOK);
                }
                else
                {
                    throw new WeChatException(WeChatErrorCode.ResponseError, json["BaseResponse"]["ErrMsg"].ToString());
                }

            }
            throw WeChatException.CreateException(WeChatErrorCode.ResponseError);
        }
예제 #15
0
        public override Task<ActionEvent> HandleResponse(HttpResponseItem responseItem)
        {
            /*
                <error>
                  <ret>0</ret>
                  <message/>
                  <skey>@crypt_c498484a_beffad67aa727e24f7c669c51d5c895f</skey>
                  <wxsid>Lr2AUrW1+FSCmtHZ</wxsid>
                  <wxuin>463678295</wxuin>
                  <pass_ticket>SSR%2BWEx6yJf8MTN2G2XjsWtRpXWQ0J6wBHc5BeHGL3gATmsW%2FMiFX0GBqWrmm7dN</pass_ticket>
                  <isgrayscale>1</isgrayscale>
                </error>
            */
            var str = responseItem.ResponseString;
            var root = XDocument.Parse(str).Root;
            Session.Skey = root.Element("skey").Value;
            Session.Sid = root.Element("wxsid").Value;
            Session.Uin = root.Element("wxuin").Value;
            Session.PassTicket = root.Element("pass_ticket").Value;

            Session.State = SessionState.Online;

            return NotifyActionEventAsync(ActionEventType.EvtOK);
        }
예제 #16
0
        public override Task<ActionEvent> HandleResponse(HttpResponseItem responseItem)
        {
            /*
                {
                    "BaseResponse": {
                        "Ret": 0,
                        "ErrMsg": ""
                    },
                    "Count": 11,
                    "ContactList": [...],
                    "SyncKey": {
                        "Count": 4,
                        "List": [
                            {
                                "Key": 1,
                                "Val": 635705559
                            },
                            ...
                        ]
                    },
                    "User": {
                        "Uin": xxx,
                        "UserName": xxx,
                        "NickName": xxx,
                        "HeadImgUrl": xxx,
                        "RemarkName": "",
                        "PYInitial": "",
                        "PYQuanPin": "",
                        "RemarkPYInitial": "",
                        "RemarkPYQuanPin": "",
                        "HideInputBarFlag": 0,
                        "StarFriend": 0,
                        "Sex": 1,
                        "Signature": "Apt-get install B",
                        "AppAccountFlag": 0,
                        "VerifyFlag": 0,
                        "ContactFlag": 0,
                        "WebWxPluginSwitch": 0,
                        "HeadImgFlag": 1,
                        "SnsFlag": 17
                    },
                    "ChatSet": xxx,
                    "SKey": xxx,
                    "ClientVersion": 369297683,
                    "SystemTime": 1453124908,
                    "GrayScale": 1,
                    "InviteStartCount": 40,
                    "MPSubscribeMsgCount": 2,
                    "MPSubscribeMsgList": [...],
                    "ClickReportInterval": 600000
                }
             */
            /*
                本次ContactList里只有10个好友or群组,应该是最近的10个活跃对象(个数不是固定的);
                另外,可以通过UserName来区分好友or群组,一个”@”为好友,两个”@”为群组。
                MPSubscribeMsg为公众号推送的阅读文章
                User其实就是自己账号信息(用在顶部的头像)
             */
            var str = responseItem.ResponseString;
            if (!str.IsNullOrEmpty())
            {
                var json = JObject.Parse(str);
                if (json["BaseResponse"]["Ret"].ToString() == "0")
                {
                    Session.SyncKey = json["SyncKey"];
                    // Session.SyncKeyStr = Session.SyncKey["List"].ToArray().Select(m => $"{m["Key"]}_{m["Val"]}").JoinWith("|");
                    Session.UserToken = json["User"];
                    return NotifyActionEventAsync(ActionEventType.EvtOK);
                }
                else
                {
                    throw new WeChatException(WeChatErrorCode.ResponseError, json["BaseResponse"]["ErrMsg"].ToString());
                }

            }
            throw WeChatException.CreateException(WeChatErrorCode.ResponseError);
        }
예제 #17
0
        public override Task<ActionEvent> HandleResponse(HttpResponseItem responseItem)
        {
            /*
                {
                    "BaseResponse": {
                        "Ret": 0,
                        "ErrMsg": ""
                    },
                    "MemberCount": 334,
                    "MemberList": [
                        {
                            "Uin": 0,
                            "UserName": xxx,
                            "NickName": "Urinx",
                            "HeadImgUrl": xxx,
                            "ContactFlag": 3,
                            "MemberCount": 0,
                            "MemberList": [],
                            "RemarkName": "",
                            "HideInputBarFlag": 0,
                            "Sex": 0,
                            "Signature": "我是二蛋",
                            "VerifyFlag": 8,
                            "OwnerUin": 0,
                            "PYInitial": "URINX",
                            "PYQuanPin": "Urinx",
                            "RemarkPYInitial": "",
                            "RemarkPYQuanPin": "",
                            "StarFriend": 0,
                            "AppAccountFlag": 0,
                            "Statues": 0,
                            "AttrStatus": 0,
                            "Province": "",
                            "City": "",
                            "Alias": "Urinxs",
                            "SnsFlag": 0,
                            "UniFriend": 0,
                            "DisplayName": "",
                            "ChatRoomId": 0,
                            "KeyWord": "gh_",
                            "EncryChatRoomId": ""
                        },
                        ...
                    ],
                    "Seq": 0
                }
            */
            var json = responseItem.ResponseString.ToJToken();
            if (json["BaseResponse"]["Ret"].ToString() == "0")
            {
                Store.MemberCount = json["MemberCount"].ToObject<int>();
                var list = json["MemberList"].ToObject<ContactMember[]>();
                Store.ContactMemberDic.ReplaceBy(list, m => m.UserName);

                var selfName = Session.UserToken["UserName"].ToString();
                Session.User = Store.ContactMemberDic[selfName];
                Store.ContactMemberDic.Remove(selfName);

                Logger.LogInformation($"应有{Store.MemberCount}个联系人,读取到联系人{Store.ContactMemberDic.Count}个");
                Logger.LogInformation($"共有{Store.GroupCount}个群|{Store.FriendCount}个好友|{Store.SpecialUserCount}个特殊账号|{Store.PublicUserCount}公众号或服务号");
                return NotifyActionEventAsync(ActionEventType.EvtOK);
            }
            else
            {
                throw new WeChatException(WeChatErrorCode.ResponseError, responseItem.ResponseString);
            }
        }
예제 #18
0
        public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
        {
            /*
                {
                    "retcode": 0,
                    "result": {
                        "stats": [
                            {
                                "client_type": 1,
                                "uin": 2146674552,
                                "stat": 50
                            }
                        ],
                        "minfo": [
                            {
                                "nick": "昵称",
                                "province": "北京",
                                "gender": "male",
                                "uin": 3623536468,
                                "country": "中国",
                                "city": ""
                            }
                        ],
                        "ginfo": {
                            "face": 0,
                            "memo": "群公告!",
                            "class": 25,
                            "fingermemo": "",
                            "code": 591539174,
                            "createtime": 1231435199,
                            "flag": 721421329,
                            "level": 4,
                            "name": "群名称",
                            "gid": 2419762790,
                            "owner": 3509557797,
                            "members": [
                                {
                                    "muin": 3623536468,
                                    "mflag": 192
                                }
                            ],
                            "option": 2
                        },
                        "cards": [
                            {
                                "muin": 3623536468,
                                "card": "群名片"
                            }
                        ],
                        "vipinfo": [
                            {
                                "vip_level": 6,
                                "u": 2390929289,
                                "is_vip": 1
                            }
                        ]
                    }
                }
            */
            var json = response.ResponseString.ToJToken();
            if (json["retcode"].ToString() == "0")
            {
                var result = json["result"];
                var groupInfo = result["ginfo"].ToObject<GroupInfo>();
                var members = result["ginfo"]["members"].ToObject<GroupMember[]>().Distinct(m => m.Uin).ToDictionary(m => m.Uin, m => m);

                // 成员信息
                result["minfo"].ToObject<GroupMemberInfo[]>().ForEach(m =>
                {
                    members.GetAndDo(m.Uin, member => Mapper.Map(m, member));
                });

                // 成员状态
                result["stats"]?.ToObject<UserStatus[]>().ForEach(m =>
                {
                    members.GetAndDo(m.Uin, member => Mapper.Map(m, member));
                });

                // 成员名片
                result["cards"]?.ToObject<GroupMemberCard[]>().ForEach(card =>
                {
                    members.GetAndDo(card.Uin, member => Mapper.Map(card, member));
                });

                // vip信息
                result["vipinfo"]?.ToObject<UserVipInfo[]>().ForEach(m =>
                {
                    members.GetAndDo(m.Uin, member => Mapper.Map(m, member));
                });

                groupInfo.MapTo(_group);
                _group.Members.ReplaceBy(members);

                return NotifyActionEventAsync(ActionEventType.EvtOK);
            }
            else
            {
                throw new QQException(QQErrorCode.ResponseError, response.ResponseString);
            }
        }
예제 #19
0
        public virtual async Task<HttpResponseItem> ExecuteHttpRequestAsync(HttpRequestItem requestItem, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            var responseItem = new HttpResponseItem { RequestItem = requestItem };
            var httpRequest = GetHttpRequest(requestItem);
            using (var response = await _httpClient.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false))
            {
                response.EnsureSuccessStatusCode();
                responseItem.StatusCode = response.StatusCode;
                ReadHeader(response, responseItem);
                await ReadContentAsync(response, responseItem).ConfigureAwait(false);
                return responseItem;
            }
        }
예제 #20
0
 public abstract Task<ActionEvent> HandleResponse(HttpResponseItem response);
예제 #21
0
        public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
        {
            /*
                {
                    retcode: 0,
                    result: {
                        gmasklist: [
                            {
                                gid: 1000,
                                mask: "3"
                            }
                        ],
                        gnamelist: [
                            {
                                flag: 17957889,
                                name: " 獨①無Ⅱ",
                                gid: 809647823,
                                code: 3675041622
                            },
                        ],
                        gmarklist: [
                            {
                                uin: 2944307192,
                                markname: "郑问"
                            }
                        ]
                    }
                }
             */
            var json = response.ResponseString.ToJToken();
            if (json["retcode"].ToString() == "0")
            {
                var result = json["result"];

                var groups = result["gnamelist"].ToObject<List<QQGroup>>();
                groups.ForEach(Store.AddGroup);

                // 用不上
                //var gMaskList = result["gmasklist"].ToJArray();
                //foreach (var gMask in gMaskList)
                //{
                //    var gid = gMask["gid"].ToLong();
                //    var group = Store.GetGroupByGid(gid);
                //    if (group.IsNotNull())
                //        group.Mask = gMask["mask"].ToInt();
                //}

                // 群备注
                var gMarkList = result["gmarklist"].ToJArray();
                foreach (var gMark in gMarkList)
                {
                    var gid = gMark["uin"].ToLong();
                    Store.GroupDic.GetAndDo(gid, group => group.MarkName = gMark["markname"].ToString());
                }

                return NotifyActionEventAsync(ActionEventType.EvtOK);
            }
            else
            {
                throw new QQException(QQErrorCode.ResponseError, response.ResponseString);
            }
        }
        public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
        {
            var str = response.ResponseString;
            var json = str.ToJToken();
            var code = json["code"].ToString();
            var reply = "";

            switch (code)
            {
                // 文本类
                case "100000":
                    reply = json["text"].ToString();
                    break;

                // 链接类,包括列车、航班
                case "200000":
                    {
                        var text = json["text"].ToString();
                        var url = json["url"].ToString();
                        reply = $"{text} \n网址:{url}";
                        break;
                    }

                // 新闻类
                case "302000":
                    {
                        var text = json["text"].ToString();
                        var list = json["list"].ToObject<JArray>();
                        var sb = new StringBuilder(text);
                        foreach (var item in list)
                        {
                            var article = item["article"].ToString();
                            var source = item["source"].ToString();
                            var icon = item["icon"].ToString();
                            var detailurl = item["detailurl"].ToString();
                            sb.AppendLine(article);
                        }
                        reply = sb.ToString();
                        break;
                    }

                // 菜谱类
                case "308000":
                    {
                        var text = json["text"].ToString();
                        var list = json["list"].ToObject<JArray>();
                        var sb = new StringBuilder(text);
                        foreach (var item in list)
                        {
                            var name = item["name"].ToString();
                            var icon = item["icon"].ToString();
                            var info = item["info"].ToString();
                            var detailurl = item["detailurl"].ToString();
                            sb.AppendLine($"{name}:info");
                        }
                        reply = sb.ToString();
                        break;
                    }

                // 异常码
                case "40001": return NotifyErrorEventAsync(WeChatException.CreateException(WeChatErrorCode.ResponseError, $"[参数key错误]:{str}"));
                case "40002": return NotifyErrorEventAsync(WeChatException.CreateException(WeChatErrorCode.ResponseError, $"[请求内容info为空]:{str}"));
                case "40004": return NotifyErrorEventAsync(WeChatException.CreateException(WeChatErrorCode.ResponseError, $"[当天请求次数已使用完]:{str}"));
                case "40007": return NotifyErrorEventAsync(WeChatException.CreateException(WeChatErrorCode.ResponseError, $"[数据格式异常]:{str}"));

                default:
                    reply = json["text"].ToString();
                    break;
            }
            return NotifyOkActionEventAsync(reply);
        }
예제 #23
0
 public override Task<ActionEvent> HandleResponse(HttpResponseItem responseItem)
 {
     return NotifyActionEventAsync(ActionEventType.EvtOK, Image.FromStream(responseItem.ResponseStream));
 }
예제 #24
0
        public override Task<ActionEvent> HandleResponse(HttpResponseItem response)
        {
            /*
                {
                    retcode: 0,
                    result: {
                        friends: [
                            {
                                flag: 4,
                                uin: 3246906007,
                                categories: 1
                            },
                        ],
                        marknames: [
                            {
                                uin: 3246906007,
                                markname: "xxxxxxx",
                                type: 0
                            },
                        ],
                        categories: [
                            {
                                index: 0,
                                sort: 1,
                                name: "我的好友"
                            },
                        ],
                        vipinfo: [
                            {
                                vip_level: 0,
                                u: 4091731542,
                                is_vip: 0
                            },
                        ],
                        info: [
                            {
                                face: 0,
                                flag: 29884998,
                                nick: "!空*^白^%",
                                uin: 3246906007
                            },
                        ]
                    }
                }
             */
            var json = response.ResponseString.ToJToken();
            if (json["retcode"].ToString() == "0")
            {
                var result = json["result"];

                var categories = result["categories"].ToObject<List<Category>>();
                categories.ForEach(Store.AddCategory);

                var friends = result["friends"].ToObject<List<QQFriend>>();
                friends.ForEach(Store.AddFriend);

                // 好友信息 face/flag/nick/uin
                var infos = result["info"].ToObject<FriendBaseInfo[]>();
                foreach (var info in infos)
                {
                    Store.FriendDic.GetAndDo(info.Uin, m => Mapper.Map(info, m));
                }

                // 好友备注 uin/markname/type
                var marknames = result["marknames"].ToObject<FriendMarkName[]>();
                foreach (var markname in marknames)
                {
                    Store.FriendDic.GetAndDo(markname.Uin, m => Mapper.Map(markname, m));
                }

                // vip信息
                var mVipInfo = result["vipinfo"].ToObject<UserVipInfo[]>();
                foreach (var vip in mVipInfo)
                {
                    Store.FriendDic.GetAndDo(vip.Uin, m => Mapper.Map(vip, m));
                }

                return NotifyActionEventAsync(ActionEventType.EvtOK);
            }
            else
            {
                throw new QQException(QQErrorCode.ResponseError, response.ResponseString);
            }
        }