@@ -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> | ||||
* | * | ||||
*/ | */ | ||||