Aquarius.Weixin 微信公众号开发教程(1)- Qu
在今天,Aquarius.Weixin发布了nuget包版本1.1.2,算是1.0版本的正式上线,github的readme中有Aquarius.Weixin的快速开发入门,本博客从快速入门开始,分步介绍Aquarius.Weixin的使用方法,以及分享在微信公众号开发中遇到的各种坑。
1、关于Aquarius.Weixin
Aquarius.Weixin是一个为.net core 2.0开发的微信公众号开发框架,目前实现了网页授权、菜单创建、消息管理、素材管理、消息收发、模板消息管理与推送、微信支付等,便于.net core开发者专注于业务,快速开发微信公众号。
项目地址Github,欢迎大家的star和fork,有任何问题可以提issue或者与我联系(readme里有我的微信号)。
2、关于本文
本文主要作为快速开发入门,主要介绍网页授权、菜单创建、消息收发功能。
3、那么,现在开始咯
在正式开始之前,先说两句闲话,我第一次做公众号开发是公司要求将我们的app产品移植到微信公众号,作为一个从来没做过微信公众号开发的萌新,第一件事就是去看微信的文档(然而并没看懂),然后又去百度 微信公众号 .net
(我们公司后台是用的.net framework),网上大部分的文档一上来就是在介绍如何配置服务器链接怎么去验证签名(在配置服务器链接的时候),但是我们公众号开发的大部分情况下并不需要消息收发的功能,我们要的只是用户打开网页,获取到用户的openid足矣。而网页授权获取openid的时候是不需要配置服务器链接的(摔 (′д` )…彡…彡,本文以测试号为例从网页授权开始介绍,以及在什么情况下需要配置什么东西。
现在真的正式开始了。
准备步骤:
(1)安装Aquarius.Weixin
从nuget包管理器进行安装,目前版本为1.1.2
(2)注册测试号(已经注册过的同学可跳过本步)
点击进入微信测试平台,微信扫码登陆,查看测试账号的appid和appsecret
微信测试账号.png
(3)修改startup.cs中的ConfigureServices,添加如下代码:
services.AddAquariusWeixin(opt =>
{
opt.BaseSetting = new BaseSettings()
{
Debug = true,
IsRepetValid = false,
AppId = "your appid",
AppSecret = "your appsecret",
Token = "token"
};
opt.CacheType = CacheType.InMemory;
opt.MsgMiddlewareType = MessageMiddlewareType.Plain;
});
将上述appid和appsecret配置为自己的appid和appsecret,CacheType为缓存模式,当前使用InMemory模式,MsgMiddlewareType为消息中间件模式(消息加解密方式),当前使用Plain(明文)。
然后,新建名为WeixinController的空控制器类,并删除其中的Index方法。
至此,准备工作完成。
创建菜单
注意:由于微信测试号的限制,只能通过api方式配置菜单,所以此处首先进行菜单配置,使用服务号的同学如果不想了解配置菜单可以直接看网页授权。
新建一个CreateMenu方法,代码如下:
public IActionResult CreateMenu()
{
//创建菜单对象
var menu = new Menu()
{
button = new List<IButton>()
{
new SingleClickButton("按钮1")
{
key = "Button1"
},
new SubButton("二级菜单")
{
sub_button = new List<SingleButton>()
{
new SingleClickButton("按钮2")
{
key = "Button2"
},
new SingleViewButton("网页")
{
url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=http://yourdomain.com/Weixin/Authorization&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"
}
}
}
}
};
//获取AccessToken
var accessToken = _accessTokenContainer.GetAccessToken();
//创建菜单
var result = _menuInterfaceCaller.CreateMenu(accessToken, menu.ToJson());
return Content(result);
}
创建的菜单样式如下:
其中“网页”菜单中的url需将APPID替换为自己的appid,scope使用snsapi_userinfo可以获取用户详细信息,并将yourdomain.com替换成自己的公网项目地址,此处介绍一个工具
ngrok
可以将内网端口映射到外网,运行 ngrok http port
其中port为当前web项目端口,如下:ngrok.png
然后使用映射后的域名替换yourdomain.com,之后浏览器打开http://localhost:port/Weixin/CreateMenu创建菜单。
注意:使用服务号测试的同学必须先到后台配置业务域名,然后浏览器访问http://f0323206.ngrok.io/Weixin/CreateMenu创建菜单,不然获取AccessToken会报错。
业务域名.png
浏览器返回ok即菜单创建成功:
创建菜单.png
注意:菜单创建成功之后有一定的缓存期,可以通过重新关注来刷新菜单。
网页授权
在上一节创建菜单中我们创建了一个网页跳转按钮,如果你是用的服务号,直接到后台菜单配置中配置菜单链接即可。
在WeixinController中新建Authorization方法,代码如下:
public IActionResult Authorization(string code)
{
//通过code获取openId
var openId = _authorizationContainer.GetOpenId(code);
//通过openId获取userInfo
var userInfo = _authorizationContainer.GetUserInfo(openId, Language.zh_CN);
return Content($"your openId is {openId}, your nickname is {userInfo.nickname}");
}
注意,该方法的code参数不可少。
然后到测试号后台配置网页授权域名:
网页授权域名位置.png
网页授权域名修改.png
使用服务号的同学,前往如下位置配置:
服务号网页授权域名配置.png
运行项目后,点击二级菜单下的网页按钮,运行效果如下:
网页授权效果.png
消息收发
在WeixinController中新建Index方法,代码如下:
public async Task<IActionResult> Index(string signature, string timestamp, string nonce, string echostr, string encrypt_type, string msg_signature)
{
try
{
if (!string.IsNullOrEmpty(echostr))
{
//服务器认证
if (_verifyer.VerifySignature(signature, timestamp, nonce, "token"))
{
return Content(echostr);
}
else
{
return Content("success");
}
}
else
{
//消息接收
using (var sr = new StreamReader(Request.Body))
{
string data = await sr.ReadToEndAsync();
//接收消息中间处理
data = _messageMiddleware.ReceiveMessageMiddle(signature, msg_signature, timestamp, nonce, data);
//解析消息
IMessage message = MessageParser.ParseMessage(data);
//处理消息,生成回复
string reply = _messageProcesser.ProcessMessage(message);
//回复消息中间处理
reply = _messageMiddleware.ReplyMessageMiddle(reply);
return Content(reply);
}
}
}
catch (Exception ex)
{
//log something
return Content("success");
}
}
然后配置接口如下:
接口配置.png
将域名替换为自己的域名,token填写为startup中设置的token。
使用服务号的同学在开发-基本配置中配置:
服务号接口配置.png
并可选择加密模式,本例中使用明文模式(在startup中已设置)。配置完成后点击“启动”。
注意:该消息处理方法在生产环境中也建议如此编写。
至此,我们完成了接口的编写和配置,在Aquarius.Weixin中所有消息均未进行任何处理直接回复success(即用户收不到任何回复)。
下一步,实现一个点击按钮返回文本消息的类。
新建类ClickEventReplyTextHandler,代码如下:
public class ClickEventReplyTextHandler : ClickEvtMessageHandlerBase
{
private readonly IMessageReply<TextMessage> _messageReply;
public ClickEventReplyTextHandler(IMessageReply<TextMessage> messageReply)
{
_messageReply = messageReply;
}
public override string ClickEventHandler(ClickEvtMessage message)
{
//组装文本消息
var textMessage = new TextMessage(message)
{
CreateTime = UtilityHelper.GetTimeStamp(),
Content = $"你点击了{message.EventKey}按钮"
};
return _messageReply.CreateXml(textMessage);
}
}
①ClickEventReplyTextHandler所继承的类ClickEvtMessageHandlerBase即为要重写的消息类型处理类,本例为点击事件消息处理,在之后的教程中将详细介绍接收的消息类型处理基类。
②_messageReply字段的类型为IMessageReply<T>类型,类型T即为返回的消息类型,在之后的教程中将详细介绍可以返回的消息类型。
然后在startup类的ConfigureServices方法中AddAquariusWeixin之后添加如下代码,注意一定是之后:
services.AddScoped<ClickEvtMessageHandlerBase, ClickEventReplyTextHandler>();
使用刚才编写的ClickEventReplyTextHandler类处理点击事件消息。
点击按钮,效果如下:
点击按钮回复文本效果.png
4、附录
WeixinController类中使用到的所有字段声明如下:
private readonly AccessTokenContainer _accessTokenContainer;
private readonly MenuInterfaceCaller _menuInterfaceCaller;
private readonly AuthorizationContainer _authorizationContainer;
private readonly Verifyer _verifyer;
private readonly IMessageMiddleware _messageMiddleware;
private readonly MessageProcesser _messageProcesser;
或者查看源码
另外,之后的教程目录还在构思中,如果有那一块想先了解可以评论告诉我。