mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 18:46:10 +08:00 
			
		
		
		
	🎨 #1722 企业微信增加互联企业发送应用消息的接口,并重构消息相关类的包结构
This commit is contained in:
		| @ -121,31 +121,6 @@ public class WxConsts { | ||||
|     public static final String MINIPROGRAM_NOTICE = "miniprogram_notice"; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 群机器人的消息类型. | ||||
|    */ | ||||
|   public static class GroupRobotMsgType { | ||||
|     /** | ||||
|      * 文本消息. | ||||
|      */ | ||||
|     public static final String TEXT = "text"; | ||||
|  | ||||
|     /** | ||||
|      * 图片消息. | ||||
|      */ | ||||
|     public static final String IMAGE = "image"; | ||||
|  | ||||
|     /** | ||||
|      * markdown消息. | ||||
|      */ | ||||
|     public static final String MARKDOWN = "markdown"; | ||||
|  | ||||
|     /** | ||||
|      * 图文消息(点击跳转到外链). | ||||
|      */ | ||||
|     public static final String NEWS = "news"; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 表示是否是保密消息,0表示否,1表示是,默认0. | ||||
|    */ | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.api; | ||||
|  | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.bean.WxCpAppChatMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpChat; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @ -1,8 +1,9 @@ | ||||
| package me.chanjar.weixin.cp.api; | ||||
|  | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult; | ||||
|  | ||||
| /** | ||||
|  * 消息推送接口. | ||||
| @ -14,12 +15,26 @@ public interface WxCpMessageService { | ||||
|   /** | ||||
|    * <pre> | ||||
|    * 发送消息 | ||||
|    * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E | ||||
|    * 详情请见: https://work.weixin.qq.com/api/doc/90000/90135/90236 | ||||
|    * </pre> | ||||
|    * | ||||
|    * @param message 要发送的消息对象 | ||||
|    * @return the wx cp message send result | ||||
|    * @throws WxErrorException the wx error exception | ||||
|    */ | ||||
|   WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException; | ||||
|   WxCpMessageSendResult send(WxCpMessage message) throws WxErrorException; | ||||
|  | ||||
|   /** | ||||
|    * <pre> | ||||
|    * 互联企业的应用支持推送文本、图片、视频、文件、图文等类型。 | ||||
|    * | ||||
|    * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/linkedcorp/message/send?access_token=ACCESS_TOKEN | ||||
|    * 文章地址:https://work.weixin.qq.com/api/doc/90000/90135/90250 | ||||
|    * </pre> | ||||
|    * | ||||
|    * @param message 要发送的消息对象 | ||||
|    * @return the wx cp message send result | ||||
|    * @throws WxErrorException the wx error exception | ||||
|    */ | ||||
|   WxCpMessageSendResult sendLinkedCorpMessage(WxCpLinkedCorpMessage message) throws WxErrorException; | ||||
| } | ||||
|  | ||||
| @ -8,8 +8,6 @@ import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | ||||
| import me.chanjar.weixin.cp.bean.WxCpProviderToken; | ||||
| import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
|  | ||||
|  | ||||
| @ -6,7 +6,7 @@ import me.chanjar.weixin.common.util.json.GsonParser; | ||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
| import me.chanjar.weixin.cp.api.WxCpChatService; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpAppChatMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpChat; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
|  | ||||
| @ -1,17 +1,19 @@ | ||||
| package me.chanjar.weixin.cp.api.impl; | ||||
|  | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.api.WxCpGroupRobotService; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpGroupRobotMessage; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpGroupRobotMessage; | ||||
| import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
| import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType; | ||||
| import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType.*; | ||||
|  | ||||
| /** | ||||
|  * 微信群机器人消息发送api 实现 | ||||
|  * | ||||
| @ -30,7 +32,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService { | ||||
|   @Override | ||||
|   public void sendText(String content, List<String> mentionedList, List<String> mobileList) throws WxErrorException { | ||||
|     WxCpGroupRobotMessage message = new WxCpGroupRobotMessage() | ||||
|       .setMsgType(WxConsts.GroupRobotMsgType.TEXT) | ||||
|       .setMsgType(TEXT) | ||||
|       .setContent(content) | ||||
|       .setMentionedList(mentionedList) | ||||
|       .setMentionedMobileList(mobileList); | ||||
| @ -40,7 +42,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService { | ||||
|   @Override | ||||
|   public void sendMarkDown(String content) throws WxErrorException { | ||||
|     WxCpGroupRobotMessage message = new WxCpGroupRobotMessage() | ||||
|       .setMsgType(WxConsts.GroupRobotMsgType.MARKDOWN) | ||||
|       .setMsgType(MARKDOWN) | ||||
|       .setContent(content); | ||||
|     cpService.postWithoutToken(this.getApiUrl(), message.toJson()); | ||||
|   } | ||||
| @ -48,7 +50,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService { | ||||
|   @Override | ||||
|   public void sendImage(String base64, String md5) throws WxErrorException { | ||||
|     WxCpGroupRobotMessage message = new WxCpGroupRobotMessage() | ||||
|       .setMsgType(WxConsts.GroupRobotMsgType.IMAGE) | ||||
|       .setMsgType(GroupRobotMsgType.IMAGE) | ||||
|       .setBase64(base64) | ||||
|       .setMd5(md5); | ||||
|     cpService.postWithoutToken(this.getApiUrl(), message.toJson()); | ||||
| @ -57,7 +59,7 @@ public class WxCpGroupRobotServiceImpl implements WxCpGroupRobotService { | ||||
|   @Override | ||||
|   public void sendNews(List<NewArticle> articleList) throws WxErrorException { | ||||
|     WxCpGroupRobotMessage message = new WxCpGroupRobotMessage() | ||||
|       .setMsgType(WxConsts.GroupRobotMsgType.NEWS) | ||||
|       .setMsgType(GroupRobotMsgType.NEWS) | ||||
|       .setArticles(articleList); | ||||
|     cpService.postWithoutToken(this.getApiUrl(), message.toJson()); | ||||
|   } | ||||
|  | ||||
| @ -4,8 +4,9 @@ import lombok.RequiredArgsConstructor; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.api.WxCpMessageService; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult; | ||||
| import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | ||||
|  | ||||
| /** | ||||
| @ -19,7 +20,7 @@ public class WxCpMessageServiceImpl implements WxCpMessageService { | ||||
|   private final WxCpService cpService; | ||||
|  | ||||
|   @Override | ||||
|   public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException { | ||||
|   public WxCpMessageSendResult send(WxCpMessage message) throws WxErrorException { | ||||
|     Integer agentId = message.getAgentId(); | ||||
|     if (null == agentId) { | ||||
|       message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId()); | ||||
| @ -28,4 +29,15 @@ public class WxCpMessageServiceImpl implements WxCpMessageService { | ||||
|     return WxCpMessageSendResult.fromJson(this.cpService.post(this.cpService.getWxCpConfigStorage() | ||||
|       .getApiUrl(WxCpApiPathConsts.Message.MESSAGE_SEND), message.toJson())); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxCpMessageSendResult sendLinkedCorpMessage(WxCpLinkedCorpMessage message) throws WxErrorException { | ||||
|     Integer agentId = message.getAgentId(); | ||||
|     if (null == agentId) { | ||||
|       message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId()); | ||||
|     } | ||||
|  | ||||
|     return WxCpMessageSendResult.fromJson(this.cpService.post(this.cpService.getWxCpConfigStorage() | ||||
|       .getApiUrl(WxCpApiPathConsts.Message.LINKEDCORP_MESSAGE_SEND), message.toJson())); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -37,4 +37,8 @@ public class NewArticle implements Serializable { | ||||
|    */ | ||||
|   private String picUrl; | ||||
|  | ||||
|   /** | ||||
|    * 按钮文字,仅在图文数为1条时才生效。 默认为“阅读全文”, 不超过4个文字,超过自动截断。该设置只在企业微信上生效,微工作台(原企业号)上不生效。 | ||||
|    */ | ||||
|   private String btnText; | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | ||||
| @ -10,7 +10,7 @@ import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| import static me.chanjar.weixin.common.api.WxConsts.GroupRobotMsgType.*; | ||||
| import static me.chanjar.weixin.cp.constant.WxCpConsts.GroupRobotMsgType.*; | ||||
| 
 | ||||
| /** | ||||
|  * 微信群机器人消息 | ||||
| @ -0,0 +1,244 @@ | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
|  | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Builder; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| import lombok.experimental.Accessors; | ||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | ||||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
| import org.apache.commons.lang3.ArrayUtils; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import static me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType.*; | ||||
|  | ||||
| /** | ||||
|  * 互联企业消息. | ||||
|  * | ||||
|  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
|  * @date 2020-08-30 | ||||
|  */ | ||||
| @Data | ||||
| @Builder | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| @Accessors(chain = true) | ||||
| public class WxCpLinkedCorpMessage implements Serializable { | ||||
|   private static final long serialVersionUID = 8833792280163704238L; | ||||
|  | ||||
|   /** | ||||
|    * 1表示发送给应用可见范围内的所有人(包括互联企业的成员),默认为0 | ||||
|    */ | ||||
|   private Boolean isToAll; | ||||
|  | ||||
|   /** | ||||
|    * 成员ID列表(消息接收者,最多支持1000个)。每个元素的格式为: corpid/userid,其中,corpid为该互联成员所属的企业,userid为该互联成员所属企业中的帐号。如果是本企业的成员,则直接传userid即可 | ||||
|    */ | ||||
|   private String[] toUsers; | ||||
|   /** | ||||
|    * 部门ID列表,最多支持100个。partyid在互联圈子内唯一。每个元素都是字符串类型,格式为:linked_id/party_id,其中linked_id是互联id,party_id是在互联圈子中的部门id。如果是本企业的部门,则直接传party_id即可。 | ||||
|    */ | ||||
|   private String[] toParties; | ||||
|   /** | ||||
|    * 本企业的标签ID列表,最多支持100个。 | ||||
|    */ | ||||
|   private String[] toTags; | ||||
|  | ||||
|   /** | ||||
|    * 企业应用的id,整型。可在应用的设置页面查看 | ||||
|    */ | ||||
|   private Integer agentId; | ||||
|   private String msgType; | ||||
|   /** | ||||
|    * 消息内容,最长不超过2048个字节 | ||||
|    */ | ||||
|   private String content; | ||||
|  | ||||
|   /** | ||||
|    * 图片媒体文件id,可以调用上传临时素材接口获取 | ||||
|    */ | ||||
|   private String mediaId; | ||||
|   private String thumbMediaId; | ||||
|   private String title; | ||||
|   private String description; | ||||
|   /** | ||||
|    * 表示是否是保密消息,0表示否,1表示是,默认0 | ||||
|    */ | ||||
|   private Boolean isSafe; | ||||
|   private String url; | ||||
|   private String btnTxt; | ||||
|   private List<NewArticle> articles = new ArrayList<>(); | ||||
|   private List<MpnewsArticle> mpNewsArticles = new ArrayList<>(); | ||||
|   private String appId; | ||||
|   private String page; | ||||
|   private Boolean emphasisFirstItem; | ||||
|   private Map<String, String> contentItems; | ||||
|  | ||||
|   /** | ||||
|    * <pre> | ||||
|    * 请使用. | ||||
|    * {@link LinkedCorpMsgType#TEXT} | ||||
|    * {@link LinkedCorpMsgType#IMAGE} | ||||
|    * {@link LinkedCorpMsgType#VIDEO} | ||||
|    * {@link LinkedCorpMsgType#NEWS} | ||||
|    * {@link LinkedCorpMsgType#MPNEWS} | ||||
|    * {@link LinkedCorpMsgType#MARKDOWN} | ||||
|    * {@link LinkedCorpMsgType#MINIPROGRAM_NOTICE} | ||||
|    * </pre> | ||||
|    * | ||||
|    * @param msgType 消息类型 | ||||
|    */ | ||||
|   public void setMsgType(String msgType) { | ||||
|     this.msgType = msgType; | ||||
|   } | ||||
|  | ||||
|   public String toJson() { | ||||
|     JsonObject messageJson = new JsonObject(); | ||||
|  | ||||
|     if (ArrayUtils.isNotEmpty(this.getToUsers())) { | ||||
|       messageJson.add("touser", WxGsonBuilder.create().toJsonTree(this.getToUsers())); | ||||
|     } | ||||
|  | ||||
|     if (ArrayUtils.isNotEmpty(this.getToParties())) { | ||||
|       messageJson.add("toparty", WxGsonBuilder.create().toJsonTree(this.getToParties())); | ||||
|     } | ||||
|  | ||||
|     if (ArrayUtils.isNotEmpty(this.getToTags())) { | ||||
|       messageJson.add("totag", WxGsonBuilder.create().toJsonTree(this.getToTags())); | ||||
|     } | ||||
|  | ||||
|     if (this.getIsToAll() != null) { | ||||
|       messageJson.addProperty("toall", this.getIsToAll() ? 1 : 0); | ||||
|     } | ||||
|     messageJson.addProperty("msgtype", this.getMsgType()); | ||||
|  | ||||
|     if (this.getAgentId() != null) { | ||||
|       messageJson.addProperty("agentid", this.getAgentId()); | ||||
|     } | ||||
|  | ||||
|     this.handleMsgType(messageJson); | ||||
|  | ||||
|     if (this.getIsSafe() != null) { | ||||
|       messageJson.addProperty("safe", this.getIsSafe() ? 1 : 0); | ||||
|     } | ||||
|  | ||||
|     return messageJson.toString(); | ||||
|   } | ||||
|  | ||||
|   private void handleMsgType(JsonObject messageJson) { | ||||
|     switch (this.getMsgType()) { | ||||
|       case TEXT: { | ||||
|         JsonObject text = new JsonObject(); | ||||
|         text.addProperty("content", this.getContent()); | ||||
|         messageJson.add("text", text); | ||||
|         break; | ||||
|       } | ||||
|       case MARKDOWN: { | ||||
|         JsonObject text = new JsonObject(); | ||||
|         text.addProperty("content", this.getContent()); | ||||
|         messageJson.add("markdown", text); | ||||
|         break; | ||||
|       } | ||||
|       case TEXTCARD: { | ||||
|         JsonObject text = new JsonObject(); | ||||
|         text.addProperty("title", this.getTitle()); | ||||
|         text.addProperty("description", this.getDescription()); | ||||
|         text.addProperty("url", this.getUrl()); | ||||
|         text.addProperty("btntxt", this.getBtnTxt()); | ||||
|         messageJson.add("textcard", text); | ||||
|         break; | ||||
|       } | ||||
|       case IMAGE: { | ||||
|         JsonObject image = new JsonObject(); | ||||
|         image.addProperty("media_id", this.getMediaId()); | ||||
|         messageJson.add("image", image); | ||||
|         break; | ||||
|       } | ||||
|       case FILE: { | ||||
|         JsonObject image = new JsonObject(); | ||||
|         image.addProperty("media_id", this.getMediaId()); | ||||
|         messageJson.add("file", image); | ||||
|         break; | ||||
|       } | ||||
|       case VIDEO: { | ||||
|         JsonObject video = new JsonObject(); | ||||
|         video.addProperty("media_id", this.getMediaId()); | ||||
|         video.addProperty("title", this.getTitle()); | ||||
|         video.addProperty("description", this.getDescription()); | ||||
|         messageJson.add("video", video); | ||||
|         break; | ||||
|       } | ||||
|       case NEWS: { | ||||
|         JsonObject newsJsonObject = new JsonObject(); | ||||
|         JsonArray articleJsonArray = new JsonArray(); | ||||
|         for (NewArticle article : this.getArticles()) { | ||||
|           JsonObject articleJson = new JsonObject(); | ||||
|           articleJson.addProperty("title", article.getTitle()); | ||||
|           articleJson.addProperty("description", article.getDescription()); | ||||
|           articleJson.addProperty("url", article.getUrl()); | ||||
|           articleJson.addProperty("picurl", article.getPicUrl()); | ||||
|           articleJson.addProperty("btntxt", article.getBtnText()); | ||||
|           articleJsonArray.add(articleJson); | ||||
|         } | ||||
|         newsJsonObject.add("articles", articleJsonArray); | ||||
|         messageJson.add("news", newsJsonObject); | ||||
|         break; | ||||
|       } | ||||
|       case MPNEWS: { | ||||
|         JsonObject newsJsonObject = new JsonObject(); | ||||
|         if (this.getMediaId() != null) { | ||||
|           newsJsonObject.addProperty("media_id", this.getMediaId()); | ||||
|         } else { | ||||
|           JsonArray articleJsonArray = new JsonArray(); | ||||
|           for (MpnewsArticle article : this.getMpNewsArticles()) { | ||||
|             JsonObject articleJson = new JsonObject(); | ||||
|             articleJson.addProperty("title", article.getTitle()); | ||||
|             articleJson.addProperty("thumb_media_id", article.getThumbMediaId()); | ||||
|             articleJson.addProperty("author", article.getAuthor()); | ||||
|             articleJson.addProperty("content_source_url", article.getContentSourceUrl()); | ||||
|             articleJson.addProperty("content", article.getContent()); | ||||
|             articleJson.addProperty("digest", article.getDigest()); | ||||
|             if (article.getShowCoverPic() != null) { | ||||
|               articleJson.addProperty("show_cover_pic", article.getShowCoverPic()); | ||||
|             } | ||||
|             articleJsonArray.add(articleJson); | ||||
|           } | ||||
|  | ||||
|           newsJsonObject.add("articles", articleJsonArray); | ||||
|         } | ||||
|         messageJson.add("mpnews", newsJsonObject); | ||||
|         break; | ||||
|       } | ||||
|       case MINIPROGRAM_NOTICE: { | ||||
|         JsonObject notice = new JsonObject(); | ||||
|         notice.addProperty("appid", this.getAppId()); | ||||
|         notice.addProperty("page", this.getPage()); | ||||
|         notice.addProperty("title", this.getTitle()); | ||||
|         notice.addProperty("description", this.getDescription()); | ||||
|         notice.addProperty("emphasis_first_item", this.getEmphasisFirstItem()); | ||||
|         JsonArray content = new JsonArray(); | ||||
|         for (Map.Entry<String, String> item : this.getContentItems().entrySet()) { | ||||
|           JsonObject articleJson = new JsonObject(); | ||||
|           articleJson.addProperty("key", item.getKey()); | ||||
|           articleJson.addProperty("value", item.getValue()); | ||||
|           content.add(articleJson); | ||||
|         } | ||||
|         notice.add("content_item", content); | ||||
|  | ||||
|         messageJson.add("miniprogram_notice", notice); | ||||
|         break; | ||||
|       } | ||||
|       default: { | ||||
|         // do nothing | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.util.Collections; | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.util.Map; | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| @ -1,4 +1,4 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
|  | ||||
| public class BaseBuilder<T> { | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
|  | ||||
| /** | ||||
|  * 获得消息builder | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
|  | ||||
| /** | ||||
|  * 获得消息builder | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
|  | ||||
| /** | ||||
|  * <pre> | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
|  | ||||
| import java.util.Map; | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
|  | ||||
| /** | ||||
|  * 文本消息builder | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
|  | ||||
| /** | ||||
|  * <pre> | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
|  | ||||
| /** | ||||
|  * 视频消息builder | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.messagebuilder; | ||||
|  | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
|  | ||||
| /** | ||||
|  * 语音消息builder | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package me.chanjar.weixin.cp.bean.outxmlbuilder; | ||||
|  | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
|  | ||||
| public abstract class BaseBuilder<BuilderType, ValueType> { | ||||
|  | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package me.chanjar.weixin.cp.bean.outxmlbuilder; | ||||
|  | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage; | ||||
|  | ||||
| /** | ||||
|  * 图片消息builder | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean.outxmlbuilder; | ||||
|  | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage.Item; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage.Item; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package me.chanjar.weixin.cp.bean.outxmlbuilder; | ||||
|  | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage; | ||||
|  | ||||
| /** | ||||
|  * 文本消息builder | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package me.chanjar.weixin.cp.bean.outxmlbuilder; | ||||
|  | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage; | ||||
|  | ||||
| /** | ||||
|  * 视频消息builder | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package me.chanjar.weixin.cp.bean.outxmlbuilder; | ||||
|  | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage; | ||||
|  | ||||
| /** | ||||
|  * 语音消息builder | ||||
|  | ||||
| @ -166,6 +166,75 @@ public class WxCpConsts { | ||||
|  | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 互联企业发送应用消息的消息类型. | ||||
|    */ | ||||
|   public static class LinkedCorpMsgType { | ||||
|     /** | ||||
|      * 文本消息. | ||||
|      */ | ||||
|     public static final String TEXT = "text"; | ||||
|     /** | ||||
|      * 图片消息. | ||||
|      */ | ||||
|     public static final String IMAGE = "image"; | ||||
|     /** | ||||
|      * 视频消息. | ||||
|      */ | ||||
|     public static final String VIDEO = "video"; | ||||
|     /** | ||||
|      * 图文消息(点击跳转到外链). | ||||
|      */ | ||||
|     public static final String NEWS = "news"; | ||||
|     /** | ||||
|      * 图文消息(点击跳转到图文消息页面). | ||||
|      */ | ||||
|     public static final String MPNEWS = "mpnews"; | ||||
|     /** | ||||
|      * markdown消息. | ||||
|      * (目前仅支持markdown语法的子集,微工作台(原企业号)不支持展示markdown消息) | ||||
|      */ | ||||
|     public static final String MARKDOWN = "markdown"; | ||||
|     /** | ||||
|      * 发送文件. | ||||
|      */ | ||||
|     public static final String FILE = "file"; | ||||
|     /** | ||||
|      * 文本卡片消息. | ||||
|      */ | ||||
|     public static final String TEXTCARD = "textcard"; | ||||
|  | ||||
|     /** | ||||
|      * 小程序通知消息. | ||||
|      */ | ||||
|     public static final String MINIPROGRAM_NOTICE = "miniprogram_notice"; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 群机器人的消息类型. | ||||
|    */ | ||||
|   public static class GroupRobotMsgType { | ||||
|     /** | ||||
|      * 文本消息. | ||||
|      */ | ||||
|     public static final String TEXT = "text"; | ||||
|  | ||||
|     /** | ||||
|      * 图片消息. | ||||
|      */ | ||||
|     public static final String IMAGE = "image"; | ||||
|  | ||||
|     /** | ||||
|      * markdown消息. | ||||
|      */ | ||||
|     public static final String MARKDOWN = "markdown"; | ||||
|  | ||||
|     /** | ||||
|      * 图文消息(点击跳转到外链). | ||||
|      */ | ||||
|     public static final String NEWS = "news"; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 应用推送消息的消息类型. | ||||
|    */ | ||||
|  | ||||
| @ -3,8 +3,8 @@ package me.chanjar.weixin.cp.message; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.session.WxSessionManager; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
|  | ||||
| import java.util.Map; | ||||
|  | ||||
|  | ||||
| @ -3,7 +3,7 @@ package me.chanjar.weixin.cp.message; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.session.WxSessionManager; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
|  | ||||
| import java.util.Map; | ||||
|  | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| package me.chanjar.weixin.cp.message; | ||||
|  | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
|  | ||||
| /** | ||||
|  * 消息匹配器,用在消息路由的时候 | ||||
|  | ||||
| @ -18,8 +18,8 @@ import me.chanjar.weixin.common.session.InternalSessionManager; | ||||
| import me.chanjar.weixin.common.session.WxSessionManager; | ||||
| import me.chanjar.weixin.common.util.LogExceptionHandler; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
|  | ||||
| /** | ||||
|  * <pre> | ||||
|  | ||||
| @ -4,8 +4,8 @@ import me.chanjar.weixin.common.api.WxErrorExceptionHandler; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.session.WxSessionManager; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
|  | ||||
| @ -1,135 +1,135 @@ | ||||
| package me.chanjar.weixin.cp.util.xml; | ||||
|  | ||||
| import java.io.InputStream; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| import com.thoughtworks.xstream.XStream; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||
| import me.chanjar.weixin.cp.bean.WxCpTpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage; | ||||
|  | ||||
| public class XStreamTransformer { | ||||
|  | ||||
|   protected static final Map<Class, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance(); | ||||
|  | ||||
|   /** | ||||
|    * xml -> pojo | ||||
|    */ | ||||
|   @SuppressWarnings("unchecked") | ||||
|   public static <T> T fromXml(Class<T> clazz, String xml) { | ||||
|     T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml); | ||||
|     return object; | ||||
|   } | ||||
|  | ||||
|   @SuppressWarnings("unchecked") | ||||
|   public static <T> T fromXml(Class<T> clazz, InputStream is) { | ||||
|     T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is); | ||||
|     return object; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 注册扩展消息的解析器. | ||||
|    * | ||||
|    * @param clz     类型 | ||||
|    * @param xStream xml解析器 | ||||
|    */ | ||||
|   public static void register(Class clz, XStream xStream) { | ||||
|     CLASS_2_XSTREAM_INSTANCE.put(clz, xStream); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * pojo -> xml. | ||||
|    */ | ||||
|   public static <T> String toXml(Class<T> clazz, T object) { | ||||
|     return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); | ||||
|   } | ||||
|  | ||||
|   private static Map<Class, XStream> configXStreamInstance() { | ||||
|     Map<Class, XStream> map = new HashMap<>(); | ||||
|     map.put(WxCpXmlMessage.class, configWxCpXmlMessage()); | ||||
|     map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage()); | ||||
|     map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage()); | ||||
|     map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage()); | ||||
|     map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage()); | ||||
|     map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage()); | ||||
|     map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage()); | ||||
|     map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage()); | ||||
|     return map; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class); | ||||
|     xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class); | ||||
|     xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class); | ||||
|     xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutImageMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutImageMessage.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutNewsMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutNewsMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutTextMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutTextMessage.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutVideoMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutVideoMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutVoiceMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutVoiceMessage.class); | ||||
|     return xstream; | ||||
|   } | ||||
|    | ||||
|   private static XStream configWxCpTpXmlPackage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|     xstream.processAnnotations(WxCpTpXmlPackage.class); | ||||
|      | ||||
|     return xstream; | ||||
|   } | ||||
|    | ||||
|   private static XStream configWxCpTpXmlMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|     xstream.processAnnotations(WxCpTpXmlMessage.class); | ||||
|      | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
| } | ||||
| package me.chanjar.weixin.cp.util.xml; | ||||
|  | ||||
| import java.io.InputStream; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| import com.thoughtworks.xstream.XStream; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamInitializer; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage; | ||||
|  | ||||
| public class XStreamTransformer { | ||||
|  | ||||
|   protected static final Map<Class, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance(); | ||||
|  | ||||
|   /** | ||||
|    * xml -> pojo | ||||
|    */ | ||||
|   @SuppressWarnings("unchecked") | ||||
|   public static <T> T fromXml(Class<T> clazz, String xml) { | ||||
|     T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml); | ||||
|     return object; | ||||
|   } | ||||
|  | ||||
|   @SuppressWarnings("unchecked") | ||||
|   public static <T> T fromXml(Class<T> clazz, InputStream is) { | ||||
|     T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is); | ||||
|     return object; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 注册扩展消息的解析器. | ||||
|    * | ||||
|    * @param clz     类型 | ||||
|    * @param xStream xml解析器 | ||||
|    */ | ||||
|   public static void register(Class clz, XStream xStream) { | ||||
|     CLASS_2_XSTREAM_INSTANCE.put(clz, xStream); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * pojo -> xml. | ||||
|    */ | ||||
|   public static <T> String toXml(Class<T> clazz, T object) { | ||||
|     return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); | ||||
|   } | ||||
|  | ||||
|   private static Map<Class, XStream> configXStreamInstance() { | ||||
|     Map<Class, XStream> map = new HashMap<>(); | ||||
|     map.put(WxCpXmlMessage.class, configWxCpXmlMessage()); | ||||
|     map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage()); | ||||
|     map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage()); | ||||
|     map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage()); | ||||
|     map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage()); | ||||
|     map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage()); | ||||
|     map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage()); | ||||
|     map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage()); | ||||
|     return map; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class); | ||||
|     xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class); | ||||
|     xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class); | ||||
|     xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutImageMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutImageMessage.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutNewsMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutNewsMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutTextMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutTextMessage.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutVideoMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutVideoMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpXmlOutVoiceMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|  | ||||
|     xstream.processAnnotations(WxCpXmlOutMessage.class); | ||||
|     xstream.processAnnotations(WxCpXmlOutVoiceMessage.class); | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpTpXmlPackage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|     xstream.processAnnotations(WxCpTpXmlPackage.class); | ||||
|  | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
|   private static XStream configWxCpTpXmlMessage() { | ||||
|     XStream xstream = XStreamInitializer.getInstance(); | ||||
|     xstream.processAnnotations(WxCpTpXmlMessage.class); | ||||
|  | ||||
|     return xstream; | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -6,8 +6,8 @@ import me.chanjar.weixin.common.session.WxSessionManager; | ||||
| import me.chanjar.weixin.cp.message.WxCpMessageHandler; | ||||
| import me.chanjar.weixin.cp.message.WxCpMessageMatcher; | ||||
| import me.chanjar.weixin.cp.message.WxCpMessageRouter; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import org.testng.Assert; | ||||
| import org.testng.annotations.DataProvider; | ||||
| import org.testng.annotations.Test; | ||||
|  | ||||
| @ -11,7 +11,7 @@ import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.constant.WxCpConsts.AppChatMsgType; | ||||
| import me.chanjar.weixin.cp.api.ApiTestModule; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpAppChatMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpChat; | ||||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
|  | ||||
| @ -16,8 +16,6 @@ import java.io.InputStream; | ||||
| import java.util.stream.Collectors; | ||||
| import java.util.stream.Stream; | ||||
|  | ||||
| import static org.testng.Assert.*; | ||||
|  | ||||
| /** | ||||
|  * 微信群机器人消息发送api 单元测试 | ||||
|  * | ||||
| @ -62,7 +60,8 @@ public class WxCpGroupRobotServiceImplTest { | ||||
|  | ||||
|   @Test | ||||
|   public void testSendNews() throws WxErrorException { | ||||
|     NewArticle article = new NewArticle("图文消息测试","hello world","http://www.baidu.com","http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png"); | ||||
|     NewArticle article = new NewArticle("图文消息测试", "hello world", "http://www.baidu.com", | ||||
|       "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png", null); | ||||
|     robotService.sendNews(Stream.of(article).collect(Collectors.toList())); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -9,8 +9,9 @@ import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.api.ApiTestModule; | ||||
| import me.chanjar.weixin.cp.api.ApiTestModuleWithMockServer; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult; | ||||
| import org.testng.annotations.AfterTest; | ||||
| import org.testng.annotations.BeforeTest; | ||||
| import org.testng.annotations.Guice; | ||||
| @ -57,7 +58,7 @@ public class WxCpMessageServiceImplTest { | ||||
|     message.setToUser(configStorage.getUserId()); | ||||
|     message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | ||||
|  | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message); | ||||
|     assertNotNull(messageSendResult); | ||||
|     System.out.println(messageSendResult); | ||||
|     System.out.println(messageSendResult.getInvalidPartyList()); | ||||
| @ -74,7 +75,7 @@ public class WxCpMessageServiceImplTest { | ||||
|       .content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>") | ||||
|       .build(); | ||||
|  | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message); | ||||
|     assertNotNull(messageSendResult); | ||||
|     System.out.println(messageSendResult); | ||||
|     System.out.println(messageSendResult.getInvalidPartyList()); | ||||
| @ -102,7 +103,7 @@ public class WxCpMessageServiceImplTest { | ||||
|         "                >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)") | ||||
|       .build(); | ||||
|  | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message); | ||||
|     assertNotNull(messageSendResult); | ||||
|     System.out.println(messageSendResult); | ||||
|     System.out.println(messageSendResult.getInvalidPartyList()); | ||||
| @ -121,7 +122,7 @@ public class WxCpMessageServiceImplTest { | ||||
|       .title("领奖通知") | ||||
|       .build(); | ||||
|  | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message); | ||||
|     assertNotNull(messageSendResult); | ||||
|     System.out.println(messageSendResult); | ||||
|     System.out.println(messageSendResult.getInvalidPartyList()); | ||||
| @ -144,11 +145,20 @@ public class WxCpMessageServiceImplTest { | ||||
|         "会议时间", "2018年8月1日 09:00-09:30")) | ||||
|       .build(); | ||||
|  | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().messageSend(message); | ||||
|     WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message); | ||||
|     assertNotNull(messageSendResult); | ||||
|     System.out.println(messageSendResult); | ||||
|     System.out.println(messageSendResult.getInvalidPartyList()); | ||||
|     System.out.println(messageSendResult.getInvalidUserList()); | ||||
|     System.out.println(messageSendResult.getInvalidTagList()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testLinkedCorpMessageSend() throws WxErrorException { | ||||
|     this.wxService.getMessageService().sendLinkedCorpMessage(WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(WxConsts.KefuMsgType.TEXT) | ||||
|       .toUsers(new String[]{configStorage.getUserId()}) | ||||
|       .content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>") | ||||
|       .build()); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -4,8 +4,8 @@ import com.google.inject.Inject; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.api.ApiTestModule; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult; | ||||
| import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; | ||||
| import org.testng.annotations.Guice; | ||||
| import org.testng.annotations.Test; | ||||
| @ -49,7 +49,7 @@ public class WxCpTaskCardServiceImplTest { | ||||
|       .buttons(Arrays.asList(btn1, btn2)) | ||||
|       .build(); | ||||
|  | ||||
|     WxCpMessageSendResult messageSendResult = this.wxCpService.getMessageService().messageSend(message); | ||||
|     WxCpMessageSendResult messageSendResult = this.wxCpService.getMessageService().send(message); | ||||
|     assertNotNull(messageSendResult); | ||||
|     System.out.println(messageSendResult); | ||||
|     System.out.println(messageSendResult.getInvalidPartyList()); | ||||
|  | ||||
| @ -0,0 +1,374 @@ | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
|  | ||||
| import com.google.common.collect.ImmutableMap; | ||||
| import com.google.common.collect.Lists; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.common.util.json.GsonParser; | ||||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
| import org.testng.annotations.Test; | ||||
|  | ||||
| import static me.chanjar.weixin.common.api.WxConsts.*; | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
|  | ||||
| /** | ||||
|  * 测试用例中的json参考 https://work.weixin.qq.com/api/doc/90000/90135/90250 | ||||
|  * | ||||
|  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
|  * @date 2020-08-30 | ||||
|  */ | ||||
| public class WxCpLinkedCorpMessageTest { | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_text() { | ||||
|     WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(KefuMsgType.TEXT) | ||||
|       .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) | ||||
|       .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) | ||||
|       .toTags(new String[]{"tagid1", "tagid2"}) | ||||
|       .agentId(1) | ||||
|       .isToAll(false) | ||||
|       .isSafe(false) | ||||
|       .content("你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>,聪明避开排队。") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + | ||||
|       "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + | ||||
|       "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" + | ||||
|       "    \"toall\" : 0,\n" + | ||||
|       "    \"msgtype\" : \"text\",\n" + | ||||
|       "   \"agentid\" : 1,\n" + | ||||
|       "   \"text\" : {\n" + | ||||
|       "       \"content\" : \"你的快递已到,请携带工卡前往邮件中心领取。\\n出发前可查看<a href=\\\"http://work.weixin.qq.com\\\">邮件中心视频实况</a>,聪明避开排队。\"\n" + | ||||
|       "   },\n" + | ||||
|       "   \"safe\":0\n" + | ||||
|       "}"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_image() { | ||||
|     WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(KefuMsgType.IMAGE) | ||||
|       .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) | ||||
|       .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) | ||||
|       .toTags(new String[]{"tagid1", "tagid2"}) | ||||
|       .agentId(1) | ||||
|       .isToAll(false) | ||||
|       .isSafe(false) | ||||
|       .mediaId("MEDIA_ID") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + | ||||
|       "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + | ||||
|       "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" + | ||||
|       "    \"toall\" : 0,\n" + | ||||
|       "   \"msgtype\" : \"image\",\n" + | ||||
|       "   \"agentid\" : 1,\n" + | ||||
|       "   \"image\" : {\n" + | ||||
|       "        \"media_id\" : \"MEDIA_ID\"\n" + | ||||
|       "   },\n" + | ||||
|       "   \"safe\":0\n" + | ||||
|       "}"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_video() { | ||||
|     WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(KefuMsgType.VIDEO) | ||||
|       .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) | ||||
|       .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) | ||||
|       .toTags(new String[]{"tagid1", "tagid2"}) | ||||
|       .agentId(1) | ||||
|       .isToAll(false) | ||||
|       .isSafe(false) | ||||
|       .mediaId("MEDIA_ID") | ||||
|       .title("Title") | ||||
|       .description("Description") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + | ||||
|       "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + | ||||
|       "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" + | ||||
|       "    \"toall\" : 0,\n" + | ||||
|       "   \"msgtype\" : \"video\",\n" + | ||||
|       "   \"agentid\" : 1,\n" + | ||||
|       "   \"video\" : {\n" + | ||||
|       "        \"media_id\" : \"MEDIA_ID\",\n" + | ||||
|       "        \"title\" : \"Title\",\n" + | ||||
|       "       \"description\" : \"Description\"\n" + | ||||
|       "   },\n" + | ||||
|       "   \"safe\":0\n" + | ||||
|       "}\n"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_file() { | ||||
|     WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(KefuMsgType.FILE) | ||||
|       .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) | ||||
|       .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) | ||||
|       .toTags(new String[]{"tagid1", "tagid2"}) | ||||
|       .agentId(1) | ||||
|       .isToAll(false) | ||||
|       .isSafe(false) | ||||
|       .mediaId("1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + | ||||
|       "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + | ||||
|       "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" + | ||||
|       "    \"toall\" : 0,\n" + | ||||
|       "   \"msgtype\" : \"file\",\n" + | ||||
|       "   \"agentid\" : 1,\n" + | ||||
|       "   \"file\" : {\n" + | ||||
|       "        \"media_id\" : \"1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o\"\n" + | ||||
|       "   },\n" + | ||||
|       "   \"safe\":0\n" + | ||||
|       "}\n"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_textCard() { | ||||
|     WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(KefuMsgType.TEXTCARD) | ||||
|       .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) | ||||
|       .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) | ||||
|       .toTags(new String[]{"tagid1", "tagid2"}) | ||||
|       .agentId(1) | ||||
|       .isToAll(false) | ||||
|       .title("领奖通知") | ||||
|       .description("<div class=\"gray\">2016年9月26日</div> <div class=\"normal\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\"highlight\">请于2016年10月10日前联系行政同事领取</div>") | ||||
|       .url("URL") | ||||
|       .btnTxt("更多") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + | ||||
|       "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + | ||||
|       "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" + | ||||
|       "    \"toall\" : 0,\n" + | ||||
|       "   \"msgtype\" : \"textcard\",\n" + | ||||
|       "   \"agentid\" : 1,\n" + | ||||
|       "   \"textcard\" : {\n" + | ||||
|       "            \"title\" : \"领奖通知\",\n" + | ||||
|       "            \"description\" : \"<div class=\\\"gray\\\">2016年9月26日</div> <div class=\\\"normal\\\">恭喜你抽中iPhone 7一台,领奖码:xxxx</div><div class=\\\"highlight\\\">请于2016年10月10日前联系行政同事领取</div>\",\n" + | ||||
|       "            \"url\" : \"URL\",\n" + | ||||
|       "            \"btntxt\":\"更多\"\n" + | ||||
|       "   }\n" + | ||||
|       "}\n"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_news() { | ||||
|     WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(KefuMsgType.NEWS) | ||||
|       .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) | ||||
|       .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) | ||||
|       .toTags(new String[]{"tagid1", "tagid2"}) | ||||
|       .agentId(1) | ||||
|       .isToAll(false) | ||||
|       .articles(Lists.newArrayList(NewArticle.builder() | ||||
|         .title("中秋节礼品领取") | ||||
|         .description("今年中秋节公司有豪礼相送") | ||||
|         .url("URL") | ||||
|         .picUrl("http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png") | ||||
|         .btnText("更多") | ||||
|         .build())) | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + | ||||
|       "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + | ||||
|       "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" + | ||||
|       "    \"toall\" : 0,\n" + | ||||
|       "   \"msgtype\" : \"news\",\n" + | ||||
|       "   \"agentid\" : 1,\n" + | ||||
|       "   \"news\" : {\n" + | ||||
|       "       \"articles\" : [\n" + | ||||
|       "           {\n" + | ||||
|       "               \"title\" : \"中秋节礼品领取\",\n" + | ||||
|       "               \"description\" : \"今年中秋节公司有豪礼相送\",\n" + | ||||
|       "               \"url\" : \"URL\",\n" + | ||||
|       "               \"picurl\" : \"http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png\",\n" + | ||||
|       "               \"btntxt\":\"更多\"\n" + | ||||
|       "           }\n" + | ||||
|       "        ]\n" + | ||||
|       "   }\n" + | ||||
|       "}\n"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_mpnews() { | ||||
|     WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(KefuMsgType.MPNEWS) | ||||
|       .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) | ||||
|       .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) | ||||
|       .toTags(new String[]{"tagid1", "tagid2"}) | ||||
|       .agentId(1) | ||||
|       .isToAll(false) | ||||
|       .isSafe(false) | ||||
|       .mpNewsArticles(Lists.newArrayList(MpnewsArticle.newBuilder() | ||||
|         .title("Title") | ||||
|         .thumbMediaId("MEDIA_ID") | ||||
|         .author("Author") | ||||
|         .contentSourceUrl("URL") | ||||
|         .content("Content") | ||||
|         .digest("Digest description") | ||||
|         .build())) | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + | ||||
|       "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + | ||||
|       "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" + | ||||
|       "    \"toall\" : 0,\n" + | ||||
|       "   \"msgtype\" : \"mpnews\",\n" + | ||||
|       "   \"agentid\" : 1,\n" + | ||||
|       "   \"mpnews\" : {\n" + | ||||
|       "       \"articles\":[\n" + | ||||
|       "           {\n" + | ||||
|       "               \"title\": \"Title\", \n" + | ||||
|       "               \"thumb_media_id\": \"MEDIA_ID\",\n" + | ||||
|       "               \"author\": \"Author\",\n" + | ||||
|       "               \"content_source_url\": \"URL\",\n" + | ||||
|       "               \"content\": \"Content\",\n" + | ||||
|       "               \"digest\": \"Digest description\"\n" + | ||||
|       "            }\n" + | ||||
|       "       ]\n" + | ||||
|       "   },\n" + | ||||
|       "   \"safe\":0\n" + | ||||
|       "}\n"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_markdown() { | ||||
|     WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(KefuMsgType.MARKDOWN) | ||||
|       .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) | ||||
|       .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) | ||||
|       .toTags(new String[]{"tagid1", "tagid2"}) | ||||
|       .agentId(1) | ||||
|       .isToAll(false) | ||||
|       .content("您的会议室已经预定,稍后会同步到`邮箱`\n" + | ||||
|         "                >**事项详情**\n" + | ||||
|         "                >事 项:<font color=\"info\">开会</font>\n" + | ||||
|         "                >组织者:@miglioguan\n" + | ||||
|         "                >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang\n" + | ||||
|         "                >\n" + | ||||
|         "                >会议室:<font color=\"info\">广州TIT 1楼 301</font>\n" + | ||||
|         "                >日 期:<font color=\"warning\">2018年5月18日</font>\n" + | ||||
|         "                >时 间:<font color=\"comment\">上午9:00-11:00</font>\n" + | ||||
|         "                >\n" + | ||||
|         "                >请准时参加会议。\n" + | ||||
|         "                >\n" + | ||||
|         "                >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "   \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + | ||||
|       "   \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + | ||||
|       "   \"totag\" : [\"tagid1\",\"tagid2\"],\n" + | ||||
|       "   \"toall\" : 0,\n" + | ||||
|       "   \"msgtype\" : \"markdown\",\n" + | ||||
|       "   \"agentid\" : 1,\n" + | ||||
|       "   \"markdown\": {\n" + | ||||
|       "        \"content\": \"您的会议室已经预定,稍后会同步到`邮箱`\n" + | ||||
|       "                >**事项详情**\n" + | ||||
|       "                >事 项:<font color=\\\"info\\\">开会</font>\n" + | ||||
|       "                >组织者:@miglioguan\n" + | ||||
|       "                >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang\n" + | ||||
|       "                >\n" + | ||||
|       "                >会议室:<font color=\\\"info\\\">广州TIT 1楼 301</font>\n" + | ||||
|       "                >日 期:<font color=\\\"warning\\\">2018年5月18日</font>\n" + | ||||
|       "                >时 间:<font color=\\\"comment\\\">上午9:00-11:00</font>\n" + | ||||
|       "                >\n" + | ||||
|       "                >请准时参加会议。\n" + | ||||
|       "                >\n" + | ||||
|       "                >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)\"\n" + | ||||
|       "   }\n" + | ||||
|       "}\n"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_miniProgramNotice() { | ||||
|     WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder() | ||||
|       .msgType(KefuMsgType.MINIPROGRAM_NOTICE) | ||||
|       .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"}) | ||||
|       .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"}) | ||||
|       .toTags(new String[]{"tagid1", "tagid2"}) | ||||
|       .emphasisFirstItem(true) | ||||
|       .description("4月27日 16:16") | ||||
|       .title("会议室预订成功通知") | ||||
|       .appId("wx123123123123123") | ||||
|       .page("pages/index?userid=zhangsan&orderid=123123123") | ||||
|       .contentItems(ImmutableMap.of("会议室","402", | ||||
|         "会议地点","广州TIT-402会议室", | ||||
|         "会议时间","2018年8月1日 09:00-09:30", | ||||
|         "参与人员","周剑轩")) | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "    \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" + | ||||
|       "    \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" + | ||||
|       "    \"totag\" : [\"tagid1\",\"tagid2\"],\n" + | ||||
|       "   \"msgtype\" : \"miniprogram_notice\",\n" + | ||||
|       "   \"miniprogram_notice\" : {\n" + | ||||
|       "        \"appid\": \"wx123123123123123\",\n" + | ||||
|       "        \"page\": \"pages/index?userid=zhangsan&orderid=123123123\",\n" + | ||||
|       "        \"title\": \"会议室预订成功通知\",\n" + | ||||
|       "        \"description\": \"4月27日 16:16\",\n" + | ||||
|       "        \"emphasis_first_item\": true,\n" + | ||||
|       "        \"content_item\": [\n" + | ||||
|       "            {\n" + | ||||
|       "                \"key\": \"会议室\",\n" + | ||||
|       "                \"value\": \"402\"\n" + | ||||
|       "            },\n" + | ||||
|       "            {\n" + | ||||
|       "                \"key\": \"会议地点\",\n" + | ||||
|       "                \"value\": \"广州TIT-402会议室\"\n" + | ||||
|       "            },\n" + | ||||
|       "            {\n" + | ||||
|       "                \"key\": \"会议时间\",\n" + | ||||
|       "                \"value\": \"2018年8月1日 09:00-09:30\"\n" + | ||||
|       "            },\n" + | ||||
|       "            {\n" + | ||||
|       "                \"key\": \"参与人员\",\n" + | ||||
|       "                \"value\": \"周剑轩\"\n" + | ||||
|       "            }\n" + | ||||
|       "        ]\n" + | ||||
|       "    }\n" + | ||||
|       "}\n"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
| } | ||||
| @ -1,7 +1,8 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| @ -1,6 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.constant.WxCpConsts; | ||||
| import me.chanjar.weixin.cp.util.xml.XStreamTransformer; | ||||
| import org.testng.annotations.Test; | ||||
| @ -1,5 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import org.testng.Assert; | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| @ -1,5 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage; | ||||
| import org.testng.Assert; | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| @ -1,5 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage; | ||||
| import org.testng.Assert; | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| @ -1,5 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage; | ||||
| import org.testng.Assert; | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| @ -1,5 +1,7 @@ | ||||
| package me.chanjar.weixin.cp.bean; | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
| 
 | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage; | ||||
| import org.testng.Assert; | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| @ -13,9 +13,9 @@ import me.chanjar.weixin.common.session.WxSessionManager; | ||||
| import me.chanjar.weixin.cp.constant.WxCpConsts; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage; | ||||
| import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
| import me.chanjar.weixin.cp.message.WxCpMessageHandler; | ||||
| import me.chanjar.weixin.cp.message.WxCpMessageRouter; | ||||
|  | ||||
| @ -3,8 +3,8 @@ package me.chanjar.weixin.cp.demo; | ||||
| import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
| import me.chanjar.weixin.cp.message.WxCpMessageRouter; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; | ||||
| import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
|  | ||||
|  | ||||
| @ -14,5 +14,13 @@ | ||||
|     "response": { | ||||
|       "text": "{\"errcode\":0,\"errmsg\":\"ok\",\"invaliduser\":\"\"}" | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     "request": { | ||||
|       "uri": "/cgi-bin/linkedcorp/message/send" | ||||
|     }, | ||||
|     "response": { | ||||
|       "text": "{\"errcode\":0,\"errmsg\":\"ok\",\"invaliduser\":\"\"}" | ||||
|     } | ||||
|   } | ||||
| ] | ||||
|  | ||||
| @ -12,13 +12,13 @@ | ||||
|  | ||||
|   <test name="Bean_Test"> | ||||
|     <classes> | ||||
|       <class name="me.chanjar.weixin.cp.bean.WxCpMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.WxCpXmlMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.message.WxCpMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.message.WxCpXmlMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessageTest"/> | ||||
|       <class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessageTest"/> | ||||
|     </classes> | ||||
|   </test> | ||||
| </suite> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Binary Wang
					Binary Wang