文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java实现公众号功能、关注、消息推送

2023-10-20 07:51

关注

Java实现公众号功能开发

文章目录

描述

 使用Java实现公众号功能的接入,配合业务实现: 用户关注、取消关注、推送数据服务、用户在公众号信息转发人工服务等功能 本文章说明公众号代码配置实现,公众号申请,注册方式,自行查看官网说明

引入依赖

<!--微信公众号(包括订阅号和服务号)-->        <dependency>            <groupId>com.github.binarywang</groupId>            <artifactId>weixin-java-mp</artifactId>            <version>4.4.2.B</version>        </dependency>

注册公众号配置

@Slf4j@Configuration@RequiredArgsConstructor@ConditionalOnClass(WxMpService.class)@EnableConfigurationProperties()public class WxMpConfiguration {    private final MpConfigMapper mpConfigMapper;    private final LogHandler logHandler;    private final SubscribeHandler subscribeHandler;    private final UnsubscribeHandler unsubscribeHandler;    private final TextMsgHandler textMsgHandler;        private static Map<String, Integer> MP_USER_CONF = new HashMap<>();    public static Long getCustomId(String appid) {        return Long.valueOf(MP_USER_CONF.getOrDefault(appid, 0));    }    @Bean    public WxMpService wxMpService() {    //这个是数据库公众号信息配置表        List<MpConfig> mpConfigs = mpConfigMapper.selectList(Wrappers.emptyWrapper());        if (CollectionUtil.isEmpty(mpConfigs)) {            log.error("读取配置为空,公众号配置类加载失败!");            return new WxMpServiceImpl();        }        log.info("公众号的配置:{}", JSON.toJSONString(mpConfigs));        Map<String, WxMpConfigStorage> multiConfigStorages = new HashMap<>(16);        for (MpConfig mpConfig : mpConfigs) {            WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();            configStorage.setAppId(mpConfig.getAppid());            configStorage.setSecret(mpConfig.getSecret());            configStorage.setToken(mpConfig.getToken());            configStorage.setAesKey(mpConfig.getAeskey());            multiConfigStorages.put(mpConfig.getCustomerCode(), configStorage);            MP_USER_CONF.put(mpConfig.getAppid(), mpConfig.getCustomerId());        }        WxMpService mpService = new WxMpServiceImpl();        mpService.setMultiConfigStorages(multiConfigStorages);        return mpService;    }             @Bean    public WxMpMessageRouter messageRouter(WxMpService wxMpService) {        final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);        // 记录所有事件的日志 (异步执行)        newRouter.rule().handler(this.logHandler).next();        // 关注事件        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).                event(WxConsts.EventType.SUBSCRIBE).handler(this.subscribeHandler).end();        //取消关注事件        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT). event(WxConsts.EventType.UNSUBSCRIBE).handler(this.unsubscribeHandler).end(); //用户往公众号发送消息事件处理        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.TEXT).                handler(this.textMsgHandler).end();        return newRouter;    } }

公众号各事件处理

实现公众号事件处理类

public abstract class AbstractHandler implements WxMpMessageHandler {    protected Logger logger = LoggerFactory.getLogger(getClass());}

实现公众号日志记录处理器

@Componentpublic class LogHandler extends AbstractHandler {    @Override    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,        Map<String, Object> context, WxMpService wxMpService,        WxSessionManager sessionManager) {        this.logger.info("【公众号】-记录请求日志,内容:{}", JSON.toJSONString(wxMessage));        return null;    }}

实现公众号用户关注处理器

@Component@RequiredArgsConstructorpublic class SubscribeHandler extends AbstractHandler {//公众号用户表    private final MpUserParentMapper mpUserParentMapper;    //小程序用户表(一般公众号和小程序配套使用)    private final MiniappUserParentMapper miniappUserParentMapper;    //公众号配置表    private final MpConfigMapper mpConfigMapper;@Override    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,        Map<String, Object> context, WxMpService wxMpService,        WxSessionManager sessionManager) throws WxErrorException {        this.logger.info("【公众号-关注功能】-新关注用户 OPENID: " + wxMessage.getFromUser());        // 获取微信用户基本信息        try {            WxMpUser userWxInfo = wxMpService.getUserService()                    .userInfo(wxMessage.getFromUser(), null);            String appId = wxMpService.getWxMpConfigStorage().getAppId();            Long customerId = WxMpConfiguration.getCustomId(appId);            logger.info("userWxInfo:{}", userWxInfo);            if (userWxInfo != null) {            //查询数据库,公众号用户表,是否有这个用户                MpUserParent existMpUser = mpUserParentMapper.selectOneByOpenId(userWxInfo.getOpenId());                //不存在则新增一条公众号用户记录                if (existMpUser == null) {                    MpUserParent mpUser = new MpUserParent();                    mpUser.setOpenId(userWxInfo.getOpenId());                    mpUser.setUnionId(userWxInfo.getUnionId());                    mpUser.setAvatarUrl(userWxInfo.getHeadImgUrl());                    mpUser.setNickName(userWxInfo.getNickname());                    mpUser.setCustomerId(customerId);                    mpUserParentMapper.insert(mpUser);                    //检测是否有跟小程序账号关联                    MiniappUserParent maUserParent = miniappUserParentMapper.selectOneByUnionId(mpUser.getUnionId(), customerId);                    if (maUserParent != null && StringUtil.isBlank(maUserParent.getMpOpenId())) {                        maUserParent.setMpOpenId(mpUser.getOpenId());                        maUserParent.setUpdateTime(new Date());                        miniappUserParentMapper.updateById(maUserParent);                        this.logger.info("【公众号-关注功能】-公众号账号和小程序绑定成功!unionId:{},mpOpenId:{} ", mpUser.getUnionId(), mpUser.getOpenId());                    }                } else {                    //之前有关注过的,无需重复写入,更改关注状态即可                    MpUserParent updateUser = new MpUserParent();                    updateUser.setMpId(existMpUser.getMpId());                    updateUser.setFollowStatus(1);                    updateUser.setUpdateTime(new Date());                    updateUser.setCustomerId(customerId);                    updateUser.setUnionId(userWxInfo.getUnionId());                    mpUserParentMapper.updateById(updateUser);                }}        } catch (WxErrorException e) {            if (e.getError().getErrorCode() == 48001) {                this.logger.error("【公众号-关注功能】-该公众号没有获取用户信息权限!");            }            logger.error("【公众号-关注功能异常】-异常信息:{}", e);        }WxMpXmlOutMessage responseResult = null;        try {            responseResult = this.handleSpecial(wxMessage);        } catch (Exception e) {            this.logger.error(e.getMessage(), e);        }        if (responseResult != null) {            return responseResult;        }        String appId = wxMpService.getWxMpConfigStorage().getAppId();        try {            logger.info("获取公众号appid:{}", appId);            MpConfig miniappConfig = mpConfigMapper.selectByAppid(appId);            //关注公众号,发送消息给用户            return new TextBuilder().build("感谢关注,将持续为您推送信息", wxMessage, wxMpService);        } catch (Exception e) {            this.logger.error(e.getMessage(), e);        }return null;    }            private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage) throws Exception {        //TODO        return null;    }}

实现公众号用户取消关注处理器

@Component@RequiredArgsConstructorpublic class UnsubscribeHandler extends AbstractHandler {    private final MpUserParentMapper mpUserParentMapper;    private final MpConfigMapper mpConfigMapper;@Override    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,        Map<String, Object> context, WxMpService wxMpService,        WxSessionManager sessionManager) {        String openId = wxMessage.getFromUser();        this.logger.info("取消关注用户 OPENID: " + openId);        //更新关注状态为取消关注状态        UpdateWrapper<MpUserParent> updateWrapper = new UpdateWrapper();        updateWrapper.eq("openId", openId);        updateWrapper.eq("followStatus", 1);        MpUserParent updateMpUser = new MpUserParent();        updateMpUser.setFollowStatus(2);        //不删除公众号用户信息,修改关注状态值即可        mpUserParentMapper.update(updateMpUser, updateWrapper);        String appId = wxMpService.getWxMpConfigStorage().getAppId();        logger.info("获取公众号appid:{}",appId);        MpConfig miniappConfig = mpConfigMapper.selectByAppid(appId);        //取消关注,发送信息给用户        return new TextBuilder().build("已退订", wxMessage, wxMpService);    }}

实现公众号用户发送消息处理器

@Slf4j@Component@RequiredArgsConstructorpublic class TextMsgHandler extends AbstractHandler {    private final static Integer TEXT_TYPE = 1;    @Override    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService, WxSessionManager sessionManager) throws WxErrorException {        String content = wxMessage.getContent();        log.info("【公众号-消息】-用户:{} , 发送消息:{}, ", wxMessage.getFromUser(), content);        // 获取微信用户基本信息        try {            String appId = wxMpService.getWxMpConfigStorage().getAppId();            Long customerId = WxMpConfiguration.getCustomId(appId);            //自动回复匹配的关键字            MpAutoReplyDTO autoReply = InitConfDataUtil.getAutoReply(customerId, content);            if (autoReply != null) {                Integer replyType = autoReply.getReplyType();                String reply = autoReply.getReply();                if (TEXT_TYPE.equals(replyType)) {                //文字处理                    return new TextBuilder().build(reply, wxMessage, wxMpService);                } else {                //图片处理                    return new ImageBuilder().build(reply, wxMessage, wxMpService);                }            } else {                //自动回复没有匹配的就转到人工                WxMpXmlOutMessage build = new TextBuilder().build(wxMessage.getContent(), wxMessage, wxMpService);                //msgType设置固定值就转到人工:transfer_customer_service                build.setMsgType("transfer_customer_service");                return build;            }        } catch (Exception e) {            log.info("回复失败e:{}", e);        }        return null;    }}

用户消息事件分类处理Builder

定义处理抽象类
//该类定义处理标准,后续根据业务自行扩展public abstract class AbstractBuilder {    protected final Logger logger = LoggerFactory.getLogger(getClass());    public abstract WxMpXmlOutMessage build(String content,                WxMpXmlMessage wxMessage, WxMpService service);}
实现处理抽象类–子类–文本消息
public class TextBuilder extends AbstractBuilder {    @Override    public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,       WxMpService service) {        return WxMpXmlOutMessage.TEXT().content(content)                .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())                .build();    }}
实现处理抽象类–子类–图片消息
public class ImageBuilder extends AbstractBuilder {    @Override    public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,       WxMpService service) {        return WxMpXmlOutMessage.IMAGE().mediaId(content)                .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())                .build();    }}

公众号模板消息推送

以上实现了Java整合公众号,后续业务扩展,需要往关注公众号的用户进行相关的消息推送,消息推送前,需要在微信公众号申请推送模板,拿到对应的模板ID,这个有用,生成推送消息时,需要往模板填充信息,如何申请公众号模板,自行参考下官网说明
@Slf4j@RequiredArgsConstructor@Componentpublic class MpMsgPush {//微信的公众号推送处理类    private final WxMpService wxMpAgentService;    //数据库公众号模板消息表    private final MpTemplateManage mpTemplateManage;     @Async    public Boolean sendTemplateMsg(MpPushDTO mpPushDTO) {        log.info("【公众号告警模板信息推送】-推送信息:{}", JSONObject.toJSONString(mpPushDTO));        Long customerId = mpPushDTO.getCustomerId();        String name = mpPushDTO.getMpName();        //选择往哪个公众号发送模板消息,这个上面注册公众号的Bean的时候已经注入        WxMpService wxMpService = wxMpAgentService.switchoverTo(mpPushDTO.getCustomerCode());        //自己搞的一个枚举,根据当前的消息实体类信息,来判断使用哪个模板ID        String templateId = TemplateConfConstant.getWXTemplateConf(customerId, mpPushTypeEnum.getValue());        // 获取模板消息接口        WxMpTemplateMessage templateMessage = mpTemplateManage.getWarnTemplate(mpPushDTO, templateId, name);        if (templateMessage != null) {            log.info("发送消息:{}", JSONObject.toJSONString(templateMessage));        } else {            log.error("获取消息模板为空!");            return false;        }        String msgId = null;        try {            Long parentId = mpPushDTO.getParentId();            String imeiNo = mpPushDTO.getImeiNo();            // 发送模板消息            msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);        } catch (Exception e) {            log.error("【公众号模板信息推送】-推送失败,异常信息:", e);        }        log.warn("·==++--·推送公众号模板信息:{}·--++==·", msgId != null ? "成功" : "失败");        return msgId != null;    }        public WxMpTemplateMessage getWarnTemplate(MpPushDTO mpPushDTO, String templateId, String name) {        // 发送模板消息接口        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()                // 接收者openid                .toUser(mpPushDTO.getOpenId())                // 模板id                .templateId(templateId)                .build();        StringBuilder keyword1 = new StringBuilder();        keyword1.append(mpPushDTO.getStudentName()).                append("(").append(mpPushDTO.getImeiNo()).append(")");        // 添加模板数据        templateMessage.addData(new WxMpTemplateData("first", "您好,你有一条新的提醒"))                .addData(new WxMpTemplateData("keyword1", keyword1.toString()))                .addData(new WxMpTemplateData("keyword2", mpPushDTO.getTemplateType()))                .addData(new WxMpTemplateData("remark", name + "智能推送系统"));        return templateMessage;    }}

来源地址:https://blog.csdn.net/weixin_41451078/article/details/129818448

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯