Quellcode durchsuchen

#1050 客服消息支持发送菜单消息

master
Binary Wang vor 5 Jahren
Ursprung
Commit
084ffcf8bb
6 geänderte Dateien mit 183 neuen und 86 gelöschten Zeilen
  1. +7
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
  2. +26
    -11
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java
  3. +7
    -1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
  4. +46
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/WxMsgMenuBuilder.java
  5. +83
    -71
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java
  6. +14
    -1
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java

+ 7
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java Datei anzeigen

@@ -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";
}

/**


+ 26
- 11
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java Datei anzeigen

@@ -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;


+ 7
- 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java Datei anzeigen

@@ -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>", "");


+ 46
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/WxMsgMenuBuilder.java Datei anzeigen

@@ -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;
}
}

+ 83
- 71
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java Datei anzeigen

@@ -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())) {


+ 14
- 1
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java Datei anzeigen

@@ -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\":\"欢迎再次光临\"}}");
}

}

Laden…
Abbrechen
Speichern