mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-04-05 17:38:05 +08:00
#1050 客服消息支持发送菜单消息
This commit is contained in:
parent
2422a28f9a
commit
084ffcf8bb
@ -85,14 +85,19 @@ public class WxConsts {
|
||||
public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
|
||||
|
||||
/**
|
||||
* 小程序卡片(要求小程序与公众号已关联)
|
||||
* 小程序卡片(要求小程序与公众号已关联).
|
||||
*/
|
||||
public static final String MINIPROGRAMPAGE = "miniprogrampage";
|
||||
|
||||
/**
|
||||
* 任务卡片消息
|
||||
* 任务卡片消息.
|
||||
*/
|
||||
public static final String TASKCARD = "taskcard";
|
||||
|
||||
/**
|
||||
* 菜单消息.
|
||||
*/
|
||||
public static final String MSGMENU = "msgmenu";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 客服消息
|
||||
* 客服消息.
|
||||
*
|
||||
* @author chanjarster
|
||||
*/
|
||||
@ -34,64 +34,79 @@ public class WxMpKefuMessage implements Serializable {
|
||||
private String miniProgramPagePath;
|
||||
private List<WxArticle> articles = new ArrayList<>();
|
||||
|
||||
private String headContent;
|
||||
private String tailContent;
|
||||
/**
|
||||
* 获得文本消息builder
|
||||
* 菜单消息里的菜单内容.
|
||||
* 请使用逗号分割的形式将id和content连起来放在数组的里面
|
||||
*/
|
||||
private String[] msgMenuList;
|
||||
|
||||
/**
|
||||
* 获得文本消息builder.
|
||||
*/
|
||||
public static TextBuilder TEXT() {
|
||||
return new TextBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得图片消息builder
|
||||
* 获得图片消息builder.
|
||||
*/
|
||||
public static ImageBuilder IMAGE() {
|
||||
return new ImageBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得语音消息builder
|
||||
* 获得语音消息builder.
|
||||
*/
|
||||
public static VoiceBuilder VOICE() {
|
||||
return new VoiceBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得视频消息builder
|
||||
* 获得视频消息builder.
|
||||
*/
|
||||
public static VideoBuilder VIDEO() {
|
||||
return new VideoBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得音乐消息builder
|
||||
* 获得音乐消息builder.
|
||||
*/
|
||||
public static MusicBuilder MUSIC() {
|
||||
return new MusicBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得图文消息(点击跳转到外链)builder
|
||||
* 获得图文消息(点击跳转到外链)builder.
|
||||
*/
|
||||
public static NewsBuilder NEWS() {
|
||||
return new NewsBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得图文消息(点击跳转到图文消息页面)builder
|
||||
* 获得图文消息(点击跳转到图文消息页面)builder.
|
||||
*/
|
||||
public static MpNewsBuilder MPNEWS() {
|
||||
return new MpNewsBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得卡券消息builder
|
||||
* 获得卡券消息builder.
|
||||
*/
|
||||
public static WxCardBuilder WXCARD() {
|
||||
return new WxCardBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序卡片
|
||||
* 获得菜单消息builder.
|
||||
*/
|
||||
public static WxMsgMenuBuilder MSGMENU() {
|
||||
return new WxMsgMenuBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序卡片.
|
||||
*/
|
||||
public static MiniProgramPageBuilder MINIPROGRAMPAGE() {
|
||||
return new MiniProgramPageBuilder();
|
||||
@ -110,8 +125,8 @@ public class WxMpKefuMessage implements Serializable {
|
||||
* {@link WxConsts.KefuMsgType#WXCARD}
|
||||
* {@link WxConsts.KefuMsgType#MINIPROGRAMPAGE}
|
||||
* {@link WxConsts.KefuMsgType#TASKCARD}
|
||||
* {@link WxConsts.KefuMsgType#MSGMENU}
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public void setMsgType(String msgType) {
|
||||
this.msgType = msgType;
|
||||
|
@ -634,11 +634,17 @@ public class WxMpXmlMessage implements Serializable {
|
||||
private String regionCode;
|
||||
|
||||
/**
|
||||
* 审核未通过的原因。
|
||||
* 审核未通过的原因.
|
||||
*/
|
||||
@XStreamAlias("ReasonMsg")
|
||||
private String reasonMsg;
|
||||
|
||||
/**
|
||||
* 给用户发菜单消息类型的客服消息后,用户所点击的菜单ID.
|
||||
*/
|
||||
@XStreamAlias("bizmsgmenuid")
|
||||
private String bizMsgMenuId;
|
||||
|
||||
public static WxMpXmlMessage fromXml(String xml) {
|
||||
//修改微信变态的消息内容格式,方便解析
|
||||
xml = xml.replace("</PicList><PicList>", "");
|
||||
|
@ -0,0 +1,46 @@
|
||||
package me.chanjar.weixin.mp.builder.kefu;
|
||||
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
|
||||
|
||||
/**
|
||||
* 卡券消息builder
|
||||
* <pre>
|
||||
* 用法: WxMpKefuMessage m = WxMpKefuMessage.WXCARD().cardId(...).toUser(...).build();
|
||||
* </pre>
|
||||
*
|
||||
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||
*/
|
||||
public final class WxMsgMenuBuilder extends BaseBuilder<WxMsgMenuBuilder> {
|
||||
private String headContent;
|
||||
private String tailContent;
|
||||
private String[] msgMenuList;
|
||||
|
||||
public WxMsgMenuBuilder() {
|
||||
this.msgType = WxConsts.KefuMsgType.MSGMENU;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxMpKefuMessage build() {
|
||||
WxMpKefuMessage m = super.build();
|
||||
m.setHeadContent(this.headContent);
|
||||
m.setMsgMenuList(this.msgMenuList);
|
||||
m.setTailContent(this.tailContent);
|
||||
return m;
|
||||
}
|
||||
|
||||
public WxMsgMenuBuilder headContent(String headContent) {
|
||||
this.headContent = headContent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WxMsgMenuBuilder tailContent(String tailContent) {
|
||||
this.tailContent = tailContent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WxMsgMenuBuilder msgMenuList(String... msgMenuList) {
|
||||
this.msgMenuList = msgMenuList;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package me.chanjar.weixin.mp.util.json;
|
||||
|
||||
import com.google.gson.*;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.api.WxConsts.KefuMsgType;
|
||||
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -16,77 +15,90 @@ public class WxMpKefuMessageGsonAdapter implements JsonSerializer<WxMpKefuMessag
|
||||
messageJson.addProperty("touser", message.getToUser());
|
||||
messageJson.addProperty("msgtype", message.getMsgType());
|
||||
|
||||
if (WxConsts.KefuMsgType.TEXT.equals(message.getMsgType())) {
|
||||
JsonObject text = new JsonObject();
|
||||
text.addProperty("content", message.getContent());
|
||||
messageJson.add("text", text);
|
||||
}
|
||||
|
||||
if (WxConsts.KefuMsgType.IMAGE.equals(message.getMsgType())) {
|
||||
JsonObject image = new JsonObject();
|
||||
image.addProperty("media_id", message.getMediaId());
|
||||
messageJson.add("image", image);
|
||||
}
|
||||
|
||||
if (WxConsts.KefuMsgType.VOICE.equals(message.getMsgType())) {
|
||||
JsonObject voice = new JsonObject();
|
||||
voice.addProperty("media_id", message.getMediaId());
|
||||
messageJson.add("voice", voice);
|
||||
}
|
||||
|
||||
if (WxConsts.KefuMsgType.VIDEO.equals(message.getMsgType())) {
|
||||
JsonObject video = new JsonObject();
|
||||
video.addProperty("media_id", message.getMediaId());
|
||||
video.addProperty("thumb_media_id", message.getThumbMediaId());
|
||||
video.addProperty("title", message.getTitle());
|
||||
video.addProperty("description", message.getDescription());
|
||||
messageJson.add("video", video);
|
||||
}
|
||||
|
||||
if (WxConsts.KefuMsgType.MUSIC.equals(message.getMsgType())) {
|
||||
JsonObject music = new JsonObject();
|
||||
music.addProperty("title", message.getTitle());
|
||||
music.addProperty("description", message.getDescription());
|
||||
music.addProperty("thumb_media_id", message.getThumbMediaId());
|
||||
music.addProperty("musicurl", message.getMusicUrl());
|
||||
music.addProperty("hqmusicurl", message.getHqMusicUrl());
|
||||
messageJson.add("music", music);
|
||||
}
|
||||
|
||||
if (WxConsts.KefuMsgType.NEWS.equals(message.getMsgType())) {
|
||||
JsonObject newsJsonObject = new JsonObject();
|
||||
JsonArray articleJsonArray = new JsonArray();
|
||||
for (WxMpKefuMessage.WxArticle article : message.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);
|
||||
switch (message.getMsgType()) {
|
||||
case KefuMsgType.TEXT:
|
||||
JsonObject text = new JsonObject();
|
||||
text.addProperty("content", message.getContent());
|
||||
messageJson.add("text", text);
|
||||
break;
|
||||
case KefuMsgType.IMAGE:
|
||||
JsonObject image = new JsonObject();
|
||||
image.addProperty("media_id", message.getMediaId());
|
||||
messageJson.add("image", image);
|
||||
break;
|
||||
case KefuMsgType.VOICE:
|
||||
JsonObject voice = new JsonObject();
|
||||
voice.addProperty("media_id", message.getMediaId());
|
||||
messageJson.add("voice", voice);
|
||||
break;
|
||||
case KefuMsgType.VIDEO:
|
||||
JsonObject video = new JsonObject();
|
||||
video.addProperty("media_id", message.getMediaId());
|
||||
video.addProperty("thumb_media_id", message.getThumbMediaId());
|
||||
video.addProperty("title", message.getTitle());
|
||||
video.addProperty("description", message.getDescription());
|
||||
messageJson.add("video", video);
|
||||
break;
|
||||
case KefuMsgType.MUSIC:
|
||||
JsonObject music = new JsonObject();
|
||||
music.addProperty("title", message.getTitle());
|
||||
music.addProperty("description", message.getDescription());
|
||||
music.addProperty("thumb_media_id", message.getThumbMediaId());
|
||||
music.addProperty("musicurl", message.getMusicUrl());
|
||||
music.addProperty("hqmusicurl", message.getHqMusicUrl());
|
||||
messageJson.add("music", music);
|
||||
break;
|
||||
case KefuMsgType.NEWS:
|
||||
JsonObject newsJsonObject = new JsonObject();
|
||||
JsonArray articleJsonArray = new JsonArray();
|
||||
for (WxMpKefuMessage.WxArticle article : message.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 KefuMsgType.MPNEWS:
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("media_id", message.getMpNewsMediaId());
|
||||
messageJson.add("mpnews", json);
|
||||
break;
|
||||
case KefuMsgType.WXCARD:
|
||||
JsonObject wxcard = new JsonObject();
|
||||
wxcard.addProperty("card_id", message.getCardId());
|
||||
messageJson.add("wxcard", wxcard);
|
||||
break;
|
||||
case KefuMsgType.MINIPROGRAMPAGE:
|
||||
JsonObject miniProgramPage = new JsonObject();
|
||||
miniProgramPage.addProperty("title", message.getTitle());
|
||||
miniProgramPage.addProperty("appid", message.getMiniProgramAppId());
|
||||
miniProgramPage.addProperty("pagepath", message.getMiniProgramPagePath());
|
||||
miniProgramPage.addProperty("thumb_media_id", message.getThumbMediaId());
|
||||
messageJson.add("miniprogrampage", miniProgramPage);
|
||||
break;
|
||||
case KefuMsgType.MSGMENU: {
|
||||
JsonObject msgMenu = new JsonObject();
|
||||
JsonArray array = new JsonArray();
|
||||
for (String s : message.getMsgMenuList()) {
|
||||
JsonObject innerJson = new JsonObject();
|
||||
final String[] split = s.split(",");
|
||||
innerJson.addProperty("id", split[0]);
|
||||
innerJson.addProperty("content", split[1]);
|
||||
array.add(innerJson);
|
||||
}
|
||||
msgMenu.addProperty("head_content", message.getHeadContent());
|
||||
msgMenu.add("list", array);
|
||||
msgMenu.addProperty("tail_content", message.getTailContent());
|
||||
messageJson.add("msgmenu", msgMenu);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("非法消息类型,暂不支持");
|
||||
}
|
||||
newsJsonObject.add("articles", articleJsonArray);
|
||||
messageJson.add("news", newsJsonObject);
|
||||
}
|
||||
|
||||
if (WxConsts.KefuMsgType.MPNEWS.equals(message.getMsgType())) {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("media_id", message.getMpNewsMediaId());
|
||||
messageJson.add("mpnews", json);
|
||||
}
|
||||
|
||||
if (WxConsts.KefuMsgType.WXCARD.equals(message.getMsgType())) {
|
||||
JsonObject wxcard = new JsonObject();
|
||||
wxcard.addProperty("card_id", message.getCardId());
|
||||
messageJson.add("wxcard", wxcard);
|
||||
}
|
||||
|
||||
if (KefuMsgType.MINIPROGRAMPAGE.equals(message.getMsgType())) {
|
||||
JsonObject miniProgramPage = new JsonObject();
|
||||
miniProgramPage.addProperty("title", message.getTitle());
|
||||
miniProgramPage.addProperty("appid", message.getMiniProgramAppId());
|
||||
miniProgramPage.addProperty("pagepath", message.getMiniProgramPagePath());
|
||||
miniProgramPage.addProperty("thumb_media_id", message.getThumbMediaId());
|
||||
messageJson.add("miniprogrampage", miniProgramPage);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(message.getKfAccount())) {
|
||||
|
@ -5,6 +5,8 @@ import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage.WxArticle;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@Test
|
||||
public class WxMpKefuMessageTest {
|
||||
|
||||
@ -141,7 +143,6 @@ public class WxMpKefuMessageTest {
|
||||
}
|
||||
|
||||
public void testMiniProgramPageBuild() {
|
||||
|
||||
WxMpKefuMessage reply = WxMpKefuMessage.MINIPROGRAMPAGE()
|
||||
.toUser("OPENID")
|
||||
.title("title")
|
||||
@ -154,4 +155,16 @@ public class WxMpKefuMessageTest {
|
||||
"{\"touser\":\"OPENID\",\"msgtype\":\"miniprogrampage\",\"miniprogrampage\":{\"title\":\"title\",\"appid\":\"appid\",\"pagepath\":\"pagepath\",\"thumb_media_id\":\"thumb_media_id\"}}");
|
||||
}
|
||||
|
||||
public void testMsgMenuBuild() {
|
||||
WxMpKefuMessage reply = WxMpKefuMessage.MSGMENU()
|
||||
.toUser("OPENID")
|
||||
.msgMenuList("101,满意", "102,不满意")
|
||||
.headContent("您对本次服务是否满意呢?")
|
||||
.tailContent("欢迎再次光临")
|
||||
.build();
|
||||
|
||||
assertThat(reply.toJson())
|
||||
.isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"msgmenu\",\"msgmenu\":{\"head_content\":\"您对本次服务是否满意呢?\",\"list\":[{\"id\":\"101\",\"content\":\"满意\"},{\"id\":\"102\",\"content\":\"不满意\"}],\"tail_content\":\"欢迎再次光临\"}}");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user