mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 02:28:25 +08:00 
			
		
		
		
	🆕 #2725【企业微信】增加家校沟通-发送「学校通知」的接口
This commit is contained in:
		| @ -10,7 +10,7 @@ import static me.chanjar.weixin.common.error.WxMpErrorMsgEnum.*; | ||||
| /** | ||||
|  * 微信开发所使用到的常量类. | ||||
|  * | ||||
|  * @author Daniel Qian & binarywang | ||||
|  * @author Daniel Qian & binarywang & Wang_Wong | ||||
|  */ | ||||
| public class WxConsts { | ||||
|   /** | ||||
| @ -133,6 +133,54 @@ public class WxConsts { | ||||
|     public static final String MP_NEWS_ARTICLE = "mpnewsarticle"; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 发送「学校通知」类型 | ||||
|    * https://developer.work.weixin.qq.com/document/path/92321 | ||||
|    */ | ||||
|   public static class SchoolContactMsgType { | ||||
|  | ||||
|     /** | ||||
|      * 文本消息. | ||||
|      */ | ||||
|     public static final String TEXT = "text"; | ||||
|  | ||||
|     /** | ||||
|      * 图片消息. | ||||
|      */ | ||||
|     public static final String IMAGE = "image"; | ||||
|  | ||||
|     /** | ||||
|      * 语音消息. | ||||
|      */ | ||||
|     public static final String VOICE = "voice"; | ||||
|  | ||||
|     /** | ||||
|      * 视频消息. | ||||
|      */ | ||||
|     public static final String VIDEO = "video"; | ||||
|  | ||||
|     /** | ||||
|      * 文件消息 | ||||
|      */ | ||||
|     public static final String FILE = "file"; | ||||
|  | ||||
|     /** | ||||
|      * 图文消息 | ||||
|      */ | ||||
|     public static final String NEWS = "news"; | ||||
|  | ||||
|     /** | ||||
|      * 图文消息(mpnews) | ||||
|      */ | ||||
|     public static final String MPNEWS = "mpnews"; | ||||
|  | ||||
|     /** | ||||
|      * 小程序消息 | ||||
|      */ | ||||
|     public static final String MINIPROGRAM = "miniprogram"; | ||||
|  | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 企业微信模板卡片消息的卡片类型 | ||||
|    */ | ||||
|  | ||||
| @ -50,4 +50,20 @@ public interface WxCpMessageService { | ||||
|    * @throws WxErrorException the wx error exception | ||||
|    */ | ||||
|   WxCpLinkedCorpMessageSendResult sendLinkedCorpMessage(WxCpLinkedCorpMessage message) throws WxErrorException; | ||||
|  | ||||
|   /** | ||||
|    * 发送「学校通知」 | ||||
|    * https://developer.work.weixin.qq.com/document/path/92321 | ||||
|    * <p> | ||||
|    * 学校可以通过此接口来给家长发送不同类型的学校通知,来满足多种场景下的学校通知需求。目前支持的消息类型为文本、图片、语音、视频、文件、图文。 | ||||
|    * <p> | ||||
|    * 请求方式:POST(HTTPS) | ||||
|    * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/externalcontact/message/send?access_token=ACCESS_TOKEN | ||||
|    * | ||||
|    * @param message 要发送的消息对象 | ||||
|    * @return | ||||
|    * @throws WxErrorException | ||||
|    */ | ||||
|   WxCpSchoolContactMessageSendResult sendSchoolContactMessage(WxCpSchoolContactMessage message) throws WxErrorException; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -29,6 +29,39 @@ public interface WxCpSchoolUserService { | ||||
|    */ | ||||
|   WxCpBaseResp createStudent(@NonNull String studentUserId, @NonNull String name, @NonNull List<Integer> departments) throws WxErrorException; | ||||
|  | ||||
|   /** | ||||
|    * 批量创建学生 | ||||
|    * 请求方式:POST(HTTPS) | ||||
|    * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/batch_create_student?access_token=ACCESS_TOKEN | ||||
|    * | ||||
|    * @param request | ||||
|    * @return | ||||
|    * @throws WxErrorException | ||||
|    */ | ||||
|   WxCpBatchResultList batchCreateStudent(@NonNull WxCpBatchCreateStudentRequest request) throws WxErrorException; | ||||
|  | ||||
|   /** | ||||
|    * 批量删除学生 | ||||
|    * 请求方式:POST(HTTPS) | ||||
|    * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/batch_delete_student?access_token=ACCESS_TOKEN | ||||
|    * | ||||
|    * @param request | ||||
|    * @return | ||||
|    * @throws WxErrorException | ||||
|    */ | ||||
|   WxCpBatchResultList batchDeleteStudent(@NonNull WxCpBatchDeleteStudentRequest request) throws WxErrorException; | ||||
|  | ||||
|   /** | ||||
|    * 批量更新学生 | ||||
|    * 请求方式:POST(HTTPS) | ||||
|    * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/batch_update_student?access_token=ACCESS_TOKEN | ||||
|    * | ||||
|    * @param request | ||||
|    * @return | ||||
|    * @throws WxErrorException | ||||
|    */ | ||||
|   WxCpBatchResultList batchUpdateStudent(@NonNull WxCpBatchUpdateStudentRequest request) throws WxErrorException; | ||||
|  | ||||
|   /** | ||||
|    * 删除学生 | ||||
|    * 请求方式:GET(HTTPS) | ||||
|  | ||||
| @ -46,4 +46,15 @@ public class WxCpMessageServiceImpl implements WxCpMessageService { | ||||
|     return WxCpLinkedCorpMessageSendResult.fromJson(this.cpService.post(this.cpService.getWxCpConfigStorage() | ||||
|       .getApiUrl(Message.LINKEDCORP_MESSAGE_SEND), message.toJson())); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxCpSchoolContactMessageSendResult sendSchoolContactMessage(WxCpSchoolContactMessage message) throws WxErrorException { | ||||
|     if (null == message.getAgentId()) { | ||||
|       message.setAgentId(this.cpService.getWxCpConfigStorage().getAgentId()); | ||||
|     } | ||||
|  | ||||
|     return WxCpSchoolContactMessageSendResult.fromJson(this.cpService.post(this.cpService.getWxCpConfigStorage() | ||||
|       .getApiUrl(Message.EXTERNAL_CONTACT_MESSAGE_SEND), message.toJson())); | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -47,6 +47,27 @@ public class WxCpSchoolUserServiceImpl implements WxCpSchoolUserService { | ||||
|     return WxCpBaseResp.fromJson(responseContent); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxCpBatchResultList batchCreateStudent(@NonNull WxCpBatchCreateStudentRequest request) throws WxErrorException { | ||||
|     String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(BATCH_CREATE_STUDENT); | ||||
|     String responseContent = this.cpService.post(apiUrl, request.toJson()); | ||||
|     return WxCpBatchResultList.fromJson(responseContent); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxCpBatchResultList batchDeleteStudent(@NonNull WxCpBatchDeleteStudentRequest request) throws WxErrorException { | ||||
|     String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(BATCH_DELETE_STUDENT); | ||||
|     String responseContent = this.cpService.post(apiUrl, request.toJson()); | ||||
|     return WxCpBatchResultList.fromJson(responseContent); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxCpBatchResultList batchUpdateStudent(@NonNull WxCpBatchUpdateStudentRequest request) throws WxErrorException { | ||||
|     String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(BATCH_UPDATE_STUDENT); | ||||
|     String responseContent = this.cpService.post(apiUrl, request.toJson()); | ||||
|     return WxCpBatchResultList.fromJson(responseContent); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxCpBaseResp deleteStudent(@NonNull String studentUserId) throws WxErrorException { | ||||
|     String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(DELETE_STUDENT) + studentUserId; | ||||
|  | ||||
| @ -20,18 +20,22 @@ import java.io.Serializable; | ||||
| @NoArgsConstructor | ||||
| public class NewArticle implements Serializable { | ||||
|   private static final long serialVersionUID = 4087852055781140659L; | ||||
|  | ||||
|   /** | ||||
|    * 标题,不超过128个字节,超过会自动截断 | ||||
|    */ | ||||
|   private String title; | ||||
|  | ||||
|   /** | ||||
|    * 描述,不超过512个字节,超过会自动截断 | ||||
|    */ | ||||
|   private String description; | ||||
|  | ||||
|   /** | ||||
|    * 点击后跳转的链接。 | ||||
|    */ | ||||
|   private String url; | ||||
|  | ||||
|   /** | ||||
|    * 图文消息的图片链接,支持JPG、PNG格式,较好的效果为大图1068*455,小图150*150。 | ||||
|    */ | ||||
| @ -42,9 +46,14 @@ public class NewArticle implements Serializable { | ||||
|    */ | ||||
|   private String btnText; | ||||
|  | ||||
|   /**小程序appid,必须是与当前应用关联的小程序,appid和pagepath必须同时填写,填写后会忽略url字段**/ | ||||
|   /** | ||||
|    * 小程序appid,必须是与当前应用关联的小程序,appid和pagepath必须同时填写,填写后会忽略url字段 | ||||
|    */ | ||||
|   private String appid; | ||||
|  | ||||
|   /**点击消息卡片后的小程序页面,仅限本小程序内的页面。appid和pagepath必须同时填写,填写后会忽略url字段**/ | ||||
|   /** | ||||
|    * 点击消息卡片后的小程序页面,仅限本小程序内的页面。appid和pagepath必须同时填写,填写后会忽略url字段 | ||||
|    */ | ||||
|   private String pagepath; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -21,6 +21,7 @@ import static me.chanjar.weixin.cp.constant.WxCpConsts.LinkedCorpMsgType.*; | ||||
|  | ||||
| /** | ||||
|  * 互联企业消息. | ||||
|  * https://developer.work.weixin.qq.com/document/path/90250 | ||||
|  * | ||||
|  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
|  * @date 2020-08-30 | ||||
|  | ||||
| @ -0,0 +1,311 @@ | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
|  | ||||
| import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | ||||
| import com.google.gson.annotations.SerializedName; | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Builder; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| import lombok.experimental.Accessors; | ||||
| import me.chanjar.weixin.common.api.WxConsts.SchoolContactMsgType; | ||||
| 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 static me.chanjar.weixin.common.api.WxConsts.SchoolContactMsgType.*; | ||||
|  | ||||
| /** | ||||
|  * 发送「学校通知」 | ||||
|  * https://developer.work.weixin.qq.com/document/path/92321 | ||||
|  * | ||||
|  * @author <a href="https://github.com/0katekate0">Wang_Wong</a> | ||||
|  * @date 2022-06-29 | ||||
|  */ | ||||
| @Data | ||||
| @Builder | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| @Accessors(chain = true) | ||||
| public class WxCpSchoolContactMessage implements Serializable { | ||||
|   private static final long serialVersionUID = 8833792280163704238L; | ||||
|  | ||||
|   /** | ||||
|    * 指定发送对象,0表示发送给家长,1表示发送给学生,2表示发送给家长和学生,默认为0。 | ||||
|    */ | ||||
|   @SerializedName("recv_scope") | ||||
|   private Integer recvScope = 0; | ||||
|  | ||||
|   /** | ||||
|    * 家校通讯录家长列表,recv_scope为0或2表示发送给对应的家长,recv_scope为1忽略,(最多支持1000个) | ||||
|    */ | ||||
|   @SerializedName("to_parent_userid") | ||||
|   private String[] toParentUserId; | ||||
|  | ||||
|   /** | ||||
|    * 家校通讯录学生列表,recv_scope为0表示发送给学生的所有家长,recv_scope为1表示发送给学生,recv_scope为2表示发送给学生和学生的所有家长(最多支持1000个) | ||||
|    */ | ||||
|   @SerializedName("to_student_userid") | ||||
|   private String[] toStudentUserId; | ||||
|  | ||||
|   /** | ||||
|    * 家校通讯录部门列表,recv_scope为0表示发送给班级的所有家长,recv_scope为1表示发送给班级的所有学生,recv_scope为2表示发送给班级的所有学生和家长(最多支持100个) | ||||
|    */ | ||||
|   @SerializedName("to_party") | ||||
|   private String[] toParty; | ||||
|  | ||||
|   /** | ||||
|    * 1表示字段生效,0表示字段无效。recv_scope为0表示发送给学校的所有家长,recv_scope为1表示发送给学校的所有学生,recv_scope为2表示发送给学校的所有学生和家长,默认为0 | ||||
|    */ | ||||
|   @SerializedName("toall") | ||||
|   private Boolean toAll = false; | ||||
|  | ||||
|   /** | ||||
|    * 消息类型 | ||||
|    */ | ||||
|   @SerializedName("msgtype") | ||||
|   private String msgType; | ||||
|  | ||||
|   /** | ||||
|    * 企业应用的id,整型。可在应用的设置页面查看 | ||||
|    */ | ||||
|   @SerializedName("agentid") | ||||
|   private Integer agentId; | ||||
|  | ||||
|   /** | ||||
|    * 消息内容,最长不超过2048个字节(支持id转译) | ||||
|    */ | ||||
|   @SerializedName("content") | ||||
|   private String content; | ||||
|  | ||||
|   /** | ||||
|    * enable_id_trans | ||||
|    * 表示是否开启id转译,0表示否,1表示是,默认0 | ||||
|    */ | ||||
|   @SerializedName("enable_id_trans") | ||||
|   private Boolean enableIdTrans = false; | ||||
|  | ||||
|   /** | ||||
|    * enable_duplicate_check | ||||
|    * 表示是否开启重复消息检查,0表示否,1表示是,默认0 | ||||
|    */ | ||||
|   @SerializedName("enable_duplicate_check") | ||||
|   private Boolean enableDuplicateCheck = false; | ||||
|  | ||||
|   /** | ||||
|    * duplicate_check_interval | ||||
|    * 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时 | ||||
|    */ | ||||
|   @SerializedName("duplicate_check_interval") | ||||
|   private Integer duplicateCheckInterval; | ||||
|  | ||||
|   /** | ||||
|    * 图片媒体文件id,可以调用上传临时素材接口获取 | ||||
|    */ | ||||
|   @SerializedName("media_id") | ||||
|   private String mediaId; | ||||
|  | ||||
|   /** | ||||
|    * 视频消息的标题,不超过128个字节,超过会自动截断 | ||||
|    */ | ||||
|   @SerializedName("title") | ||||
|   private String title; | ||||
|  | ||||
|   /** | ||||
|    * 视频消息的描述,不超过512个字节,超过会自动截断 | ||||
|    */ | ||||
|   @SerializedName("description") | ||||
|   private String description; | ||||
|  | ||||
|   /** | ||||
|    * 小程序消息封面的mediaid,封面图建议尺寸为520*416 | ||||
|    */ | ||||
|   @SerializedName("thumb_media_id") | ||||
|   private String thumbMediaId; | ||||
|  | ||||
|   /** | ||||
|    * 小程序appid,必须是关联到企业的小程序应用 | ||||
|    */ | ||||
|   @SerializedName("appid") | ||||
|   private String appId; | ||||
|  | ||||
|   /** | ||||
|    * 点击消息卡片后进入的小程序页面路径 | ||||
|    */ | ||||
|   @SerializedName("pagepath") | ||||
|   private String pagePath; | ||||
|  | ||||
|   /** | ||||
|    * 图文消息 | ||||
|    * https://developer.work.weixin.qq.com/document/path/92321#%E5%9B%BE%E6%96%87%E6%B6%88%E6%81%AF | ||||
|    */ | ||||
|   private List<NewArticle> articles = new ArrayList<>(); | ||||
|  | ||||
|   /** | ||||
|    * 图文消息(mpnews) | ||||
|    * https://developer.work.weixin.qq.com/document/path/92321#%E5%9B%BE%E6%96%87%E6%B6%88%E6%81%AF%EF%BC%88mpnews%EF%BC%89 | ||||
|    * <p> | ||||
|    * mpnews类型的图文消息,跟普通的图文消息一致,唯一的差异是图文内容存储在企业微信。 | ||||
|    * 多次发送mpnews,会被认为是不同的图文,阅读、点赞的统计会被分开计算。 | ||||
|    */ | ||||
|   private List<MpnewsArticle> mpNewsArticles = new ArrayList<>(); | ||||
|  | ||||
|   /** | ||||
|    * <pre> | ||||
|    * 请使用. | ||||
|    * {@link SchoolContactMsgType#TEXT} | ||||
|    * {@link SchoolContactMsgType#IMAGE} | ||||
|    * {@link SchoolContactMsgType#VOICE} | ||||
|    * {@link SchoolContactMsgType#VIDEO} | ||||
|    * {@link SchoolContactMsgType#NEWS} | ||||
|    * {@link SchoolContactMsgType#MPNEWS} | ||||
|    * {@link SchoolContactMsgType#MINIPROGRAM} | ||||
|    * </pre> | ||||
|    * | ||||
|    * @param msgType 消息类型 | ||||
|    */ | ||||
|   public void setMsgType(String msgType) { | ||||
|     this.msgType = msgType; | ||||
|   } | ||||
|  | ||||
|   public String toJson() { | ||||
|     JsonObject messageJson = new JsonObject(); | ||||
|  | ||||
|     if (this.getRecvScope() != null) { | ||||
|       messageJson.addProperty("recv_scope", this.getRecvScope()); | ||||
|     } | ||||
|  | ||||
|     if (ArrayUtils.isNotEmpty(this.getToParentUserId())) { | ||||
|       messageJson.add("to_parent_userid", WxGsonBuilder.create().toJsonTree(this.getToParentUserId())); | ||||
|     } | ||||
|  | ||||
|     if (ArrayUtils.isNotEmpty(this.getToStudentUserId())) { | ||||
|       messageJson.add("to_student_userid", WxGsonBuilder.create().toJsonTree(this.getToStudentUserId())); | ||||
|     } | ||||
|  | ||||
|     if (ArrayUtils.isNotEmpty(this.getToParty())) { | ||||
|       messageJson.add("to_party", WxGsonBuilder.create().toJsonTree(this.getToParty())); | ||||
|     } | ||||
|  | ||||
|     if (this.getToAll() != null) { | ||||
|       messageJson.addProperty("toall", this.getToAll() ? 1 : 0); | ||||
|     } | ||||
|  | ||||
|     messageJson.addProperty("msgtype", this.getMsgType()); | ||||
|  | ||||
|     if (this.getAgentId() != null) { | ||||
|       messageJson.addProperty("agentid", this.getAgentId()); | ||||
|     } | ||||
|  | ||||
|     if (this.getEnableIdTrans() != null && this.getEnableIdTrans()) { | ||||
|       messageJson.addProperty("enable_id_trans", 1); | ||||
|     } | ||||
|  | ||||
|     if (this.getEnableDuplicateCheck() != null && this.getEnableDuplicateCheck()) { | ||||
|       messageJson.addProperty("enable_duplicate_check", 1); | ||||
|     } | ||||
|  | ||||
|     if (this.getDuplicateCheckInterval() != null) { | ||||
|       messageJson.addProperty("duplicate_check_interval", this.getDuplicateCheckInterval()); | ||||
|     } | ||||
|  | ||||
|     this.handleMsgType(messageJson); | ||||
|  | ||||
|     return messageJson.toString(); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 封装消息类型 | ||||
|    * | ||||
|    * @param messageJson | ||||
|    */ | ||||
|   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 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 VOICE: { | ||||
|         JsonObject voice = new JsonObject(); | ||||
|         voice.addProperty("media_id", this.getMediaId()); | ||||
|         messageJson.add("voice", voice); | ||||
|         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()); | ||||
|           articleJsonArray.add(articleJson); | ||||
|         } | ||||
|         newsJsonObject.add("articles", articleJsonArray); | ||||
|         messageJson.add("news", newsJsonObject); | ||||
|         break; | ||||
|       } | ||||
|       case MPNEWS: { | ||||
|         JsonObject newsJsonObject = new JsonObject(); | ||||
|         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()); | ||||
|           articleJsonArray.add(articleJson); | ||||
|         } | ||||
|         newsJsonObject.add("articles", articleJsonArray); | ||||
|         messageJson.add("mpnews", newsJsonObject); | ||||
|         break; | ||||
|       } | ||||
|       case MINIPROGRAM: { | ||||
|         JsonObject miniprogram = new JsonObject(); | ||||
|         miniprogram.addProperty("appid", this.getAppId()); | ||||
|         miniprogram.addProperty("pagepath", this.getPagePath()); | ||||
|         miniprogram.addProperty("title", this.getTitle()); | ||||
|         miniprogram.addProperty("thumb_media_id", this.getThumbMediaId()); | ||||
|  | ||||
|         messageJson.add("miniprogram", miniprogram); | ||||
|         break; | ||||
|       } | ||||
|       default: { | ||||
|         // do nothing | ||||
|       } | ||||
|  | ||||
|     } | ||||
|  | ||||
|   } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,36 @@ | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
|  | ||||
| import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | ||||
| import me.chanjar.weixin.cp.bean.WxCpBaseResp; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
|  | ||||
| /** | ||||
|  * 发送「学校通知」返回实体 | ||||
|  * https://developer.work.weixin.qq.com/document/path/92321 | ||||
|  * | ||||
|  * @author <a href="https://github.com/0katekate0">Wang_Wong</a> | ||||
|  * @date 2022-06-29 | ||||
|  */ | ||||
| @Data | ||||
| public class WxCpSchoolContactMessageSendResult extends WxCpBaseResp { | ||||
|   private static final long serialVersionUID = 3990693822996824333L; | ||||
|  | ||||
|   @SerializedName("invalid_parent_userid") | ||||
|   private String[] invalidParentUserId; | ||||
|  | ||||
|   @SerializedName("invalid_student_userid") | ||||
|   private String[] invalidStudentUserId; | ||||
|  | ||||
|   @SerializedName("invalid_party") | ||||
|   private String[] invalidParty; | ||||
|  | ||||
|   public String toJson() { | ||||
|     return WxCpGsonBuilder.create().toJson(this); | ||||
|   } | ||||
|  | ||||
|   public static WxCpSchoolContactMessageSendResult fromJson(String json) { | ||||
|     return WxCpGsonBuilder.create().fromJson(json, WxCpSchoolContactMessageSendResult.class); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,59 @@ | ||||
| package me.chanjar.weixin.cp.bean.school.user; | ||||
|  | ||||
| import com.google.gson.annotations.SerializedName; | ||||
| import lombok.*; | ||||
| import lombok.experimental.Accessors; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 批量创建学生请求. | ||||
|  * | ||||
|  * @author Wang_Wong | ||||
|  * @date 2022-07-01 | ||||
|  */ | ||||
| @Data | ||||
| @Builder | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| @Accessors(chain = true) | ||||
| public class WxCpBatchCreateStudentRequest implements Serializable { | ||||
|   private static final long serialVersionUID = -4960239393895754138L; | ||||
|  | ||||
|   @SerializedName("students") | ||||
|   private List<Student> students; | ||||
|  | ||||
|   @Setter | ||||
|   @Getter | ||||
|   public static class Student implements Serializable { | ||||
|  | ||||
|     @SerializedName("student_userid") | ||||
|     private String studentUserId; | ||||
|  | ||||
|     @SerializedName("name") | ||||
|     private String name; | ||||
|  | ||||
|     @SerializedName("department") | ||||
|     private List<Integer> department; | ||||
|  | ||||
|     public static Student fromJson(String json) { | ||||
|       return WxCpGsonBuilder.create().fromJson(json, Student.class); | ||||
|     } | ||||
|  | ||||
|     public String toJson() { | ||||
|       return WxCpGsonBuilder.create().toJson(this); | ||||
|     } | ||||
|  | ||||
|   } | ||||
|  | ||||
|   public static WxCpBatchCreateStudentRequest fromJson(String json) { | ||||
|     return WxCpGsonBuilder.create().fromJson(json, WxCpBatchCreateStudentRequest.class); | ||||
|   } | ||||
|  | ||||
|   public String toJson() { | ||||
|     return WxCpGsonBuilder.create().toJson(this); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,36 @@ | ||||
| package me.chanjar.weixin.cp.bean.school.user; | ||||
|  | ||||
| import com.google.gson.annotations.SerializedName; | ||||
| import lombok.*; | ||||
| import lombok.experimental.Accessors; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 批量删除学生请求. | ||||
|  * | ||||
|  * @author Wang_Wong | ||||
|  * @date 2022-07-01 | ||||
|  */ | ||||
| @Data | ||||
| @Builder | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| @Accessors(chain = true) | ||||
| public class WxCpBatchDeleteStudentRequest implements Serializable { | ||||
|   private static final long serialVersionUID = -4960239393895754138L; | ||||
|  | ||||
|   @SerializedName("useridlist") | ||||
|   private List<String> userIdList; | ||||
|  | ||||
|   public static WxCpBatchDeleteStudentRequest fromJson(String json) { | ||||
|     return WxCpGsonBuilder.create().fromJson(json, WxCpBatchDeleteStudentRequest.class); | ||||
|   } | ||||
|  | ||||
|   public String toJson() { | ||||
|     return WxCpGsonBuilder.create().toJson(this); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,54 @@ | ||||
| package me.chanjar.weixin.cp.bean.school.user; | ||||
|  | ||||
| import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | ||||
| import lombok.Getter; | ||||
| import lombok.Setter; | ||||
| import me.chanjar.weixin.cp.bean.WxCpBaseResp; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 批量返回结果. | ||||
|  * | ||||
|  * @author Wang_Wong | ||||
|  * @date 2022-07-01 | ||||
|  */ | ||||
| @Data | ||||
| public class WxCpBatchResultList extends WxCpBaseResp implements Serializable { | ||||
|   private static final long serialVersionUID = -5028321625140879571L; | ||||
|  | ||||
|   @SerializedName("result_list") | ||||
|   private List<ResultList> resultList; | ||||
|  | ||||
|   @Setter | ||||
|   @Getter | ||||
|   public static class ResultList extends WxCpBaseResp{ | ||||
|  | ||||
|     @SerializedName("parent_userid") | ||||
|     private String parentUserId; | ||||
|  | ||||
|     @SerializedName("student_userid") | ||||
|     private String studentUserId; | ||||
|  | ||||
|     public static ResultList fromJson(String json) { | ||||
|       return WxCpGsonBuilder.create().fromJson(json, ResultList.class); | ||||
|     } | ||||
|  | ||||
|     public String toJson() { | ||||
|       return WxCpGsonBuilder.create().toJson(this); | ||||
|     } | ||||
|  | ||||
|   } | ||||
|  | ||||
|   public static WxCpBatchResultList fromJson(String json) { | ||||
|     return WxCpGsonBuilder.create().fromJson(json, WxCpBatchResultList.class); | ||||
|   } | ||||
|  | ||||
|   public String toJson() { | ||||
|     return WxCpGsonBuilder.create().toJson(this); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,62 @@ | ||||
| package me.chanjar.weixin.cp.bean.school.user; | ||||
|  | ||||
| import com.google.gson.annotations.SerializedName; | ||||
| import lombok.*; | ||||
| import lombok.experimental.Accessors; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 批量更新学生请求. | ||||
|  * | ||||
|  * @author Wang_Wong | ||||
|  * @date 2022-07-01 | ||||
|  */ | ||||
| @Data | ||||
| @Builder | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| @Accessors(chain = true) | ||||
| public class WxCpBatchUpdateStudentRequest implements Serializable { | ||||
|   private static final long serialVersionUID = -4960239393895754138L; | ||||
|  | ||||
|   @SerializedName("students") | ||||
|   private List<Student> students; | ||||
|  | ||||
|   @Setter | ||||
|   @Getter | ||||
|   public static class Student implements Serializable { | ||||
|  | ||||
|     @SerializedName("student_userid") | ||||
|     private String studentUserId; | ||||
|  | ||||
|     @SerializedName("new_student_userid") | ||||
|     private String newStudentUserId; | ||||
|  | ||||
|     @SerializedName("name") | ||||
|     private String name; | ||||
|  | ||||
|     @SerializedName("department") | ||||
|     private List<Integer> department; | ||||
|  | ||||
|     public static Student fromJson(String json) { | ||||
|       return WxCpGsonBuilder.create().fromJson(json, Student.class); | ||||
|     } | ||||
|  | ||||
|     public String toJson() { | ||||
|       return WxCpGsonBuilder.create().toJson(this); | ||||
|     } | ||||
|  | ||||
|   } | ||||
|  | ||||
|   public static WxCpBatchUpdateStudentRequest fromJson(String json) { | ||||
|     return WxCpGsonBuilder.create().fromJson(json, WxCpBatchUpdateStudentRequest.class); | ||||
|   } | ||||
|  | ||||
|   public String toJson() { | ||||
|     return WxCpGsonBuilder.create().toJson(this); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @ -28,6 +28,7 @@ public interface WxCpApiPathConsts { | ||||
|    * https://work.weixin.qq.com/api/doc/90000/90135/90235 | ||||
|    */ | ||||
|   interface Message { | ||||
|  | ||||
|     /** | ||||
|      * 发送应用消息 | ||||
|      */ | ||||
| @ -40,8 +41,16 @@ public interface WxCpApiPathConsts { | ||||
|  | ||||
|     /** | ||||
|      * 互联企业发送应用消息 | ||||
|      * https://developer.work.weixin.qq.com/document/path/90250 | ||||
|      */ | ||||
|     String LINKEDCORP_MESSAGE_SEND = "/cgi-bin/linkedcorp/message/send"; | ||||
|  | ||||
|     /** | ||||
|      * 发送「学校通知」 | ||||
|      * https://developer.work.weixin.qq.com/document/path/92321 | ||||
|      */ | ||||
|     String EXTERNAL_CONTACT_MESSAGE_SEND = "/cgi-bin/externalcontact/message/send"; | ||||
|  | ||||
|   } | ||||
|  | ||||
|   interface Agent { | ||||
| @ -183,6 +192,10 @@ public interface WxCpApiPathConsts { | ||||
|     String GET_STUDENT_CUSTOMIZE_HEALTH_INFO = "/cgi-bin/school/user/get_student_customize_health_info"; | ||||
|     String GET_HEALTH_QRCODE = "/cgi-bin/school/user/get_health_qrcode"; | ||||
|  | ||||
|     String BATCH_CREATE_STUDENT = "/cgi-bin/school/user/batch_create_student"; | ||||
|     String BATCH_DELETE_STUDENT = "/cgi-bin/school/user/batch_delete_student"; | ||||
|     String BATCH_UPDATE_STUDENT = "/cgi-bin/school/user/batch_update_student"; | ||||
|  | ||||
|     String CREATE_STUDENT = "/cgi-bin/school/user/create_student"; | ||||
|     String DELETE_STUDENT = "/cgi-bin/school/user/delete_student?userid="; | ||||
|     String UPDATE_STUDENT = "/cgi-bin/school/user/update_student"; | ||||
|  | ||||
| @ -52,6 +52,86 @@ public class WxCpSchoolUserTest { | ||||
|     final String exUserId = "wmOQpTDwAAJFHrryZ8I8ALLEZuLHIUKA"; | ||||
|  | ||||
|  | ||||
|     // 返回值 | ||||
|     String batchResult = "{\n" + | ||||
|       "\t\"errcode\": 1,\n" + | ||||
|       "\t\"errmsg\": \"invalid student_userid: zhangsan\",\n" + | ||||
|       "\t\"result_list\": [\n" + | ||||
|       "\t\t{\n" + | ||||
|       "\t\t\t\"student_userid\": \"zhangsan\",\n" + | ||||
|       "\t\t\t\"errcode\": 1,\n" + | ||||
|       "\t\t\t\"errmsg\": \"invalid student_userid: zhangsan\"\n" + | ||||
|       "\t\t}\n" + | ||||
|       "\t]\n" + | ||||
|       "}"; | ||||
|  | ||||
|     WxCpBatchResultList batchResultList = WxCpBatchResultList.fromJson(batchResult); | ||||
|     log.info("batchResultList: {}", batchResultList.toJson()); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 批量更新学生 | ||||
|      * https://developer.work.weixin.qq.com/document/path/92330 | ||||
|      * | ||||
|      * 请求方式:POST(HTTPS) | ||||
|      * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/batch_update_student?access_token=ACCESS_TOKEN | ||||
|      */ | ||||
|     String batchUpdateStudent = "{\n" + | ||||
|       "\t\"students\":[\n" + | ||||
|       "        {\n" + | ||||
|       "\t\t\t\"student_userid\": \"zhangsan\",\n" + | ||||
|       "\t\t\t\"new_student_userid\":\"zhangsan_new\",\n" + | ||||
|       "\t\t\t\"name\": \"张三\",\n" + | ||||
|       "\t\t\t\"department\": [1, 2]\n" + | ||||
|       "\t\t},\n" + | ||||
|       "        {\n" + | ||||
|       "\t\t\t\"student_userid\": \"lisi\",\n" + | ||||
|       "\t\t\t\"name\": \"李四\",\n" + | ||||
|       "\t\t\t\"department\": [3, 4]\n" + | ||||
|       "\t\t}\n" + | ||||
|       "     ]\n" + | ||||
|       "}"; | ||||
|     WxCpBatchUpdateStudentRequest batchUpdateStudentRequest = WxCpBatchUpdateStudentRequest.fromJson(batchUpdateStudent); | ||||
|     WxCpBatchResultList list3 = cpService.getSchoolUserService().batchUpdateStudent(batchUpdateStudentRequest); | ||||
|     log.info("list3: {}", list3.toJson()); | ||||
|  | ||||
|     /** | ||||
|      * 批量删除学生 | ||||
|      * https://developer.work.weixin.qq.com/document/path/92329 | ||||
|      * | ||||
|      * 请求方式:POST(HTTPS) | ||||
|      * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/batch_delete_student?access_token=ACCESS_TOKEN | ||||
|      */ | ||||
|     String batchDeleteStudent = "{\n" + | ||||
|       "\t\"useridlist\": [\"zhangsan\", \"lisi\"]\n" + | ||||
|       "}\n"; | ||||
|     WxCpBatchDeleteStudentRequest batchDeleteStudentRequest = WxCpBatchDeleteStudentRequest.fromJson(batchDeleteStudent); | ||||
|     WxCpBatchResultList list2 = cpService.getSchoolUserService().batchDeleteStudent(batchDeleteStudentRequest); | ||||
|     log.info("list2: {}", list2.toJson()); | ||||
|  | ||||
|     /** | ||||
|      * 批量创建学生 | ||||
|      * https://developer.work.weixin.qq.com/document/path/92328 | ||||
|      */ | ||||
|     String batchCreateStudent = "{\n" + | ||||
|       "\t\"students\":[\n" + | ||||
|       "        {\n" + | ||||
|       "\t\t\t\"student_userid\": \"zhangsan\",\n" + | ||||
|       "\t\t\t\"name\": \"张三\",\n" + | ||||
|       "\t\t\t\"department\": [1, 2]\n" + | ||||
|       "\t\t},\n" + | ||||
|       "        {\n" + | ||||
|       "\t\t\t\"student_userid\": \"lisi\",\n" + | ||||
|       "\t\t\t\"name\": \"李四\",\n" + | ||||
|       "\t\t\t\"department\": [3, 4]\n" + | ||||
|       "\t\t}\n" + | ||||
|       "     ]\n" + | ||||
|       "}"; | ||||
|     WxCpBatchCreateStudentRequest batchCreateStudentRequest = WxCpBatchCreateStudentRequest.fromJson(batchCreateStudent); | ||||
|     WxCpBatchResultList list1 = cpService.getSchoolUserService().batchCreateStudent(batchCreateStudentRequest); | ||||
|     log.info("list1: {}", list1.toJson()); | ||||
|  | ||||
|  | ||||
| //    String changeContact = WxCpConsts.EventType.CHANGE_CONTACT; | ||||
|     /** | ||||
|      * 增加变更事件类型: | ||||
|  | ||||
| @ -7,7 +7,6 @@ import com.google.inject.Inject; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| 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.message.WxCpLinkedCorpMessage; | ||||
| import me.chanjar.weixin.cp.bean.message.WxCpMessage; | ||||
|  | ||||
| @ -0,0 +1,395 @@ | ||||
| package me.chanjar.weixin.cp.bean.message; | ||||
|  | ||||
| import com.google.common.collect.Lists; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.json.GsonParser; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; | ||||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
| import me.chanjar.weixin.cp.config.WxCpConfigStorage; | ||||
| import me.chanjar.weixin.cp.demo.WxCpDemoInMemoryConfigStorage; | ||||
| import org.testng.annotations.Test; | ||||
|  | ||||
| import java.io.InputStream; | ||||
|  | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
|  | ||||
| /** | ||||
|  * 发送「学校通知」消息测试类 | ||||
|  * https://developer.work.weixin.qq.com/document/path/92321 | ||||
|  * | ||||
|  * @author <a href="https://github.com/0katekate0">Wang_Wong</a> | ||||
|  * @date 2022-06-29 | ||||
|  */ | ||||
| @Slf4j | ||||
| public class WxCpSchoolContactMessageTest { | ||||
|  | ||||
|   private static WxCpConfigStorage wxCpConfigStorage; | ||||
|   private static WxCpService cpService; | ||||
|  | ||||
|  | ||||
|   /** | ||||
|    * 发送「学校通知」 | ||||
|    * 学校可以通过此接口来给家长发送不同类型的学校通知,来满足多种场景下的学校通知需求。目前支持的消息类型为文本、图片、语音、视频、文件、图文。 | ||||
|    * | ||||
|    * https://developer.work.weixin.qq.com/document/path/92321 | ||||
|    * | ||||
|    * 消息体类型请参考测试类 | ||||
|    * WxCpSchoolContactMessageTest | ||||
|    * {@link WxCpSchoolContactMessageTest} | ||||
|    * @throws WxErrorException | ||||
|    */ | ||||
|   @Test | ||||
|   public void testSendSchoolContactMessage() throws WxErrorException { | ||||
|  | ||||
|     InputStream inputStream = ClassLoader.getSystemResourceAsStream("test-config.xml"); | ||||
|     WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(inputStream); | ||||
|  | ||||
|     wxCpConfigStorage = config; | ||||
|     cpService = new WxCpServiceImpl(); | ||||
|     cpService.setWxCpConfigStorage(config); | ||||
|  | ||||
|     WxCpSchoolContactMessageSendResult sendResult = this.cpService.getMessageService().sendSchoolContactMessage( | ||||
|  | ||||
|       WxCpSchoolContactMessage.builder() | ||||
|         .recvScope(0) | ||||
|         .msgType(WxConsts.SchoolContactMsgType.TEXT) | ||||
|         .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) | ||||
|         .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) | ||||
|         .toParty(new String[]{"partyid1", "partyid2"}) | ||||
|         .toAll(false) | ||||
|         .agentId(1) | ||||
|         .content("你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>,聪明避开排队。") | ||||
|         .enableIdTrans(false) | ||||
|         .enableDuplicateCheck(false) | ||||
|         .duplicateCheckInterval(1800) | ||||
|         .build() | ||||
|  | ||||
|     ); | ||||
|  | ||||
|     log.info("sendResult: {}", sendResult.toJson()); | ||||
|  | ||||
|   } | ||||
|  | ||||
|   //    WxCpConsts.SchoolContactChangeType | ||||
|   @Test | ||||
|   public void testToJson_text() { | ||||
|  | ||||
|     WxCpSchoolContactMessage message = WxCpSchoolContactMessage.builder() | ||||
|       .recvScope(0) | ||||
|       .msgType(WxConsts.SchoolContactMsgType.TEXT) | ||||
|       .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) | ||||
|       .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) | ||||
|       .toParty(new String[]{"partyid1", "partyid2"}) | ||||
|       .toAll(false) | ||||
|       .agentId(1) | ||||
|       .content("你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>,聪明避开排队。") | ||||
|       .enableIdTrans(false) | ||||
|       .enableDuplicateCheck(false) | ||||
|       .duplicateCheckInterval(1800) | ||||
|       .build(); | ||||
|  | ||||
|     WxCpSchoolContactMessage schoolContactMessage1 = new WxCpSchoolContactMessage(); | ||||
|     schoolContactMessage1.setMsgType(WxConsts.SchoolContactMsgType.TEXT); | ||||
|     schoolContactMessage1.setRecvScope(0); | ||||
|     schoolContactMessage1.setToParentUserId(new String[]{"parent_userid1", "parent_userid2"}); | ||||
|     schoolContactMessage1.setToStudentUserId(new String[]{"student_userid1", "student_userid2"}); | ||||
|     schoolContactMessage1.setToParty(new String[]{"partyid1", "partyid2"}); | ||||
|     schoolContactMessage1.setToAll(false); | ||||
|     schoolContactMessage1.setAgentId(1); | ||||
|     schoolContactMessage1.setContent("你的快递已到,请携带工卡前往邮件中心领取"); | ||||
|     schoolContactMessage1.setEnableIdTrans(false); | ||||
|     schoolContactMessage1.setEnableDuplicateCheck(false); | ||||
|     schoolContactMessage1.setDuplicateCheckInterval(1800); | ||||
|     final String jsonMsg = schoolContactMessage1.toJson(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "\t\"recv_scope\" : 0,\n" + | ||||
|       "\t\"to_parent_userid\": [\"parent_userid1\", \"parent_userid2\"],\n" + | ||||
|       "\t\"to_student_userid\": [\"student_userid1\", \"student_userid2\"],\n" + | ||||
|       "\t\"to_party\": [\"partyid1\", \"partyid2\"],\n" + | ||||
|       "\t\"toall\" : 0,\n" + | ||||
|       "\t\"msgtype\" : \"text\",\n" + | ||||
|       "\t\"agentid\" : 1,\n" + | ||||
|       "\t\"text\" : {\n" + | ||||
|       "\t\t\"content\" : \"你的快递已到,请携带工卡前往邮件中心领取。\\n出发前可查看<a href=\\\"http://work.weixin.qq.com\\\">邮件中心视频实况</a>,聪明避开排队。\"\n" + | ||||
|       "\t},\n" + | ||||
|       "\t\"enable_id_trans\": 0,\n" + | ||||
|       "\t\"enable_duplicate_check\": 0,\n" + | ||||
|       "\t\"duplicate_check_interval\": 1800\n" + | ||||
|       "}"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_image() { | ||||
|     WxCpSchoolContactMessage message = WxCpSchoolContactMessage.builder() | ||||
|       .recvScope(0) | ||||
|       .msgType(WxConsts.SchoolContactMsgType.IMAGE) | ||||
|       .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) | ||||
|       .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) | ||||
|       .toParty(new String[]{"partyid1", "partyid2"}) | ||||
|       .toAll(false) | ||||
|       .agentId(1) | ||||
|       .mediaId("MEDIA_ID") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "\t\"recv_scope\" : 0,\n" + | ||||
|       "\t\"to_parent_userid\": [\"parent_userid1\", \"parent_userid2\"],\n" + | ||||
|       "\t\"to_student_userid\": [\"student_userid1\", \"student_userid2\"],\n" + | ||||
|       "\t\"to_party\": [\"partyid1\", \"partyid2\"],\n" + | ||||
|       "\t\"toall\" : 0,\n" + | ||||
|       "\t\"msgtype\" : \"image\",\n" + | ||||
|       "\t\"agentid\" : 1,\n" + | ||||
|       "\t\"image\" : {\n" + | ||||
|       "\t\t\"media_id\" : \"MEDIA_ID\"\n" + | ||||
|       "\t},\n" + | ||||
|       "\t\"enable_duplicate_check\": 0,\n" + | ||||
|       "\t\"duplicate_check_interval\": 1800\n" + | ||||
|       "}"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_voice() { | ||||
|     WxCpSchoolContactMessage message = WxCpSchoolContactMessage.builder() | ||||
|       .recvScope(0) | ||||
|       .msgType(WxConsts.SchoolContactMsgType.VOICE) | ||||
|       .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) | ||||
|       .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) | ||||
|       .toParty(new String[]{"partyid1", "partyid2"}) | ||||
|       .toAll(false) | ||||
|       .agentId(1) | ||||
|       .mediaId("MEDIA_ID") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "\t\"recv_scope\" : 0,\n" + | ||||
|       "\t\"to_parent_userid\": [\"parent_userid1\", \"parent_userid2\"],\n" + | ||||
|       "\t\"to_student_userid\": [\"student_userid1\", \"student_userid2\"],\n" + | ||||
|       "\t\"to_party\": [\"partyid1\", \"partyid2\"],\n" + | ||||
|       "\t\"toall\" : 0,\n" + | ||||
|       "\t\"msgtype\" : \"voice\",\n" + | ||||
|       "\t\"agentid\" : 1,\n" + | ||||
|       "\t\"voice\" : {\n" + | ||||
|       "\t\t\"media_id\" : \"MEDIA_ID\"\n" + | ||||
|       "\t},\n" + | ||||
|       "\t\"enable_duplicate_check\": 0,\n" + | ||||
|       "\t\"duplicate_check_interval\": 1800\n" + | ||||
|       "}"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_video() { | ||||
|     WxCpSchoolContactMessage message = WxCpSchoolContactMessage.builder() | ||||
|       .recvScope(0) | ||||
|       .msgType(WxConsts.SchoolContactMsgType.VIDEO) | ||||
|       .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) | ||||
|       .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) | ||||
|       .toParty(new String[]{"partyid1", "partyid2"}) | ||||
|       .toAll(false) | ||||
|       .agentId(1) | ||||
|       .mediaId("MEDIA_ID") | ||||
|       .title("Title") | ||||
|       .description("Description") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "\t\"recv_scope\" : 0,\n" + | ||||
|       "\t\"to_parent_userid\": [\"parent_userid1\", \"parent_userid2\"],\n" + | ||||
|       "\t\"to_student_userid\": [\"student_userid1\", \"student_userid2\"],\n" + | ||||
|       "\t\"to_party\": [\"partyid1\", \"partyid2\"],\n" + | ||||
|       "\t\"toall\" : 0,\n" + | ||||
|       "\t\"msgtype\" : \"video\",\n" + | ||||
|       "\t\"agentid\" : 1,\n" + | ||||
|       "\t\"video\" : {\n" + | ||||
|       "        \"media_id\" : \"MEDIA_ID\",\n" + | ||||
|       "        \"title\" : \"Title\",\n" + | ||||
|       "       \"description\" : \"Description\"\n" + | ||||
|       "\t},\n" + | ||||
|       "\t\"enable_duplicate_check\": 0,\n" + | ||||
|       "\t\"duplicate_check_interval\": 1800\n" + | ||||
|       "}"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_file() { | ||||
|     WxCpSchoolContactMessage message = WxCpSchoolContactMessage.builder() | ||||
|       .recvScope(0) | ||||
|       .msgType(WxConsts.SchoolContactMsgType.FILE) | ||||
|       .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) | ||||
|       .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) | ||||
|       .toParty(new String[]{"partyid1", "partyid2"}) | ||||
|       .toAll(false) | ||||
|       .agentId(1) | ||||
|       .mediaId("1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "\t\"recv_scope\" : 0,\n" + | ||||
|       "\t\"to_parent_userid\": [\"parent_userid1\", \"parent_userid2\"],\n" + | ||||
|       "\t\"to_student_userid\": [\"student_userid1\", \"student_userid2\"],\n" + | ||||
|       "\t\"to_party\": [\"partyid1\", \"partyid2\"],\n" + | ||||
|       "\t\"toall\" : 0,\n" + | ||||
|       "\t\"msgtype\" : \"file\",\n" + | ||||
|       "\t\"agentid\" : 1,\n" + | ||||
|       "\t\"file\" : {\n" + | ||||
|       "        \"media_id\" : \"1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o\"\n" + | ||||
|       "\t},\n" + | ||||
|       "\t\"enable_duplicate_check\": 0,\n" + | ||||
|       "\t\"duplicate_check_interval\": 1800\n" + | ||||
|       "}"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_news() { | ||||
|     WxCpSchoolContactMessage message = WxCpSchoolContactMessage.builder() | ||||
|       .recvScope(0) | ||||
|       .msgType(WxConsts.SchoolContactMsgType.NEWS) | ||||
|       .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) | ||||
|       .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) | ||||
|       .toParty(new String[]{"partyid1", "partyid2"}) | ||||
|       .toAll(false) | ||||
|       .agentId(1) | ||||
|       .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") | ||||
|         .build())) | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "   \"recv_scope\" : 0,\n" + | ||||
|       "   \"to_parent_userid\": [\"parent_userid1\", \"parent_userid2\"],\n" + | ||||
|       "   \"to_student_userid\": [\"student_userid1\", \"student_userid2\"],\n" + | ||||
|       "   \"to_party\": [\"partyid1\", \"partyid2\"],\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" + | ||||
|       "           }\n" + | ||||
|       "\t\t]\n" + | ||||
|       "   },\n" + | ||||
|       "   \"enable_id_trans\": 0,\n" + | ||||
|       "   \"enable_duplicate_check\": 0,\n" + | ||||
|       "   \"duplicate_check_interval\": 1800\n" + | ||||
|       "}"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_mpnews() { | ||||
|     WxCpSchoolContactMessage message = WxCpSchoolContactMessage.builder() | ||||
|       .recvScope(0) | ||||
|       .msgType(WxConsts.SchoolContactMsgType.MPNEWS) | ||||
|       .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) | ||||
|       .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) | ||||
|       .toParty(new String[]{"partyid1", "partyid2"}) | ||||
|       .toAll(false) | ||||
|       .agentId(1) | ||||
|       .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" + | ||||
|       "   \"recv_scope\" : 0,\n" + | ||||
|       "   \"to_parent_userid\": [\"parent_userid1\", \"parent_userid2\"],\n" + | ||||
|       "   \"to_student_userid\": [\"student_userid1\", \"student_userid2\"],\n" + | ||||
|       "   \"to_party\": [\"partyid1\", \"partyid2\"],\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" + | ||||
|       "   \"enable_id_trans\": 0,\n" + | ||||
|       "   \"enable_duplicate_check\": 0,\n" + | ||||
|       "   \"duplicate_check_interval\": 1800\n" + | ||||
|       "}\n"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void testToJson_miniProgram() { | ||||
|     WxCpSchoolContactMessage message = WxCpSchoolContactMessage.builder() | ||||
|       .recvScope(0) | ||||
|       .msgType(WxConsts.SchoolContactMsgType.MINIPROGRAM) | ||||
|       .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) | ||||
|       .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) | ||||
|       .toParty(new String[]{"partyid1", "partyid2"}) | ||||
|       .toAll(false) | ||||
|       .agentId(1) | ||||
|       .appId("APPID") | ||||
|       .title("欢迎报名夏令营") | ||||
|       .thumbMediaId("MEDIA_ID") | ||||
|       .pagePath("PAGE_PATH") | ||||
|       .build(); | ||||
|  | ||||
|     final String json = message.toJson(); | ||||
|     String expectedJson = "{\n" + | ||||
|       "   \"recv_scope\" : 0,\n" + | ||||
|       "   \"to_parent_userid\": [\"parent_userid1\", \"parent_userid2\"],\n" + | ||||
|       "   \"to_student_userid\": [\"student_userid1\", \"student_userid2\"],\n" + | ||||
|       "   \"to_party\": [\"partyid1\", \"partyid2\"],\n" + | ||||
|       "   \"toall\" : 0,\n" + | ||||
|       "   \"agentid\" : 1,\n" + | ||||
|       "   \"msgtype\" : \"miniprogram\",\n" + | ||||
|       "   \"miniprogram\" : {\n" + | ||||
|       "       \"appid\": \"APPID\",\n" + | ||||
|       "       \"title\": \"欢迎报名夏令营\",\n" + | ||||
|       "       \"thumb_media_id\": \"MEDIA_ID\",\n" + | ||||
|       "       \"pagepath\": \"PAGE_PATH\"\n" + | ||||
|       "   },\n" + | ||||
|       "   \"enable_id_trans\": 0,\n" + | ||||
|       "   \"enable_duplicate_check\": 0,\n" + | ||||
|       "   \"duplicate_check_interval\": 1800\n" + | ||||
|       "}\n"; | ||||
|  | ||||
|     assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString()); | ||||
|   } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 0katekate0
					0katekate0