一、订阅消息流程

微信订阅号接入ChatGPT 订阅号消息微信_前端

注意:目前微信这边只支持一次性订阅,就是同意几次发送几次,永久性订阅目前只支持一些政府,医疗等行业。所以我们做不到一次订阅就可以一直发消息,需要每次订阅发一次。

但是前端支持一次订阅三个不同的模板id,这样就可以做到一次订阅可以发三次(不同模板id的消息)消息。

所以这个订阅消息,对于后端来说就只是调用微信的接口,发送消息就可以了,重点还是在前端去考虑如何在合适的地点去吊起弹窗,去上用户进行授权。

二、获取模板id

首先登录微信公众平台,作为开发者,你可以去选取订阅的模板,也可以去自己创建模板,但是自己创建的模板一个月只有十次机会,并且你创建了,微信这边给你审核,一般审核时间在3-7天,并且审核失败你需要重新提交审核,这也会消耗你的每月十次机会的。

微信订阅号接入ChatGPT 订阅号消息微信_微信_02

选中一个订阅模板,进入编辑

微信订阅号接入ChatGPT 订阅号消息微信_后端_03

选中之后再我的模板

微信订阅号接入ChatGPT 订阅号消息微信_微信_04

点击详情

微信订阅号接入ChatGPT 订阅号消息微信_微信订阅号接入ChatGPT_05

注意这个详细内容很重要。

三、代码展示

1. 导入微信小程序包依赖(pom中配置)
<!--微信小程序工具包-->
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-miniapp</artifactId>
            <version>4.0.0</version>
        </dependency>
2.配置微信的必要参数(yml文件中配置)
wx:
    miniapp:
        app-id: wxba11af1453cscs
        app-secret: f86410070e07cscscsc

这些参数很重要,都可以在微信公众平台找到

微信订阅号接入ChatGPT 订阅号消息微信_后端_06

3.微信配置

  1. 属性配置
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxProperties {

    /**
     * 设置微信小程序的appid.
     */
    private String appId;

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


}
  1. 将微信小程序注入到spring中
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@AllArgsConstructor
public class WxConfig {

    private final WxProperties properties;


    /**
     * 小程序service配置
     */
    @Bean
    public WxMaService wxMaService() {
        WxMaDefaultConfigImpl wxMaConfig = new WxMaDefaultConfigImpl();
        wxMaConfig.setAppid(this.properties.getAppId());
        wxMaConfig.setSecret(this.properties.getAppSecret());
        WxMaService wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(wxMaConfig);
        return wxMaService;
    }



}

4.获得微信的openid

@Slf4j  // 这个是为了记录log的,写在类的最前方

private final WxMaService wxMaService;

      /**
     *  获得微信openid
     * @param code 前端给的微信code
     * @return openid
     */
    public String wxLogin(String code) {

        try {
            WxMaUserService wxMaUserService = wxMaService.getUserService();
            WxMaJscode2SessionResult sessionInfo = wxMaUserService.getSessionInfo(code);
            String openid = sessionInfo.getOpenid();
            return openid;
        } catch (WxErrorException e) {
            log.error("微信授权异常: 错误码:{}, 错误码描述:{}",
                    e.getError().getErrorCode(), e.getError().getErrorMsg());
            //出现异常直接抛出异常,这是自己自定义的异常,需要修改成自己项目定义的,或者直接在后面return null;
            throw new ApiErrorException(ErrorCode.WX_CODE_EXPIRED);
            
        }

    }
5.处理订阅消息的主体

微信订阅号接入ChatGPT 订阅号消息微信_后端_07

/**
     * 设置会议订阅消息
     *
     * @param form 消息条件
     * @return 订阅会议消息
     */
    public static List<WxMaSubscribeMessage.Data> setMeetingMsg (MeetingMsgForm form) {

        List<WxMaSubscribeMessage.Data> dataList = new ArrayList<>();
        //这里要完全按照订阅消息模板详情去设置,thing1 ,thing2...不能变
        WxMaSubscribeMessage.Data data1 = new WxMaSubscribeMessage.Data();
        data1.setName("thing1");
        data1.setValue(form.getTitle());
        dataList.add(data1);
        WxMaSubscribeMessage.Data data2 = new WxMaSubscribeMessage.Data();
        data2.setName("date2");
        DateTime time = DateUtil.parse(form.getDate(), "yyy-MM-dd HH:mm");
        data2.setValue(time.toString("yyy-MM-dd HH:mm"));
        dataList.add(data2);
        WxMaSubscribeMessage.Data data3 = new WxMaSubscribeMessage.Data();
        data3.setName("thing3");
        data3.setValue(form.getMeetingName());
        dataList.add(data3);
        return dataList;
    }
import lombok.Data;


@Data
public class MeetingMsgForm {

    /**
     * 会议名称
     */
    private String title;

    /**
     * 会议日期
     */
    private String date;

    /**
     * 会议备注
     */
    private String content;
}
6.业务处理,发送订阅消息
@Slf4j  // 这个是为了记录log的,写在类的最前方

/**
     * 根据模板id发送消息
     *
     * @param form       消息主体
     * @param userOpenIds   用户的openid列表
     * @param templateId 模板id
     */
    private void sendWxMsg(MeetingMsgForm form, Long recordId, List<String> userOpenIds) {

        for (String openId : userOpenIds) {

            WxMaSubscribeMessage.WxMaSubscribeMessageBuilder builder = WxMaSubscribeMessage.builder();
            //发送人openid
            builder.toUser(openId);
            //发送的模板id
            builder.templateId(templateId);
            //消息主体
            builder.data(GetMsgUtil.setMeetingMsg(form));
            //点击订阅消息的跳转链接(默认是正式发布的小程序页面,当然也可以通过参数进行控制)
            builder.page("/cs/cs");
            WxMaSubscribeMessage msg = builder.build();
            try {
                wxMaService.getMsgService().sendSubscribeMsg(msg);
            } catch (WxErrorException e) {
                log.error("会议通知发送失败,用户openId:{}, 错误码:{},错误信息:{}",
                        openId, e.getError().getErrorCode(), e.getError().getErrorMsg());
            }
        }
    }

四、总结

发送订阅消息主要是一次性订阅,我们后端可以无限次数的请求微信的服务器,但是微信服务器会根据用户是否授权,以及授权了几次去进行发送,所以这里最容易出的问题就是发送了消息,但是提示报错为用户未授权。

如果做这个订阅消息,一定和需求的制定者说清楚,目前不支持永久性订阅,只能是订阅一次发送一次。需要前端去设置在那里弹起订阅。