@@ -61,6 +61,11 @@ | |||
<artifactId>joda-time</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.assertj</groupId> | |||
<artifactId>assertj-guava</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>redis.clients</groupId> | |||
<artifactId>jedis</artifactId> | |||
@@ -1,8 +1,12 @@ | |||
package cn.binarywang.wx.miniapp.bean; | |||
import cn.binarywang.wx.miniapp.builder.ImageBuilder; | |||
import cn.binarywang.wx.miniapp.builder.LinkBuilder; | |||
import cn.binarywang.wx.miniapp.builder.TextBuilder; | |||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||
import com.google.gson.GsonBuilder; | |||
import com.google.gson.annotations.SerializedName; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Builder; | |||
import lombok.Data; | |||
import java.io.Serializable; | |||
@@ -16,13 +20,59 @@ import java.io.Serializable; | |||
public class WxMaKefuMessage implements Serializable { | |||
private static final long serialVersionUID = -9196732086954365246L; | |||
@SerializedName("touser") | |||
private String toUser; | |||
@SerializedName("msgtype") | |||
private String msgType; | |||
private String content; | |||
private String mediaId; | |||
private String thumbMediaId; | |||
private String title; | |||
private String description; | |||
@SerializedName("text") | |||
private KfText text; | |||
@SerializedName("image") | |||
private KfImage image; | |||
@SerializedName("link") | |||
private KfLink link; | |||
@SerializedName("miniprogrampage") | |||
private KfMaPage maPage; | |||
@Data | |||
@AllArgsConstructor | |||
public static class KfText { | |||
private String content; | |||
} | |||
@Data | |||
@AllArgsConstructor | |||
public static class KfImage { | |||
@SerializedName("media_id") | |||
private String mediaId; | |||
} | |||
@Data | |||
@Builder | |||
public static class KfLink { | |||
private String title; | |||
private String description; | |||
private String url; | |||
@SerializedName("thumb_url") | |||
private String thumbUrl; | |||
} | |||
@Data | |||
@Builder | |||
public static class KfMaPage { | |||
private String title; | |||
@SerializedName("pagepath") | |||
private String pagePath; | |||
@SerializedName("thumb_media_id") | |||
private String thumbMediaId; | |||
} | |||
/** | |||
* 获得文本消息builder. | |||
@@ -38,8 +88,15 @@ public class WxMaKefuMessage implements Serializable { | |||
return new ImageBuilder(); | |||
} | |||
/** | |||
* 获得图文链接消息builder. | |||
*/ | |||
public static LinkBuilder newLinkBuilder() { | |||
return new LinkBuilder(); | |||
} | |||
public String toJson() { | |||
return WxMaGsonBuilder.create().toJson(this); | |||
return new GsonBuilder().create().toJson(this); | |||
} | |||
} |
@@ -31,8 +31,9 @@ public class WxMaWxcodeLimit extends AbstractWxMaQrcodeWrapper implements Serial | |||
return WxMaGsonBuilder.create().fromJson(json, WxMaWxcodeLimit.class); | |||
} | |||
@Override | |||
public String toString() { | |||
return super.toString(); | |||
} | |||
} | |||
} |
@@ -4,6 +4,8 @@ import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | |||
import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||
/** | |||
* 图片消息builder. | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
public final class ImageBuilder extends BaseBuilder<ImageBuilder> { | |||
@@ -21,7 +23,7 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder> { | |||
@Override | |||
public WxMaKefuMessage build() { | |||
WxMaKefuMessage m = super.build(); | |||
m.setMediaId(this.mediaId); | |||
m.setImage(new WxMaKefuMessage.KfImage(this.mediaId)); | |||
return m; | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
package cn.binarywang.wx.miniapp.builder; | |||
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | |||
import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||
/** | |||
* 图文链接builder | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
public class LinkBuilder extends BaseBuilder<LinkBuilder> { | |||
private String title; | |||
private String description; | |||
private String url; | |||
private String thumbUrl; | |||
public LinkBuilder() { | |||
this.msgType = WxMaConstants.KefuMsgType.IMAGE; | |||
} | |||
public LinkBuilder title(String title) { | |||
this.title = title; | |||
return this; | |||
} | |||
public LinkBuilder description(String description) { | |||
this.description = description; | |||
return this; | |||
} | |||
public LinkBuilder url(String url) { | |||
this.url = url; | |||
return this; | |||
} | |||
public LinkBuilder thumbUrl(String thumbUrl) { | |||
this.thumbUrl = thumbUrl; | |||
return this; | |||
} | |||
@Override | |||
public WxMaKefuMessage build() { | |||
WxMaKefuMessage m = super.build(); | |||
m.setLink(WxMaKefuMessage.KfLink.builder().title(this.title) | |||
.description(this.description) | |||
.url(this.url) | |||
.thumbUrl(this.thumbUrl) | |||
.build() | |||
); | |||
return m; | |||
} | |||
} |
@@ -4,6 +4,8 @@ import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | |||
import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||
/** | |||
* 文本消息builder. | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
public final class TextBuilder extends BaseBuilder<TextBuilder> { | |||
@@ -21,7 +23,7 @@ public final class TextBuilder extends BaseBuilder<TextBuilder> { | |||
@Override | |||
public WxMaKefuMessage build() { | |||
WxMaKefuMessage m = super.build(); | |||
m.setContent(this.content); | |||
m.setText(new WxMaKefuMessage.KfText(this.content)); | |||
return m; | |||
} | |||
} |
@@ -2,29 +2,29 @@ package cn.binarywang.wx.miniapp.constant; | |||
/** | |||
* <pre> | |||
* 小程序常量 | |||
* 小程序常量. | |||
* </pre> | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
public class WxMaConstants { | |||
/** | |||
* 微信接口返回的参数errcode | |||
* 微信接口返回的参数errcode. | |||
*/ | |||
public static final String ERRCODE = "errcode"; | |||
/** | |||
* 素材类型 | |||
* 素材类型. | |||
*/ | |||
public static class MediaType { | |||
/** | |||
* 图片 | |||
* 图片. | |||
*/ | |||
public static final String IMAGE = "image"; | |||
} | |||
/** | |||
* 消息格式 | |||
* 消息格式. | |||
*/ | |||
public static class MsgDataFormat { | |||
public static final String XML = "XML"; | |||
@@ -32,32 +32,40 @@ public class WxMaConstants { | |||
} | |||
/** | |||
* 客服消息的消息类型 | |||
* 客服消息的消息类型. | |||
*/ | |||
public static class KefuMsgType { | |||
/** | |||
* 文本消息 | |||
* 文本消息. | |||
*/ | |||
public static final String TEXT = "text"; | |||
/** | |||
* 图片消息 | |||
* 图片消息. | |||
*/ | |||
public static final String IMAGE = "image"; | |||
/** | |||
* 图文链接. | |||
*/ | |||
public static final String LINK = "link"; | |||
/** | |||
* 小程序卡片消息. | |||
*/ | |||
public static final String MA_PAGE = "miniprogrampage"; | |||
} | |||
public static final class ErrorCode { | |||
/** | |||
* 40001 获取access_token时AppSecret错误,或者access_token无效 | |||
* 40001 获取access_token时AppSecret错误,或者access_token无效. | |||
*/ | |||
public static final int ERR_40001 = 40001; | |||
/** | |||
* 42001 access_token超时 | |||
* 42001 access_token超时. | |||
*/ | |||
public static final int ERR_42001 = 42001; | |||
/** | |||
* 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期) | |||
* 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期). | |||
*/ | |||
public static final int ERR_40014 = 40014; | |||
} | |||
@@ -1,6 +1,5 @@ | |||
package cn.binarywang.wx.miniapp.util.json; | |||
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | |||
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; | |||
import com.google.gson.Gson; | |||
import com.google.gson.GsonBuilder; | |||
@@ -13,7 +12,6 @@ public class WxMaGsonBuilder { | |||
static { | |||
INSTANCE.disableHtmlEscaping(); | |||
INSTANCE.registerTypeAdapter(WxMaKefuMessage.class, new WxMaKefuMessageGsonAdapter()); | |||
INSTANCE.registerTypeAdapter(WxMaTemplateMessage.class, new WxMaTemplateMessageGsonAdapter()); | |||
} | |||
@@ -1,38 +0,0 @@ | |||
package cn.binarywang.wx.miniapp.util.json; | |||
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | |||
import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||
import com.google.gson.JsonElement; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonSerializationContext; | |||
import com.google.gson.JsonSerializer; | |||
import java.lang.reflect.Type; | |||
/** | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
public class WxMaKefuMessageGsonAdapter implements JsonSerializer<WxMaKefuMessage> { | |||
@Override | |||
public JsonElement serialize(WxMaKefuMessage message, Type typeOfSrc, JsonSerializationContext context) { | |||
JsonObject messageJson = new JsonObject(); | |||
messageJson.addProperty("touser", message.getToUser()); | |||
messageJson.addProperty("msgtype", message.getMsgType()); | |||
if (WxMaConstants.KefuMsgType.TEXT.equals(message.getMsgType())) { | |||
JsonObject text = new JsonObject(); | |||
text.addProperty("content", message.getContent()); | |||
messageJson.add("text", text); | |||
} | |||
if (WxMaConstants.KefuMsgType.IMAGE.equals(message.getMsgType())) { | |||
JsonObject image = new JsonObject(); | |||
image.addProperty("media_id", message.getMediaId()); | |||
messageJson.add("image", image); | |||
} | |||
return messageJson; | |||
} | |||
} |
@@ -7,16 +7,14 @@ import cn.binarywang.wx.miniapp.test.ApiTestModule; | |||
import cn.binarywang.wx.miniapp.test.TestConfig; | |||
import com.google.common.collect.Lists; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
import org.testng.annotations.*; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
/** | |||
* 测试客服相关接口 | |||
* 测试消息相关接口 | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
@@ -25,26 +23,14 @@ import java.util.Date; | |||
public class WxMaMsgServiceImplTest { | |||
@Inject | |||
protected WxMaService wxService; | |||
public void testSendKefuMpNewsMessage() throws WxErrorException { | |||
TestConfig configStorage = (TestConfig) this.wxService | |||
.getWxMaConfig(); | |||
WxMaKefuMessage message = new WxMaKefuMessage(); | |||
message.setMsgType(WxConsts.KefuMsgType.MPNEWS); | |||
message.setToUser(configStorage.getOpenid()); | |||
this.wxService.getMsgService().sendKefuMsg(message); | |||
} | |||
private WxMaService wxService; | |||
public void testSendKefuMessage() throws WxErrorException { | |||
TestConfig config = (TestConfig) this.wxService | |||
.getWxMaConfig(); | |||
WxMaKefuMessage message = new WxMaKefuMessage(); | |||
message.setMsgType(WxConsts.KefuMsgType.TEXT); | |||
message.setToUser(config.getOpenid()); | |||
message.setContent( | |||
"欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||
TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); | |||
WxMaKefuMessage message = WxMaKefuMessage.newTextBuilder() | |||
.toUser(config.getOpenid()) | |||
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>") | |||
.build(); | |||
this.wxService.getMsgService().sendKefuMsg(message); | |||
} | |||
@@ -1,8 +1,8 @@ | |||
package cn.binarywang.wx.miniapp.bean; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import org.testng.Assert; | |||
import org.testng.annotations.Test; | |||
import org.testng.annotations.*; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
/** | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
@@ -10,30 +10,35 @@ import org.testng.annotations.Test; | |||
@Test | |||
public class WxMaKefuMessageTest { | |||
public void testTextReply() { | |||
WxMaKefuMessage reply = new WxMaKefuMessage(); | |||
reply.setToUser("OPENID"); | |||
reply.setMsgType(WxConsts.KefuMsgType.TEXT); | |||
reply.setContent("sfsfdsdf"); | |||
Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); | |||
} | |||
public void testTextBuild() { | |||
WxMaKefuMessage reply = WxMaKefuMessage.newTextBuilder().toUser("OPENID").content("sfsfdsdf").build(); | |||
Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); | |||
public void testTextBuilder() { | |||
WxMaKefuMessage reply = WxMaKefuMessage.newTextBuilder() | |||
.toUser("OPENID") | |||
.content("sfsfdsdf") | |||
.build(); | |||
assertThat(reply.toJson()) | |||
.isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); | |||
} | |||
public void testImageReply() { | |||
WxMaKefuMessage reply = new WxMaKefuMessage(); | |||
reply.setToUser("OPENID"); | |||
reply.setMsgType(WxConsts.KefuMsgType.IMAGE); | |||
reply.setMediaId("MEDIA_ID"); | |||
Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); | |||
public void testImageBuilder() { | |||
WxMaKefuMessage reply = WxMaKefuMessage.newImageBuilder() | |||
.toUser("OPENID") | |||
. mediaId("MEDIA_ID") | |||
.build(); | |||
assertThat(reply.toJson()) | |||
.isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); | |||
} | |||
public void testImageBuild() { | |||
WxMaKefuMessage reply = WxMaKefuMessage.newImageBuilder().toUser("OPENID").mediaId("MEDIA_ID").build(); | |||
Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); | |||
public void testLinkBuilder() { | |||
WxMaKefuMessage reply = WxMaKefuMessage.newLinkBuilder() | |||
.toUser("OPENID") | |||
.url("url") | |||
.description("description") | |||
.title("title") | |||
.thumbUrl("thumbUrl") | |||
.build(); | |||
assertThat(reply.toJson()) | |||
.isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"image\"," + | |||
"\"link\":{\"title\":\"title\",\"description\":\"description\",\"url\":\"url\",\"thumb_url\":\"thumbUrl\"}}"); | |||
} | |||