지난 달에는 C#으로 WeChat 포털 및 애플리케이션 개발을 소개하고 공유할 여러 에세이를 작성했습니다. 시간 제약으로 인해 한동안 이 블로그 시리즈를 계속 작성하지 못했습니다. 이에 대한 연구를 중단했습니다. 하지만 이 분야의 기술을 계속해서 심층적으로 탐구하여 이를 더 잘 적용하기 위해 기반 기술 개발에 집중했습니다.
WeChat의 매우 중요한 기능은 플랫폼의 거대한 사용자 기반을 활용할 수 있으므로 CRM(고객 관계 관리) 시스템에 쉽게 통합할 수 있으며 구독을 통해 관련성을 높일 수 있다는 것입니다. 제품 소식, 48시간 이내에 메시지와 이벤트에 응답한 활성 사용자와의 대화형 대화 따라서 사용자 정보는 WeChat API에서 매우 중요한 부분입니다. , 그룹 관리 등 애플리케이션을 개발합니다.
위챗 관리 플랫폼에서는 아래와 같이 우리 계정의 팔로어 사용자와 사용자 그룹 정보를 확인할 수 있습니다.
위의 관리 인터페이스에서는 팔로어 사용자의 기본 정보를 볼 수 있지만 WeChat API를 사용하여 얻는 것은 OpenID라는 목록입니다. 무슨 일이야? WeChat API에 대한 설명은 다음과 같습니다.
팔로어 목록은 OpenID(암호화된 WeChat ID)의 문자열로 구성됩니다. 각 공식 계정에 대한 각 사용자의 OpenID는 고유합니다. 사용자의 openid가 다릅니다). 공식 계정은 이 인터페이스를 사용하여 OpenID를 기반으로 닉네임, 아바타, 성별, 도시, 언어 및 팔로우 시간을 포함한 기본 사용자 정보를 얻을 수 있습니다.
위 분석의 의미는 매우 분명합니다. 즉, 사용자가 당사 공식 계정을 팔로우하면 아무리 많이 팔로우하더라도 이는 당사 공식 계정에 대한 특정 가치입니다. 다른 공개 계정의 경우 OpenID가 다릅니다.
WeChat은 사용자 관련 콘텐츠를 기록하기 위해 몇 가지 키워드 정보를 제공하며, 사용자의 관련 정의를 기반으로 검색된 사용자 정보를 배치하는 엔터티 클래스를 정의합니다.
/// <summary> /// 高级接口获取的用户信息。 /// 在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID /// (加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。 /// 公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。 /// </summary> public class UserJson : BaseJsonResult { /// <summary> /// 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 /// </summary> public int subscribe { get; set; } /// <summary> /// 用户的标识,对当前公众号唯一 /// </summary> public string openid { get; set; } /// <summary> /// 用户的昵称 /// </summary> public string nickname { get; set; } /// <summary> /// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 /// </summary> public int sex { get; set; } /// <summary> /// 用户的语言,简体中文为zh_CN /// </summary> public string language { get; set; } /// <summary> /// 用户所在城市 /// </summary> public string city { get; set; } /// <summary> /// 用户所在省份 /// </summary> public string province { get; set; } /// <summary> /// 用户所在国家 /// </summary> public string country { get; set; } /// <summary> /// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 /// </summary> public string headimgurl { get; set; } /// <summary> /// 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间 /// </summary> public long subscribe_time { get; set; } }
그룹화 정보 정의에 따라 그룹화된 엔터티 클래스 정보를 정의합니다.
/// <summary> /// 分组信息 /// </summary> public class GroupJson : BaseJsonResult { /// <summary> /// 分组id,由微信分配 /// </summary> public int id { get; set; } /// <summary> /// 分组名字,UTF8编码 /// </summary> public string name { get; set; } }
WeChat API를 개발할 때 AccessToken을 전달해야 하는 경우가 많습니다. 호출자를 구별하고 세션 정보를 기록하는 문자열이므로 모든 API 개발을 배우기 전에 이 접근 제어 매개 변수를 잘 이해해야 합니다.
WeChat의 API 설명에서 이 객체의 정의에 대해 알아볼 수 있습니다.
access_token은 공용 계정의 전역적으로 고유한 티켓입니다. 공용 계정은 각 인터페이스를 호출할 때 access_token을 사용해야 합니다. 일반적인 상황에서는 access_token이 7200초 동안 유효합니다. 반복적으로 획득하면 마지막 access_token이 무효화됩니다. access_token을 얻기 위한 API 호출 횟수는 매우 제한되어 있으므로 개발자는 access_token을 전역적으로 저장하고 업데이트하는 것이 좋습니다. access_token을 자주 새로 고치면 API 호출이 제한되어 비즈니스에 영향을 미칩니다.
위의 정의에 따르면 ID 및 세션 시간과 관련된 매개 변수이며 생성할 수 있는 횟수에는 제한이 있음을 알 수 있으므로 세션이 만료되기 전에 이 매개변수를 최대한 재사용하여 반복 요청을 피하고 서버 압력과 호출 시간을 늘려야 합니다.
관련 Access Token을 생성하고 생성하는 메소드를 정의했는데, 캐싱 기능이 있지만, 이를 캐싱하고 사용하는 방법은 API 호출에 투명합니다. 그것.
/// 获取凭证接口 /// </summary> /// <param name="appid">第三方用户唯一凭证</param> /// <param name="secret">第三方用户唯一凭证密钥,既appsecret</param> string GetAccessToken(string appid, string secret);
캐시는 주로 .NET4에 추가된 클래스 라이브러리인 MemoryCache를 기반으로 하는 아주 좋은 캐시 클래스입니다.
AccessToken을 얻기 위한 나의 작업 구현 코드는 다음과 같습니다.
/// <summary> /// 获取每次操作微信API的Token访问令牌 /// </summary> /// <param name="appid">应用ID</param> /// <param name="secret">开发者凭据</param> /// <returns></returns> public string GetAccessToken(string appid, string secret) { //正常情况下access_token有效期为7200秒,这里使用缓存设置短于这个时间即可 string access_token = MemoryCacheHelper.GetCacheItem<string>("access_token", delegate() { string grant_type = "client_credential"; var url = string.Format("//m.sbmmt.com/{0}&appid={1}&secret={2}", grant_type, appid, secret); HttpHelper helper = new HttpHelper(); string result = helper.GetHtml(url); string regex = "\"access_token\":\"(?<token>.*?)\""; string token = CRegex.GetText(result, regex, "token"); return token; }, new TimeSpan(0, 0, 7000)//7000秒过期 ); return access_token; }
AccessToken은 기본적으로 7200초 후에 만료된다는 것을 알고 있으므로 이 기간 동안 가능한 한 캐시를 사용하여 값을 기록합니다. 이 시간 이후에 이 메서드를 호출하면 자동으로 새 값을 얻게 됩니다.
한 번의 풀 API 호출로 최대 10,000명의 팔로어 OpenID를 가져올 수 있습니다. 여러 번. WeChat의 인터페이스 정의는 다음과 같습니다.
http 요청 방법: GET(https 프로토콜을 사용하세요)
//m.sbmmt.com/
这个接口返回的数据是
{"total":2,"count":2,"data":{"openid":["","OPENID1","OPENID2"]},"next_openid":"NEXT_OPENID"}
根据返回的Json数据定义,我们还需要定义两个实体类,用来存放返回的结果。
/// <summary> /// 获取关注用户列表的Json结果 /// </summary> public class UserListJsonResult : BaseJsonResult { /// <summary> /// 关注该公众账号的总用户数 /// </summary> public int total { get; set; } /// <summary> /// 拉取的OPENID个数,最大值为10000 /// </summary> public int count { get; set; } /// <summary> /// 列表数据,OPENID的列表 /// </summary> public OpenIdListData data { get; set; } /// <summary> /// 拉取列表的后一个用户的OPENID /// </summary> public string next_openid { get; set; } } /// <summary> /// 列表数据,OPENID的列表 /// </summary> public class OpenIdListData { /// <summary> /// OPENID的列表 /// </summary> public List<string> openid { get; set; } }
为了获取相关的用户信息,我定义了一个接口,用来获取用户的信息,接口定义如下所示。
/// <summary> /// 微信用户管理的API接口 /// </summary> public interface IUserApi { /// <summary> /// 获取关注用户列表 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <param name="nextOpenId">第一个拉取的OPENID,不填默认从头开始拉取</param> /// <returns></returns> List<string> GetUserList(string accessToken, string nextOpenId = null); /// <summary> /// 获取用户基本信息 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <param name="openId">普通用户的标识,对当前公众号唯一</param> /// <param name="lang">返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语</param> UserJson GetUserDetail(string accessToken, string openId, Language lang = Language.zh_CN);
然后在实现类里面,我们分别对上面两个接口进行实现,获取用户列表信息如下所示。
/// <summary> /// 获取关注用户列表 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <param name="nextOpenId">第一个拉取的OPENID,不填默认从头开始拉取</param> /// <returns></returns> public List<string> GetUserList(string accessToken, string nextOpenId = null) { List<string> list = new List<string>(); string url = string.Format("//m.sbmmt.com/{0}", accessToken); if (!string.IsNullOrEmpty(nextOpenId)) { url += "&next_openid=" + nextOpenId; } UserListJsonResult result = JsonHelper<UserListJsonResult>.ConvertJson(url); if (result != null && result.data != null) { list.AddRange(result.data.openid); } return list; }
我们看到,转换的逻辑已经放到了JsonHelper里面去了,这个辅助类里面分别对数值进行了获取内容,验证返回值,然后转换正确实体类几个部分的操作。
获取内容,通过辅助类HttpHelper进行,这个在我的公用类库里面,里面的逻辑主要就是通过HttpRequest进行数据的获取操作,不在赘述。
HttpHelper helper = new HttpHelper();string content = helper.GetHtml(url);
由于返回的内容,我们需要判断它是否正确返回所需的结果,如果没有,抛出自定义的相关异常,方便处理,具体如下所示。
/// <summary> /// 检查返回的记录,如果返回没有错误,或者结果提示成功,则不抛出异常 /// </summary> /// <param name="content">返回的结果</param> /// <returns></returns> private static bool VerifyErrorCode(string content) { if (content.Contains("errcode")) { ErrorJsonResult errorResult = JsonConvert.DeserializeObject<ErrorJsonResult>(content); //非成功操作才记录异常,因为有些操作是返回正常的结果({"errcode": 0, "errmsg": "ok"}) if (errorResult != null && errorResult.errcode != ReturnCode.请求成功) { string error = string.Format("微信请求发生错误!错误代码:{0},说明:{1}", (int)errorResult.errcode, errorResult.errmsg); LogTextHelper.Error(errorResult); throw new WeixinException(error);//抛出错误 } } return true; }
然后转换为相应的格式,就是通过Json.NET的类库进行转换。
T result = JsonConvert.DeserializeObject<T>(content); return result;
这样我们就可以在ConvertJson函数实体里面,完整的进行处理和转换了,转换完整的函数代码如下所示。
////// Json字符串操作辅助类 /// public class JsonHelperwhere T : class, new() { /// <summary> /// 检查返回的记录,如果返回没有错误,或者结果提示成功,则不抛出异常 /// </summary> /// <param name="content">返回的结果</param> /// <returns></returns> private static bool VerifyErrorCode(string content) { if (content.Contains("errcode")) { ErrorJsonResult errorResult = JsonConvert.DeserializeObject<ErrorJsonResult>(content); //非成功操作才记录异常,因为有些操作是返回正常的结果({"errcode": 0, "errmsg": "ok"}) if (errorResult != null && errorResult.errcode != ReturnCode.请求成功) { string error = string.Format("微信请求发生错误!错误代码:{0},说明:{1}", (int)errorResult.errcode, errorResult.errmsg); LogTextHelper.Error(errorResult); throw new WeixinException(error);//抛出错误 } } return true; } /// /// 转换Json字符串到具体的对象 /// /// 返回Json数据的链接地址 ///public static T ConvertJson(string url) { HttpHelper helper = new HttpHelper(); string content = helper.GetHtml(url); VerifyErrorCode(content); T result = JsonConvert.DeserializeObject<T>(content); return result; } }
调用这个API的界面层代码如下所示(测试代码)
IUserApi userBLL = new UserApi(); List<string> userList = userBLL.GetUserList(token)
上面的获取列表操作,相对比较简单,而且不用POST任何数据,因此通过Get协议就能获取到所需的数据。
本小节继续介绍获取用户详细信息的操作,这个操作也是通过GET协议就可以完成的。
这个API的调用定义如下所示:
http请求方式: GET https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
通过传入一个OpenId,我们就能很好获取到用户的相关信息了。
前面小节我们已经定义了它的接口,说明了传入及返回值,根据定义,它的实现函数如下所示。
/// <summary> /// 获取用户基本信息 /// </summary> /// <param name="accessToken">调用接口凭证</param> /// <param name="openId">普通用户的标识,对当前公众号唯一</param> /// <param name="lang">返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语</param> public UserJson GetUserDetail(string accessToken, string openId, Language lang = Language.zh_CN) { string url = string.Format("//m.sbmmt.com/{0}&openid={1}&lang={2}", accessToken, openId, lang.ToString()); UserJson result = JsonHelper<UserJson>.ConvertJson(url); return result; }
最后,我们结合获取用户列表和获取用户详细信息的两个API,我们看看调用的代码(测试代码)。
private void btnGetUsers_Click(object sender, EventArgs e) { IUserApi userBLL = new UserApi(); List<string> userList = userBLL.GetUserList(token); foreach (string openId in userList) { UserJson userInfo = userBLL.GetUserDetail(token, openId); if (userInfo != null) { string tips = string.Format("{0}:{1}", userInfo.nickname, userInfo.openid); Console.WriteLine(tips); } } }
更多C#开发微信门户及应用(4)--关注用户列表及详细信息管理 相关文章请关注PHP中文网!