| @@ -88,6 +88,11 @@ public class WxConsts { | |||||
| * 小程序卡片(要求小程序与公众号已关联) | * 小程序卡片(要求小程序与公众号已关联) | ||||
| */ | */ | ||||
| public static final String MINIPROGRAMPAGE = "miniprogrampage"; | public static final String MINIPROGRAMPAGE = "miniprogrampage"; | ||||
| /** | |||||
| * 任务卡片消息 | |||||
| */ | |||||
| public static final String TASKCARD = "taskcard"; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -84,6 +84,11 @@ public class WxCpConsts { | |||||
| */ | */ | ||||
| public static final String LOCATION_SELECT = "location_select"; | public static final String LOCATION_SELECT = "location_select"; | ||||
| /** | |||||
| * 任务卡片事件推送. | |||||
| */ | |||||
| public static final String TASKCARD_CLICK = "taskcard_click"; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -301,6 +301,13 @@ public interface WxCpService { | |||||
| */ | */ | ||||
| WxCpChatService getChatService(); | WxCpChatService getChatService(); | ||||
| /** | |||||
| * 获取任务卡片服务 | |||||
| * | |||||
| * @return 任务卡片服务 | |||||
| */ | |||||
| WxCpTaskCardService getTaskCardService(); | |||||
| WxCpAgentService getAgentService(); | WxCpAgentService getAgentService(); | ||||
| WxCpOAService getOAService(); | WxCpOAService getOAService(); | ||||
| @@ -0,0 +1,30 @@ | |||||
| package me.chanjar.weixin.cp.api; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import java.util.List; | |||||
| /** | |||||
| * <pre> | |||||
| * 任务卡片管理接口. | |||||
| * Created by Jeff on 2019-05-16. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/domainname">Jeff</a> | |||||
| * @date 2019-05-16 | |||||
| */ | |||||
| public interface WxCpTaskCardService { | |||||
| /** | |||||
| * <pre> | |||||
| * 更新任务卡片消息状态 | |||||
| * 详情请见: https://work.weixin.qq.com/api/doc#90000/90135/91579 | |||||
| * | |||||
| * 注意: 这个方法使用WxCpConfigStorage里的agentId | |||||
| * </pre> | |||||
| * | |||||
| * @param userIds 企业的成员ID列表 | |||||
| * @param taskId 任务卡片ID | |||||
| * @param clickedKey 已点击按钮的Key | |||||
| */ | |||||
| void update(List<String> userIds, String taskId, String clickedKey) throws WxErrorException; | |||||
| } | |||||
| @@ -46,6 +46,7 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH | |||||
| private WxCpTagService tagService = new WxCpTagServiceImpl(this); | private WxCpTagService tagService = new WxCpTagServiceImpl(this); | ||||
| private WxCpAgentService agentService = new WxCpAgentServiceImpl(this); | private WxCpAgentService agentService = new WxCpAgentServiceImpl(this); | ||||
| private WxCpOAService oaService = new WxCpOAServiceImpl(this); | private WxCpOAService oaService = new WxCpOAServiceImpl(this); | ||||
| private WxCpTaskCardService taskCardService = new WxCpTaskCardServiceImpl(this); | |||||
| /** | /** | ||||
| * 全局的是否正在刷新access token的锁 | * 全局的是否正在刷新access token的锁 | ||||
| @@ -392,6 +393,11 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH | |||||
| return oaService; | return oaService; | ||||
| } | } | ||||
| @Override | |||||
| public WxCpTaskCardService getTaskCardService() { | |||||
| return taskCardService; | |||||
| } | |||||
| @Override | @Override | ||||
| public RequestHttp<?, ?> getRequestHttp() { | public RequestHttp<?, ?> getRequestHttp() { | ||||
| return this; | return this; | ||||
| @@ -0,0 +1,39 @@ | |||||
| package me.chanjar.weixin.cp.api.impl; | |||||
| import lombok.RequiredArgsConstructor; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
| import me.chanjar.weixin.cp.api.WxCpService; | |||||
| import me.chanjar.weixin.cp.api.WxCpTaskCardService; | |||||
| import java.util.HashMap; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * <pre> | |||||
| * 任务卡片管理接口. | |||||
| * Created by Jeff on 2019-05-16. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/domainname">Jeff</a> | |||||
| * @date 2019-05-16 | |||||
| */ | |||||
| @RequiredArgsConstructor | |||||
| public class WxCpTaskCardServiceImpl implements WxCpTaskCardService { | |||||
| private final WxCpService mainService; | |||||
| @Override | |||||
| public void update(List<String> userIds, String taskId, String clickedKey) throws WxErrorException { | |||||
| Integer agentId = this.mainService.getWxCpConfigStorage().getAgentId(); | |||||
| Map<String, Object> data = new HashMap<>(4); | |||||
| data.put("userids", userIds); | |||||
| data.put("agentid", agentId); | |||||
| data.put("task_id", taskId); | |||||
| data.put("clicked_key", clickedKey); | |||||
| String url = "https://qyapi.weixin.qq.com/cgi-bin/message/update_taskcard"; | |||||
| this.mainService.post(url, WxGsonBuilder.create().toJson(data)); | |||||
| } | |||||
| } | |||||
| @@ -1,26 +1,18 @@ | |||||
| package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
| import java.io.Serializable; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import com.google.gson.JsonArray; | import com.google.gson.JsonArray; | ||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| import me.chanjar.weixin.common.api.WxConsts.KefuMsgType; | import me.chanjar.weixin.common.api.WxConsts.KefuMsgType; | ||||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
| import me.chanjar.weixin.cp.bean.messagebuilder.FileBuilder; | |||||
| import me.chanjar.weixin.cp.bean.messagebuilder.ImageBuilder; | |||||
| import me.chanjar.weixin.cp.bean.messagebuilder.MarkdownMsgBuilder; | |||||
| import me.chanjar.weixin.cp.bean.messagebuilder.MpnewsBuilder; | |||||
| import me.chanjar.weixin.cp.bean.messagebuilder.NewsBuilder; | |||||
| import me.chanjar.weixin.cp.bean.messagebuilder.TextBuilder; | |||||
| import me.chanjar.weixin.cp.bean.messagebuilder.TextCardBuilder; | |||||
| import me.chanjar.weixin.cp.bean.messagebuilder.VideoBuilder; | |||||
| import me.chanjar.weixin.cp.bean.messagebuilder.VoiceBuilder; | |||||
| import me.chanjar.weixin.cp.bean.messagebuilder.*; | |||||
| import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import java.io.Serializable; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| /** | /** | ||||
| * 消息. | * 消息. | ||||
| @@ -49,6 +41,12 @@ public class WxCpMessage implements Serializable { | |||||
| private List<NewArticle> articles = new ArrayList<>(); | private List<NewArticle> articles = new ArrayList<>(); | ||||
| private List<MpnewsArticle> mpnewsArticles = new ArrayList<>(); | private List<MpnewsArticle> mpnewsArticles = new ArrayList<>(); | ||||
| /** | |||||
| * 任务卡片特有的属性 | |||||
| */ | |||||
| private String taskId; | |||||
| private List<TaskCardButton> taskButtons = new ArrayList<>(); | |||||
| /** | /** | ||||
| * 获得文本消息builder. | * 获得文本消息builder. | ||||
| */ | */ | ||||
| @@ -112,6 +110,13 @@ public class WxCpMessage implements Serializable { | |||||
| return new FileBuilder(); | return new FileBuilder(); | ||||
| } | } | ||||
| /** | |||||
| * 获得任务卡片消息builder. | |||||
| */ | |||||
| public static TaskCardBuilder TASKCARD() { | |||||
| return new TaskCardBuilder(); | |||||
| } | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -124,6 +129,7 @@ public class WxCpMessage implements Serializable { | |||||
| * {@link KefuMsgType#NEWS} | * {@link KefuMsgType#NEWS} | ||||
| * {@link KefuMsgType#MPNEWS} | * {@link KefuMsgType#MPNEWS} | ||||
| * {@link KefuMsgType#MARKDOWN} | * {@link KefuMsgType#MARKDOWN} | ||||
| * {@link KefuMsgType#TASKCARD} | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param msgType 消息类型 | * @param msgType 消息类型 | ||||
| @@ -249,6 +255,42 @@ public class WxCpMessage implements Serializable { | |||||
| messageJson.add("mpnews", newsJsonObject); | messageJson.add("mpnews", newsJsonObject); | ||||
| break; | break; | ||||
| } | } | ||||
| case KefuMsgType.TASKCARD: { | |||||
| JsonObject text = new JsonObject(); | |||||
| text.addProperty("title", this.getTitle()); | |||||
| text.addProperty("description", this.getDescription()); | |||||
| if (StringUtils.isNotBlank(this.getUrl())) { | |||||
| text.addProperty("url", this.getUrl()); | |||||
| } | |||||
| text.addProperty("task_id", this.getTaskId()); | |||||
| JsonArray buttonJsonArray = new JsonArray(); | |||||
| for (TaskCardButton button : this.getTaskButtons()) { | |||||
| JsonObject buttonJson = new JsonObject(); | |||||
| buttonJson.addProperty("key", button.getKey()); | |||||
| buttonJson.addProperty("name", button.getName()); | |||||
| if (StringUtils.isNotBlank(button.getReplaceName())) { | |||||
| buttonJson.addProperty("replace_name", button.getReplaceName()); | |||||
| } | |||||
| if (StringUtils.isNotBlank(button.getColor())) { | |||||
| buttonJson.addProperty("color", button.getColor()); | |||||
| } | |||||
| if (button.getBold() != null) { | |||||
| buttonJson.addProperty("is_bold", button.getBold()); | |||||
| } | |||||
| buttonJsonArray.add(buttonJson); | |||||
| } | |||||
| text.add("btn", buttonJsonArray); | |||||
| messageJson.add("taskcard", text); | |||||
| break; | |||||
| } | |||||
| default: { | default: { | ||||
| // do nothing | // do nothing | ||||
| } | } | ||||
| @@ -0,0 +1,42 @@ | |||||
| package me.chanjar.weixin.cp.bean; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.AllArgsConstructor; | |||||
| import lombok.Data; | |||||
| import lombok.NoArgsConstructor; | |||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * <pre> | |||||
| * 更新任务卡片消息状态的返回类 | |||||
| * 参考文档:https://work.weixin.qq.com/api/doc#90000/90135/91579 | |||||
| * Created by Jeff on 2019-05-16. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/domainname">Jeff</a> | |||||
| * @date 2019-05-16 | |||||
| */ | |||||
| @Data | |||||
| @AllArgsConstructor | |||||
| @NoArgsConstructor | |||||
| public class WxCpTaskCardUpdateResult implements Serializable { | |||||
| @SerializedName("errcode") | |||||
| private Integer errcode; | |||||
| @SerializedName("errmsg") | |||||
| private String errmsg; | |||||
| /** | |||||
| * 用户列表 | |||||
| */ | |||||
| @SerializedName("invaliduser") | |||||
| private List<String> invalidUsers; | |||||
| public static WxCpTaskCardUpdateResult fromJson(String json) { | |||||
| return WxCpGsonBuilder.create().fromJson(json, WxCpTaskCardUpdateResult.class); | |||||
| } | |||||
| } | |||||
| @@ -1,18 +1,8 @@ | |||||
| package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.Serializable; | |||||
| import java.nio.charset.StandardCharsets; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import com.thoughtworks.xstream.annotations.XStreamImplicit; | |||||
| import org.apache.commons.io.IOUtils; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | import com.thoughtworks.xstream.annotations.XStreamAlias; | ||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| import com.thoughtworks.xstream.annotations.XStreamImplicit; | |||||
| import lombok.Data; | import lombok.Data; | ||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
| @@ -22,6 +12,15 @@ import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||||
| import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| import me.chanjar.weixin.cp.util.xml.XStreamTransformer; | import me.chanjar.weixin.cp.util.xml.XStreamTransformer; | ||||
| import org.apache.commons.io.IOUtils; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.Serializable; | |||||
| import java.nio.charset.StandardCharsets; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -157,6 +156,10 @@ public class WxCpXmlMessage implements Serializable { | |||||
| @XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
| private String recognition; | private String recognition; | ||||
| @XStreamAlias("TaskId") | |||||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||||
| private String taskId; | |||||
| /** | /** | ||||
| * 通讯录变更事件. | * 通讯录变更事件. | ||||
| * 请参考常量 me.chanjar.weixin.cp.WxCpConsts.ContactChangeType | * 请参考常量 me.chanjar.weixin.cp.WxCpConsts.ContactChangeType | ||||
| @@ -0,0 +1,68 @@ | |||||
| 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.taskcard.TaskCardButton; | |||||
| import java.util.List; | |||||
| /** | |||||
| * <pre> | |||||
| * 任务卡片消息Builder | |||||
| * 用法: WxCustomMessage m = WxCustomMessage.TASKCARD().title(...)....toUser(...).build(); | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/domainname">Jeff</a> | |||||
| * @date 2019-05-16 | |||||
| */ | |||||
| public class TaskCardBuilder extends BaseBuilder<TaskCardBuilder> { | |||||
| private String title; | |||||
| private String description; | |||||
| private String url; | |||||
| private String taskId; | |||||
| /** | |||||
| * 按钮个数为1~2个 | |||||
| */ | |||||
| private List<TaskCardButton> buttons; | |||||
| public TaskCardBuilder() { | |||||
| this.msgType = WxConsts.KefuMsgType.TASKCARD; | |||||
| } | |||||
| public TaskCardBuilder title(String title) { | |||||
| this.title = title; | |||||
| return this; | |||||
| } | |||||
| public TaskCardBuilder description(String description) { | |||||
| this.description = description; | |||||
| return this; | |||||
| } | |||||
| public TaskCardBuilder url(String url) { | |||||
| this.url = url; | |||||
| return this; | |||||
| } | |||||
| public TaskCardBuilder taskId(String taskId) { | |||||
| this.taskId = taskId; | |||||
| return this; | |||||
| } | |||||
| public TaskCardBuilder buttons(List<TaskCardButton> buttons) { | |||||
| this.buttons = buttons; | |||||
| return this; | |||||
| } | |||||
| @Override | |||||
| public WxCpMessage build() { | |||||
| WxCpMessage m = super.build(); | |||||
| m.setSafe(null); | |||||
| m.setTitle(this.title); | |||||
| m.setDescription(this.description); | |||||
| m.setUrl(this.url); | |||||
| m.setTaskId(this.taskId); | |||||
| m.setTaskButtons(this.buttons); | |||||
| return m; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| package me.chanjar.weixin.cp.bean.taskcard; | |||||
| import lombok.Builder; | |||||
| import lombok.Data; | |||||
| /** | |||||
| * <pre> | |||||
| * 任务卡片按钮 | |||||
| * Created by Jeff on 2019-05-16. | |||||
| * </pre> | |||||
| * | |||||
| * @author <a href="https://github.com/domainname">Jeff</a> | |||||
| * @date 2019-05-16 | |||||
| */ | |||||
| @Data | |||||
| @Builder | |||||
| public class TaskCardButton { | |||||
| private String key; | |||||
| private String name; | |||||
| private String replaceName; | |||||
| private String color; | |||||
| private Boolean bold; | |||||
| } | |||||
| @@ -0,0 +1,65 @@ | |||||
| package me.chanjar.weixin.cp.api.impl; | |||||
| 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.taskcard.TaskCardButton; | |||||
| import org.testng.annotations.Guice; | |||||
| import org.testng.annotations.Test; | |||||
| import java.util.Arrays; | |||||
| import static org.testng.Assert.assertNotNull; | |||||
| /** | |||||
| * 测试任务卡片服务 | |||||
| * | |||||
| * @author <a href="https://github.com/domainname">Jeff</a> | |||||
| * @date 2019-05-16 | |||||
| */ | |||||
| @Guice(modules = ApiTestModule.class) | |||||
| public class WxCpTaskCardServiceImplTest { | |||||
| @Inject | |||||
| private WxCpService wxCpService; | |||||
| @Test | |||||
| public void testSendTaskCard() throws WxErrorException { | |||||
| TaskCardButton btn1 = TaskCardButton.builder() | |||||
| .key("key1") | |||||
| .name("同意") | |||||
| .replaceName("已同意") | |||||
| .bold(true) | |||||
| .build(); | |||||
| TaskCardButton btn2 = TaskCardButton.builder() | |||||
| .key("key2") | |||||
| .name("拒绝") | |||||
| .replaceName("已拒绝") | |||||
| .color("red") | |||||
| .build(); | |||||
| WxCpMessage message = WxCpMessage.TASKCARD() | |||||
| .toUser("jeff|mr.t") | |||||
| .title("有一个待审批的请求") | |||||
| .description("申请:购买图书\n金额:100 元") | |||||
| .taskId("task_1") | |||||
| .url("http://www.qq.com") | |||||
| .buttons(Arrays.asList(btn1, btn2)) | |||||
| .build(); | |||||
| WxCpMessageSendResult messageSendResult = this.wxCpService.messageSend(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 testUpdate() throws Exception { | |||||
| wxCpService.getTaskCardService().update(Arrays.asList("jeff", "mr.t"), "task_1", "key1"); | |||||
| } | |||||
| } | |||||
| @@ -1,9 +1,11 @@ | |||||
| package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
| import org.testng.annotations.*; | |||||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | import me.chanjar.weixin.cp.bean.article.NewArticle; | ||||
| import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; | |||||
| import org.testng.annotations.Test; | |||||
| import java.util.Arrays; | |||||
| import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
| @@ -67,7 +69,7 @@ public class WxCpMessageTest { | |||||
| WxCpMessage reply = WxCpMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); | WxCpMessage reply = WxCpMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); | ||||
| assertThat(reply.toJson()) | assertThat(reply.toJson()) | ||||
| .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":" + | |||||
| .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":" + | |||||
| "[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}," + | "[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}," + | ||||
| "{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}," + | "{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}," + | ||||
| "\"safe\":\"0\"}"); | "\"safe\":\"0\"}"); | ||||
| @@ -97,7 +99,7 @@ public class WxCpMessageTest { | |||||
| WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1, article2).build(); | WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1, article2).build(); | ||||
| assertThat(reply.toJson()) | assertThat(reply.toJson()) | ||||
| .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"articles\":" + | |||||
| .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"articles\":" + | |||||
| "[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\"," + | "[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\"," + | ||||
| "\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}" + | "\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}" + | ||||
| ",{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\"," + | ",{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\"," + | ||||
| @@ -112,4 +114,30 @@ public class WxCpMessageTest { | |||||
| .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"media_id\":\"mmm\"},\"safe\":\"0\"}"); | .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"media_id\":\"mmm\"},\"safe\":\"0\"}"); | ||||
| } | } | ||||
| public void testTaskCardBuilder() { | |||||
| TaskCardButton button1 = TaskCardButton.builder() | |||||
| .key("yes") | |||||
| .name("批准") | |||||
| .replaceName("已批准") | |||||
| .color("blue") | |||||
| .bold(true) | |||||
| .build(); | |||||
| TaskCardButton button2 = TaskCardButton.builder() | |||||
| .key("yes") | |||||
| .name("拒绝") | |||||
| .replaceName("已拒绝") | |||||
| .color("red") | |||||
| .bold(false) | |||||
| .build(); | |||||
| WxCpMessage reply = WxCpMessage.TASKCARD().toUser("OPENID") | |||||
| .title("任务卡片") | |||||
| .description("有一条待处理任务") | |||||
| .url("http://www.qq.com") | |||||
| .taskId("task_123") | |||||
| .buttons(Arrays.asList(button1, button2)) | |||||
| .build(); | |||||
| assertThat(reply.toJson()) | |||||
| .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"taskcard\",\"taskcard\":{\"title\":\"任务卡片\",\"description\":\"有一条待处理任务\",\"url\":\"http://www.qq.com\",\"task_id\":\"task_123\",\"btn\":[{\"key\":\"yes\",\"name\":\"批准\",\"replace_name\":\"已批准\",\"color\":\"blue\",\"is_bold\":true},{\"key\":\"yes\",\"name\":\"拒绝\",\"replace_name\":\"已拒绝\",\"color\":\"red\",\"is_bold\":false}]}}"); | |||||
| } | |||||
| } | } | ||||
| @@ -1,9 +1,11 @@ | |||||
| package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
| import org.testng.annotations.*; | |||||
| import org.testng.annotations.Test; | |||||
| import static org.testng.Assert.*; | |||||
| import static me.chanjar.weixin.cp.WxCpConsts.EventType.TASKCARD_CLICK; | |||||
| import static org.testng.Assert.assertEquals; | |||||
| import static org.testng.Assert.assertNotNull; | |||||
| @Test | @Test | ||||
| public class WxCpXmlMessageTest { | public class WxCpXmlMessageTest { | ||||
| @@ -149,4 +151,26 @@ public class WxCpXmlMessageTest { | |||||
| assertEquals(wxMessage.getExtAttrs().getItems().get(0).getName(), "爱好"); | assertEquals(wxMessage.getExtAttrs().getItems().get(0).getName(), "爱好"); | ||||
| } | } | ||||
| public void testTaskCardEvent() { | |||||
| String xml = "<xml>" + | |||||
| "<ToUserName><![CDATA[toUser]]></ToUserName>" + | |||||
| "<FromUserName><![CDATA[FromUser]]></FromUserName>" + | |||||
| "<CreateTime>123456789</CreateTime>" + | |||||
| "<MsgType><![CDATA[event]]></MsgType>" + | |||||
| "<Event><![CDATA[taskcard_click]]></Event>" + | |||||
| "<EventKey><![CDATA[key111]]></EventKey>" + | |||||
| "<TaskId><![CDATA[taskid111]]></TaskId >" + | |||||
| "<AgentID>1</AgentID>" + | |||||
| "</xml>"; | |||||
| WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml); | |||||
| assertEquals(wxMessage.getToUserName(), "toUser"); | |||||
| assertEquals(wxMessage.getFromUserName(), "FromUser"); | |||||
| assertEquals(wxMessage.getCreateTime(), Long.valueOf(123456789L)); | |||||
| assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT); | |||||
| assertEquals(wxMessage.getAgentId(), Integer.valueOf(1)); | |||||
| assertEquals(wxMessage.getEvent(), TASKCARD_CLICK); | |||||
| assertEquals(wxMessage.getEventKey(), "key111"); | |||||
| assertEquals(wxMessage.getTaskId(), "taskid111"); | |||||
| } | |||||
| } | } | ||||
| @@ -109,6 +109,7 @@ public class WxMpKefuMessage implements Serializable { | |||||
| * {@link WxConsts.KefuMsgType#MPNEWS} | * {@link WxConsts.KefuMsgType#MPNEWS} | ||||
| * {@link WxConsts.KefuMsgType#WXCARD} | * {@link WxConsts.KefuMsgType#WXCARD} | ||||
| * {@link WxConsts.KefuMsgType#MINIPROGRAMPAGE} | * {@link WxConsts.KefuMsgType#MINIPROGRAMPAGE} | ||||
| * {@link WxConsts.KefuMsgType#TASKCARD} | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| */ | */ | ||||