예제 #1
0
        /// <summary>
        /// 获取用户身上的标签列表
        /// </summary>
        /// <param name="openId">粉丝OpenId</param>
        /// <returns>标签列表集合</returns>
        public List <int> GetIdList(string openId)
        {
            string         url    = $" https://api.weixin.qq.com/cgi-bin/tags/getidlist?access_token={_accountModel.GetAccessToken()}";
            GetIdListModel result = WeiXinHttpHelper.PostResultByJson <GetIdListModel>(url, new { openid = openId });

            return(result?.TagIds ?? new List <int>(0));
        }
예제 #2
0
        /// <summary>
        /// 获取选项值。
        /// </summary>
        /// <param name="optionName">选项名称。</param>
        /// <param name="authorizerAppId">授权者AppId。</param>
        /// <returns>选项值。</returns>
        /// <remarks>
        /// location_report(地理位置上报选项)(0	无上报 1	进入会话时上报2	每5s上报)
        /// voice_recognize(语音识别开关选项)(0	关闭语音识别 1	开启语音识别)
        /// customer_service(客服开关选项)(0	关闭多客服1	开启多客服)
        /// </remarks>
        public string GetOptionValue(string optionName, string authorizerAppId)
        {
            Func <string, string> get = accessToken => WeiXinHttpHelper.PostString(
                "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option?component_access_token=" +
                accessToken, new
            {
                component_appid  = _accountModel.AppId,
                authorizer_appid = authorizerAppId,
                option_name      = optionName
            });
            string content;

            try
            {
                content = get(GetAccessToken().AccessToken);
            }
            catch (WeiXinException exception)
            {
                if (exception.ErrorCode == 40001 ||
                    exception.Message == "invalid credential, access_token is invalid or not latest")
                {
                    content = get(GetAccessToken(true).AccessToken);
                }
                else
                {
                    throw;
                }
            }

            return(JObject.Parse(content).Value <string>("option_value"));
        }
예제 #3
0
        /// <summary>
        /// 查询code。
        /// </summary>
        /// <param name="code">单张卡券的唯一标识。</param>
        /// <param name="cardId">卡券ID代表一类卡券。</param>
        /// <remarks>调用查询code接口可获取code的有效性(非自定义code),该code对应的用户openid、卡券有效期等信息。 自定义code(use_custom_code为true)的卡券调用接口时,post数据中需包含card_id,非自定义code不需上报。</remarks>
        /// <returns>查询结果。</returns>
        public SearchCodeResult SearchCode(string code, string cardId = null)
        {
            var url = "https://api.weixin.qq.com/card/code/get?access_token=" + _accountModel.GetAccessToken();

            object postData;

            if (string.IsNullOrWhiteSpace(cardId))
            {
                postData = new { code };
            }
            else
            {
                postData = new { code, card_id = cardId };
            }
            var content = WeiXinHttpHelper.PostString(url, postData);
            var obj     = JObject.Parse(content);

            var card = obj["card"];

            return(new SearchCodeResult
            {
                BeginTime = DateTimeHelper.GetTimeByTimeStamp(card.Value <long>("begin_time")),
                CardId = card.Value <string>("card_id"),
                EndTime = DateTimeHelper.GetTimeByTimeStamp(card.Value <long>("end_time")),
                OpenId = obj.Value <string>("openid")
            });
        }
예제 #4
0
        /// <summary>
        /// 获取公众号的全局唯一票据。
        /// </summary>
        /// <param name="ignoreCached">是否忽略缓存。</param>
        /// <returns>第三方用户唯一凭证密钥,即appsecret。</returns>
        public AccessTokenModel GetAccessToken(bool ignoreCached = false)
        {
            const string grantType = "client_credential";

            var appId     = _accountModel.AppId;
            var appSecret = _accountModel.AppSecret;

            Func <AccessTokenModel> get = () =>
            {
                var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type={0}&appid={1}&secret={2}", grantType, appId, appSecret);
                return(WeiXinHttpHelper.GetResultByJson <AccessTokenModel>(url));
            };

            return(Dictionary.AddOrUpdate(appId, key => get(), (k, m) =>
            {
                //忽略缓存则负担和最新的数据。
                if (ignoreCached)
                {
                    return get();
                }

                //没有过期则直接返回。
                if (!m.IsExpired())
                {
                    return m;
                }

                var newModel = get();
                return newModel.AccessToken == m.AccessToken ? m : newModel;
            }));
        }
예제 #5
0
        /// <summary>
        /// 设置选项值。
        /// </summary>
        /// <param name="optionName">选项名称。</param>
        /// <param name="optionValue">选项值。</param>
        /// <param name="authorizerAppId">授权者AppId。</param>
        /// <remarks>
        /// location_report(地理位置上报选项)(0	无上报 1	进入会话时上报2	每5s上报)
        /// voice_recognize(语音识别开关选项)(0	关闭语音识别 1	开启语音识别)
        /// customer_service(客服开关选项)(0	关闭多客服1	开启多客服)
        /// </remarks>
        public void SetOptionValue(string optionName, string optionValue, string authorizerAppId)
        {
            Action <string> set = accessToken =>
            {
                WeiXinHttpHelper.PostString(
                    "https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option?component_access_token=" +
                    accessToken, new
                {
                    component_appid  = _accountModel.AppId,
                    authorizer_appid = authorizerAppId,
                    option_name      = optionName,
                    option_value     = optionValue
                });
            };

            try
            {
                set(GetAccessToken().AccessToken);
            }
            catch (WeiXinException exception)
            {
                if (exception.ErrorCode == 40001 ||
                    exception.Message == "invalid credential, access_token is invalid or not latest")
                {
                    set(GetAccessToken(true).AccessToken);
                }
                else
                {
                    throw;
                }
            }
        }
예제 #6
0
        /// <summary>
        /// 获取发送模板的Id。
        /// </summary>
        /// <param name="templateShortId">模板短Id。</param>
        /// <returns>发送模板的Id。</returns>
        public string GetTemplateId(string templateShortId)
        {
            var postUrl = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=" + _accountModel.GetAccessToken();
            var content = WeiXinHttpHelper.PostString(postUrl, new { template_id_short = templateShortId });

            return(JObject.Parse(content).Value <string>("template_id"));
        }
예제 #7
0
        private PublicAccountAuthorizerInfo InternalGetPublicAccountAuthorizerInfo(string authorizationCode)
        {
            var get = new Func <string, PublicAccountAuthorizerInfo>(accessToken =>
            {
                var content = WeiXinHttpHelper.PostString(
                    "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=" +
                    accessToken,
                    new
                {
                    component_appid    = _accountModel.AppId,
                    authorization_code = authorizationCode
                });
                var obj = JObject.Parse(content)["authorization_info"];

                var model    = JsonConvert.DeserializeObject <PublicAccountAuthorizerInfo>(obj.ToString());
                model.Rights = GetRights(obj);

                return(model);
            });

            try
            {
                return(get(GetAccessToken().AccessToken));
            }
            catch (WeiXinException exception)
            {
                if (exception.ErrorCode == 40001 ||
                    exception.Message == "invalid credential, access_token is invalid or not latest")
                {
                    return(get(GetAccessToken(true).AccessToken));
                }
                throw;
            }
        }
예제 #8
0
        /// <summary>
        /// 获取授权码。
        /// </summary>
        /// <param name="ignoreCached">是否忽略缓存。</param>
        /// <returns>授权码结果。</returns>
        public AuthorizeCodeResult GetAuthorizeCode(bool ignoreCached = false)
        {
            Func <string, AuthorizeCodeResult> get = accessToken => WeiXinHttpHelper.PostResultByJson <AuthorizeCodeResult>(
                "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=" +
                accessToken, new { component_appid = _accountModel.AppId });

            if (_authorizeCodeResult == null || _authorizeCodeResult.IsExpired() || ignoreCached)
            {
                AuthorizeCodeResult newModel;
                try
                {
                    newModel = get(GetAccessToken().AccessToken);
                }
                catch (WeiXinException exception)
                {
                    if (exception.ErrorCode == 40001 ||
                        exception.Message == "invalid credential, access_token is invalid or not latest")
                    {
                        newModel = get(GetAccessToken(true).AccessToken);
                    }
                    else
                    {
                        throw;
                    }
                }
                if (_authorizeCodeResult != null && _authorizeCodeResult.AuthCode == newModel.AuthCode)
                {
                    return(_authorizeCodeResult);
                }
                return(_authorizeCodeResult = newModel);
            }
            return(_authorizeCodeResult);
        }
예제 #9
0
        /// <summary>
        /// 根据菜单Id删除自定义菜单。
        /// </summary>
        /// <param name="menuId">菜单Id。</param>
        public void DeleteByMenuId(int menuId)
        {
            var url = "https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token=" +
                      _accountModel.GetAccessToken();

            WeiXinHttpHelper.PostString(url, new { menuid = menuId });
        }
예제 #10
0
        private RefreshAccessToken InternalRefreshToken(string authorizerAppId, string authorizerRefreshToken)
        {
            Func <string, RefreshAccessToken> get = accessToken => WeiXinHttpHelper.PostResultByJson <RefreshAccessToken>(
                "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=" +
                accessToken,
                new
            {
                component_appid          = _accountModel.AppId,
                authorizer_appid         = authorizerAppId,
                authorizer_refresh_token = authorizerRefreshToken
            });

            try
            {
                return(get(GetAccessToken().AccessToken));
            }
            catch (WeiXinException exception)
            {
                if (exception.ErrorCode == 40001 ||
                    exception.Message == "invalid credential, access_token is invalid or not latest")
                {
                    return(get(GetAccessToken(true).AccessToken));
                }
                throw;
            }
        }
예제 #11
0
        /// <summary>
        /// 获取所有标签
        /// </summary>
        /// <returns>标签集合</returns>
        public List <TagInfo> Get()
        {
            string url    = $"https://api.weixin.qq.com/cgi-bin/tags/get?access_token={_accountModel.GetAccessToken()}";
            var    result = WeiXinHttpHelper.GetResultByJson <TagWarp>(url);

            return(result.Tags);
        }
예제 #12
0
        /// <summary>
        /// 获取第三方平台的全局唯一票据。
        /// </summary>
        /// <param name="ignoreCached">是否忽略缓存。</param>
        /// <returns>第三方用户唯一凭证密钥,即appsecret。</returns>
        public AccessTokenModel GetAccessToken(bool ignoreCached = false)
        {
            Func <AccessTokenModel> get = () => WeiXinHttpHelper.PostResultByJson <AccessTokenModel>(
                "https://api.weixin.qq.com/cgi-bin/component/api_component_token",
                new
            {
                component_appid         = _accountModel.AppId,
                component_appsecret     = _accountModel.AppSecret,
                component_verify_ticket = _accountModel.GetVerifyTicket()
            });

            //是否需要重新获取(无效、忽略缓存、过期)
            Func <bool> needGet = () => _accessTokenModel == null || ignoreCached || _accessTokenModel.IsExpired();

            if (needGet())
            {
                lock (this)
                {
                    if (needGet())
                    {
                        /*                        var newModel = get();
                         *                      if (_accessTokenModel != null && _accessTokenModel.AccessToken == newModel.AccessToken)
                         *                          return _accessTokenModel;
                         *                      return _accessTokenModel = newModel;*/
                        return(_accessTokenModel = get());
                    }
                }
            }

            return(_accessTokenModel);
        }
예제 #13
0
        /// <summary>
        /// 创建标签
        /// </summary>
        /// <param name="name">标签名(30个字符以内)</param>
        /// <returns>返回标签编号</returns>
        public TagInfo Create(string name)
        {
            string url    = $"https://api.weixin.qq.com/cgi-bin/tags/create?access_token={_accountModel.GetAccessToken()}";
            var    result = WeiXinHttpHelper.PostResultByJson <TagWarp>(url, new { tag = new { name } });

            return(result.Tag);
        }
예제 #14
0
        /// <summary>
        /// 批量获取用户信息。
        /// </summary>
        /// <param name="filters">筛选信息。</param>
        /// <returns>用户信息集合。</returns>
        public UserInfo[] GetUserInfoList(params GetUserListFilterItem[] filters)
        {
            var url     = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=" + _accountModel.GetAccessToken();
            var content = WeiXinHttpHelper.PostString(url, new { user_list = filters });

            return(JsonConvert.DeserializeObject <UserInfo[]>(JObject.Parse(content)["user_info_list"].ToString()));
        }
예제 #15
0
        private GroupSendResult SendMessage(GroupMessage message, Action <JObject> action)
        {
            var url = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=" + _accountModel.GetAccessToken();

            string msgtype;

            switch (message.Type)
            {
            case GroupMessageType.News:
                msgtype = "mpnews";
                break;

            case GroupMessageType.Card:
                msgtype = "wxcard";
                break;

            case GroupMessageType.Image:
                msgtype = "image";
                break;

            case GroupMessageType.Music:
                msgtype = "music";
                break;

            case GroupMessageType.Text:
                msgtype = "text";
                break;

            case GroupMessageType.Video:
                msgtype = "mpvideo";
                var videoMessage   = (GroupMessageVideo)message;
                var uploadVideoUrl = "https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token=" + _accountModel.GetAccessToken();
                var result         = WeiXinHttpHelper.PostString(uploadVideoUrl, new
                {
                    media_id    = videoMessage.MediaId,
                    title       = videoMessage.Title,
                    description = videoMessage.Description
                });
                videoMessage.MediaId = JObject.Parse(result)["media_id"].Value <string>();
                break;

            case GroupMessageType.Voice:
                msgtype = "voice";
                break;

            default:
                throw new NotSupportedException("不支持的消息类型:" + message.Type);
            }

            var postObj = new JObject();

            action(postObj);
            postObj["msgtype"] = msgtype;
            postObj[msgtype]   = JObject.Parse(JsonConvert.SerializeObject(message));

            var content = WeiXinHttpHelper.PostString(url, Encoding.UTF8.GetBytes(postObj.ToString()));

            return(JsonConvert.DeserializeObject <GroupSendResult>(content));
        }
예제 #16
0
        /// <summary>
        /// 获取卡券可用颜色。
        /// </summary>
        /// <returns>可用颜色数组。</returns>
        public CardColorItem[] GetCardColors()
        {
            var url = "https://api.weixin.qq.com/card/getcolors?access_token=" + _accountModel.GetAccessToken();

            var json = WeiXinHttpHelper.GetString(url);

            return(JsonConvert.DeserializeObject <CardColorItem[]>(JObject.Parse(json)["colors"].ToString()));
        }
예제 #17
0
        /// <summary>
        /// 解码Code。
        /// </summary>
        /// <param name="encryptCode">编码的Code值。</param>
        /// <returns>解码的Code值。</returns>
        public string DecryptCode(string encryptCode)
        {
            var url = "https://api.weixin.qq.com/card/code/decrypt?access_token=" + _accountModel.GetAccessToken();

            var content = WeiXinHttpHelper.PostString(url, new { encrypt_code = encryptCode });

            return(JObject.Parse(content).Value <string>("code"));
        }
예제 #18
0
        /// <summary>
        /// 创建分组。
        /// </summary>

        /// <param name="name">分组名称(30字以内)</param>
        /// <returns>创建分组结果模型。</returns>
        public CreateGroupResultModel Create(string name)
        {
            var url = "https://api.weixin.qq.com/cgi-bin/groups/create?access_token=" + _accountModel.GetAccessToken();

            var content = WeiXinHttpHelper.PostString(url, new { group = new { name } });

            return(CreateGroupResultModel.Create(JObject.Parse(content)));
        }
예제 #19
0
        /// <summary>
        /// 获取自定义菜单信息。
        /// </summary>
        /// <returns>自定义菜单信息。</returns>
        public CustomMenuModel Get()
        {
            var url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=" + _accountModel.GetAccessToken();

            var content = WeiXinHttpHelper.GetString(url);

            return(GetByJson(content));
        }
예제 #20
0
        /// <summary>
        /// 获取指定用户的自定义菜单信息。
        /// </summary>
        /// <param name="openIdOrWeChatAccount">用户的Id或是微信账号。</param>
        /// <returns>自定义菜单数组。</returns>
        public CustomMenuButtonBase[] GetList(string openIdOrWeChatAccount)
        {
            var url = "https://api.weixin.qq.com/cgi-bin/menu/trymatch?access_token=" + _accountModel.GetAccessToken();

            var content = WeiXinHttpHelper.PostString(url, new { user_id = openIdOrWeChatAccount });

            return(GetListByJson(content));
        }
예제 #21
0
        /// <summary>
        /// 获取菜单Json原始数据
        /// </summary>
        /// <returns></returns>
        public JToken GetMenuJsonData()
        {
            var url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=" + _accountModel.GetAccessToken();

            var content = WeiXinHttpHelper.GetString(url);

            return(JToken.Parse(content));
        }
예제 #22
0
        /// <summary>
        /// 根据OpenId获取分组Id。
        /// </summary>

        /// <param name="openId">用户唯一标识符。</param>
        /// <returns>分组Id。</returns>
        public ulong GetGroupByOpenId(string openId)
        {
            var url = "https://api.weixin.qq.com/cgi-bin/groups/getid?access_token=" + _accountModel.GetAccessToken();

            var data    = WeiXinHttpHelper.Post(url, new { openid = openId });
            var content = Encoding.UTF8.GetString(data);

            return(JObject.Parse(content).Value <ulong>("groupid"));
        }
예제 #23
0
        /// <summary>
        /// 删除门店。
        /// </summary>
        /// <param name="storeId">门店Id。</param>
        /// <remarks>删除已经成功创建的门店。请商户慎重调用该接口,门店信息被删除后,可能会影响其他与门店相关的业务使用,如卡券等。同样,该门店信息也不会在微信的商户详情页显示,不会再推荐入附近功能。</remarks>
        public void Delete(ulong storeId)
        {
            var url = "http://api.weixin.qq.com/cgi-bin/poi/delpoi?access_token=" + _accountModel.GetAccessToken();

            WeiXinHttpHelper.Post(url, new
            {
                poi_id = storeId
            });
        }
예제 #24
0
        /// <summary>
        /// 获取服务器Ip地址列表。
        /// </summary>
        /// <returns>服务器Ip地址列表。</returns>
        public string[] GetServerIpList()
        {
            var url = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=" + _accountModel.GetAccessToken();

            var json  = WeiXinHttpHelper.GetString(url);
            var array = (JArray)JObject.Parse(json)["ip_list"];

            return(array.Select(i => i.Value <string>()).ToArray());
        }
예제 #25
0
        /// <summary>
        /// 添加多图文素材。
        /// </summary>
        /// <param name="articles">文章模型。</param>
        /// <returns>图文素材Id。</returns>
        public string AddNews(NewsArticleModel[] articles)
        {
            var url = "https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=" + _accountModel.GetAccessToken();

            var data    = WeiXinHttpHelper.Post(url, new { articles });
            var content = Encoding.UTF8.GetString(data);

            ResultHelper.TryThrowError(content);
            return(JObject.Parse(content).Value <string>("media_id"));
        }
예제 #26
0
        /// <summary>
        /// 获取自定义菜单信息。
        /// </summary>
        /// <returns>自定义菜单数组。</returns>
        public CustomMenuButtonBase[] GetList()
        {
            var url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=" + _accountModel.GetAccessToken();

            var content = WeiXinHttpHelper.GetString(url);

            var buttons = (JArray)JObject.Parse(content)["menu"]["button"];

            return(buttons.Select(token => GetMenuItemByWeiXin((JObject)token)).ToArray());
        }
예제 #27
0
        /// <summary>
        /// 设置自定义菜单。
        /// </summary>
        /// <param name="menus">自定义菜单数组。</param>
        /// <exception cref="ArgumentNullException"><paramref name="menus"/> 为null。</exception>
        /// <exception cref="ArgumentException"><paramref name="menus"/> 长度超过3。</exception>
        public void Set(CustomMenuButtonBase[] menus)
        {
            if (menus.NotNull("menus").Length > 3)
            {
                throw new ArgumentException("顶级菜单项不能超过3个。", "menus");
            }

            var url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + _accountModel.GetAccessToken();

            WeiXinHttpHelper.Post(url, new { button = menus.Select(GetMenuItem) });
        }
        /// <summary>
        /// 创建会话。
        /// </summary>
        /// <param name="openId">客户openid</param>
        /// <param name="account">完整客服账号,格式为:账号前缀@公众号微信号</param>
        /// <param name="text">附加信息,文本会展示在客服人员的多客服客户端</param>
        /// <remarks>开发者可以使用本接口,为多客服的客服工号创建会话,将某个客户直接指定给客服工号接待,需要注意此接口不会受客服自动接入数以及自动接入开关限制。只能为在线的客服(PC客户端在线,或者已绑定多客服助手)创建会话。</remarks>
        public void Create(string openId, string account, string text = null)
        {
            var url = "https://api.weixin.qq.com/customservice/kfsession/create?access_token=" + _accountModel.GetAccessToken();

            WeiXinHttpHelper.Post(url, new
            {
                kf_account = account,
                openid     = openId,
                text
            });
        }
예제 #29
0
        private AccessTokenModel InternalGetAccessToken()
        {
            const string grantType = "client_credential";

            var appId     = _accountModel.AppId;
            var appSecret = _accountModel.AppSecret;

            var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type={0}&appid={1}&secret={2}", grantType, appId, appSecret);

            return(WeiXinHttpHelper.GetResultByJson <AccessTokenModel>(url));
        }
예제 #30
0
        /// <summary>
        /// 获取用户信息。
        /// </summary>
        /// <param name="openId">普通用户的标识,对当前公众号唯一</param>
        /// <param name="language">返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语</param>
        /// <returns>用户信息。</returns>
        public UserInfo GetUser(string openId, string language = null)
        {
            var url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}",
                                    _accountModel.GetAccessToken(), openId);

            if (!string.IsNullOrWhiteSpace(language))
            {
                url = url + "&lang=" + language;
            }

            return(WeiXinHttpHelper.GetResultByJson <UserInfo>(url));
        }