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

这篇具有很好参考价值的文章主要介绍了Java实现公众号功能、关注、消息推送。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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对象
     */
	@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;
    }
 }

公众号各事件处理

实现公众号事件处理类

/**
 * 微信公众号AbstractHandler
 */
public abstract class AbstractHandler implements WxMpMessageHandler {
    protected Logger logger = LoggerFactory.getLogger(getClass());
}

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

/**
 * 微信公众号日志记录处理器
 */
@Component
public 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
@RequiredArgsConstructor
public 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
@RequiredArgsConstructor
public 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
@RequiredArgsConstructor
public 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
@Component
public class MpMsgPush {
	//微信的公众号推送处理类
    private final WxMpService wxMpAgentService;
    //数据库公众号模板消息表
    private final MpTemplateManage mpTemplateManage;

 	/**
     * 发送微信模板信息
     *
     * @param mpPushDTO 推送信息实体类
     * @return 是否推送成功
     */
    @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;
    }
    
	/**
     * 获取提醒模板
     *
     * @param mpPushDTO
     * @return
     */
    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://www.toymoban.com/news/detail-715294.html

到了这里,关于Java实现公众号功能、关注、消息推送的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信公众号配置 Token 认证以及消息推送功能

    🔭 嗨,您好 👋 我是 vnjohn,在互联网企业担任 Java 开发,CSDN 优质创作者 📖 推荐专栏:Spring、MySQL、Nacos、Java,后续其他专栏会持续优化更新迭代 🌲文章所在专栏:业务设计 🤔 我当前正在学习微服务领域、云原生领域、消息中间件等架构、原理知识 💬 向我询问任何您

    2024年02月09日
    浏览(35)
  • uni-app中实现微信小程序/公众号订阅消息推送功能

    👨🏻‍💻 热爱摄影的程序员 👨🏻‍🎨 喜欢编码的设计师 🧕🏻 擅长设计的剪辑师 🧑🏻‍🏫 一位高冷无情的编码爱好者 大家好,我是全栈 IT 工程师摘星人 欢迎分享 / 收藏 / 赞 / 在看! 开发业务时时常遇到需要向用户发送一些通知,如欠费通知、会员到期通知等等。

    2024年02月02日
    浏览(80)
  • 【Java项目】SpringBoot项目完成微信公众号收到用户消息自动回复功能附带视频(超详细)

    视频讲解 首先你需要先注册一个你的微信公众号 微信公众号平台 然后打开下面的自动回复功能 之后进入到你的开发者中心 开发者中心基本配置 然后生成你的开发者密码,开发者id,以及设置你的IP白名单。 这里的IP白名单中的IP必须是一个公网IP,因为微信官方会把他们的

    2024年02月13日
    浏览(35)
  • 微信公众号模板消息源码实现,打破服务号群发推送次数限制

    公众号服务号每个月只能群发推送四次文章,我们可以使用模板消息为公众号粉丝推送信息 下面是使用golang实现的模板消息发送类库封装,轻松实现模板消息发送 wechat.go 我们的使用方式 推送的效果如图所示,点击模板就能跳转到我们自定义的url上 我在自己客服系统中也是

    2024年02月15日
    浏览(32)
  • spring boot +微信小程序项目,通过微信公众号实现指定用户消息长期推送

    用户登录小程序,后台记录用户的小程序openId和用户唯一的UnionId。然后用户触发公众号事件(关注公众号或者发送指定消息),后台获取到用户公众号的openId,再调用接口通过公众号的openId查询用户的UnionId,再和数据库里的UnionId进行匹配,将用户的公众号openId存入数据库。此

    2024年02月03日
    浏览(36)
  • Java代码 微信公众号推送(代码详细)

    用的是idea, 需要修改的地方在于这些地方改了     然后吧账号密码填写进去就好了  运行类是   Yi   这个类 非常简单 祝大家成功 ,不会的关注私聊   微信公众号测试注册地址:微信公众平台 (qq.com)  我用的模板是这个只有一个数据 ,当然这个可以自己添加  做出来的效果

    2024年02月12日
    浏览(34)
  • 微信小程序生态8-基于weixin-java-mp实现微信公众号被动回复消息

    微信小程序生态1-初识小程序 微信小程序生态2-创建一个微信小程序 微信小程序生态3-微信小程序登录流程设计 微信小程序生态4-扫普通二维码进入小程序、打开短链接进入小程序 微信小程序生态5-微信公众号扫码登录PC端网页 微信小程序生态6-微信公众号授权登录(适用于H

    2024年02月10日
    浏览(33)
  • 微信公众号推送模板消息给用户

    前置条件: 1.公众号为服务号,而非订阅号 2.认证(300元) 3.进入公众号申请模板推送功能 4.添加模板(注意:推送的消息只能使用微信提供的模板,不可自定义,但也是比较全的) 4.2 获取accessToken时,需要将开发环境的电脑ip添加到微信后台的ip白名单(线上环境亦是如此

    2024年02月12日
    浏览(47)
  • 微信公众号推送天气教程,自动定时推送【Java版】开发者和小白详细教程

    久违的大更新: 建议先打开,因为GitHub在国内加载很慢。 点击打开 Java版本,教程最近一次更新时间为: 2023-08-23 重大更新: 1: 谚语功能修复。 2: 新增农历生日。 已经部署的伙伴,务必在公众号后台更新新的模块以及applicantion.yml配置文件中的模板ID,新的模板在本教程当中

    2024年01月23日
    浏览(45)
  • 微信小程序向公众号推送消息模板

    由于微信小程序长期订阅的消息模板全部失效以后,对于小程序的消息推送可以改成往公众号推。 这里将介绍如何使用小程序向公众号推送消息,并且消息可以跳转到小程序 1、微信公众平台注册 服务号 (订阅号是不可以推送的)与小程序,两者都需要认证并且 认证主体是

    2024年02月06日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包