序言
由于微信小程序長期訂閱的消息模板和下發(fā)統(tǒng)一消息推送接口全部失效以后,對于小程序的消息推送可以往公眾號推可以使用本文章方案。在網(wǎng)上看了挺多方案,有用用戶列表做匹配的等,最終覺得通過關(guān)注事件觸發(fā)的方案是最省事。
準(zhǔn)備
1、微信公眾平臺注冊服務(wù)號(訂閱號是不可以推送的)與小程序,兩者都需要認證并且認證主體是一致
2、微信開放平臺注冊賬號(該賬號也需要認證),綁定小程序與公眾號
3、公眾號根據(jù)想要的模板消息綁定服務(wù)類目,去模板消息中先挑選你的模板消息。(如果是剛注冊的公眾號還需要去新的功能頁面添加模板消息功能,需要微信審核,不過很快)
4、微信公眾號綁定小程序
5、小程序與公眾號配置服務(wù)器的ip地址白名單
6、公眾號配置服務(wù)器地址
整體實現(xiàn)流程
通過在開放平臺綁定的公眾號與小程序后,我們在調(diào)用微信code2Session接口的時候會返回unionid,這個unionid就是推送的關(guān)鍵。文章來源:http://www.zghlxwxcb.cn/news/detail-763903.html
-
用到微信接口:
1、關(guān)注事件推送:用關(guān)注事件推送接口文檔地址
2、查詢用戶基礎(chǔ)信息:用戶基礎(chǔ)信息接口文檔地址
3、獲取accessToken:獲取accessToken接口文檔地址
4、消息模板推送:消息模板推送接口文檔地址
實現(xiàn)代碼(Java)
這里使用第三方工具包Wx-Java(非常方便),直接實現(xiàn)推送代碼。具體源碼可以瀏覽https://gitee.com/binary/weixin-java-tools文章來源地址http://www.zghlxwxcb.cn/news/detail-763903.html
- 先在配置文件yml配置公眾號信息
# 公眾號配置
wx:
mp:
appId: xiaochengxuappid
secret: xiaochengxusecrect
token: xiaochengxutoken
aesKey: xiaochengxuaes
# token存儲在redis
config-storage:
type: RedisTemplate
- 封裝推送工具類
/**
* 微信公眾號推送模板消息
*
* @param openid 用戶openid
* @param templateData 模板參數(shù)
*/
public void sendTemplateMsg(String openid, List<WxMpTemplateData> templateData) {
WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
.toUser(openid)
// 模板id
.templateId(templateId)
// 跳轉(zhuǎn)小程序appid,跳轉(zhuǎn)路徑
.miniProgram(new WxMpTemplateMessage.MiniProgram(weAppAppId, "", false))
// 模板參數(shù)
.data(templateData)
.build();
try {
log.debug("微信公眾號推送模板消息入?yún)ⅲ簕}", templateMessage);
// 成功返回msgId,否則都是拋異常
wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
} catch (WxErrorException e) {
log.error("微信公眾號推送模板消息異常", e);
}
}
- 公眾號接入服務(wù)器開發(fā)的代碼
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @author quan
* @date 2023/11/7 18:19
*/
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/wx")
public class WxPortalController {
@Autowired
private final WxMpService wxService;
@Autowired
private final WxMpMessageRouter messageRouter;
@GetMapping(produces = "text/plain;charset=utf-8")
public String authGet(@PathVariable String appid,
@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) {
log.info("接收到來自微信服務(wù)器的認證消息:[{}, {}, {}, {}]", signature, timestamp, nonce, echostr);
if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
throw new IllegalArgumentException("請求參數(shù)非法,請核實!");
}
if (!this.wxService.switchover(appid)) {
throw new IllegalArgumentException(String.format("未找到對應(yīng)appid=[%s]的配置,請核實!", appid));
}
if (wxService.checkSignature(timestamp, nonce, signature)) {
return echostr;
}
return "非法請求";
}
@PostMapping(produces = "application/xml; charset=UTF-8")
public String post(@PathVariable String appid,
@RequestBody String requestBody,
@RequestParam("signature") String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce,
@RequestParam("openid") String openid,
@RequestParam(name = "encrypt_type", required = false) String encType,
@RequestParam(name = "msg_signature", required = false) String msgSignature) {
log.info("接收微信請求:[openid=[{}], [signature=[{}], encType=[{}], msgSignature=[{}],"
+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
openid, signature, encType, msgSignature, timestamp, nonce, requestBody);
if (!this.wxService.switchover(appid)) {
throw new IllegalArgumentException(String.format("未找到對應(yīng)appid=[%s]的配置,請核實!", appid));
}
if (!wxService.checkSignature(timestamp, nonce, signature)) {
throw new IllegalArgumentException("非法請求,可能屬于偽造的請求!");
}
String out = null;
if (encType == null) {
// 明文傳輸?shù)南?/span>
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
WxMpXmlOutMessage outMessage = this.route(inMessage);
if (outMessage == null) {
return "";
}
out = outMessage.toXml();
} else if ("aes".equalsIgnoreCase(encType)) {
// aes加密的消息
WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxService.getWxMpConfigStorage(),
timestamp, nonce, msgSignature);
log.debug("消息解密后內(nèi)容為:{} ", inMessage);
WxMpXmlOutMessage outMessage = this.route(inMessage);
if (outMessage == null) {
return "";
}
out = outMessage.toEncryptedXml(wxService.getWxMpConfigStorage());
}
log.debug("組裝回復(fù)信息:{}", out);
return out;
}
private WxMpXmlOutMessage route(WxMpXmlMessage message) {
try {
return this.messageRouter.route(message);
} catch (Exception e) {
log.error("路由消息時出現(xiàn)異常!", e);
}
return null;
}
}
- 微信消息路由配置類
/**
* @author quan
* @date 2023/11/7 18:23
*/
@AllArgsConstructor
@Configuration
public class WxMpConfiguration {
private final SubscribeHandler subscribeHandler;
@Bean
public WxMpMessageRouter messageRouter(WxMpService wxMpService) {
final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
// 關(guān)注事件
newRouter.rule().async(false).msgType(EVENT).event(SUBSCRIBE).handler(this.subscribeHandler).end();
return newRouter;
}
}
- 微信關(guān)注事件處理類
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tfcs.web.domain.bus.BusWxMpUser;
import com.tfcs.web.service.BusWxMpUserService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 關(guān)注處理器
*
* @author quan
* @date 2023/9/15 14:05
*/
@Slf4j
@Component
public class SubscribeHandler implements WxMpMessageHandler {
@Autowired
private BusWxMpUserService wxMpUserService;
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService weixinService,
WxSessionManager sessionManager) {
log.info("新關(guān)注用戶 OPENID: " + wxMessage.getFromUser());
// 獲取微信用戶基本信息
try {
WxMpUser userWxInfo = weixinService.getUserService()
.userInfo(wxMessage.getFromUser(), null);
if (userWxInfo != null) {
// TODO 先檢查是否存在該用戶,不存在再存到數(shù)據(jù)庫
}
} catch (WxErrorException e) {
log.error("微信公眾號獲取用戶信息異常:", e);
if (e.getError().getErrorCode() == 48001) {
log.info("該公眾號沒有獲取用戶信息權(quán)限!");
}
}
return null;
}
}
- 業(yè)務(wù)代碼調(diào)用demo
// 通過unionid查出公眾號openid
BusWxMpUser wxMpUser = wxMpUserService.getOne(new LambdaQueryWrapper<BusWxMpUser>()
.eq(BusWxMpUser::getUnionid, user.getUnionid()));
if (null != wxMpUser) {
List<WxMpTemplateData> templateData = new ArrayList<>(5);
// 對應(yīng)消息模板的key
templateData.add(new WxMpTemplateData("character_string2", event.getFlightNo()));
templateData.add(new WxMpTemplateData("thing10", event.getStartPlace()));
templateData.add(new WxMpTemplateData("thing11", event.getDestPlace()));
templateData.add(new WxMpTemplateData("time3", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, event.getFlightStartTime())));
templateData.add(new WxMpTemplateData("thing9", "請及時處理關(guān)注事件"));
weChatUtil.sendTemplateMsg(wxMpUser.getOpenid(), templateData);
}
- 推送效果
到了這里,關(guān)于【微信公眾號推送小程序消息通知】--下發(fā)統(tǒng)一消息接口被回收后新方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!