/// <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)); }
/// <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")); }
/// <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") }); }
/// <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; })); }
/// <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; } } }
/// <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")); }
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; } }
/// <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); }
/// <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 }); }
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; } }
/// <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); }
/// <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); }
/// <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); }
/// <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())); }
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)); }
/// <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())); }
/// <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")); }
/// <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))); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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")); }
/// <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 }); }
/// <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()); }
/// <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")); }
/// <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()); }
/// <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 }); }
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)); }
/// <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)); }