/// <summary>
        /// 群发消息预览,微信支持多种预览账号,但每次只能一个,所以OpenIdSendParam.touser参数只第一个值有效并转成微信需要的参数键名
        /// </summary>
        /// <param name="previewAccount">touser字段都可以改为towxname,这样就可以针对微信号进行预览(而非openID),towxname和touser同时赋值时,以towxname优先</param>
        /// <param name="openIdSendParam">与实际群发参数一致</param>
        /// <returns>群发消息预览发送结果</returns>
        public WeChatResult <GroupSendResult> PreviewSendAll(PreviewAccount previewAccount, OpenIdSendParam openIdSendParam)
        {
            string accessToken = connect.GetAccessToken();
            string url         = $"https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token={accessToken}";

            if (openIdSendParam.touser == null || openIdSendParam.touser.Count == 0)
            {
                throw new ArgumentException("OpenIdSendParam.touser必须指定最少一个预览账号");
            }
            string  previewWx  = openIdSendParam.touser[0];
            string  originJson = JsonConvert.SerializeObject(openIdSendParam);
            JObject jobject    = JObject.Parse(originJson);

            jobject.Remove("touser");
            if (previewAccount == PreviewAccount.OpenId)
            {
                jobject.Add($"\"touser\":\"{previewWx}\"");
            }
            else
            {
                jobject.Add($"\"towxname\":\"{previewWx}\"");
            }
            string resultStr = SimulateRequest.HttpPost(url, jobject.ToString());
            WeChatResult <GroupSendResult> weChatResult = JsonConvert.DeserializeObject <WeChatResult <GroupSendResult> >(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"群发消息预览PreviewSendAll,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
示例#2
0
        /// <summary>
        /// 推送订阅模板消息给到授权微信用户
        /// </summary>
        /// <param name="subscribeMsg">订阅模板消息</param>
        /// <returns>订阅模板消息推送结果</returns>
        public WeChatResult SendSubscribe(OnceSubscribeMsg subscribeMsg)
        {
            string       accessToken  = connect.GetAccessToken();
            string       url          = $"https://api.weixin.qq.com/cgi-bin/message/template/subscribe?access_token={accessToken}";
            string       resultData   = SimulateRequest.HttpPost(url, subscribeMsg);
            WeChatResult weChatResult = new WeChatResult(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"推送订阅模板消息给到授权微信用户SendSubscribe,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 发送模板消息
        /// </summary>
        /// <param name="templateMessage">发送模板消息的参数</param>
        /// <returns>发送模板消息获得的消息ID</returns>
        public WeChatResult <Msg_ID> SendTemplate(TemplateMessageParam templateMessage)
        {
            string accessToken = connect.GetAccessToken();
            string url         = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
            string resultData  = SimulateRequest.HttpPost(url, templateMessage);
            WeChatResult <Msg_ID> weChatResult = new WeChatResult <Msg_ID>(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"发送模板消息SendTemplate,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
示例#4
0
        /// <summary>
        /// 新增永久图文素材
        /// </summary>
        /// <param name="articleNews">图文消息素材</param>
        /// <returns>图文素材MediaId</returns>
        public WeChatResult <Media_Msg> AddNews(ArticleNews articleNews)
        {
            string accessToken = connect.GetAccessToken();
            string url         = $"https://api.weixin.qq.com/cgi-bin/material/add_news?access_token={accessToken}";
            string resultStr   = SimulateRequest.HttpPost(url, articleNews);
            WeChatResult <Media_Msg> weChatResult = new WeChatResult <Media_Msg>(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(MethodBase.GetCurrentMethod(), $"新增永久图文素材AddNews,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 根据标签进行群发
        /// </summary>
        /// <param name="tagSendParam">标签群发参数</param>
        /// <returns>标签进行群发结果</returns>
        public WeChatResult <GroupSendResult> SendAll(TagSendParam tagSendParam)
        {
            string accessToken = connect.GetAccessToken();
            string url         = $"https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={accessToken}";
            string resultData  = SimulateRequest.HttpPost(url, tagSendParam);
            WeChatResult <GroupSendResult> weChatResult = new WeChatResult <GroupSendResult>(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"根据标签进行群发SendAll,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 上传图文消息素材
        /// </summary>
        /// <param name="articleNews">图文消息素材</param>
        /// <returns>上传图文消息素材结果</returns>
        public WeChatResult <UploadNewsResult> UpdateNews(ArticleNews articleNews)
        {
            string accessToken = connect.GetAccessToken();
            string url         = $"https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token={accessToken}";
            string resultStr   = SimulateRequest.HttpPost(url, articleNews);
            WeChatResult <UploadNewsResult> weChatResult = new WeChatResult <UploadNewsResult>(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"上传图文消息素材UpdateNews,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 设置群发速度
        /// </summary>
        /// <param name="msgId">群发消息后返回的消息id</param>
        /// <returns>发送状态查询结果</returns>
        public WeChatResult SetSendSpeed(int speed)
        {
            string       accessToken  = connect.GetAccessToken();
            string       url          = $"https://api.weixin.qq.com/cgi-bin/message/mass/speed/set?access_token={accessToken}";
            string       resultData   = SimulateRequest.HttpPost(url, new { speed });
            WeChatResult weChatResult = new WeChatResult(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"设置群发速度SetSendSpeed,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 查询群发消息发送状态
        /// </summary>
        /// <param name="msgId">群发消息后返回的消息id</param>
        /// <returns>发送状态查询结果</returns>
        public WeChatResult <GroupSendStatusResult> GetSendStatus(int msgId)
        {
            string accessToken = connect.GetAccessToken();
            string url         = $"https://api.weixin.qq.com/cgi-bin/message/mass/get?access_token={accessToken}";
            string resultData  = SimulateRequest.HttpPost(url, new { msg_id = msgId });
            WeChatResult <GroupSendStatusResult> weChatResult = new WeChatResult <GroupSendStatusResult>(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"查询群发消息发送状态GetSendStatus,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
示例#9
0
        /// <summary>
        /// 删除永久素材
        /// </summary>
        /// <param name="mediaId">要删除的永久素材Id</param>
        /// <returns>微信服务返回的删除结果</returns>
        public WeChatResult DelMaterial(string mediaId)
        {
            string       accessToken  = connect.GetAccessToken();
            string       url          = "https://api.weixin.qq.com/cgi-bin/material/del_material?access_token=" + accessToken;
            string       resultStr    = SimulateRequest.HttpPost(url, new { media_id = mediaId });
            WeChatResult weChatResult = new WeChatResult(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(MethodBase.GetCurrentMethod(), $"删除永久素材DelMaterial,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 发送客服输入状态
        /// <para>下发输入状态,需要客服之前30秒内跟用户有过消息交互</para>
        /// <para>在输入状态中(持续15s),不可重复下发输入态</para>
        /// <para>在输入状态中,如果向用户下发消息,会同时取消输入状态</para>
        /// </summary>
        /// <param name="serviceMsg">需发送的客服消息,可指定客服账号</param>
        /// <returns>发送客服消息的微信结果</returns>
        public WeChatResult SendTyping(string openId, WxMsgCommand msgCommand)
        {
            string       accessToken  = connect.GetAccessToken();
            string       url          = "https://api.weixin.qq.com/cgi-bin/message/custom/typing?access_token=" + accessToken;
            string       resultStr    = SimulateRequest.HttpPost(url, new { touser = openId, command = msgCommand.ToString() });
            WeChatResult weChatResult = new WeChatResult(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"获取所有客服账号SearchKFList,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 根据OpenID列表群发
        /// </summary>
        /// <param name="tagSendParam">OpenID列表群发参数</param>
        /// <returns>OpenID列表群发结果</returns>
        public WeChatResult <GroupSendResult> SendAll(OpenIdSendParam openIdSendParam)
        {
            string accessToken = connect.GetAccessToken();
            string url         = $"https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={accessToken}";
            string resultData  = SimulateRequest.HttpPost(url, openIdSendParam);
            WeChatResult <GroupSendResult> weChatResult = new WeChatResult <GroupSendResult>(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(MethodBase.GetCurrentMethod(), $"根据OpenID列表群发SendAll,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 测试个性化菜单匹配结果
        /// </summary>
        /// <param name="userId">user_id可以是粉丝的OpenID,也可以是粉丝的微信号</param>
        /// <returns>微信服务返回的匹配菜单</returns>
        public WeChatResult <OrdinaryMenu> TryMatchMenu(string userId)
        {
            string accessToken = connect.GetAccessToken();
            string url         = "https://api.weixin.qq.com/cgi-bin/menu/trymatch?access_token=" + accessToken;
            var    matchParam  = new { user_id = userId };
            string resultStr   = SimulateRequest.HttpPost(url, matchParam, "application/json");
            WeChatResult <OrdinaryMenu> matchMenuResult = new WeChatResult <OrdinaryMenu>(resultStr);

            if (matchMenuResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"测试个性化菜单匹配结果TryMatchMenu(),微信服务报错:{matchMenuResult}");
            }
            return(matchMenuResult);
        }
        /// <summary>
        /// 删除指定的个性化菜单
        /// </summary>
        /// <param name="menuId">个性化菜单的Id</param>
        /// <returns>微信服务返回的删除结果</returns>
        public WeChatResult DeleteMenu(string menuId)
        {
            string       accessToken  = connect.GetAccessToken();
            string       url          = "https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token=" + accessToken;
            var          delMenu      = new { menuid = menuId };
            string       resultStr    = SimulateRequest.HttpPost(url, delMenu, "application/json");
            WeChatResult deleteResult = new WeChatResult(resultStr);

            if (deleteResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"删除指定的个性化菜单DeleteMenu(),微信服务报错:{deleteResult}");
            }
            return(deleteResult);
        }
        /// <summary>
        /// 发送客服消息给指定微信用户,可指定客服账号
        /// </summary>
        /// <param name="serviceMsg">需发送的客服消息,可指定客服账号</param>
        /// <returns>发送客服消息的微信结果</returns>
        public WeChatResult SendMsg(CustomerServiceMsg serviceMsg)
        {
            string       accessToken  = connect.GetAccessToken();
            string       url          = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + accessToken;
            string       postData     = JsonConvert.SerializeObject(serviceMsg);
            string       resultStr    = SimulateRequest.HttpPost(url, postData);
            WeChatResult weChatResult = new WeChatResult(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"获取所有客服账号SearchKFList,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 设置所属行业,每月可修改行业1次
        /// </summary>
        /// <param name="industry1">公众号模板消息所属行业编号</param>
        /// <param name="industry2">公众号模板消息所属行业编号</param>
        /// <returns></returns>
        public WeChatResult SetIndustry(WeChatIndustry industry1, WeChatIndustry industry2)
        {
            string       accessToken  = connect.GetAccessToken();
            string       url          = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=" + accessToken;//POST
            string       postData     = JsonConvert.SerializeObject(new { industry_id1 = industry1, industry_id2 = industry2 });
            string       resultStr    = SimulateRequest.HttpPost(url, postData);
            WeChatResult weChatResult = new WeChatResult(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"设置所属行业SetIndustry,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 给公众号添加消息模板,获得模板ID
        /// </summary>
        /// <param name="templateShortId">模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式</param>
        /// <returns>公众号获得的模板ID</returns>
        public WeChatResult <TemplateID> AddTemplate(string templateShortId)
        {
            string accessToken = connect.GetAccessToken();
            string url         = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=" + accessToken;
            string resultData  = SimulateRequest.HttpPost(url, new
            {
                template_id_short = templateShortId
            });
            WeChatResult <TemplateID> weChatResult = new WeChatResult <TemplateID>(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"获取设置的行业信息GetIndustry,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 删除公众号指定的模板
        /// </summary>
        /// <param name="templateId">公众帐号下模板消息ID</param>
        /// <returns>删除模板结果</returns>
        public WeChatResult DeleteTemplate(string templateId)
        {
            string accessToken = connect.GetAccessToken();
            string url         = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=" + accessToken;
            string resultData  = SimulateRequest.HttpPost(url, new
            {
                template_id = templateId
            });
            WeChatResult weChatResult = new WeChatResult(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"删除公众号指定的模板DeleteTemplate,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 对公众号的所有api调用次数进行清零,每个有接口调用限额的接口都进行清零操作
        /// </summary>
        /// <returns>清零结果</returns>
        public WeChatResult ApiClearQuota()
        {
            //每月共10次清零操作机会,清零生效一次即用掉一次机会(10次包括了平台上的清零和调用接口API的清零)
            string url         = "https://api.weixin.qq.com/cgi-bin/clear_quota?access_token={0}";
            string accessToken = this.GetAccessToken();

            url = String.Format(url, accessToken);
            string       resultData   = SimulateRequest.HttpPost(url, new { appid = WeChatConfig.AppID });
            WeChatResult weChatResult = new WeChatResult(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(MethodBase.GetCurrentMethod(), $"获取微信服务器IP地址GetWeChatServerIP(),微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
示例#19
0
        /// <summary>
        /// 修改永久图文素材
        /// </summary>
        /// <param name="mediaId">要修改的永久图文素材Id</param>
        /// <param name="index">要更新的文章在图文消息中的位置(多图文消息时,此字段才有意义),第一篇为0</param>
        /// <returns>微信服务返回的修改结果</returns>
        public WeChatResult UpdateNews(string mediaId, int index, ArticleMaterial articleMaterial)
        {
            string accessToken = connect.GetAccessToken();
            string url         = "https://api.weixin.qq.com/cgi-bin/material/update_news?access_token=" + accessToken;
            string resultStr   = SimulateRequest.HttpPost(url, new
            {
                media_id = mediaId,
                index,
                articles = articleMaterial
            });
            WeChatResult weChatResult = new WeChatResult(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(MethodBase.GetCurrentMethod(), $"修改永久图文素材UpdateNews,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 删除群发消息
        /// </summary>
        /// <param name="msgId">发送出去的消息ID</param>
        /// <param name="articleIndex">要删除的文章在图文消息中的位置,第一篇编号为1,该字段不填或填0会删除全部文章</param>
        /// <returns>删除结果</returns>
        public WeChatResult DeleteSendInfo(int msgId, int articleIndex = 0)
        {
            string accessToken = connect.GetAccessToken();
            string url         = $"https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token={accessToken}";
            string resultData  = SimulateRequest.HttpPost(url,
                                                          new
            {
                msg_id      = msgId,
                article_idx = articleIndex
            });
            WeChatResult weChatResult = new WeChatResult(resultData);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"上传图文消息素材UpdateNews,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 创建自定义菜单
        /// </summary>
        /// <param name="menuButton">菜单按钮数组</param>
        /// <returns>微信服务返回的创建结果</returns>
        public WeChatResult CreateMenu(List <MenuButton> menuButtonList)
        {
            if (menuButtonList == null)
            {
                return(null);
            }
            string       accessToken  = connect.GetAccessToken();
            string       url          = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + accessToken;//POST
            string       menuBtnData  = JsonConvert.SerializeObject(new { button = menuButtonList });
            string       resultStr    = SimulateRequest.HttpPost(url, menuBtnData);
            WeChatResult weChatResult = new WeChatResult(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"创建自定义菜单CreateMenu,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 修改客服帐号
        /// </summary>
        /// <param name="account">账号,如:[email protected]</param>
        /// <param name="nickName">昵称,如:客服1</param>
        /// <param name="password">客服登录密码,内部会转成md5</param>
        /// <returns>修改的微信结果</returns>
        public WeChatResult UpdateAccount(string account, string nickName, string password)
        {
            string accessToken = connect.GetAccessToken();
            string url         = "https://api.weixin.qq.com/customservice/kfaccount/update?access_token=" + accessToken;//POST
            string postData    = JsonConvert.SerializeObject(
                new
            {
                kf_account = account,
                nickname   = nickName,
                password   = EncryptHelper.HashMD532(password)
            });
            string       resultStr    = SimulateRequest.HttpPost(url, postData);
            WeChatResult weChatResult = new WeChatResult(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"修改客服帐号UpdateAccount,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
示例#23
0
        /// <summary>
        /// 获取素材列表
        /// </summary>
        /// <param name="type">素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)</param>
        /// <param name="offset">从全部素材的该偏移位置开始返回,0表示从第一个素材 返回</param>
        /// <param name="count">返回素材的数量,取值在1到20之间</param>
        /// <returns>微信服务返回的素材列表结果</returns>
        public WeChatResult <MaterialListInfo> GetMaterialList(string type, int offset, int count)
        {
            string accessToken = connect.GetAccessToken();
            string url         = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=" + accessToken;
            string resultStr   = SimulateRequest.HttpPost(url, new { type, offset, count });
            WeChatResult <MaterialListInfo> weChatResult = new WeChatResult <MaterialListInfo>(resultStr);

            weChatResult.resultData.item.Clear();
            JObject wechatResultObj = JsonConvert.DeserializeObject <JObject>(resultStr);

            if ("news".Equals(type)) //图文消息素材
            {
                weChatResult.resultData.item.AddRange(JsonConvert.DeserializeObject <List <NewsMaterialItem> >(wechatResultObj["item"].ToString()));
            }
            else //其他多媒体素材
            {
                weChatResult.resultData.item.AddRange(JsonConvert.DeserializeObject <List <MediaMaterialItem> >(wechatResultObj["item"].ToString()));
            }
            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(MethodBase.GetCurrentMethod(), $"获取素材列表GetMaterialList,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }
        /// <summary>
        /// 创建个性化菜单按钮,menuButton公众号的所有个性化菜单,最多只能设置为跳转到3个域名下的链接;matchrule共六个字段,均可为空,但至少要有一个匹配信息是不为空的
        /// </summary>
        /// <param name="menuButton">菜单按钮数组,其中链接跳转不能多于3个</param>
        /// <param name="matchRule">matchrule共六个字段,均可为空,但不能全部为空,至少要有一个匹配信息是不为空的</param>
        /// <returns>微信服务返回的创建结果</returns>
        public WeChatResult <MenuCreateInfo> CreatePersonalMenu(List <MenuButton> menuButtonList, MatchRule matchRule)
        {
            if (menuButtonList == null)
            {
                return(null);
            }
            if (matchRule == null)
            {
                matchRule = new MatchRule()
                {
                    country  = "中国",
                    province = "广东",
                    language = "zh_CN"
                }
            }
            ;
            string menuBtnData = JsonConvert.SerializeObject(new { button = menuButtonList, matchrule = "{0}" });
            //开始生成菜单按钮的个性化匹配规则
            //country、province、city组成地区信息,将按照country、province、city的顺序进行验证,要符合地区信息表的内容。
            //地区信息从大到小验证
            StringBuilder ruleBuilder = new StringBuilder();

            ruleBuilder.Append("{");
            if (!string.IsNullOrEmpty(matchRule.tag_id))
            {
                ruleBuilder.Append($"\"tag_id\":\"{matchRule.tag_id}\",");
            }
            if (matchRule.sex.HasValue)
            {
                ruleBuilder.Append($"\"sex\":\"{matchRule.sex}\",");
            }
            if (!string.IsNullOrEmpty(matchRule.country))
            {
                ruleBuilder.Append($"\"country\":\"{matchRule.country}\",");
            }
            if (!string.IsNullOrEmpty(matchRule.province))
            {
                ruleBuilder.Append($"\"province\":\"{matchRule.province}\",");
            }
            if (!string.IsNullOrEmpty(matchRule.city))
            {
                ruleBuilder.Append($"\"city\":\"{matchRule.city}\",");
            }
            if (matchRule.client_platform_type.HasValue)
            {
                ruleBuilder.Append($"\"client_platform_type\":\"{matchRule.client_platform_type}\",");
            }
            if (!string.IsNullOrEmpty(matchRule.language))
            {
                ruleBuilder.Append($"\"language\":\"{matchRule.language}\",");
            }
            if (ruleBuilder.ToString().EndsWith(","))
            {
                ruleBuilder.Remove(ruleBuilder.Length - 1, 1);
            }
            ruleBuilder.Append("}");
            string[] menuBtnSplitAry = menuBtnData.Split("\"{0}\"");//把"{0}"替换成matchRule对象
            menuBtnData = string.Join(ruleBuilder.ToString(), menuBtnSplitAry);
            string accessToken = connect.GetAccessToken();
            string url         = "https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=" + accessToken;//POST
            string resultStr   = SimulateRequest.HttpPost(url, menuBtnData);
            WeChatResult <MenuCreateInfo> weChatResult = new WeChatResult <MenuCreateInfo>(resultStr);

            if (weChatResult.errcode != WeChatErrorCode.SUCCESS)
            {
                SystemLogHelper.Warn(GetType().FullName, $"创建个性化菜单CreatePersonalMenu,微信服务报错:{weChatResult}");
            }
            return(weChatResult);
        }