mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-05-04 12:47:46 +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 TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小程序卡片(要求小程序与公众号已关联)
|
* 小程序卡片(要求小程序与公众号已关联).
|
||||||
*/
|
*/
|
||||||
public static final String MINIPROGRAMPAGE = "miniprogrampage";
|
public static final String MINIPROGRAMPAGE = "miniprogrampage";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务卡片消息
|
* 任务卡片消息.
|
||||||
*/
|
*/
|
||||||
public static final String TASKCARD = "taskcard";
|
public static final String TASKCARD = "taskcard";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单消息.
|
||||||
|
*/
|
||||||
|
public static final String MSGMENU = "msgmenu";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,7 +10,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客服消息
|
* 客服消息.
|
||||||
*
|
*
|
||||||
* @author chanjarster
|
* @author chanjarster
|
||||||
*/
|
*/
|
||||||
@ -34,64 +34,79 @@ public class WxMpKefuMessage implements Serializable {
|
|||||||
private String miniProgramPagePath;
|
private String miniProgramPagePath;
|
||||||
private List<WxArticle> articles = new ArrayList<>();
|
private List<WxArticle> articles = new ArrayList<>();
|
||||||
|
|
||||||
|
private String headContent;
|
||||||
|
private String tailContent;
|
||||||
/**
|
/**
|
||||||
* 获得文本消息builder
|
* 菜单消息里的菜单内容.
|
||||||
|
* 请使用逗号分割的形式将id和content连起来放在数组的里面
|
||||||
|
*/
|
||||||
|
private String[] msgMenuList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得文本消息builder.
|
||||||
*/
|
*/
|
||||||
public static TextBuilder TEXT() {
|
public static TextBuilder TEXT() {
|
||||||
return new TextBuilder();
|
return new TextBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得图片消息builder
|
* 获得图片消息builder.
|
||||||
*/
|
*/
|
||||||
public static ImageBuilder IMAGE() {
|
public static ImageBuilder IMAGE() {
|
||||||
return new ImageBuilder();
|
return new ImageBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得语音消息builder
|
* 获得语音消息builder.
|
||||||
*/
|
*/
|
||||||
public static VoiceBuilder VOICE() {
|
public static VoiceBuilder VOICE() {
|
||||||
return new VoiceBuilder();
|
return new VoiceBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得视频消息builder
|
* 获得视频消息builder.
|
||||||
*/
|
*/
|
||||||
public static VideoBuilder VIDEO() {
|
public static VideoBuilder VIDEO() {
|
||||||
return new VideoBuilder();
|
return new VideoBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得音乐消息builder
|
* 获得音乐消息builder.
|
||||||
*/
|
*/
|
||||||
public static MusicBuilder MUSIC() {
|
public static MusicBuilder MUSIC() {
|
||||||
return new MusicBuilder();
|
return new MusicBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得图文消息(点击跳转到外链)builder
|
* 获得图文消息(点击跳转到外链)builder.
|
||||||
*/
|
*/
|
||||||
public static NewsBuilder NEWS() {
|
public static NewsBuilder NEWS() {
|
||||||
return new NewsBuilder();
|
return new NewsBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得图文消息(点击跳转到图文消息页面)builder
|
* 获得图文消息(点击跳转到图文消息页面)builder.
|
||||||
*/
|
*/
|
||||||
public static MpNewsBuilder MPNEWS() {
|
public static MpNewsBuilder MPNEWS() {
|
||||||
return new MpNewsBuilder();
|
return new MpNewsBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得卡券消息builder
|
* 获得卡券消息builder.
|
||||||
*/
|
*/
|
||||||
public static WxCardBuilder WXCARD() {
|
public static WxCardBuilder WXCARD() {
|
||||||
return new WxCardBuilder();
|
return new WxCardBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小程序卡片
|
* 获得菜单消息builder.
|
||||||
|
*/
|
||||||
|
public static WxMsgMenuBuilder MSGMENU() {
|
||||||
|
return new WxMsgMenuBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序卡片.
|
||||||
*/
|
*/
|
||||||
public static MiniProgramPageBuilder MINIPROGRAMPAGE() {
|
public static MiniProgramPageBuilder MINIPROGRAMPAGE() {
|
||||||
return new MiniProgramPageBuilder();
|
return new MiniProgramPageBuilder();
|
||||||
@ -110,8 +125,8 @@ public class WxMpKefuMessage implements Serializable {
|
|||||||
* {@link WxConsts.KefuMsgType#WXCARD}
|
* {@link WxConsts.KefuMsgType#WXCARD}
|
||||||
* {@link WxConsts.KefuMsgType#MINIPROGRAMPAGE}
|
* {@link WxConsts.KefuMsgType#MINIPROGRAMPAGE}
|
||||||
* {@link WxConsts.KefuMsgType#TASKCARD}
|
* {@link WxConsts.KefuMsgType#TASKCARD}
|
||||||
|
* {@link WxConsts.KefuMsgType#MSGMENU}
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public void setMsgType(String msgType) {
|
public void setMsgType(String msgType) {
|
||||||
this.msgType = msgType;
|
this.msgType = msgType;
|
||||||
|
@ -634,11 +634,17 @@ public class WxMpXmlMessage implements Serializable {
|
|||||||
private String regionCode;
|
private String regionCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审核未通过的原因。
|
* 审核未通过的原因.
|
||||||
*/
|
*/
|
||||||
@XStreamAlias("ReasonMsg")
|
@XStreamAlias("ReasonMsg")
|
||||||
private String reasonMsg;
|
private String reasonMsg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给用户发菜单消息类型的客服消息后,用户所点击的菜单ID.
|
||||||
|
*/
|
||||||
|
@XStreamAlias("bizmsgmenuid")
|
||||||
|
private String bizMsgMenuId;
|
||||||
|
|
||||||
public static WxMpXmlMessage fromXml(String xml) {
|
public static WxMpXmlMessage fromXml(String xml) {
|
||||||
//修改微信变态的消息内容格式,方便解析
|
//修改微信变态的消息内容格式,方便解析
|
||||||
xml = xml.replace("</PicList><PicList>", "");
|
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;
|
package me.chanjar.weixin.mp.util.json;
|
||||||
|
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
import me.chanjar.weixin.common.api.WxConsts;
|
|
||||||
import me.chanjar.weixin.common.api.WxConsts.KefuMsgType;
|
import me.chanjar.weixin.common.api.WxConsts.KefuMsgType;
|
||||||
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
|
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -16,77 +15,90 @@ public class WxMpKefuMessageGsonAdapter implements JsonSerializer<WxMpKefuMessag
|
|||||||
messageJson.addProperty("touser", message.getToUser());
|
messageJson.addProperty("touser", message.getToUser());
|
||||||
messageJson.addProperty("msgtype", message.getMsgType());
|
messageJson.addProperty("msgtype", message.getMsgType());
|
||||||
|
|
||||||
if (WxConsts.KefuMsgType.TEXT.equals(message.getMsgType())) {
|
switch (message.getMsgType()) {
|
||||||
JsonObject text = new JsonObject();
|
case KefuMsgType.TEXT:
|
||||||
text.addProperty("content", message.getContent());
|
JsonObject text = new JsonObject();
|
||||||
messageJson.add("text", text);
|
text.addProperty("content", message.getContent());
|
||||||
}
|
messageJson.add("text", text);
|
||||||
|
break;
|
||||||
if (WxConsts.KefuMsgType.IMAGE.equals(message.getMsgType())) {
|
case KefuMsgType.IMAGE:
|
||||||
JsonObject image = new JsonObject();
|
JsonObject image = new JsonObject();
|
||||||
image.addProperty("media_id", message.getMediaId());
|
image.addProperty("media_id", message.getMediaId());
|
||||||
messageJson.add("image", image);
|
messageJson.add("image", image);
|
||||||
}
|
break;
|
||||||
|
case KefuMsgType.VOICE:
|
||||||
if (WxConsts.KefuMsgType.VOICE.equals(message.getMsgType())) {
|
JsonObject voice = new JsonObject();
|
||||||
JsonObject voice = new JsonObject();
|
voice.addProperty("media_id", message.getMediaId());
|
||||||
voice.addProperty("media_id", message.getMediaId());
|
messageJson.add("voice", voice);
|
||||||
messageJson.add("voice", voice);
|
break;
|
||||||
}
|
case KefuMsgType.VIDEO:
|
||||||
|
JsonObject video = new JsonObject();
|
||||||
if (WxConsts.KefuMsgType.VIDEO.equals(message.getMsgType())) {
|
video.addProperty("media_id", message.getMediaId());
|
||||||
JsonObject video = new JsonObject();
|
video.addProperty("thumb_media_id", message.getThumbMediaId());
|
||||||
video.addProperty("media_id", message.getMediaId());
|
video.addProperty("title", message.getTitle());
|
||||||
video.addProperty("thumb_media_id", message.getThumbMediaId());
|
video.addProperty("description", message.getDescription());
|
||||||
video.addProperty("title", message.getTitle());
|
messageJson.add("video", video);
|
||||||
video.addProperty("description", message.getDescription());
|
break;
|
||||||
messageJson.add("video", video);
|
case KefuMsgType.MUSIC:
|
||||||
}
|
JsonObject music = new JsonObject();
|
||||||
|
music.addProperty("title", message.getTitle());
|
||||||
if (WxConsts.KefuMsgType.MUSIC.equals(message.getMsgType())) {
|
music.addProperty("description", message.getDescription());
|
||||||
JsonObject music = new JsonObject();
|
music.addProperty("thumb_media_id", message.getThumbMediaId());
|
||||||
music.addProperty("title", message.getTitle());
|
music.addProperty("musicurl", message.getMusicUrl());
|
||||||
music.addProperty("description", message.getDescription());
|
music.addProperty("hqmusicurl", message.getHqMusicUrl());
|
||||||
music.addProperty("thumb_media_id", message.getThumbMediaId());
|
messageJson.add("music", music);
|
||||||
music.addProperty("musicurl", message.getMusicUrl());
|
break;
|
||||||
music.addProperty("hqmusicurl", message.getHqMusicUrl());
|
case KefuMsgType.NEWS:
|
||||||
messageJson.add("music", music);
|
JsonObject newsJsonObject = new JsonObject();
|
||||||
}
|
JsonArray articleJsonArray = new JsonArray();
|
||||||
|
for (WxMpKefuMessage.WxArticle article : message.getArticles()) {
|
||||||
if (WxConsts.KefuMsgType.NEWS.equals(message.getMsgType())) {
|
JsonObject articleJson = new JsonObject();
|
||||||
JsonObject newsJsonObject = new JsonObject();
|
articleJson.addProperty("title", article.getTitle());
|
||||||
JsonArray articleJsonArray = new JsonArray();
|
articleJson.addProperty("description", article.getDescription());
|
||||||
for (WxMpKefuMessage.WxArticle article : message.getArticles()) {
|
articleJson.addProperty("url", article.getUrl());
|
||||||
JsonObject articleJson = new JsonObject();
|
articleJson.addProperty("picurl", article.getPicUrl());
|
||||||
articleJson.addProperty("title", article.getTitle());
|
articleJsonArray.add(articleJson);
|
||||||
articleJson.addProperty("description", article.getDescription());
|
}
|
||||||
articleJson.addProperty("url", article.getUrl());
|
newsJsonObject.add("articles", articleJsonArray);
|
||||||
articleJson.addProperty("picurl", article.getPicUrl());
|
messageJson.add("news", newsJsonObject);
|
||||||
articleJsonArray.add(articleJson);
|
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())) {
|
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.Assert;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public class WxMpKefuMessageTest {
|
public class WxMpKefuMessageTest {
|
||||||
|
|
||||||
@ -141,7 +143,6 @@ public class WxMpKefuMessageTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testMiniProgramPageBuild() {
|
public void testMiniProgramPageBuild() {
|
||||||
|
|
||||||
WxMpKefuMessage reply = WxMpKefuMessage.MINIPROGRAMPAGE()
|
WxMpKefuMessage reply = WxMpKefuMessage.MINIPROGRAMPAGE()
|
||||||
.toUser("OPENID")
|
.toUser("OPENID")
|
||||||
.title("title")
|
.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\"}}");
|
"{\"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