系列目錄
前言
本節主要是關注者(即用戶)和用戶組的管理,微信公眾號提供了用戶和用戶組的管理,我們可以在微信公眾號官方里面進行操作,添加備注和標簽,以及移動用戶組別,同時,微信公眾號也提供了相應的接口另我們本地可以操作.我們主要是同步到本地,這樣我們可以自己為用戶定義更多的信息,以及與本地的業務更好的對接起來.

實現
一、關注與訂閱事件
看到我們之前的消息處理類 我們需要擴展一個事件類,這個類與之前消息處理類是一樣的分部類,同樣來自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之前觸發,具有以下一些特征: // 1、如果返回null,則繼續執行OnTextRequest或OnEventRequest // 2、如果返回不為null,則終止執行OnTextRequest或OnEventRequest,返回最終ResponseMessage // 3、如果是事件,則會將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
表字段是根據官網,用戶管理對應字段而建立,基本與官方提供的用戶信息是一樣的,無非是存點用戶的姓名,籍貫,頭像,關注事件等
三、同步數據
這時我們就可以實現OnEvent_SubscribeRequest (關注時)的代碼,基本沒有實現難度,步驟如下:
- 獲得OpenID(requestMessage.FromUserName)
- 調用信息接口( UserInfoJson userJson = UserApi.Info(account.AccessToken, requestMessage.FromUserName);)
- 把信息添加到本地
- 啟用訂閱時回復的內容(回復在前面已經放出)
/// <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; } }
后台管理
后台管理最直接的效益是分析統計用戶的數據狀況,這里只演示從服務器同步用戶信息,其他都是以前寫得發愁的,增刪改查了
前端JS
$("#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'); }
});
后端控制器代碼
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到公眾號同步到數據,再將本地數據修改
同步接口在Senparc WX SDK下的Senparc.Weixin.MP.AdvancedAPIs UserApi
同時這個類也提供了:獲取用戶信息,獲取關注者OpenId信息,修改關注者備注信息,批量獲取用戶基本信息
