9、多公众号集中管理
1、概述
通过前面8篇关于微信开发相关文章的学习,我们已经对微信常用开发有了一个比较深入的了解。前面的文章都是基于某一特定公众号的,在现实业务中同一单位个体运营着不至一个公众号,此时就需要对多个公众号集中管理,随意切换。本篇文章主要介绍多公众号集中管理的方法、表设计、设置默认公众号、生成指定格式的URL资源服务器、刷新Access_Token等。
2、公众号集中管理的方法
我们知道操作微信公众号时微信服务器都会返回相应的信息到我们自己的中转服务器上,涉及多个微信公众号管理时,我们就需要知道是那个公众号返回的数据以及我们要操作的是那个公众号。我们通过集中设计一个公众号管理的界面就可以完成对多公众号的管理,下面我们介绍具体的方法供大家参考。
3、多公众号管理表设计
在进行表设计之前,我们先回忆一下我们在申请公众号时需要填写的必要信息,如下图所示 。
在上图中,我们可以看出界面上我们标记的5个数据项是必须的,分别为公众号(OFFICIAL_ID)、应用ID(APP_ID)、应用密钥(APP_SECRET)、服务器地址(API_URL)、令牌(TOKEN)。我们可以根据我们实际业务扩展其他的字段方便使用。公众号管理参考表设计如下图所示。
上面的表设计我们对申请各种类型公众号所需的字段都进行了处理。要做到多公众号管理,我们可以利用主键来切分公众号,这个主键ID就需要放到我们公众号接口配置信息中的URL中,如下图所示。
我们只需要在我们的微信开发服务端得到这个ID值就能知道当前操作的公众号信息,这是多公众号管理设计中的精髓。具体参考本文后面的生成指定格式的URL资源服务器的讲解。
4、默认公众号设置
默认公众号就是当前操作的公众号,所有涉及公众号的操作都以默认公众号为基础。在上一节我们的表设计中有一个IS_DEFAULT当前操作公众号的字段,只要设置为1就是默认公众号。特别注意的是所有操作公众号中只允许有一个默认公众号,设置为一个公众号为默认公众号后,其他的公众号都要取消默认公众号的设置。
要设置默认公众号只需要调用我们框架提供的接口:
RDIFrameworkService.Instance.WeixinBasicService.SetDefaultOfficialAccount(UserInfo userInfo, string id);
设置好默认公众号后,我们可以通过下面的接口得到当前操作的公众号:
RDIFrameworkService.Instance.WeixinBasicService.GetCurrentOfficialAccountEntity(UserInfo userInfo);
代码参考
/// <summary>
/// 设置当前公众号为默认操作公众号
/// </summary>
/// <param name="key">主键值</param>
/// <returns></returns>
[AjaxOnly]
[HttpPost]
[ManagerPermission(PermissionMode.Enforce)]
public virtual ActionResult SetDefault(string key)
{
int returnValue = 0;
try
{
if (!string.IsNullOrEmpty(key))
{
returnValue += RDIFrameworkService.Instance.WeixinBasicService.SetDefaultOfficialAccount(ManageProvider.Provider.Current(), key);
}
return Content(returnValue > 0
? new JsonMessage { Success = true, Data = "1", Type = ResultType.Success, Message = RDIFramework.Utilities.RDIFrameworkMessage.MSG3010 }.ToString()
: new JsonMessage { Success = false, Data = "0", Type = ResultType.Warning, Message = RDIFramework.Utilities.RDIFrameworkMessage.MSG3020 }.ToString());
}
catch (Exception ex)
{
return Content(new JsonMessage { Success = false, Data = "-1", Type = ResultType.Error, Message = RDIFramework.Utilities.RDIFrameworkMessage.MSG3020 + ex.Message }.ToString());
}
}
5、生成指定格式的URL资源服务器
在阅读本节之前,建议参考了解一下我们的微信公众号开发系列-2、微信公众平台接入指南对微信的接入有了一个比较全面的了解。接入服务器地址URL是开发者用来接收微信消息和事件的接口URL,是我们服务器的响应微信请求的地址。
假设我们自己的服务器域名是www.rdiframework.net,准备用/WeiXin/WeChat/来接收消息,就填写:
http://www.rdiframework.net/WeiXin/WeChat/
上面的这个地址针对一个公众号时可以,但如果对多公众号管理来说就不能这样用了,我们可以指定一个ID来区分公众号的来源:
http://www.rdiframework.net/WeiXin/WeChat/?id=********
在我们的的微信服务端接入代码中加上对这个ID的处理即可。
处理Get请求代码参考如下:
[HttpGet]
[ActionName("Index")]
public Task<ActionResult> Get(string signature, string timestamp, string nonce, string echostr)
{
string currentOfficialId = Request["id"];
return Task.Factory.StartNew(() =>
{
if (string.IsNullOrEmpty(currentOfficialId))
{
return "非法路径请求!";
}
WeixinOfficialAccountEntity weixinOfficialAccountEntity = RDIFrameworkService.Instance.WeixinBasicService.GetOfficialAccountEntity(currentOfficialId);
if (CheckSignature.Check(signature, timestamp, nonce, weixinOfficialAccountEntity.Token))
{
return echostr; //返回随机字符串则表示验证通过
}
else
{
return "failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, weixinOfficialAccountEntity.Token) + "。" + "如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。";
}
}).ContinueWith<ActionResult>(task => Content(task.Result));
}
处理Post请求代码参考如下:
/// <summary>
/// 最简化的处理流程
/// </summary>
[HttpPost]
[ActionName("Index")]
public Task<ActionResult> Post(PostModel postModel)
{
string currentOfficialId = Request["id"];
return Task.Factory.StartNew<ActionResult>(() =>
{
//没有参数,带有id才能知道是访问哪个公众号
if (string.IsNullOrEmpty(currentOfficialId))
{
return new WeixinResult("非法路径请求!");
}
WeixinOfficialAccountEntity weixinOfficialAccountEntity = RDIFrameworkService.Instance.WeixinBasicService.GetOfficialAccountEntity(currentOfficialId);
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, weixinOfficialAccountEntity.Token))
{
return new WeixinResult("参数错误!");
}
postModel.Token = weixinOfficialAccountEntity.Token;
postModel.EncodingAESKey = weixinOfficialAccountEntity.OfficialKey; //根据自己后台的设置保持一致
postModel.AppId = weixinOfficialAccountEntity.AppId; //根据自己后台的设置保持一致
var messageHandler = new CustomMessageHandler(Request.InputStream, postModel, currentOfficialId, 10);
messageHandler.Execute(); //执行微信处理过程
return new FixWeixinBugWeixinResult(messageHandler);
}).ContinueWith<ActionResult>(task => task.Result);
}
6、刷新Access_Token
由于Access Token有效期只有7200秒,而每天调用获取的次数只有2000次,所以需要将Access Token进行缓存来保证不触发超过最大调用次数。另外在微信公众平台中,绝大多数高级接口都需要Access Token授权才能进行调用,开发者需要使用中控服务器统一进行缓存与更新,以避免各自刷新而混乱。
获得Token:我们可以直接使用Senparc.WeiXin SDK的方法。
Senparc.Weixin.MP.CommonAPIs.CommonApi.GetToken(model.AppId, model.AppSecret).access_token;
通过传入AppId和Appsecret,微信服务器将给你一个可访问的Token。
虽然他帮我们封装了,但是不用他的方法,我们也可以直接调用微信的接口方法:
var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type={0}&appid={1}&secret={2}", grant_type.AsUrlData(), appid.AsUrlData(), secret.AsUrlData());
AccessTokenResult result = Get.GetJson<AccessTokenResult>(url);
return result;
这个接口,只有几个参数,具体参数可以查看帮助文档 传送门 成功返回:
{"access_token":"ACCESS_TOKEN","expires_in":7200}