diff --git a/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java b/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java index c425dfa..5f3c807 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java +++ b/austin-common/src/main/java/com/java3y/austin/common/constant/SendAccountConstant.java @@ -54,6 +54,17 @@ public class SendAccountConstant { public static final String ENTERPRISE_WECHAT_ACCOUNT_KEY = "enterpriseWechatAccount"; public static final String ENTERPRISE_WECHAT_PREFIX = "enterprise_wechat_"; + /** + * 微信服务号 应用消息 账号 + */ + public static final String WECHAT_OFFICIAL_ACCOUNT_KEY = "officialAccount"; + public static final String WECHAT_OFFICIAL__PREFIX = "official_"; + + /** + * 微信小程序 应用消息 账号 + */ + public static final String WECHAT_MINI_PROGRAM_ACCOUNT_KEY = "miniProgramAccount"; + public static final String WECHAT_MINI_PROGRAM_PREFIX = "mini_program_"; /** * 短信 账号 diff --git a/austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatMiniProgramAccount.java b/austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatMiniProgramAccount.java new file mode 100644 index 0000000..1e8d4e5 --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatMiniProgramAccount.java @@ -0,0 +1,44 @@ +package com.java3y.austin.common.dto.account; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * + * 小程序订阅消息参数 + *

+ * 参数示例: + * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html + * * @author sunql + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class WeChatMiniProgramAccount { + + /** + * 订阅消息模板ID + */ + private String templateId; + + /** + * 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 + */ + private String miniProgramState; + + /** + * 击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。 + */ + private String page; + + /** + * 账号相关 + */ + private String appId; + private String appSecret; + private String grantType; + +} diff --git a/austin-common/src/main/java/com/java3y/austin/common/dto/account/WechatOfficialAccount.java b/austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatOfficialAccount.java similarity index 74% rename from austin-common/src/main/java/com/java3y/austin/common/dto/account/WechatOfficialAccount.java rename to austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatOfficialAccount.java index 1dfecc0..3f1a1c6 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/dto/account/WechatOfficialAccount.java +++ b/austin-common/src/main/java/com/java3y/austin/common/dto/account/WeChatOfficialAccount.java @@ -19,17 +19,7 @@ import java.util.Map; @Builder @AllArgsConstructor @NoArgsConstructor -public class WechatOfficialAccount { - - /** - * 服务号关注者的openId - */ - private String openId; - - /** - * 需要使用的模板信息Id - */ - private String templateId; +public class WeChatOfficialAccount { /** * 模板消息跳转的url @@ -47,7 +37,9 @@ public class WechatOfficialAccount { private String path; /** - * 模板消息的信息载体 + * 账号相关 */ - private Map map; + private String appId; + private String secret; + private String templateId; } diff --git a/austin-common/src/main/java/com/java3y/austin/common/dto/model/MiniProgramContentModel.java b/austin-common/src/main/java/com/java3y/austin/common/dto/model/MiniProgramContentModel.java index 4601781..5e15ed3 100644 --- a/austin-common/src/main/java/com/java3y/austin/common/dto/model/MiniProgramContentModel.java +++ b/austin-common/src/main/java/com/java3y/austin/common/dto/model/MiniProgramContentModel.java @@ -1,8 +1,22 @@ package com.java3y.austin.common.dto.model; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + /** * @author 3y */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor public class MiniProgramContentModel extends ContentModel { - + /** + * 模板消息发送的数据 + */ + Map map; } diff --git a/austin-cron/src/main/java/com/java3y/austin/cron/handler/RefreshDingDingAccessTokenHandler.java b/austin-cron/src/main/java/com/java3y/austin/cron/handler/RefreshDingDingAccessTokenHandler.java index f2ce549..25f378e 100644 --- a/austin-cron/src/main/java/com/java3y/austin/cron/handler/RefreshDingDingAccessTokenHandler.java +++ b/austin-cron/src/main/java/com/java3y/austin/cron/handler/RefreshDingDingAccessTokenHandler.java @@ -46,7 +46,7 @@ public class RefreshDingDingAccessTokenHandler { log.info("refreshAccessTokenJob#execute!"); SupportThreadPoolConfig.getPendingSingleThreadPool().execute(() -> { for (int index = SendAccountConstant.START; true; index = index + SendAccountConstant.STEP) { - DingDingWorkNoticeAccount account = accountUtils.getAccount(index, SendAccountConstant.DING_DING_WORK_NOTICE_ACCOUNT_KEY, SendAccountConstant.DING_DING_WORK_NOTICE_PREFIX, new DingDingWorkNoticeAccount()); + DingDingWorkNoticeAccount account = accountUtils.getAccount(index, SendAccountConstant.DING_DING_WORK_NOTICE_ACCOUNT_KEY, SendAccountConstant.DING_DING_WORK_NOTICE_PREFIX, DingDingWorkNoticeAccount.class); if (account == null) { break; } diff --git a/austin-handler/pom.xml b/austin-handler/pom.xml index 6fdac1a..7f542c6 100644 --- a/austin-handler/pom.xml +++ b/austin-handler/pom.xml @@ -46,6 +46,11 @@ com.github.binarywang weixin-java-mp + + + com.github.binarywang + weixin-java-miniapp + @@ -54,4 +59,4 @@ - \ No newline at end of file + diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatMiniProgramParam.java b/austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatMiniProgramParam.java new file mode 100644 index 0000000..54bab4f --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatMiniProgramParam.java @@ -0,0 +1,38 @@ +package com.java3y.austin.handler.domain.wechat; + +import lombok.Builder; +import lombok.Data; + +import java.util.Map; +import java.util.Set; + +/** + * @author sunql + * @date 2022年05月06日 15:56 + * + * 小程序参数 + */ +@Data +@Builder +public class WeChatMiniProgramParam { + /** + * 业务Id + */ + private Long messageTemplateId; + + /** + * 发送账号 + */ + private Integer sendAccount; + + /** + * 接收者(用户)的 openid + */ + private Set openIds; + + /** + * 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } } + */ + private Map data; + +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatOfficialParam.java b/austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatOfficialParam.java new file mode 100644 index 0000000..ecd134c --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/domain/wechat/WeChatOfficialParam.java @@ -0,0 +1,37 @@ +package com.java3y.austin.handler.domain.wechat; + +import lombok.Builder; +import lombok.Data; + +import java.util.Map; +import java.util.Set; + +/** + * @author sunql + * @date 2022年05月06日 9:56 + * + * 服务号参数 + */ +@Data +@Builder +public class WeChatOfficialParam { + /** + * 业务Id + */ + private Long messageTemplateId; + + /** + * 关注服务号得用户 + */ + private Set openIds; + + /** + * 模板消息的信息载体 + */ + private Map data; + + /** + * 发送账号 + */ + private Integer sendAccount; +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/DingDingRobotHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/DingDingRobotHandler.java index 9a1ed77..bc4d702 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/DingDingRobotHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/DingDingRobotHandler.java @@ -45,7 +45,7 @@ public class DingDingRobotHandler extends BaseHandler implements Handler { @Override public boolean handler(TaskInfo taskInfo) { try { - DingDingRobotAccount account = accountUtils.getAccount(taskInfo.getSendAccount(), SendAccountConstant.DING_DING_ROBOT_ACCOUNT_KEY, SendAccountConstant.DING_DING_ROBOT_PREFIX, new DingDingRobotAccount()); + DingDingRobotAccount account = accountUtils.getAccount(taskInfo.getSendAccount(), SendAccountConstant.DING_DING_ROBOT_ACCOUNT_KEY, SendAccountConstant.DING_DING_ROBOT_PREFIX, DingDingRobotAccount.class); DingDingRobotParam dingDingRobotParam = assembleParam(taskInfo); String httpResult = HttpUtil.post(assembleParamUrl(account), JSON.toJSONString(dingDingRobotParam)); DingDingRobotResult dingDingRobotResult = JSON.parseObject(httpResult, DingDingRobotResult.class); diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/DingDingWorkNoticeHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/DingDingWorkNoticeHandler.java index f6211bc..3ddee90 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/DingDingWorkNoticeHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/DingDingWorkNoticeHandler.java @@ -50,7 +50,7 @@ public class DingDingWorkNoticeHandler extends BaseHandler implements Handler { @Override public boolean handler(TaskInfo taskInfo) { try { - DingDingWorkNoticeAccount account = accountUtils.getAccount(taskInfo.getSendAccount(), SendAccountConstant.DING_DING_WORK_NOTICE_ACCOUNT_KEY, SendAccountConstant.DING_DING_WORK_NOTICE_PREFIX, new DingDingWorkNoticeAccount()); + DingDingWorkNoticeAccount account = accountUtils.getAccount(taskInfo.getSendAccount(), SendAccountConstant.DING_DING_WORK_NOTICE_ACCOUNT_KEY, SendAccountConstant.DING_DING_WORK_NOTICE_PREFIX, DingDingWorkNoticeAccount.class); OapiMessageCorpconversationAsyncsendV2Request request = assembleParam(account, taskInfo); String accessToken = redisTemplate.opsForValue().get(SendAccountConstant.DING_DING_ACCESS_TOKEN_PREFIX + taskInfo.getSendAccount()); OapiMessageCorpconversationAsyncsendV2Response response = new DefaultDingTalkClient(URL).execute(request, accessToken); diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/EmailHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/EmailHandler.java index 4099515..f6e8a25 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/EmailHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/EmailHandler.java @@ -62,7 +62,7 @@ public class EmailHandler extends BaseHandler implements Handler { * @return */ private MailAccount getAccountConfig(Integer sendAccount) { - MailAccount account = accountUtils.getAccount(sendAccount, SendAccountConstant.EMAIL_ACCOUNT_KEY, SendAccountConstant.EMAIL_ACCOUNT_PREFIX, new MailAccount()); + MailAccount account = accountUtils.getAccount(sendAccount, SendAccountConstant.EMAIL_ACCOUNT_KEY, SendAccountConstant.EMAIL_ACCOUNT_PREFIX, MailAccount.class); try { MailSSLSocketFactory sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/EnterpriseWeChatHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/EnterpriseWeChatHandler.java index bee72a6..c2e9bbf 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/EnterpriseWeChatHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/EnterpriseWeChatHandler.java @@ -46,7 +46,7 @@ public class EnterpriseWeChatHandler extends BaseHandler implements Handler { @Override public boolean handler(TaskInfo taskInfo) { try { - WxCpDefaultConfigImpl accountConfig = accountUtils.getAccount(taskInfo.getSendAccount(), SendAccountConstant.ENTERPRISE_WECHAT_ACCOUNT_KEY, SendAccountConstant.ENTERPRISE_WECHAT_PREFIX, new WxCpDefaultConfigImpl()); + WxCpDefaultConfigImpl accountConfig = accountUtils.getAccount(taskInfo.getSendAccount(), SendAccountConstant.ENTERPRISE_WECHAT_ACCOUNT_KEY, SendAccountConstant.ENTERPRISE_WECHAT_PREFIX, WxCpDefaultConfigImpl.class); WxCpMessageServiceImpl messageService = new WxCpMessageServiceImpl(initService(accountConfig)); WxCpMessageSendResult result = messageService.send(buildWxCpMessage(taskInfo, accountConfig.getAgentId())); if (Integer.valueOf(WxMpErrorMsgEnum.CODE_0.getCode()).equals(result.getErrCode())) { diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/MiniProgramAccountHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/MiniProgramAccountHandler.java new file mode 100644 index 0000000..013fd15 --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/MiniProgramAccountHandler.java @@ -0,0 +1,67 @@ +package com.java3y.austin.handler.handler.impl; + +import com.alibaba.fastjson.JSON; +import com.google.common.base.Throwables; +import com.java3y.austin.common.domain.TaskInfo; +import com.java3y.austin.common.dto.model.MiniProgramContentModel; +import com.java3y.austin.common.dto.model.OfficialAccountsContentModel; +import com.java3y.austin.common.enums.ChannelType; +import com.java3y.austin.handler.domain.wechat.WeChatMiniProgramParam; +import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; +import com.java3y.austin.handler.handler.BaseHandler; +import com.java3y.austin.handler.handler.Handler; +import com.java3y.austin.handler.script.MiniProgramAccountService; +import com.java3y.austin.handler.script.OfficialAccountService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @author sunql + * 微信小程序发送订阅消息 + */ +@Component +@Slf4j +public class MiniProgramAccountHandler extends BaseHandler implements Handler { + + @Autowired + private MiniProgramAccountService miniProgramAccountService; + + public MiniProgramAccountHandler() { + channelCode = ChannelType.MINI_PROGRAM.getCode(); + } + + @Override + public boolean handler(TaskInfo taskInfo) { + WeChatMiniProgramParam miniProgramParam = buildMiniProgramParam(taskInfo); + try { + miniProgramAccountService.send(miniProgramParam); + } catch (Exception e) { + log.error("MiniProgramAccountHandler#handler fail:{},params:{}", + Throwables.getStackTraceAsString(e), JSON.toJSONString(taskInfo)); + return false; + } + return true; + } + + /** + * 通过taskInfo构建小程序订阅消息 + * + * @param taskInfo + * @return + */ + private WeChatMiniProgramParam buildMiniProgramParam(TaskInfo taskInfo) { + // 小程序订阅消息可以关联到系统业务,通过接口查询。 + WeChatMiniProgramParam miniProgramParam = WeChatMiniProgramParam.builder() + .openIds(taskInfo.getReceiver()) + .messageTemplateId(taskInfo.getMessageTemplateId()) + .sendAccount(taskInfo.getSendAccount()) + .build(); + + MiniProgramContentModel contentModel = (MiniProgramContentModel) taskInfo.getContentModel(); + miniProgramParam.setData(contentModel.getMap()); + return miniProgramParam; + } + +} + diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java index a1f274b..7e6707b 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/handler/impl/OfficialAccountHandler.java @@ -5,19 +5,15 @@ import com.google.common.base.Throwables; import com.java3y.austin.common.domain.TaskInfo; import com.java3y.austin.common.dto.model.OfficialAccountsContentModel; import com.java3y.austin.common.enums.ChannelType; +import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; import com.java3y.austin.handler.handler.BaseHandler; import com.java3y.austin.handler.handler.Handler; import com.java3y.austin.handler.script.OfficialAccountService; import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; -import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.Set; /** * @author zyg @@ -30,18 +26,24 @@ public class OfficialAccountHandler extends BaseHandler implements Handler { @Autowired private OfficialAccountService officialAccountService; - public OfficialAccountHandler() { channelCode = ChannelType.OFFICIAL_ACCOUNT.getCode(); } @Override public boolean handler(TaskInfo taskInfo) { + // 构建微信模板消息 + OfficialAccountsContentModel contentModel = (OfficialAccountsContentModel) taskInfo.getContentModel(); + WeChatOfficialParam officialParam = WeChatOfficialParam.builder() + .openIds(taskInfo.getReceiver()) + .messageTemplateId(taskInfo.getMessageTemplateId()) + .sendAccount(taskInfo.getSendAccount()) + .data(contentModel.getMap()) + .build(); - List mpTemplateMessages = buildTemplateMsg(taskInfo); // 微信模板消息需要记录响应结果 try { - List messageIds = officialAccountService.send(mpTemplateMessages); + List messageIds = officialAccountService.send(officialParam); log.info("OfficialAccountHandler#handler successfully messageIds:{}", messageIds); return true; } catch (Exception e) { @@ -51,45 +53,5 @@ public class OfficialAccountHandler extends BaseHandler implements Handler { return false; } - /** - * 通过taskInfo构建微信模板消息 - * - * @param taskInfo - * @return - */ - private List buildTemplateMsg(TaskInfo taskInfo) { - // 需是关注公众号的用户的OpenId - Set receiver = taskInfo.getReceiver(); - Long messageTemplateId = taskInfo.getMessageTemplateId(); - // 微信模板消息可以关联到系统业务,通过接口查询。 - String templateId = getRealWxMpTemplateId(messageTemplateId); - List wxMpTemplateMessages = new ArrayList<>(receiver.size()); - OfficialAccountsContentModel contentModel = (OfficialAccountsContentModel) taskInfo.getContentModel(); - String url = contentModel.getUrl(); - Map param = contentModel.getMap(); - - // 构建微信模板消息 - for (String openId : receiver) { - WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() - .toUser(openId) - .templateId(templateId) - .url(url) - .build(); - // WxMpTemplateData 对应模板消息 键 -- 值 -- color - param.forEach((k, v) -> templateMessage.addData(new WxMpTemplateData(k, v))); - wxMpTemplateMessages.add(templateMessage); - } - return wxMpTemplateMessages; - } - - /** - * 根据模板id获取真实的模板id - * - * @param messageTemplateId 系统业务模板id - * @return - */ - private String getRealWxMpTemplateId(Long messageTemplateId) { - return String.valueOf(messageTemplateId); - } } diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/MiniProgramAccountService.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/MiniProgramAccountService.java new file mode 100644 index 0000000..7a4b6da --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/MiniProgramAccountService.java @@ -0,0 +1,19 @@ +package com.java3y.austin.handler.script; + +import com.java3y.austin.handler.domain.wechat.WeChatMiniProgramParam; + +/** + * @author sunql + */ +public interface MiniProgramAccountService { + + /** + * 发送订阅消息 + * + * @param miniProgramParam 订阅消息参数 + * @return + * @throws Exception + */ + void send(WeChatMiniProgramParam miniProgramParam) throws Exception; + +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/OfficialAccountService.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/OfficialAccountService.java index 868e76f..8451869 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/OfficialAccountService.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/OfficialAccountService.java @@ -1,5 +1,6 @@ package com.java3y.austin.handler.script; +import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; import java.util.List; @@ -12,10 +13,10 @@ public interface OfficialAccountService { /** * 发送模板消息 * - * @param wxMpTemplateMessages 模板消息列表 + * @param weChatOfficialParam 模板消息参数 * @return * @throws Exception */ - List send(List wxMpTemplateMessages) throws Exception; + List send(WeChatOfficialParam weChatOfficialParam) throws Exception; } diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/MiniProgramAccountServiceImpl.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/MiniProgramAccountServiceImpl.java new file mode 100644 index 0000000..ddb2e21 --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/MiniProgramAccountServiceImpl.java @@ -0,0 +1,93 @@ +package com.java3y.austin.handler.script.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.WxMaSubscribeService; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.api.impl.WxMaSubscribeServiceImpl; +import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; +import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; +import com.java3y.austin.common.constant.SendAccountConstant; +import com.java3y.austin.common.dto.account.WeChatMiniProgramAccount; +import com.java3y.austin.handler.domain.wechat.WeChatMiniProgramParam; +import com.java3y.austin.handler.script.MiniProgramAccountService; +import com.java3y.austin.support.utils.AccountUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author sunql + * @date 2022年05月06日 16:41 + */ +@Service +@Slf4j +public class MiniProgramAccountServiceImpl implements MiniProgramAccountService { + + @Autowired + private AccountUtils accountUtils; + + @Override + public void send(WeChatMiniProgramParam miniProgramParam) throws Exception { + WeChatMiniProgramAccount miniProgramAccount = accountUtils.getAccount(miniProgramParam.getSendAccount(), + SendAccountConstant.WECHAT_MINI_PROGRAM_ACCOUNT_KEY, + SendAccountConstant.WECHAT_MINI_PROGRAM_PREFIX, + WeChatMiniProgramAccount.class); + + WxMaSubscribeService wxMaSubscribeService = initService(miniProgramAccount); + List subscribeMessageList = assembleReq(miniProgramParam, miniProgramAccount); + for (WxMaSubscribeMessage subscribeMessage : subscribeMessageList) { + wxMaSubscribeService.sendSubscribeMsg(subscribeMessage); + } + } + + /** + * 组装发送模板信息参数 + */ + private List assembleReq(WeChatMiniProgramParam miniProgramParam, WeChatMiniProgramAccount miniProgramAccount) { + Set receiver = miniProgramParam.getOpenIds(); + List messageList = new ArrayList<>(receiver.size()); + + // 构建微信小程序订阅消息 + for (String openId : receiver) { + WxMaSubscribeMessage subscribeMessage = WxMaSubscribeMessage.builder() + .toUser(openId) + .data(getWxMTemplateData(miniProgramParam.getData())) + .miniprogramState(miniProgramAccount.getMiniProgramState()) + .templateId(miniProgramAccount.getTemplateId()) + .page(miniProgramAccount.getPage()) + .build(); + messageList.add(subscribeMessage); + } + return messageList; + } + + /** + * 构建订阅消息参数 + * + * @returnp + */ + private List getWxMTemplateData(Map data) { + List templateDataList = new ArrayList<>(data.size()); + data.forEach((k, v) -> templateDataList.add(new WxMaSubscribeMessage.MsgData(k, v))); + return templateDataList; + } + + /** + * 初始化微信小程序 + * + * @return + */ + private WxMaSubscribeServiceImpl initService(WeChatMiniProgramAccount miniProgramAccount) { + WxMaService wxMaService = new WxMaServiceImpl(); + WxMaDefaultConfigImpl wxMaConfig = new WxMaDefaultConfigImpl(); + wxMaConfig.setAppid(miniProgramAccount.getAppId()); + wxMaConfig.setSecret(miniProgramAccount.getAppSecret()); + wxMaService.setWxMaConfig(wxMaConfig); + return new WxMaSubscribeServiceImpl(wxMaService); + } +} diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/OfficialAccountServiceImpl.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/OfficialAccountServiceImpl.java index fe69c4b..a0f68fc 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/OfficialAccountServiceImpl.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/OfficialAccountServiceImpl.java @@ -1,16 +1,23 @@ package com.java3y.austin.handler.script.impl; +import com.java3y.austin.common.constant.SendAccountConstant; +import com.java3y.austin.common.dto.account.WeChatOfficialAccount; +import com.java3y.austin.handler.domain.wechat.WeChatOfficialParam; import com.java3y.austin.handler.script.OfficialAccountService; +import com.java3y.austin.support.utils.AccountUtils; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Set; /** * @author zyg @@ -19,19 +26,14 @@ import java.util.List; @Slf4j public class OfficialAccountServiceImpl implements OfficialAccountService { - @Value("${wx.mp.account.appid}") - private String appId; - @Value("${wx.mp.account.secret}") - private String secret; - @Value("${wx.mp.account.token}") - private String token; - @Value("${wx.mp.account.aesKey}") - private String aesKey; - + @Autowired + private AccountUtils accountUtils; @Override - public List send(List messages) throws Exception { - WxMpService wxMpService = initService(); + public List send(WeChatOfficialParam officialParam) throws Exception { + WeChatOfficialAccount officialAccount = accountUtils.getAccount(officialParam.getSendAccount(), SendAccountConstant.WECHAT_OFFICIAL_ACCOUNT_KEY, SendAccountConstant.WECHAT_OFFICIAL__PREFIX, WeChatOfficialAccount.class); + WxMpService wxMpService = initService(officialAccount); + List messages = assembleReq(officialParam, officialAccount); List messageIds = new ArrayList<>(messages.size()); for (WxMpTemplateMessage wxMpTemplateMessage : messages) { String msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(wxMpTemplateMessage); @@ -40,18 +42,48 @@ public class OfficialAccountServiceImpl implements OfficialAccountService { return messageIds; } + /** + * 组装发送模板信息参数 + */ + private List assembleReq(WeChatOfficialParam officialParam, WeChatOfficialAccount officialAccount) { + Set receiver = officialParam.getOpenIds(); + List wxMpTemplateMessages = new ArrayList<>(receiver.size()); + + // 构建微信模板消息 + for (String openId : receiver) { + WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() + .toUser(openId) + .templateId(officialAccount.getTemplateId()) + .url(officialAccount.getUrl()) + .data(getWxMpTemplateData(officialParam.getData())) + .miniProgram(new WxMpTemplateMessage.MiniProgram(officialAccount.getMiniProgramId(), officialAccount.getPath(), false)) + .build(); + wxMpTemplateMessages.add(templateMessage); + } + return wxMpTemplateMessages; + } + + /** + * 构建模板消息参数 + * + * @return + */ + private List getWxMpTemplateData(Map data) { + List templateDataList = new ArrayList<>(data.size()); + data.forEach((k, v) -> templateDataList.add(new WxMpTemplateData(k, v))); + return templateDataList; + } + /** * 初始化微信服务号 * * @return */ - public WxMpService initService() { + public WxMpService initService(WeChatOfficialAccount officialAccount) { WxMpService wxMpService = new WxMpServiceImpl(); WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl(); - config.setAppId(appId); - config.setSecret(secret); - config.setToken(token); - config.setAesKey(aesKey); + config.setAppId(officialAccount.getAppId()); + config.setSecret(officialAccount.getSecret()); wxMpService.setWxMpConfigStorage(config); return wxMpService; } diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java index 1a1201e..f3bb434 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/script/impl/TencentSmsScript.java @@ -44,7 +44,7 @@ public class TencentSmsScript implements SmsScript { @Override public List send(SmsParam smsParam) throws Exception { - TencentSmsAccount tencentSmsAccount = accountUtils.getAccount(smsParam.getSendAccount(), SendAccountConstant.SMS_ACCOUNT_KEY, SendAccountConstant.SMS_PREFIX, TencentSmsAccount.builder().build()); + TencentSmsAccount tencentSmsAccount = accountUtils.getAccount(smsParam.getSendAccount(), SendAccountConstant.SMS_ACCOUNT_KEY, SendAccountConstant.SMS_PREFIX, TencentSmsAccount.class); SmsClient client = init(tencentSmsAccount); SendSmsRequest request = assembleReq(smsParam, tencentSmsAccount); SendSmsResponse response = client.SendSms(request); diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/AssembleAction.java b/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/AssembleAction.java index 815e838..b69592d 100644 --- a/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/AssembleAction.java +++ b/austin-service-api-impl/src/main/java/com/java3y/austin/service/api/impl/action/AssembleAction.java @@ -114,7 +114,8 @@ public class AssembleAction implements BusinessProcess { if (StrUtil.isNotBlank(originValue)) { String resultValue = ContentHolderUtil.replacePlaceHolder(originValue, variables); - ReflectUtil.setFieldValue(contentModel, field, resultValue); + Object resultObj = JSON.parseObject(resultValue, field.getType()); + ReflectUtil.setFieldValue(contentModel, field, resultObj); } } diff --git a/austin-support/src/main/java/com/java3y/austin/support/utils/AccountUtils.java b/austin-support/src/main/java/com/java3y/austin/support/utils/AccountUtils.java index 66afb12..5d08a57 100644 --- a/austin-support/src/main/java/com/java3y/austin/support/utils/AccountUtils.java +++ b/austin-support/src/main/java/com/java3y/austin/support/utils/AccountUtils.java @@ -26,15 +26,17 @@ public class AccountUtils { * (key:enterpriseWechatAccount)企业微信参数示例:[{"enterprise_wechat_10":{"corpId":"wwf87603333e00069c","corpSecret":"-IFWxS2222QxzPIorNVUQn144444D915DM","agentId":10044442,"token":"rXROB3333Kf6i","aesKey":"MKZtoFxHIM44444M7ieag3r9ZPUsl"}}] * (key:dingDingRobotAccount) 钉钉自定义机器人参数示例:[{"ding_ding_robot_10":{"secret":"SEC996d8d9d4768aded74114faae924f229229de444475a1c295d64fedf","webhook":"https://oapi.dingtalk.com/robot/send?access_token=8d03b644ffb6534b203d87333367328b0c3003d164715d2c6c6e56"}}] * (key:dingDingWorkNoticeAccount) 钉钉工作消息参数示例:[{"ding_ding_work_notice_10":{"appKey":"dingh6yyyyyyycrlbx","appSecret":"tQpvmkR863333yyyyyHP3QHyyyymy9Ao1yoL1oQX5Nlx_fYLLLlpPJWHvWKbTu","agentId":"152333383622"}}] + * (key:officialAccount) 微信服务号模板消息参数示例:[{"official_10":{"appId":"wxecb4693d2eef1ea7","secret":"6240870f4d91701640d769ba20120821","templateId":"JHUk6eE9T5Ts7a5JO3ZQqkBBrZBGn5C9iIiKNDQsk-Q","url":"http://weixin.qq.com/download","miniProgramId":"xiaochengxuappid12345","path":"index?foo=bar"}}] + * (key:miniProgramAccount) 微信小程序订阅消息参数示例:[{"mini_program_10":{"appId":"wxecb4693d2eef1ea7","appSecret":"6240870f4d91701640d769ba20120821","templateId":"JHUk6eE9T5Ts7a5JO3ZQqkBBrZBGn5C9iIiKNDQsk-Q","grantType":"client_credential","miniProgramState":"trial","page":"index?foo=bar"}}] */ - public T getAccount(Integer sendAccount, String apolloKey, String prefix, T t) { + public T getAccount(Integer sendAccount, String apolloKey, String prefix, Class clazz) { String accountValues = config.getProperty(apolloKey, AustinConstant.APOLLO_DEFAULT_VALUE_JSON_ARRAY); JSONArray jsonArray = JSON.parseArray(accountValues); for (int i = 0; i < jsonArray.size(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); - Object object = jsonObject.getObject(prefix + sendAccount, t.getClass()); + T object = jsonObject.getObject(prefix + sendAccount, clazz); if (object != null) { - return (T) object; + return object; } } return null; diff --git a/austin-web/src/main/resources/application.properties b/austin-web/src/main/resources/application.properties index 20c1b3c..28bc18d 100644 --- a/austin-web/src/main/resources/application.properties +++ b/austin-web/src/main/resources/application.properties @@ -87,10 +87,3 @@ management.endpoint.metrics.enabled=true management.endpoint.prometheus.enabled=true management.endpoints.web.exposure.include=* management.metrics.export.prometheus.enabled=true - -##################### wx mp config ##################### -##################### TODO not test by 3y,wait to apply for OfficialAccount ##################### -wx.mp.account.appid="appid" -wx.mp.account.secret="secret" -wx.mp.account.token="token" -wx.mp.account.aesKey="aesKey" \ No newline at end of file diff --git a/pom.xml b/pom.xml index 6388c08..68c2ffa 100644 --- a/pom.xml +++ b/pom.xml @@ -160,6 +160,13 @@ ${weixin-java} + + + com.github.binarywang + weixin-java-miniapp + ${weixin-java} + + io.github.lyh200