微信小程序订阅消息-java服务端整合mq实现订阅消息延时发送

微信小程序订阅消息官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html

本文通过java代码整合小程序接口和rabbitMq,实现订阅消息延时发送。

一,微信小程序开发相关接口

(1)推荐一个小程序插件jar:

<dependency>
     <groupId>com.github.binarywang</groupId>
     <artifactId>weixin-java-miniapp</artifactId>
     <version>3.6.0</version>
</dependency>

(2)yml配置文件信息中添加小程序配置信息

wx:
  miniapp:
    appid: 小程序appid
    secret: 小程序secret
    msgDataFormat: JSON

(3)添加配置类properties

@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;
}

(4)添加对应的config 加载初始化小程序配置信息

@AllArgsConstructor
@Configuration
@ConditionalOnClass(WxMaService.class)
@EnableConfigurationProperties(WxMaProperties.class)
@ConditionalOnProperty(prefix = "wx.miniapp", value = "enabled", matchIfMissing = true)
public class WxMaAutoConfiguration {
    private WxMaProperties properties;

    /**
     * 小程序service.
     *
     * @return 小程序service
     */
    @Bean
    @ConditionalOnMissingBean(WxMaService.class)
    public WxMaService service() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(StringUtils.trimToNull(this.properties.getAppid()));
        config.setSecret(StringUtils.trimToNull(this.properties.getSecret()));
        config.setToken(StringUtils.trimToNull(this.properties.getToken()));
        config.setAesKey(StringUtils.trimToNull(this.properties.getAesKey()));
        config.setMsgDataFormat(StringUtils.trimToNull(this.properties.getMsgDataFormat()));
        final WxMaServiceImpl service = new WxMaServiceImpl();
        service.setWxMaConfig(config);
        return service;
    }

}

二,添加rabbitMq相关接口

实现延时消息发送需要安装mq延时插件 官网下载地址:https://www.rabbitmq.com/community-plugins.html

(1)添加mq jar

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

(2) yml 中配置mq

queue:
  subscribeMsg-delayExchange: com.chunmi.subscribeMsg.delayExchange.local
  subscribeMsg-delayQueue: com.chunmi.subscribeMsg.delayQueue.local
  subscribeMsg-delayRoutingKey: com.chunmi.subscribeMsg.delayRoutingKey.local

(3) 添加配置类

@Configuration
public class DelayMqConfig {

    @Value("${queue.subscribeMsg-delayExchange}")
    public String delayExchange;

    @Value("${queue.subscribeMsg-delayQueue}")
    public String delayQueue;

    @Value("${queue.subscribeMsg-delayRoutingKey}")
    public String delayRoutingKey;

    @Bean
    public CustomExchange delayExchange() {
        Map<String, Object> args = new HashMap<>(16);
        args.put("x-delayed-type", "direct");
        return new CustomExchange(delayExchange, "x-delayed-message", true, false, args);
    }

    @Bean
    public Queue queue() {
        return new Queue(delayQueue, true);
    }

    @Bean
    public Binding binding(Queue queue, CustomExchange delayExchange) {
        return BindingBuilder.bind(queue).to(delayExchange).with(delayRoutingKey).noargs();
    }

}

(4)添加发送消息类

@Slf4j
@Component
public class MsgPublishService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value("${queue.subscribeMsg-delayExchange}")
    public String delayExchange;

    @Value("${queue.subscribeMsg-delayRoutingKey}")
    public String delayRoutingKey;

    public void sendSubscribeMsg(String str, long delayTimes) {
        try {
            rabbitTemplate.convertAndSend(delayExchange, delayRoutingKey, str, new MessagePostProcessor() {
                @Override
                public Message postProcessMessage(Message message) throws AmqpException {
                    message.getMessageProperties().setHeader("x-delay", delayTimes);
                    return message;
                }
            });
        } catch (Exception e) {
            log.error("发送订阅消息出错:{}", e.getMessage());
            e.printStackTrace();
        }
    }
}

(5)到这里基本配置信息已经搭建完成,在需要发送订阅消息的接口中封装信息 例如订单未支付给用户发送消息

private void sendSubscrbeMsg(Order order) {
        try {
            TemplateVo templateVo = new TemplateVo();
            templateVo.setToUser("用户openid");
            Map<String, String> map = new HashMap<>(16);
            templateVo.setTemplateId("模板TemplateId");
            templateVo.setPage("消息卡片点击跳转的地址");
            //封装data 注意map 的key 和微信公众服务配置信息一致
            map.put("character_string1", order.getOrderNo());
            //联系人名称
            map.put("amount2", order.getTotalFee().toString());
            //订单金额
            map.put("thing3", "您有一笔等支付的订单,点击查看详情。");
            templateVo.setDataMap(map);
            //延时十分钟发送订阅消息
            msgPublishService.sendSubscribeMsg(JSON.toJSONString(templateVo), 10 * 60 * 1000);
           
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

模板信息类:
@Data
public class TemplateVo implements Serializable {

   private static final long serialVersionUID = -1L;

   @ApiModelProperty("订阅模板id")
   private String templateId;

   @ApiModelProperty("接收者用户的openid")
   private String toUser;

   @ApiModelProperty("点击模板卡片后的跳转页面")
   private String page;

   @ApiModelProperty("模板内容")
   private Map<String, String> dataMap;

}

三:在mq服务处理生产者发送的消息

@Slf4j
@Service
public class SubscribeMsgConsumer {

    @Autowired
    private WxMaService wxService;

    @RabbitListener(queues = {"${queue.subscribeMsg-delayQueue}"})
    public void processMsg(String jsonStr) {
        log.info("接收订阅 时间:{},消息内容:{}", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"), jsonStr);
        TemplateVo templateVo = JSONObject.parseObject(jsonStr, TemplateVo.class);
        WxMaSubscribeMessage subscribeMessage = new WxMaSubscribeMessage();
        subscribeMessage.setPage(templateVo.getPage());
        subscribeMessage.setTemplateId(templateVo.getTemplateId());
        subscribeMessage.setToUser(templateVo.getToUser());
        List<WxMaSubscribeData> wxMaSubscribeDataList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(templateVo.getDataMap())) {
            templateVo.getDataMap().forEach((k, v) -> {
                WxMaSubscribeData data = new WxMaSubscribeData();
                data.setName(k);
                data.setValue(v);
                wxMaSubscribeDataList.add(data);
            });
        }
        subscribeMessage.setData(wxMaSubscribeDataList);
        try {
            wxService.getMsgService().sendSubscribeMsg(subscribeMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
原文地址:https://www.cnblogs.com/wlong-blog/p/15256257.html