参考文档

服务端能力——消息推送:https://developers.weixin.qq.com/miniprogram/dev/framework/server-ability/message-push.html

班纳睿——微信开发包:https://gitee.com/binary/weixin-java-tools
班纳睿——微信开发包——Demo项目:https://gitee.com/binary/weixin-java-tools/blob/master/demo.md
班纳睿——微信开发包——Spring Boot开发Demo项目:https://github.com/binarywang/weixin-java-miniapp-demo

环境说明

Spring Boot 2.1.7

本类Demo只能使用一个appid

使用班纳睿微信开发包开发,版本为:3.5.0

使用说明

在自己的Spring Boot项目里,引入maven依赖

<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
    <version>3.5.0</version>
</dependency>

添加配置(application.yml)

wx:
  miniapp:
    appid: 111
    secret: 111
    token: 111
    aesKey: 111
    msgDataFormat: JSON

配置类

属性映射类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@Data
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxMaProperties {
    /**
     * 设置微信小程序的appid
     */
    private String appid;

    /**
     * 设置微信小程序的Secret
     */
    private String secret;

    /**
     * 设置微信小程序消息服务器配置的token
     */
    private String token;

    /**
     * 设置微信小程序消息服务器配置的EncodingAESKey
     */
    private String aesKey;

    /**
     * 消息格式,XML或者JSON
     */
    private String msgDataFormat;
}

配置类

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.io.File;

/**
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@Configuration
@EnableConfigurationProperties(WxMaProperties.class)
@Slf4j
public class WxMaConfiguration {

    @Autowired
    private WxMaProperties properties;

    private static WxMaMessageRouter routers;
    private static WxMaService maServices;


    public static WxMaService getMaService() {
        WxMaService wxService = maServices;
        if (wxService == null) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", ""));
        }

        return wxService;
    }

    public static WxMaMessageRouter getRouter() {
        return routers;
    }

    /**
     * 初始化微信小程序
     */
    @PostConstruct
    public void init() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(properties.getAppid());
        config.setSecret(properties.getSecret());
        config.setToken(properties.getToken());
        config.setAesKey(properties.getAesKey());
        config.setMsgDataFormat(properties.getMsgDataFormat());
        WxMaService service = new WxMaServiceImpl();
        service.setWxMaConfig(config);
        routers = this.newRouter(service);
        maServices = service;
    }

    private WxMaMessageRouter newRouter(WxMaService service) {
        final WxMaMessageRouter router = new WxMaMessageRouter(service);
        router
                .rule().handler(logHandler).next()
                .rule().async(false).content("模板").handler(templateMsgHandler).end()
                .rule().async(false).content("文本").handler(textHandler).end()
                .rule().async(false).content("图片").handler(picHandler).end()
                .rule().async(false).content("二维码").handler(qrcodeHandler).end();
        return router;
    }

    private final WxMaMessageHandler templateMsgHandler = (wxMessage, context, service, sessionManager) -> {
        service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder()
                .templateId("此处更换为自己的模板id")
                .formId("自己替换可用的formid")
                .data(Lists.newArrayList(
                        new WxMaTemplateData("keyword1", "339208499", "#173177")))
                .toUser(wxMessage.getFromUser())
                .build());
        return null;
    };

    private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {
        System.out.println("收到消息:" + wxMessage.toString());
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson())
                .toUser(wxMessage.getFromUser()).build());
        return null;
    };

    private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
                .toUser(wxMessage.getFromUser()).build());
        return null;
    };

    private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {
        try {
            WxMediaUploadResult uploadResult = service.getMediaService()
                    .uploadMedia("image", "png",
                            ClassLoader.getSystemResourceAsStream("tmp.png"));
            service.getMsgService().sendKefuMsg(
                    WxMaKefuMessage
                            .newImageBuilder()
                            .mediaId(uploadResult.getMediaId())
                            .toUser(wxMessage.getFromUser())
                            .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        return null;
    };

    private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {
        try {
            final File file = service.getQrcodeService().createQrcode("123", 430);
            WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
            service.getMsgService().sendKefuMsg(
                    WxMaKefuMessage
                            .newImageBuilder()
                            .mediaId(uploadResult.getMediaId())
                            .toUser(wxMessage.getFromUser())
                            .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        return null;
    };

}

客服消息使用Demo

“/wxmini/portal/receive”Get 请求是认证的方法

“/wxmini/portal/receive”POST 请求是接收微信客服的请求,并执行操作的方法

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import com.anchi.car.coresystem.consumer.config.wxmini.WxMaConfiguration;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;

/**
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@RestController
@Slf4j
public class WxPortalController {

    /**
     * 微信认证接口
     */
    @GetMapping(value = "/wxmini/portal/receive", produces = "text/plain;charset=utf-8")
    public void authGet(@RequestParam(name = "signature", required = false) String signature,
                        @RequestParam(name = "timestamp", required = false) String timestamp,
                        @RequestParam(name = "nonce", required = false) String nonce,
                        @RequestParam(name = "echostr", required = false) String echostr,
                        HttpServletResponse response) {
        log.info("\n接收到来自微信服务器的认证消息:signature = [{}], timestamp = [{}], nonce = [{}], echostr = [{}]",
                signature, timestamp, nonce, echostr);

        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法,请核实!");
        }

        final WxMaService wxService = WxMaConfiguration.getMaService();
        if (wxService.checkSignature(timestamp, nonce, signature)) {
            // Spring Boot框架会在返回的echostr参数上添加双引号,所以,在此使用原生的返回避免这个问题。
            BufferedOutputStream out;
            try {
                out = new BufferedOutputStream(response.getOutputStream());
                out.write(echostr.getBytes());
                out.flush();
                out.close();
            } catch (IOException e) {
                log.error("receive is error", e);
            }
        }
    }

    /**
     * 接收微信客服的请求,并执行操作
     */
    @PostMapping(value = "/wxmini/portal/receive", produces = "application/xml; charset=UTF-8")
    public String post(@RequestBody String requestBody,
                       @RequestParam(name = "msg_signature", required = false) String msgSignature,
                       @RequestParam(name = "encrypt_type", required = false) String encryptType,
                       @RequestParam(name = "signature", required = false) String signature,
                       @RequestParam("timestamp") String timestamp,
                       @RequestParam("nonce") String nonce) throws WxErrorException {
        log.info("\n接收微信请求:[msg_signature=[{}], encrypt_type=[{}], signature=[{}]," +
                        " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
                msgSignature, encryptType, signature, timestamp, nonce, requestBody);
        final WxMaService wxService = WxMaConfiguration.getMaService();
        // 解析返回的信息
        final WxMaMessage inMessage = WxMaMessage.fromEncryptedJson(requestBody, wxService.getWxMaConfig());
        // 发送文字
        wxService.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder()
                .content("Hi 欢迎您使用本产品~")
                .toUser(inMessage.getFromUser())
                .build());
        // 发送链接
        wxService.getMsgService().sendKefuMsg(WxMaKefuMessage.newLinkBuilder()
                .title("点击本链接后开始下载")
                .description("本产品,您的放心之选")
                .thumbUrl("http://wordstorage.cookids.com.cn/logo.png")
                .url("https://www.baidu.com")
                .toUser(inMessage.getFromUser())
                .build());
        return "success";
    }

}