如何开发一个微信第三方平台?(应用篇)

    之前我们介绍了微信第三方平台的注册认证与基本介绍,以及微信第三方平台的应用授权处理介绍,本篇我们主要介绍复用公众号资质快速注册小程序、微信应用消息与事件处理这些实际应用。

复用公众号资质快速注册小程序

    现在的微信开发大部分都是围绕着公众号、小程序进行的。对于中国大陆来说,公众号认证需要300块认证费,每年还有年审(年审认证费用也是300块);小程序如果是直接创建后进行认证的话,也需要300块认证费,但不需要年审;微信开放平台也需要认证,费用同样是中国大陆300块,但不需要年审。

    一套完整的组合下来,费用都得900块,要是小程序一多,那费用还得往上涨,这时候发现微信官方提供了复用公众号资质创建小程序的功能,简单理解这个功能就是让我们能够直接使用公众号的主体信息进行小程序注册并且创建,并且这时候创建的小程序不需要手动认证且立刻有效(节省了300块的认证费用以及繁琐的认证交互流程)。登录公众号复用资质创建小程序的入口如下图所示:

如何开发一个微信第三方平台?(应用篇)
授权事件接收URL作用

    这种方式对公众号有一定的要求,必须是「已认证的企业、媒体、政府、其他组织类型公众号」,并且个体户公众号一个月可以复用资质注册1个小程序,非个体户类型(企业、媒体、政府、其他组织类型)公众号一个月可以复用资质注册5个小程序。

    同时通过这种方式认证创建的小程序,有如下一些约束:

  • 复用资质创建的小程序默认与该公众号关联;

  • 复用资质创建的小程序默认关联公众号,不下发模板消息,不默认出现在公众号资料页;

  • 一个公众号一个月内可复用资质注册小程序不多于5个。(创建成功才占用);

    更多约束与规则可以参考官方文档。

    综合考虑:如果是相同主体的话,强烈推荐各位先注册并且认证公众号,然后通过公众号复用资质创建小程序。最后根据实际开发需要再去创建并认证微信开放平台。

第三方平台复用公众号资质快速注册小程序

    说了那么多,该回归到第三方平台相关的了,首先是第三方平台提供的快速创建小程序接口,这个接口通过模板消息与企业法人人脸识别的方式可以快速创建小程序,创建的小程序同样是已认证并且免认证费的。但是流程非常麻烦,需要客户公司的法人信息、同时模板是下发到该法人微信进行人脸识别的,大公司的老板怎么有空去帮你做这些,所以非常鸡肋,甚至想给差评。

    还好第三方平台提供了复用公众号资质快速注册小程序的接口,通过这个接口,可以实现跟手动复用公众号资质快速注册小程序一致的效果。

    其前置条件是客户已经授权公众号到第三方平台,同时准备好基本的小程序权限集(账号服务权限小程序账号管理权限小程序开发管理与数据分析权限小程序认证权限小程序基本信息设置权限)以及我们业务需要的小程序权限集。基本流程如下:

  • 从第三方平台授权发起页发起微信公众平台授权注册;
  • 公众号管理员扫码确认复用公众号资质快速注册小程序;
  • 第三方平台处理微信回调;
  • 公众号管理员调整快速注册的小程序基本信息。

授权流程介绍

    首先是发起授权,这一步同样是要求在授权发起页进行,参考上一篇的授权流程>获取预授权码并生成授权链接,参考文档,所需参数有:

  • 第三方平台appId
  • 复用资质的公众号appId
  • 用户扫码授权后的回调地址

    通常这一步需要有一些我们自己的业务交互,比如标记一些业务逻辑,这里建议通过缓存将一些必要信息通过唯一key存储起来,回调地址里只携带该key,这样一些业务数据就不会暴露出去,而且可以控制复用资质授权链接的时效等。

    @GetMapping(value = "/createAuthUrl", produces = MediaType.TEXT_HTML_VALUE)
    public String createAuthUrl(@RequestParam Long wxAppId,
                                @Valid @RedirectUrl String redirectUri /*, 其他业务参数 ...*/)
 
{
        // 1、获取 wxAppId 对应的公众号信息,验证授权信息等
        // 2、将公众号信息、回调地址(验证是可信的回调)、业务参数等内容通过唯一key存储起来
        String key = "唯一key";
        Redis.set(key, info, expireTime);
        // 3、处理授权回调地址,这里一定要跳转到授权发起页域名
        String redictUrl = "${授权发起页域名}/xxx/callback" + key;
        // 4、创建授权链接,修正 Referer
        String authUrl = "https://mp.weixin.qq.com/cgi-bin/fastregisterauth?appid=${公众号appId}&component_appid=${第三方平台appId}&copy_wx_verify=1&redirect_uri=" + UrlHelper.urlEncode(redirectUri);
        return MessageFormat.format("<!DOCTYPE html><html><script>window.location.href='{0}'</script></html>", authUrl);
    }

    通过形如上述流程的操作,我们支持从任意可信的网页发起复用资质授权,同时可以配置任意可信的回调地址。

    创建完毕后即可集成到我们的应用系统中让客户直接请求我们的复用资质快速注册小程序链接,这时候将经过多次跳转到微信进行复用资质扫码确认,让客户的公众号管理员直接扫码即可进行授权。参考流程如下:

如何开发一个微信第三方平台?(应用篇)
扫码进行复用公众号资质快速注册小程序
如何开发一个微信第三方平台?(应用篇)
复用公众号资质快速注册小程序流程

    管理员只需要扫码确认即可授权快速注册小程序。确认授权后微信会回调到我们授权链接中指定的地址,这时候我们需要通过微信接口完成小程序注册流程,同时我们需要将小程序与客户在我们的应用系统中绑定在一起,同时处理一些后续逻辑:

    @GetMapping("/callback/{callbackKey}")
    public ModelAndView authCallbackCreateMiniProgram(@RequestParam(required = false) String from,
                                                      @RequestParam String ticket,
                                                      @PathVariable("callbackKey") String callbackKey) 
{
        // 通过 key 获取之前的缓存信息并进行一些必要的逻辑判断
        Object info = Redis.get(callbackKey);
        // 通过微信API完成小程序注册,获取对应的 authorizationCode
        WxOpenFastRegisterMiniProgramResult result = /*调用API完成注册*/;
        // 处理内部业务(这一步建议异步完成)
        MQ.handle(result.getAuthorizationCode(), /*其他业务参数*/);
        // 获取缓存中的回调地址进行重定向
        ModelAndView mv = new ModelAndView();
        mv.setView(new RedirectView(info.getRedirectUri()));
        return mv;
    }

    同时,微信也会将相应的复用资质消息推送到第三方平台,事件名称为:fasteregister,参考之前的推文,我们需要添加一个新的授权事件处理器实现WxAuthEventHandler,这个处理器我们需要兼容处理回调的逻辑,同时处理后续的一些业务处理,比如:设置小程序的业务域名,服务器域名等等。

@Slf4j
@Service
public class FastRegisterMiniProgramEventHandler extends AbstractAuthorizeEventHandler implements WxAuthEventHandler {

}

    2020年7月微信第三方平台更新后,通过第三方平台快速注册的小程序也可以绑定邮箱进行网页登录了(更新之前是不允许的,但是第三方平台又仅仅提供了部分小程序资料修改功能),这时候的基本操作如下:

如何开发一个微信第三方平台?(应用篇)
修改复用资质快速注册的小程序信息1
如何开发一个微信第三方平台?(应用篇)
修改复用资质快速注册的小程序信息2

微信应用消息与事件接收处理器

    当授权到第三方平台的小程序或者公众号触发了相应的消息或者事件通知时,微信会将这些消息或者事件转发到第三方平台,这时候通常可以在第三方平台对消息或者事件进行一些业务处理。常见的消息与事件没有汇总,我们需要根据我们的实际业务情况进行监听处理,首先是先进行一定程度的消息与事件定义。

定义微信应用消息与事件消息体

public class MsgEventMessage implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty("公众号或者小程序的appId")
    private String appId;

    @ApiModelProperty("公众号或者小程序")
    private WxApp wxApp;

    @ApiModelProperty("公众号或者小程序消息事件内容")
    private WxMpXmlMessage message;
}

    其中WxApp是我们应用内部封装的关于微信应用的一些常用字段定义,包括:类型(小程序还是公众号)、名称appId授权状态originId等信息,根据各自业务系统所需进行定义即可(通过之前介绍的wxOpenService.getWxOpenComponentService().getAuthorizerInfo方法即可获取得到,但通常都是已经存储起来的)。WxMpXmlMessageWxJava工具包封装提供。

定义微信应用消息与事件处理器、管理器并配置激活

// 微信第三方平台消息事件处理器
public interface WxAppMsgEventHandler {

    /**
     * 处理事件
     *
     * @param msgMessage 消息事件
     */

    void handle(MsgEventMessage msgMessage);

    /**
     * 事件处理器监听/支持的事件名称
     *
     * @return 监听/支持的事件名称
     */

    String onEvent();

    /**
     * 处理器是否支持处理特定事件
     *
     * @param event 事件名称
     * @return {@code true} 表示支持,{@code false} 表示不支持
     */

    default boolean support(String event) {
        return StringUtils.equalsIgnoreCase(this.onEvent(), event);
    }

}

// 微信第三方小程序/公众号事件管理器
@Slf4j
@AllArgsConstructor
public class WxAppMsgEventManager {

    private final Map<String, WxAppMsgEventHandler> eventHandlerMap;

    public WxAppMsgEventHandler get(String event) {
        return eventHandlerMap.get(event);
    }

}

// 微信第三方小程序/公众号事件管理器配置
@Slf4j
@Configuration
public class WxAppMsgEventManagerConfiguration {

    @Bean
    public WxAppMsgEventManager wxAppMsgEventManager(ObjectProvider<List<WxAppMsgEventHandler>> msgEventHandlerList) {
        List<WxAppMsgEventHandler> handlerList = msgEventHandlerList.getIfAvailable();
        if (CollectionUtils.isEmpty(handlerList)) {
            log.warn("None WxAppMsgEventHandler found! WxAppMsgEventManager.eventHandlerMap is empty");
            return new WxAppMsgEventManager(Collections.emptyMap());
        }
        Map<String, WxAppMsgEventHandler> handlerMap = Maps.newHashMapWithExpectedSize(handlerList.size());
        for (WxAppMsgEventHandler handler : handlerList) {
            String event = handler.onEvent();
            WxAppMsgEventHandler existHandler = handlerMap.get(event);
            if (Objects.nonNull(existHandler)) {
                log.error("Duplicate handler[{}, {}] listen on same event[{}]", existHandler.getClass().getName(), handler.getClass().getName(), event);
            }
            log.info("Append Handler[{}, listen on {}] to handlerMap", handler.getClass().getName(), event);
            handlerMap.put(event, handler);
        }
        return new WxAppMsgEventManager(Collections.unmodifiableMap(handlerMap));
    }

}

    结构与之前的授权事件处理器基本一致,这里不再赘述。

微信应用消息与事件回调

    有了消息与事件管理器,我们只需要在之前的消息与事件接收URL配置项对应地址中进行消息事件分发即可:

    @ApiOperation("微信第三方平台消息与事件推送(公众号和小程序的消息、事件推送)")
    public String handleMsgEvent(@RequestBody String reqBody,
                                 @PathVariable("appId")
 String appId,
                                 @RequestParam(required = false) Map<String, String> reqParam) 
{
        // 1、消息校验(确保消息是微信发过来的而不是伪造的)
        // 2、消息解密
        WxMpXmlMessage wxMessage = WxOpenXmlMessage.fromEncryptedMpXml(reqBody,
                wxOpenService.getWxOpenConfigStorage(), param.getTimestamp(), param.getNonce(), param.getMsgSignature());

        // 3、如果是全网发布接入检测第三方平台的测试用例消息,则以全网发布规范返回相应的消息
        if (StringUtils.equalsAnyIgnoreCase(appId, "wxd101a85aa106f53e""wx570bc396a51b8ff8")) {
        }

        // 4、判断是自己的微信应用,通过消息管理器进行消息处理
        WxAppMsgEventHandler handler = wxAppMsgEventManager.get(event);
        if (Objects.nonNull(handler)) {
            handler.handle(message);
        }
        return "success";
    }

    首先,微信的消息与事件回调参数会通过请求参数和请求体方式传递过来。其中请求参数更多是用于校验签名用途和解密的,数量可增可减,我们通过Map结构可以一次性全部接收,然后根据需要再从中获取;请求体则是加密过的xml信息,我们需要将信息进行解密才能得到真实的回调内容。

    消息解密后,我们需要判断是不是全网发布接入检测时微信触发的,是的话要以微信要求的格式进行消息处理,参考平台型第三方平台全网发布接入检测说明,最后才是我们自己的消息处理。

消息与事件类型与实例

    那么通常都有哪些消息与事件需要我们关注的呢,这里列几个目前我们使用到的消息事件:

  • weapp_audit_success:小程序代码审核通过
  • weapp_audit_fail:小程序代码审核失败
  • weapp_audit_delay:小程序代码审核延期

    这三个消息事件是授权过来的微信小程序代码审核结果通知消息,因为授权过来的小程序将不再能够使用小程序后台进行代码发布与版本管理,因此我们需要自己实现一整套小程序管理后台,实现后有自然就会涉及到小程序的一些发布与管理操作,这里的三个通知消息是目前我们用的最多的,每当有小程序审核出结果后,微信都会直接推送消息到第三方平台,这时候我们再去通知运营人员或者技术人员进行小程序发版(实现类似独立小程序的审核通知效果)。

    这一步通知可以使用短信、邮箱、微信通知、钉钉通知等方式,综合考虑钉钉通知是比较方便的,通过普通的webhook钉钉机器人可以直接将消息推送到群组里,如果有钉钉企业内部机器人,那么可以实现一些简单的交互式操作,比如:小程序审核通过后,先发送钉钉消息到群组,然后相应的负责人通过@机器人直接发布审核通过的小程序,同时通知到所有人,这样既节省了登录运营后台查询审核结果与进行发布的动作,也不再需要再手动通知所有相关人员。

    这里提供小程序审核通过的消息处理器:

@Slf4j
@Service
@AllArgsConstructor
public class WxAppAuditSuccessMsgEventHandler implements WxAppMsgEventHandler {

    public static final String EVENT = "weapp_audit_success";
    private final DingTalkProperties dingTalkProperties;
    private final IMiniProgramAuditService miniProgramAuditService;

    @Override
    public void handle(MsgEventMessage msgMessage) {
        WxMpXmlMessage message = msgMessage.getMessage();
        String appId = msgMessage.getAppId();
        String strMessage = JsonUtil.toJson(message);

        // 发送钉钉通知消息
        String versionDesc = StringUtils.trimToEmpty(miniProgramAuditService.latestAuditingVersionDesc(wxApp.getId()));
        String content = String.format("%sn[广播][广播][广播]小程序『%s』审核通过啦!n赶紧去发布吧。[爱意][爱意]n审核通过时间:%sn本次提审内容:%sn",
                dingTalkProperties.getMsgPrefix(), wxApp.getName(), successTime, versionDesc);
        for (String webHook : dingTalkProperties.getWebHookList()) {
            DingTalkHelper.send(webHook, new DingTalkTextMessage(content).setAt(DingTalkMessageAt.atAll()));
        }
    }

    @Override
    public String onEvent() {
        return EVENT;
    }

}

    具体效果参考下图:

如何开发一个微信第三方平台?(应用篇)
小程序审核通过与钉钉企业机器人交互

    其他的一些消息与事件包括:

  • subscribe:订阅公众号消息
  • unsubscribe:取消订阅公众号消息
  • TEMPLATESENDJOBFINISH:模板下发完成消息
  • wxa_nickname_audit:小程序名称修改审核结果通知(成功或者失败)
  • 其他…

    具体要根据实际微信业务确定是否有相应的消息事件推送,然后进行监听处理。

结束语

    以上就是本篇关于第三方平台复用公众号资质快速注册小程和微信应用消息与事件处理的介绍,其他的一些微信业务(比如:小程序登录、公众号登录、小程序码、小程序管理后台等)都是对微信API的调用,大部分接口都会多个component_appid参数,后面有机会可以讲解一下。


原文始发于微信公众号(三维家技术实践):如何开发一个微信第三方平台?(应用篇)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/30627.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!