本节主要是关注者(即用户)和用户组的管理,微信公众号提供了用户和用户组的管理,咱们能够在微信公众号官方里面进行操做,添加备注和标签,以及移动用户组别,同时,微信公众号也提供了相应的接口另咱们本地能够操做.咱们主要是同步到本地,这样咱们能够本身为用户定义更多的信息,以及与本地的业务更好的对接起来.html
看到咱们以前的消息处理类 咱们须要扩展一个事件类,这个类与以前消息处理类是同样的分部类,一样来自Senpars微信的SDK前端
/*---------------------------------------------------------------- Copyright (C) 2016 Senparc 文件名:CustomMessageHandler_Events.cs 文件功能描述:自定义MessageHandler 建立标识:Senparc - 20150312 ----------------------------------------------------------------*/ using System; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using System.Web; using Senparc.Weixin.MP.Agent; using Senparc.Weixin.Context; using Senparc.Weixin.MP.Entities; using Senparc.Weixin.MP.Helpers; using Senparc.Weixin.MP.MessageHandlers; using Senparc.Weixin.MP; using Apps.WC.DAL; using Apps.WC.IDAL; using System.Collections.Generic; using Apps.Models; using Apps.WC.IBLL; using Apps.WC.BLL; using Apps.Models.WC; using Apps.Models.Enum; using Apps.Common; using Senparc.Weixin.MP.AdvancedAPIs; using Senparc.Weixin.MP.AdvancedAPIs.User; namespace Apps.Web.Areas.WC.Core { /// <summary> /// 自定义MessageHandler /// </summary> public partial class CustomMessageHandler { public override IResponseMessageBase OnTextOrEventRequest(RequestMessageText requestMessage) { // 预处理文字或事件类型请求。 // 这个请求是一个比较特殊的请求,一般用于统一处理来自文字或菜单按钮的同一个执行逻辑, // 会在执行OnTextRequest或OnEventRequest以前触发,具备如下一些特征: // 一、若是返回null,则继续执行OnTextRequest或OnEventRequest // 二、若是返回不为null,则终止执行OnTextRequest或OnEventRequest,返回最终ResponseMessage // 三、若是是事件,则会将RequestMessageEvent自动转为RequestMessageText类型,其中RequestMessageText.Content就是RequestMessageEvent.EventKey if (requestMessage.Content == "OneClick") { var strongResponseMessage = CreateResponseMessage<ResponseMessageText>(); strongResponseMessage.Content = "您点击了底部按钮。\r\n为了测试微信软件换行bug的应对措施,这里作了一个——\r\n换行"; return strongResponseMessage; } return null;//返回null,则继续执行OnTextRequest或OnEventRequest } public override IResponseMessageBase OnEvent_ClickRequest(RequestMessageEvent_Click requestMessage) { IResponseMessageBase reponseMessage = null; ////菜单点击,须要跟建立菜单时的Key匹配 //switch (requestMessage.EventKey) //{ // case "OneClick": // { // //这个过程实际已经在OnTextOrEventRequest中完成,这里不会执行到。 // var strongResponseMessage = CreateResponseMessage<ResponseMessageText>(); // reponseMessage = strongResponseMessage; // strongResponseMessage.Content = "您点击了底部按钮。\r\n为了测试微信软件换行bug的应对措施,这里作了一个——\r\n换行"; // } // break; // case "SubClickRoot_Text": // { // var strongResponseMessage = CreateResponseMessage<ResponseMessageText>(); // reponseMessage = strongResponseMessage; // strongResponseMessage.Content = "您点击了子菜单按钮。"; // } // break; // case "SubClickRoot_News": // { // var strongResponseMessage = CreateResponseMessage<ResponseMessageNews>(); // reponseMessage = strongResponseMessage; // strongResponseMessage.Articles.Add(new Article() // { // Title = "您点击了子菜单图文按钮", // Description = "您点击了子菜单图文按钮,这是一条图文信息。", // PicUrl = "http://sdk.weixin.senparc.com/Images/qrcode.jpg", // Url = "http://sdk.weixin.senparc.com" // }); // } // break; // case "SubClickRoot_Music": // { // //上传缩略图 // var accessToken = Senparc.Weixin.MP.Containers.AccessTokenContainer.TryGetAccessToken(appId, appSecret); // var uploadResult = Senparc.Weixin.MP.AdvancedAPIs.MediaApi.UploadTemporaryMedia(accessToken, UploadMediaFileType.thumb, // Server.GetMapPath("~/Images/Logo.jpg")); // //设置音乐信息 // var strongResponseMessage = CreateResponseMessage<ResponseMessageMusic>(); // reponseMessage = strongResponseMessage; // strongResponseMessage.Music.Title = "天籁之音"; // strongResponseMessage.Music.Description = "真的是天籁之音"; // strongResponseMessage.Music.MusicUrl = "http://sdk.weixin.senparc.com/Content/music1.mp3"; // strongResponseMessage.Music.HQMusicUrl = "http://sdk.weixin.senparc.com/Content/music1.mp3"; // strongResponseMessage.Music.ThumbMediaId = uploadResult.thumb_media_id; // } // break; // case "SubClickRoot_Image": // { // //上传图片 // var accessToken = Senparc.Weixin.MP.Containers.AccessTokenContainer.TryGetAccessToken(appId, appSecret); // var uploadResult = Senparc.Weixin.MP.AdvancedAPIs.MediaApi.UploadTemporaryMedia(accessToken, UploadMediaFileType.image, // Server.GetMapPath("~/Images/Logo.jpg")); // //设置图片信息 // var strongResponseMessage = CreateResponseMessage<ResponseMessageImage>(); // reponseMessage = strongResponseMessage; // strongResponseMessage.Image.MediaId = uploadResult.media_id; // } // break; // case "SubClickRoot_Agent"://代理消息 // { // //获取返回的XML // DateTime dt1 = DateTime.Now; // reponseMessage = MessageAgent.RequestResponseMessage(this, agentUrl, agentToken, RequestDocument.ToString()); // //上面的方法也可使用扩展方法:this.RequestResponseMessage(this,agentUrl, agentToken, RequestDocument.ToString()); // DateTime dt2 = DateTime.Now; // if (reponseMessage is ResponseMessageNews) // { // (reponseMessage as ResponseMessageNews) // .Articles[0] // .Description += string.Format("\r\n\r\n代理过程总耗时:{0}毫秒", (dt2 - dt1).Milliseconds); // } // } // break; // case "Member"://托管代理会员信息 // { // //原始方法为:MessageAgent.RequestXml(this,agentUrl, agentToken, RequestDocument.ToString());//获取返回的XML // reponseMessage = this.RequestResponseMessage(agentUrl, agentToken, RequestDocument.ToString()); // } // break; // case "OAuth"://OAuth受权测试 // { // var strongResponseMessage = CreateResponseMessage<ResponseMessageNews>(); // strongResponseMessage.Articles.Add(new Article() // { // Title = "OAuth2.0测试", // Description = "点击【查看全文】进入受权页面。\r\n注意:此页面仅供测试(是专门的一个临时测试帐号的受权,并不是Senparc.Weixin.MP SDK官方帐号,因此若是受权后出现错误页面数正常状况),测试号随时可能过时。请将此DEMO部署到您本身的服务器上,并使用本身的appid和secret。", // Url = "http://sdk.weixin.senparc.com/oauth2", // PicUrl = "http://sdk.weixin.senparc.com/Images/qrcode.jpg" // }); // reponseMessage = strongResponseMessage; // } // break; // case "Description": // { // var strongResponseMessage = CreateResponseMessage<ResponseMessageText>(); // strongResponseMessage.Content = "GetWelcomeInfo"; // reponseMessage = strongResponseMessage; // } // break; // case "SubClickRoot_PicPhotoOrAlbum": // { // var strongResponseMessage = CreateResponseMessage<ResponseMessageText>(); // reponseMessage = strongResponseMessage; // strongResponseMessage.Content = "您点击了【微信拍照】按钮。系统将会弹出拍照或者相册发图。"; // } // break; // case "SubClickRoot_ScancodePush": // { // var strongResponseMessage = CreateResponseMessage<ResponseMessageText>(); // reponseMessage = strongResponseMessage; // strongResponseMessage.Content = "您点击了【微信扫码】按钮。"; // } // break; // case "ConditionalMenu_Male": // { // var strongResponseMessage = CreateResponseMessage<ResponseMessageText>(); // reponseMessage = strongResponseMessage; // strongResponseMessage.Content = "您点击了个性化菜单按钮,您的微信性别设置为:男。"; // } // break; // case "ConditionalMenu_Femle": // { // var strongResponseMessage = CreateResponseMessage<ResponseMessageText>(); // reponseMessage = strongResponseMessage; // strongResponseMessage.Content = "您点击了个性化菜单按钮,您的微信性别设置为:女。"; // } // break; // default: // { // var strongResponseMessage = CreateResponseMessage<ResponseMessageText>(); // strongResponseMessage.Content = "您点击了按钮,EventKey:" + requestMessage.EventKey; // reponseMessage = strongResponseMessage; // } // break; //} return reponseMessage; } public override IResponseMessageBase OnEvent_EnterRequest(RequestMessageEvent_Enter requestMessage) { var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage); responseMessage.Content = "您刚才发送了ENTER事件请求。"; return responseMessage; } public override IResponseMessageBase OnEvent_LocationRequest(RequestMessageEvent_Location requestMessage) { //这里是微信客户端(经过微信服务器)自动发送过来的位置信息 var responseMessage = CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "这里写什么都无所谓,好比:上帝爱你!"; return responseMessage;//这里也能够返回null(须要注意写日志时候null的问题) } public override IResponseMessageBase OnEvent_ScanRequest(RequestMessageEvent_Scan requestMessage) { //经过扫描关注 var responseMessage = CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = responseMessage.Content ?? string.Format("经过扫描二维码进入,场景值:{0}", requestMessage.EventKey); return responseMessage; } public override IResponseMessageBase OnEvent_ViewRequest(RequestMessageEvent_View requestMessage) { //说明:这条消息只做为接收,下面的responseMessage到达不了客户端,相似OnEvent_UnsubscribeRequest var responseMessage = CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "您点击了view按钮,将打开网页:" + requestMessage.EventKey; return responseMessage; } public override IResponseMessageBase OnEvent_MassSendJobFinishRequest(RequestMessageEvent_MassSendJobFinish requestMessage) { var responseMessage = CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "接收到了群发完成的信息。"; return responseMessage; } /// <summary> /// 订阅(关注)事件 /// </summary> /// <returns></returns> public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "欢迎关注"; return responseMessage; } /// <summary> /// 退订 /// 实际上用户没法收到非订阅帐号的消息,因此这里能够随便写。 /// unsubscribe事件的意义在于及时删除网站应用中已经记录的OpenID绑定,消除冗余数据。而且关注用户流失的状况。 /// </summary> /// <returns></returns> public override IResponseMessageBase OnEvent_UnsubscribeRequest(RequestMessageEvent_Unsubscribe requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "有空再来"; return responseMessage; } /// <summary> /// 事件之扫码推事件(scancode_push) /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnEvent_ScancodePushRequest(RequestMessageEvent_Scancode_Push requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "事件之扫码推事件"; return responseMessage; } /// <summary> /// 事件之扫码推事件且弹出“消息接收中”提示框(scancode_waitmsg) /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnEvent_ScancodeWaitmsgRequest(RequestMessageEvent_Scancode_Waitmsg requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "事件之扫码推事件且弹出“消息接收中”提示框"; return responseMessage; } /// <summary> /// 事件之弹出拍照或者相册发图(pic_photo_or_album) /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnEvent_PicPhotoOrAlbumRequest(RequestMessageEvent_Pic_Photo_Or_Album requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "事件之弹出拍照或者相册发图"; return responseMessage; } /// <summary> /// 事件之弹出系统拍照发图(pic_sysphoto) /// 实际测试时发现微信并无推送RequestMessageEvent_Pic_Sysphoto消息,只能接收到用户在微信中发送的图片消息。 /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnEvent_PicSysphotoRequest(RequestMessageEvent_Pic_Sysphoto requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "事件之弹出系统拍照发图"; return responseMessage; } /// <summary> /// 事件之弹出微信相册发图器(pic_weixin) /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnEvent_PicWeixinRequest(RequestMessageEvent_Pic_Weixin requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "事件之弹出微信相册发图器"; return responseMessage; } /// <summary> /// 事件之弹出地理位置选择器(location_select) /// </summary> /// <param name="requestMessage"></param> /// <returns></returns> public override IResponseMessageBase OnEvent_LocationSelectRequest(RequestMessageEvent_Location_Select requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "事件之弹出地理位置选择器"; return responseMessage; } } }
/// <summary> /// 订阅(关注)事件 /// </summary> /// <returns></returns> public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "欢迎关注"; return responseMessage; } /// <summary> /// 退订 /// 实际上用户没法收到非订阅帐号的消息,因此这里能够随便写。 /// unsubscribe事件的意义在于及时删除网站应用中已经记录的OpenID绑定,消除冗余数据。而且关注用户流失的状况。 /// </summary> /// <returns></returns> public override IResponseMessageBase OnEvent_UnsubscribeRequest(RequestMessageEvent_Unsubscribe requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "有空再来"; return responseMessage; }
里面有2个事件,一个用户关注时触发,一个退订时候触发,因此基本咱们无须要进行什么配置,只要加入这个类就能够了数据库
CREATE TABLE [dbo].[WC_Group]( [Id] [varchar](50) NOT NULL, [Name] [varchar](200) NOT NULL, [Count] [int] NOT NULL, [OfficalAccountId] [varchar](50) NOT NULL, CONSTRAINT [PK_WC_Group] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [dbo].[WC_Group] WITH CHECK ADD CONSTRAINT [FK_WC_Group_WC_OfficalAccounts] FOREIGN KEY([OfficalAccountId]) REFERENCES [dbo].[WC_OfficalAccounts] ([Id]) GO ALTER TABLE [dbo].[WC_Group] CHECK CONSTRAINT [FK_WC_Group_WC_OfficalAccounts] GO
CREATE TABLE [dbo].[WC_User]( [Id] [varchar](50) NOT NULL, [OpenId] [varchar](50) NOT NULL, [NickName] [varchar](200) NULL, [Sex] [int] NOT NULL, [Language] [varchar](50) NULL, [City] [varchar](50) NULL, [Province] [varchar](50) NULL, [Country] [varchar](50) NULL, [HeadImgUrl] [varchar](1000) NULL, [SubscribeTime] [datetime] NOT NULL, [UnionId] [varchar](200) NULL, [Remark] [varchar](1000) NULL, [GroupId] [varchar](50) NULL, [TagidList] [varchar](1000) NULL, [Subscribe] [int] NOT NULL, [OfficalAccountId] [varchar](50) NOT NULL, CONSTRAINT [PK_WC_User] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [dbo].[WC_User] WITH NOCHECK ADD CONSTRAINT [FK_WC_User_WC_Group] FOREIGN KEY([GroupId]) REFERENCES [dbo].[WC_Group] ([Id]) GO ALTER TABLE [dbo].[WC_User] NOCHECK CONSTRAINT [FK_WC_User_WC_Group] GO ALTER TABLE [dbo].[WC_User] WITH CHECK ADD CONSTRAINT [FK_WC_User_WC_OfficalAccounts] FOREIGN KEY([OfficalAccountId]) REFERENCES [dbo].[WC_OfficalAccounts] ([Id]) GO ALTER TABLE [dbo].[WC_User] CHECK CONSTRAINT [FK_WC_User_WC_OfficalAccounts] GO
表字段是根据官网,用户管理对应字段而创建,基本与官方提供的用户信息是同样的,无非是存点用户的姓名,籍贯,头像,关注事件等json
这时咱们就能够实现OnEvent_SubscribeRequest (关注时)的代码,基本没有实现难度,步骤以下:后端
/// <summary> /// 订阅(关注)事件 /// </summary> /// <returns></returns> public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage) { ValidationErrors errors = new ValidationErrors(); using (DBContainer db = new DBContainer()) { IWC_OfficalAccountsBLL account_BLL = new WC_OfficalAccountsBLL() { m_Rep = new WC_OfficalAccountsRepository(db) }; //得到当前公众号 WC_OfficalAccountsModel account = account_BLL.GetById(Id); //将用户提取到本地数据库 WC_UserModel userModel = new WC_UserModel(); IWC_UserBLL user_BLL = new WC_UserBLL() { m_Rep = new WC_UserRepository(db) }; user_BLL.Create(ref errors, userModel); UserInfoJson userJson = UserApi.Info(account.AccessToken, requestMessage.FromUserName); userModel.Id = ResultHelper.NewId; userModel.OpenId = userJson.openid; userModel.NickName = userJson.nickname; userModel.Sex = userJson.sex; userModel.Language = userJson.language; userModel.City = userJson.city; userModel.Province = userJson.province; userModel.Country = userJson.country; userModel.HeadImgUrl = userJson.headimgurl; userModel.SubscribeTime = ResultHelper.GetTimeByLong(userJson.subscribe_time); userModel.UnionId = userJson.unionid; userModel.Remark = userJson.remark; userModel.GroupId = userJson.groupid.ToString(); userModel.TagidList = string.Join(",", userJson.tagid_list.ToArray()); userModel.Subscribe = userJson.subscribe; userModel.OfficalAccountId = account.Id; IWC_MessageResponseRepository m_Rep = new WC_MessageResponseRepository(db); //订阅回复 List<WC_MessageResponse> messageList = m_Rep.GetSubscribeResponseContent(account.Id); if (messageList.Count() > 0) { if (messageList[0].Category == (int)WeChatReplyCategory.Text) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.CreateTime = ResultHelper.NowTime; responseMessage.ToUserName = requestMessage.FromUserName; responseMessage.FromUserName = account.OfficalId; responseMessage.Content = messageList[0].TextContent; return responseMessage; } //图文方式 else if (messageList[0].Category == (int)WeChatReplyCategory.Image) { var responseMessage = CreateResponseMessage<ResponseMessageNews>(); foreach (var model in messageList) { responseMessage.Articles.Add(new Article() { Title = model.TextContent, Description = model.ImgTextContext, PicUrl = WebChatPara.SiteUrl + model.ImgTextUrl, Url = model.ImgTextLink }); } return responseMessage; }//通常不多用到 else if (messageList[0].Category == (int)WeChatReplyCategory.Voice) { var responseMessage = base.CreateResponseMessage<ResponseMessageMusic>(); responseMessage.Music.MusicUrl = WebChatPara.SiteUrl + messageList[0].MeidaUrl; responseMessage.Music.Title = messageList[0].TextContent; responseMessage.Music.Description = messageList[0].Remark; return responseMessage; } } var errorResponseMessage = requestMessage.CreateResponseMessage<ResponseMessageText>(); return errorResponseMessage; } }
退订事件:OnEvent_UnsubscribeRequest(退订没有什么代码,只是标记这个openID已经取消关注)服务器
/// <summary> /// 订阅(关注)事件 /// </summary> /// <returns></returns> public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage) { ValidationErrors errors = new ValidationErrors(); using (DBContainer db = new DBContainer()) { IWC_OfficalAccountsBLL account_BLL = new WC_OfficalAccountsBLL() { m_Rep = new WC_OfficalAccountsRepository(db) }; //得到当前公众号 WC_OfficalAccountsModel account = account_BLL.GetById(Id); //将用户提取到本地数据库 IWC_UserBLL user_BLL = new WC_UserBLL() { m_Rep = new WC_UserRepository(db) }; WC_UserModel userModel = user_BLL.GetById(Id); //标记为取消关注 userModel.Subscribe = 0; user_BLL.Edit(ref errors, userModel); var errorResponseMessage = requestMessage.CreateResponseMessage<ResponseMessageText>(); return errorResponseMessage; } }
后台管理最直接的效益是分析统计用户的数据情况,这里只演示从服务器同步用户信息,其余都是之前写得发愁的,增删改查了微信
前端JSapp
$("#btnSync").click(function () { var rows = $('#List').datagrid('getSelections'); if (rows.length > 0) { var ids = rows.join(","); $.each(rows, function (index, row) { ids = ids + row.value + ","; }); $.post("@Url.Action("SyncUser")?ids=" + ids, function (data) { if (data.type == 1) $("#List").datagrid('load'); $.messageBox5s('@Resource.Tip', data.message); }, "json"); } else { $.messageBox5s('@Resource.Tip', '@Resource.PlaseChooseToOperatingRecords'); } });
后端控制器代码ide
public JsonResult SyncUser(string ids,string officeId) { if (!string.IsNullOrWhiteSpace(ids)) { //填充数据 string[] arrs = ids.Split(','); List<BatchGetUserInfoData> list = new List<BatchGetUserInfoData>(); foreach (var m in arrs) { list.Add(new BatchGetUserInfoData() { openid = m }); } //批量同步数据 WC_OfficalAccountsModel accountModel = account_BLL.GetById(officeId); var batchList = Senparc.Weixin.MP.AdvancedAPIs.UserApi.BatchGetUserInfo(accountModel.AccessToken, list); foreach (var info in batchList.user_info_list) { WC_UserModel userModel = m_BLL.GetById(info.openid); if (userModel != null) { userModel.City = info.city; userModel.OpenId = info.openid; userModel.Id = info.openid; userModel.HeadImgUrl = info.headimgurl; userModel.Language = info.language; userModel.NickName = info.nickname; userModel.Province = info.province; userModel.Sex = info.sex; m_BLL.Edit(ref errors, userModel); } } LogHandler.WriteServiceLog(GetUserId(), "Ids:" + ids, "成功", "删除", "WC_User"); return Json(JsonHandler.CreateMessage(1, Resource.SaveSucceed)); } else { return Json(JsonHandler.CreateMessage(0, Resource.SaveFail)); } }
代码简单易懂:经过OpenID到公众号同步到数据,再将本地数据修改post
同步接口在Senparc WX SDK下的Senparc.Weixin.MP.AdvancedAPIs UserApi
同时这个类也提供了:获取用户信息,获取关注者OpenId信息,修改关注者备注信息,批量获取用户基本信息