mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-11-01 00:46:54 +08:00 
			
		
		
		
	🆕 【企业微信】修改解析企业微信推送消息类,添加对企微客户联系变更回调事件的支持
This commit is contained in:
		| @@ -138,6 +138,29 @@ public class WxCpXmlMessage implements Serializable { | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String event; | ||||
|  | ||||
|   @XStreamAlias("UpdateDetail") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String updateDetail; | ||||
|  | ||||
|   @XStreamAlias("JoinScene") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String joinScene; | ||||
|  | ||||
|   @XStreamAlias("QuitScene") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String quitScene; | ||||
|  | ||||
|   @XStreamAlias("MemChangeCnt") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String memChangeCnt; | ||||
|  | ||||
|   @XStreamAlias("Source") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String source; | ||||
|  | ||||
|   @XStreamAlias("StrategyId") | ||||
|   private String strategyId; | ||||
|  | ||||
|   @XStreamAlias("EventKey") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String eventKey; | ||||
| @@ -453,6 +476,14 @@ public class WxCpXmlMessage implements Serializable { | ||||
|     return xmlMessage; | ||||
|   } | ||||
|  | ||||
|   public static WxCpXmlMessage fromXml(String xml, Integer agentId) { | ||||
|     //修改微信变态的消息内容格式,方便解析 | ||||
|     xml = xml.replace("</PicList><PicList>", ""); | ||||
|     final WxCpXmlMessage xmlMessage = fromXml(xml); | ||||
|     xmlMessage.setAgentId(agentId); | ||||
|     return xmlMessage; | ||||
|   } | ||||
|  | ||||
|   protected static WxCpXmlMessage fromXml(InputStream is) { | ||||
|     return XStreamTransformer.fromXml(WxCpXmlMessage.class, is); | ||||
|   } | ||||
| @@ -463,9 +494,15 @@ public class WxCpXmlMessage implements Serializable { | ||||
|   public static WxCpXmlMessage fromEncryptedXml(String encryptedXml, WxCpConfigStorage wxCpConfigStorage, | ||||
|                                                 String timestamp, String nonce, String msgSignature) { | ||||
|     WxCpCryptUtil cryptUtil = new WxCpCryptUtil(wxCpConfigStorage); | ||||
|     String plainText = cryptUtil.decryptXml(msgSignature, timestamp, nonce, encryptedXml); | ||||
|     WxCpXmlMessage wxCpXmlMessage = fromXml(encryptedXml); | ||||
|     String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedXml); | ||||
|     log.debug("解密后的原始xml消息内容:{}", plainText); | ||||
|     return fromXml(plainText); | ||||
|     if (null != wxCpXmlMessage.getAgentId()) { | ||||
|       return fromXml(plainText, wxCpXmlMessage.getAgentId()); | ||||
|     } else { | ||||
|       return fromXml(plainText); | ||||
|     } | ||||
|  | ||||
|   } | ||||
|  | ||||
|   public static WxCpXmlMessage fromEncryptedXml(InputStream is, WxCpConfigStorage wxCpConfigStorage, | ||||
|   | ||||
| @@ -0,0 +1,83 @@ | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
|  | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.common.util.xml.*; | ||||
|  | ||||
| /** | ||||
|  * @author eYoung | ||||
|  * @description: | ||||
|  * @date create at 2021/12/3 16:36 | ||||
|  */ | ||||
| @XStreamAlias("xml") | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = false) | ||||
| public class WxCpXmlOutEventMessage extends WxCpXmlOutMessage { | ||||
|  | ||||
|   @XStreamAlias("Event") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String event; | ||||
|  | ||||
|   @XStreamAlias("ChatId") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String chatId; | ||||
|  | ||||
|   @XStreamAlias("ChangeType") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String changeType; | ||||
|  | ||||
|   @XStreamAlias("UpdateDetail") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String updateDetail; | ||||
|  | ||||
|   @XStreamAlias("JoinScene") | ||||
|   private String joinScene; | ||||
|  | ||||
|   @XStreamAlias("QuitScene") | ||||
|   private String quitScene; | ||||
|  | ||||
|   @XStreamAlias("MemChangeCnt") | ||||
|   private String memChangeCnt; | ||||
|  | ||||
|   @XStreamAlias("TagType") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String tagType; | ||||
|  | ||||
|   @XStreamAlias("StrategyId") | ||||
|   private String strategyId; | ||||
|  | ||||
|   @XStreamAlias("UserID") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String userID; | ||||
|  | ||||
|   @XStreamAlias("ExternalUserID") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String externalUserID; | ||||
|  | ||||
|   @XStreamAlias("State") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String state; | ||||
|  | ||||
|   @XStreamAlias("WelcomeCode") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String welcomeCode; | ||||
|  | ||||
|   @XStreamAlias("Source") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String source; | ||||
|  | ||||
|   @XStreamAlias("FailReason") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String failReason; | ||||
|  | ||||
|   @XStreamAlias("Id") | ||||
|   @XStreamConverter(value = XStreamCDataConverter.class) | ||||
|   private String id; | ||||
|  | ||||
|   public WxCpXmlOutEventMessage() { | ||||
|     this.msgType = WxConsts.XmlMsgType.EVENT; | ||||
|   } | ||||
| } | ||||
| @@ -86,6 +86,13 @@ public abstract class WxCpXmlOutMessage implements Serializable { | ||||
|     return new UpdateButtonBuilder(); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 获得事件消息builder. | ||||
|    */ | ||||
|   public static EventBuilder EVENT() { | ||||
|     return new EventBuilder(); | ||||
|   } | ||||
|  | ||||
|   protected String toXml() { | ||||
|     return XStreamTransformer.toXml((Class) this.getClass(), this); | ||||
|   } | ||||
|   | ||||
| @@ -0,0 +1,131 @@ | ||||
| package me.chanjar.weixin.cp.bean.outxmlbuilder; | ||||
|  | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutEventMessage; | ||||
|  | ||||
| /** | ||||
|  * @author eYoung | ||||
|  * @description: | ||||
|  * @date create at 2021/12/3 16:34 | ||||
|  */ | ||||
| public class EventBuilder extends BaseBuilder<EventBuilder, WxCpXmlOutEventMessage> { | ||||
|  | ||||
|   private String event; | ||||
|   private String chatId; | ||||
|   private String changeType; | ||||
|   private String updateDetail; | ||||
|   private String joinScene; | ||||
|   private String quitScene; | ||||
|   private String memChangeCnt; | ||||
|   private String tagType; | ||||
|   private String strategyId; | ||||
|   private String userID; | ||||
|   private String externalUserID; | ||||
|   private String state; | ||||
|   private String welcomeCode; | ||||
|   private String source; | ||||
|   private String failReason; | ||||
|   private String id; | ||||
|  | ||||
|   public EventBuilder chatId(String chatId) { | ||||
|     this.chatId = chatId; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder event(String event) { | ||||
|     this.event = event; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder changeType(String changeType) { | ||||
|     this.changeType = changeType; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder updateDetail(String updateDetail) { | ||||
|     this.updateDetail = updateDetail; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder joinScene(String joinScene) { | ||||
|     this.joinScene = joinScene; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder quitScene(String quitScene) { | ||||
|     this.quitScene = quitScene; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder memChangeCnt(String memChangeCnt) { | ||||
|     this.memChangeCnt = memChangeCnt; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder tagType(String tagType) { | ||||
|     this.tagType = tagType; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder strategyId(String strategyId) { | ||||
|     this.strategyId = strategyId; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder userID(String userID) { | ||||
|     this.userID = userID; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder externalUserID(String externalUserID) { | ||||
|     this.externalUserID = externalUserID; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder state(String state) { | ||||
|     this.state = state; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder source(String source){ | ||||
|     this.source = source; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder welcomeCode(String welcomeCode) { | ||||
|     this.welcomeCode = welcomeCode; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder failReason(String failReason){ | ||||
|     this.failReason = failReason; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   public EventBuilder id(String id){ | ||||
|     this.id = id; | ||||
|     return this; | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxCpXmlOutEventMessage build() { | ||||
|     WxCpXmlOutEventMessage m = new WxCpXmlOutEventMessage(); | ||||
|     super.setCommon(m); | ||||
|     m.setEvent(this.event); | ||||
|     m.setChatId(this.chatId); | ||||
|     m.setChangeType(this.changeType); | ||||
|     m.setUpdateDetail(this.updateDetail); | ||||
|     m.setJoinScene(this.joinScene); | ||||
|     m.setQuitScene(this.quitScene); | ||||
|     m.setMemChangeCnt(this.memChangeCnt); | ||||
|     m.setTagType(this.tagType); | ||||
|     m.setStrategyId(this.strategyId); | ||||
|     m.setUserID(this.userID); | ||||
|     m.setExternalUserID(this.externalUserID); | ||||
|     m.setState(this.state); | ||||
|     m.setWelcomeCode(this.welcomeCode); | ||||
|     m.setSource(this.source); | ||||
|     m.setFailReason(this.failReason); | ||||
|     m.setId(this.id); | ||||
|     return m; | ||||
|   } | ||||
| } | ||||
| @@ -98,6 +98,16 @@ public class WxCpConsts { | ||||
|      */ | ||||
|     public static final String CHANGE_EXTERNAL_CONTACT = "change_external_contact"; | ||||
|  | ||||
|     /** | ||||
|      * 客户群事件推送 | ||||
|      */ | ||||
|     public static final String CHANGE_EXTERNAL_CHAT = "change_external_chat"; | ||||
|  | ||||
|     /** | ||||
|      * 企业客户标签事件推送 | ||||
|      */ | ||||
|     public static final String CHANGE_EXTERNAL_TAG = "change_external_tag"; | ||||
|  | ||||
|     /** | ||||
|      * 企业微信审批事件推送(自建应用审批) | ||||
|      */ | ||||
| @@ -144,6 +154,10 @@ public class WxCpConsts { | ||||
|      * 新增外部联系人 | ||||
|      */ | ||||
|     public static final String ADD_EXTERNAL_CONTACT = "add_external_contact"; | ||||
|     /** | ||||
|      * 编辑外部联系人 | ||||
|      */ | ||||
|     public static final String EDIT_EXTERNAL_CONTACT = "edit_external_contact"; | ||||
|     /** | ||||
|      * 删除外部联系人 | ||||
|      */ | ||||
| @@ -157,8 +171,97 @@ public class WxCpConsts { | ||||
|      * 删除跟进成员事件 | ||||
|      */ | ||||
|     public static final String DEL_FOLLOW_USER = "del_follow_user"; | ||||
|     /** | ||||
|      * 客户接替失败事件 | ||||
|      */ | ||||
|     public static final String TRANSFER_FAIL = "transfer_fail"; | ||||
|  | ||||
|     @UtilityClass | ||||
|     public static class ExternalContactTransferFailReason { | ||||
|       /** | ||||
|        * 客户拒绝 | ||||
|        */ | ||||
|       public static final String CUSTOMER_REFUSED = "customer_refused"; | ||||
|       /** | ||||
|        * 接替成员的客户数达到上限 | ||||
|        */ | ||||
|       public static final String CUSTOMER_LIMIT_EXCEED = "customer_limit_exceed"; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @UtilityClass | ||||
|   public static class ExternalChatChangeType { | ||||
|     /** | ||||
|      * 客户群变更事件 | ||||
|      */ | ||||
|     public static final String CREATE = "create"; | ||||
|     /** | ||||
|      * 客户群变更事件 | ||||
|      */ | ||||
|     public static final String UPDATE = "update"; | ||||
|     /** | ||||
|      * 客户群解散事件 | ||||
|      */ | ||||
|     public static final String DISMISS = "dismiss"; | ||||
|  | ||||
|     @UtilityClass | ||||
|     public static class ExternalChatUpdateDetail { | ||||
|       /** | ||||
|        * 成员入群 | ||||
|        */ | ||||
|       public static final String ADD_MEMBER = "add_member"; | ||||
|       /** | ||||
|        * 成员退群 | ||||
|        */ | ||||
|       public static final String DEL_MEMBER = "del_member"; | ||||
|       /** | ||||
|        * 成员退群 | ||||
|        */ | ||||
|       public static final String CHANGE_OWNER = "change_owner"; | ||||
|       /** | ||||
|        * 群名变更 | ||||
|        */ | ||||
|       public static final String CHANGE_NAME = "change_name"; | ||||
|       /** | ||||
|        * 群公告变更 | ||||
|        */ | ||||
|       public static final String CHANGE_NOTICE = "change_notice"; | ||||
|     } | ||||
|   } | ||||
|   @UtilityClass | ||||
|   public static class ExternalTagChangeType{ | ||||
|  | ||||
|     /** | ||||
|      * 创建企业客户标签 | ||||
|      */ | ||||
|     public static final String CREATE = "create"; | ||||
|     /** | ||||
|      * 变更企业客户标签 | ||||
|      */ | ||||
|     public static final String UPDATE = "update"; | ||||
|     /** | ||||
|      * 删除企业客户标签 | ||||
|      */ | ||||
|     public static final String DELETE = "delete"; | ||||
|     /** | ||||
|      * 重排企业客户标签 | ||||
|      */ | ||||
|     public static final String SHUFFLE = "shuffle"; | ||||
|   } | ||||
|  | ||||
|   @UtilityClass | ||||
|   public static class TageType{ | ||||
|     /** | ||||
|      * 标签 | ||||
|      */ | ||||
|     public static final String TAG = "tag"; | ||||
|     /** | ||||
|      * 标签组 | ||||
|      */ | ||||
|     public static final String TAG_GROUP = "tag_group"; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   /** | ||||
|    * 企业微信通讯录变更事件. | ||||
|    */ | ||||
| @@ -318,20 +421,20 @@ public class WxCpConsts { | ||||
|   @UtilityClass | ||||
|   public static class WorkBenchType { | ||||
|     /* | ||||
|     * 关键数据型 | ||||
|     * */ | ||||
|      * 关键数据型 | ||||
|      * */ | ||||
|     public static final String KEYDATA = "keydata"; | ||||
|     /* | ||||
|     * 图片型 | ||||
|     * */ | ||||
|      * 图片型 | ||||
|      * */ | ||||
|     public static final String IMAGE = "image"; | ||||
|     /* | ||||
|     * 列表型 | ||||
|     * */ | ||||
|      * 列表型 | ||||
|      * */ | ||||
|     public static final String LIST = "list"; | ||||
|     /* | ||||
|     * webview型 | ||||
|     * */ | ||||
|      * webview型 | ||||
|      * */ | ||||
|     public static final String WEBVIEW = "webview"; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -57,6 +57,7 @@ public class XStreamTransformer { | ||||
|     map.put(WxCpXmlOutUpdateBtnMessage.class, configWxCpXmlOutUpdateBtnMessage()); | ||||
|     map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage()); | ||||
|     map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage()); | ||||
|     map.put(WxCpXmlOutEventMessage.class, configWxCpXmlOutEventMessage()); | ||||
|     return map; | ||||
|   } | ||||
|  | ||||
| @@ -141,4 +142,11 @@ public class XStreamTransformer { | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutEventMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutEventMessage.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jamy888
					jamy888