一、说明 在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者在开发者中心处设置的服务器地址,从而开发者可以获取到该信息。二、新建partial类 partial即为定义部分类的关键字。部分类主要用于当一个类中的内容较多时将相似类中的内容拆分到不同的类中,并且部分类的名称必须相同。 CustomMessageHandler。cs加关键词partial Handler下新建CustomMessageHandlerEvents部分类用来接收事件推送 修改类名为CustomMessageHandler并添加关键词partial使得CustomMessageHandlerEvents为CustomMessageHandler的部分类,这样推送事件和普通消息事件就分开了,职责清晰,便于维护。namespaceWeiXinApi。Application。Handler{publicpartialclassCustomMessageHandler{}} 同样的我们新建MessageServiceEvents部分类 namespaceWeiXinApi。Application。Services{publicpartialinterfaceIMessageService{}}namespaceWeiXinApi。Application。Services{publicpartialclassMessageService{}} IMessageService和IMessageService也要加partial关键字 三、关注取消关注事件 IMessageServiceEvents定义接口summary订阅summaryparamnamerequestMessageparamreturnsreturnsTaskIResponseMessageBaseOnEventSubscribeRequestAsync(RequestMessageEventSubscriberequestMessage);summary取消订阅summaryparamnamerequestMessageparamreturnsreturnsTaskIResponseMessageBaseOnEventUnsubscribeRequest(RequestMessageEventUnsubscriberequestMessage); MessageServiceEvents实现接口publicasyncTaskIResponseMessageBaseOnEventSubscribeRequestAsync(RequestMessageEventSubscriberequestMessage){varresponseMessageResponseMessageBase。CreateFromRequestMessageResponseMessageText(requestMessage);varreceivesawaitDbContext。Db。QueryableMessageReceive()。ToListAsync();如果关键字搜不到,列出关键字varresultnewStringBuilder();result。AppendFormat(欢迎订阅,可以试试下面的关键字rr);for(inti0;ireceives。Count;i){result。AppendFormat(34;{i1}:{receives〔i〕。KeyWords}r);}responseMessage。Contentresult。ToString();returnresponseMessage;}summarysummaryparamnamerequestMessageparamreturnsreturnspublicasyncTaskIResponseMessageBaseOnEventUnsubscribeRequest(RequestMessageEventUnsubscriberequestMessage){实际上用户无法收到非订阅账号的消息,所以这里可以随便写。varresponseMessageResponseMessageBase。CreateFromRequestMessageResponseMessageText(requestMessage);responseMessage。Content34;再见!;Console。WriteLine(34;{requestMessage。FromUserName}取消了订阅);returnresponseMessage;} CustomMessageHandlerEvents里重写订阅和取消订阅事件summary订阅或关注事件summaryparamnamerequestMessageparamreturnsreturnspublicoverrideasyncTaskIResponseMessageBaseOnEventSubscribeRequestAsync(RequestMessageEventSubscriberequestMessage){varresultawaitmessageService。OnEventSubscribeRequestAsync(requestMessage);returnresult;}summary退订unsubscribe事件的意义在于及时删除网站应用中已经记录的OpenID绑定,消除冗余数据。并且关注用户流失的情况。summaryreturnsreturnspublicoverrideasyncTaskIResponseMessageBaseOnEventUnsubscribeRequestAsync(RequestMessageEventUnsubscriberequestMessage){varresultawaitmessageService。OnEventUnsubscribeRequest(requestMessage);returnresult;} 发布到服务器,测试下效果,成功接收到事件 四、扫描带参数二维码事件 IMessageServiceEvents定义接口summary扫描带参数二维码事件summaryparamnamerequestMessageparamreturnsreturnsTaskIResponseMessageBaseOnEventScanRequestAsync(RequestMessageEventScanrequestMessage); MessageServiceEvents实现接口publicasyncTaskIResponseMessageBaseOnEventScanRequestAsync(RequestMessageEventScanrequestMessage){varresponseMessageResponseMessageBase。CreateFromRequestMessageResponseMessageText(requestMessage);varresult扫描带二维码事件;varsceneIdrequestMessage。EventKey。ObjToInt();varreceiveawaitDbContext。Db。QueryableQrCode()。Where(itit。SceneIdsceneId)。FirstAsync();从数据库拿数据Console。WriteLine(34;是否有数据:{receive!null});if(receive!null){switch(receive。ReceiveInfo。ReceiveType){caseReceiveType。文字:result34;{receive。ReceiveInfo。ReceiveString};break;}}responseMessage。Contentresult;returnresponseMessage;} CustomMessageHandlerEvents重写扫描二维码事件summary扫描带参数二维码事件summaryparamnamerequestMessageparamreturnsreturnspublicoverrideasyncTaskIResponseMessageBaseOnEventScanRequestAsync(RequestMessageEventScanrequestMessage){varresultawaitmessageService。OnEventScanRequestAsync(requestMessage);returnresult;} 先用api接口创建一个二维码,然后发布到服务器,记得sqlite文件为始终复制,可以正常显示 先取消关注再扫码,发现只回复了扫描带二维码事件这几个字,发现原来在没有关注的情况下会将eventkey推送到订阅事件 因为关注事件和扫码二维码事件都会去数据库查数据,所以将共用的方法提取出来,编写方法GetScanRequestsummary获取扫描事件结果summaryparamnameeventKeyparamreturnsreturnsprivateasyncTaskstringGetScanRequest(stringeventKey){Console。WriteLine(34;eventKey:{eventKey});varresult扫描带二维码事件!;varsceneIdeventKey。ObjToInt();varreceiveawaitDbContext。Db。QueryableQrCode()。Where(itit。SceneIdsceneId)。FirstAsync();从数据库拿数据Console。WriteLine(34;是否有数据:{receive!null});if(receive!null){switch(receive。ReceiveInfo。ReceiveType){caseReceiveType。文字:result34;{receive。ReceiveInfo。ReceiveString};break;}}returnresult;} 修改OnEventSubscribeRequestAsync方法publicasyncTaskIResponseMessageBaseOnEventSubscribeRequestAsync(RequestMessageEventSubscriberequestMessage){varresponseMessageResponseMessageBase。CreateFromRequestMessageResponseMessageText(requestMessage);if(!string。IsNullOrWhiteSpace(requestMessage。EventKey)requestMessage。EventKey。StartsWith(qrscene))扫二维码事件{responseMessage。ContentawaitGetScanRequest(requestMessage。EventKey。Split()〔1〕);}else{varreceivesawaitDbContext。Db。QueryableMessageReceive()。ToListAsync();如果关键字搜不到,列出关键字varresultnewStringBuilder();result。AppendFormat(欢迎订阅,可以试试下面的关键字rr);for(inti0;ireceives。Count;i){result。AppendFormat(34;{i1}:{receives〔i〕。KeyWords}r);}responseMessage。Contentresult。ToString();}returnresponseMessage;} OnEventScanRequestAsync也改下publicasyncTaskIResponseMessageBaseOnEventScanRequestAsync(RequestMessageEventScanrequestMessage){varresponseMessageResponseMessageBase。CreateFromRequestMessageResponseMessageText(requestMessage);responseMessage。ContentawaitGetScanRequest(requestMessage。EventKey);returnresponseMessage;} 发布到服务器,取消关注再扫描,成功显示数据 五、上报地理位置事件 IMessageServiceEvents定义接口summary位置事件summaryparamnamerequestMessageparamreturnsreturnsTaskIResponseMessageBaseOnEventLocationRequestAsync(RequestMessageEventLocationrequestMessage); MessageServiceEvents实现接口publicasyncTaskIResponseMessageBaseOnEventLocationRequestAsync(RequestMessageEventLocationrequestMessage){这里是微信客户端(通过微信服务器)自动发送过来的位置信息varresponseMessageResponseMessageBase。CreateFromRequestMessageResponseMessageText(requestMessage);varresult34;Latitude:{requestMessage。Latitude},Longitude:{requestMessage。Longitude};Console。WriteLine(result);responseMessage。Contentresult;这里写什么都无所谓returnresponseMessage;} CustomMessageHandlerEvents重写位置事件summary位置事件summaryparamnamerequestMessageparamreturnsreturnspublicoverrideasyncTaskIResponseMessageBaseOnEventLocationRequestAsync(RequestMessageEventLocationrequestMessage){varresultawaitmessageService。OnEventLocationRequestAsync(requestMessage);returnresult;} 开通位置权限 测试一下,正常打印日志 六、自定义菜单事件6。1、创建菜单 参考自定义菜单章节6。2、点击事件 IMessageServiceEvents定义接口summary点击事件summaryparamnamerequestMessageparamreturnsreturnsTaskIResponseMessageBaseOnEventClickRequestAsync(RequestMessageEventClickrequestMessage); MessageServiceEvents实现接口publicasyncTaskIResponseMessageBaseOnEventClickRequestAsync(RequestMessageEventClickrequestMessage){Console。WriteLine(进入点击事件);IResponseMessageBasereponseMessagenull;switch(requestMessage。EventKey){caseV1001TODAYMUSIC:{varfilePathwwwrootImagesmusic。jpeg;记得调成始终复制varuploadResultawaitMediaApi。UploadTemporaryMediaAsync(appId,UploadMediaFileType。thumb,ServerUtility。ContentRootMapPath(filePath));PS:缩略图官方没有特别提示文件大小限制,实际测试哪怕114K也会返回文件过大的错误,因此尽量控制在小一点设置音乐信息varstrongResponseMessageResponseMessageBase。CreateFromRequestMessageResponseMessageMusic(requestMessage);reponseMessagestrongResponseMessage;strongResponseMessage。Music。Title天籁之音;strongResponseMessage。Music。Description真的是天籁之音;strongResponseMessage。Music。MusicUrlhttps:sdk。weixin。senparc。comContentmusic1。mp3;strongResponseMessage。Music。HQMusicUrlhttps:sdk。weixin。senparc。comContentmusic1。mp3;strongResponseMessage。Music。ThumbMediaIduploadResult。thumbmediaid;}break;default:{varstrongResponseMessageResponseMessageBase。CreateFromRequestMessageResponseMessageText(requestMessage);strongResponseMessage。Content您点击了按钮,EventKey:requestMessage。EventKey;reponseMessagestrongResponseMessage;}break;}returnreponseMessage;} CustomMessageHandlerEvents重写点击事件summary点击事件summaryparamnamerequestMessageparamreturnsreturnspublicoverrideasyncTaskIResponseMessageBaseOnEventClickRequestAsync(RequestMessageEventClickrequestMessage){varresultawaitmessageService。OnEventClickRequestAsync(requestMessage);returnresult;} 发布到服务器,测试下,没毛病,这里缩略图不知道为啥没显示,不管了,后面再看看啥问题。 七、点击菜单跳转链接时的事件推送 IMessageServiceEvents定义接口summary打开网页事件summaryparamnamerequestMessageparamreturnsreturnsTaskIResponseMessageBaseOnEventViewRequestAsync(RequestMessageEventViewrequestMessage); MessageServiceEvents实现接口publicasyncTaskIResponseMessageBaseOnEventViewRequestAsync(RequestMessageEventViewrequestMessage){Console。WriteLine(进入链接跳转事件);说明:这条消息只作为接收,下面的responseMessage到达不了客户端,类似OnEventUnsubscribeRequestvarresponseMessageResponseMessageBase。CreateFromRequestMessageResponseMessageText(requestMessage);responseMessage。Content您点击了view按钮,将打开网页:requestMessage。EventKey;returnresponseMessage;} CustomMessageHandlerEvents重写打开网页事件summary打开网页事件summaryparamnamerequestMessageparamreturnsreturnspublicoverrideasyncTaskIResponseMessageBaseOnEventViewRequestAsync(RequestMessageEventViewrequestMessage){varresultawaitmessageService。OnEventViewRequestAsync(requestMessage);returnresult;} 发布到服务器,测试下,没毛病。 八、本章Gitee地址链接 https:gitee。comhuguodong520weixinapitreeE4BA8BE4BBB6E68EA8E98081