Implement WeChat Intelligent Conversation support in MP module
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,8 @@ package me.chanjar.weixin.mp.api;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import me.chanjar.weixin.common.error.WxErrorException;
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpAiConversationRequest;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpAiConversationResponse;
|
||||||
import me.chanjar.weixin.mp.enums.AiLangType;
|
import me.chanjar.weixin.mp.enums.AiLangType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,4 +78,49 @@ public interface WxMpAiOpenService {
|
|||||||
* @throws WxErrorException the wx error exception
|
* @throws WxErrorException the wx error exception
|
||||||
*/
|
*/
|
||||||
String translate(AiLangType langFrom, AiLangType langTo, String content) throws WxErrorException;
|
String translate(AiLangType langFrom, AiLangType langTo, String content) throws WxErrorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 微信智能对话.
|
||||||
|
* 基于WeChat AI Speech平台的智能对话功能
|
||||||
|
*
|
||||||
|
* 文档地址:https://developers.weixin.qq.com/doc/aispeech/platform/INTRODUCTION.html
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param query 用户输入的对话内容
|
||||||
|
* @param sessionId 会话ID,用于保持对话上下文
|
||||||
|
* @return 智能对话回复内容
|
||||||
|
* @throws WxErrorException the wx error exception
|
||||||
|
*/
|
||||||
|
String intelligentConversation(String query, String sessionId) throws WxErrorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 微信智能对话(带语言参数).
|
||||||
|
* 基于WeChat AI Speech平台的智能对话功能
|
||||||
|
*
|
||||||
|
* 文档地址:https://developers.weixin.qq.com/doc/aispeech/platform/INTRODUCTION.html
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param query 用户输入的对话内容
|
||||||
|
* @param sessionId 会话ID,用于保持对话上下文
|
||||||
|
* @param lang 语言类型,默认中文
|
||||||
|
* @return 智能对话回复内容
|
||||||
|
* @throws WxErrorException the wx error exception
|
||||||
|
*/
|
||||||
|
String intelligentConversation(String query, String sessionId, AiLangType lang) throws WxErrorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 微信智能对话(使用请求对象).
|
||||||
|
* 基于WeChat AI Speech平台的智能对话功能,支持更复杂的请求参数
|
||||||
|
*
|
||||||
|
* 文档地址:https://developers.weixin.qq.com/doc/aispeech/platform/INTRODUCTION.html
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param request 智能对话请求对象
|
||||||
|
* @return 智能对话响应对象
|
||||||
|
* @throws WxErrorException the wx error exception
|
||||||
|
*/
|
||||||
|
WxMpAiConversationResponse intelligentConversation(WxMpAiConversationRequest request) throws WxErrorException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package me.chanjar.weixin.mp.api.impl;
|
package me.chanjar.weixin.mp.api.impl;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import me.chanjar.weixin.common.enums.WxType;
|
import me.chanjar.weixin.common.enums.WxType;
|
||||||
import me.chanjar.weixin.common.error.WxError;
|
import me.chanjar.weixin.common.error.WxError;
|
||||||
@@ -7,6 +8,8 @@ import me.chanjar.weixin.common.error.WxErrorException;
|
|||||||
import me.chanjar.weixin.common.util.json.GsonParser;
|
import me.chanjar.weixin.common.util.json.GsonParser;
|
||||||
import me.chanjar.weixin.mp.api.WxMpAiOpenService;
|
import me.chanjar.weixin.mp.api.WxMpAiOpenService;
|
||||||
import me.chanjar.weixin.mp.api.WxMpService;
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpAiConversationRequest;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpAiConversationResponse;
|
||||||
import me.chanjar.weixin.mp.enums.AiLangType;
|
import me.chanjar.weixin.mp.enums.AiLangType;
|
||||||
import me.chanjar.weixin.mp.util.requestexecuter.voice.VoiceUploadRequestExecutor;
|
import me.chanjar.weixin.mp.util.requestexecuter.voice.VoiceUploadRequestExecutor;
|
||||||
|
|
||||||
@@ -70,4 +73,59 @@ public class WxMpAiOpenServiceImpl implements WxMpAiOpenService {
|
|||||||
|
|
||||||
return GsonParser.parse(response).get("result").getAsString();
|
return GsonParser.parse(response).get("result").getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String intelligentConversation(String query, String sessionId) throws WxErrorException {
|
||||||
|
return this.intelligentConversation(query, sessionId, AiLangType.zh_CN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String intelligentConversation(String query, String sessionId, AiLangType lang) throws WxErrorException {
|
||||||
|
if (lang == null) {
|
||||||
|
lang = AiLangType.zh_CN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建请求JSON
|
||||||
|
JsonObject request = new JsonObject();
|
||||||
|
request.addProperty("query", query);
|
||||||
|
request.addProperty("session_id", sessionId);
|
||||||
|
request.addProperty("lang", lang.getCode());
|
||||||
|
|
||||||
|
final String response = this.wxMpService.post(INTELLIGENT_CONVERSATION_URL.getUrl(this.wxMpService.getWxMpConfigStorage()),
|
||||||
|
request.toString());
|
||||||
|
|
||||||
|
WxError error = WxError.fromJson(response, WxType.MP);
|
||||||
|
if (error.getErrorCode() != 0) {
|
||||||
|
throw new WxErrorException(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GsonParser.parse(response).get("reply").getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpAiConversationResponse intelligentConversation(WxMpAiConversationRequest request) throws WxErrorException {
|
||||||
|
// 构建请求JSON
|
||||||
|
JsonObject requestJson = new JsonObject();
|
||||||
|
requestJson.addProperty("query", request.getQuery());
|
||||||
|
requestJson.addProperty("session_id", request.getSessionId());
|
||||||
|
requestJson.addProperty("lang", request.getLang() != null ? request.getLang().getCode() : AiLangType.zh_CN.getCode());
|
||||||
|
|
||||||
|
final String response = this.wxMpService.post(INTELLIGENT_CONVERSATION_URL.getUrl(this.wxMpService.getWxMpConfigStorage()),
|
||||||
|
requestJson.toString());
|
||||||
|
|
||||||
|
WxError error = WxError.fromJson(response, WxType.MP);
|
||||||
|
if (error.getErrorCode() != 0) {
|
||||||
|
throw new WxErrorException(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
WxMpAiConversationResponse result = WxMpAiConversationResponse.fromJson(response);
|
||||||
|
if (result.getReply() == null) {
|
||||||
|
result.setReply(GsonParser.parse(response).get("reply").getAsString());
|
||||||
|
}
|
||||||
|
if (result.getSessionId() == null) {
|
||||||
|
result.setSessionId(request.getSessionId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package me.chanjar.weixin.mp.bean;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import me.chanjar.weixin.mp.enums.AiLangType;
|
||||||
|
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信智能对话请求对象
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WxMpAiConversationRequest implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户输入的对话内容
|
||||||
|
*/
|
||||||
|
private String query;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会话ID,用于保持对话上下文
|
||||||
|
*/
|
||||||
|
private String sessionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 语言类型,默认中文
|
||||||
|
*/
|
||||||
|
private AiLangType lang = AiLangType.zh_CN;
|
||||||
|
|
||||||
|
public String toJson() {
|
||||||
|
return WxMpGsonBuilder.create().toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WxMpAiConversationRequest fromJson(String json) {
|
||||||
|
return WxMpGsonBuilder.create().fromJson(json, WxMpAiConversationRequest.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package me.chanjar.weixin.mp.bean;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信智能对话响应对象
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class WxMpAiConversationResponse implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 智能对话回复内容
|
||||||
|
*/
|
||||||
|
private String reply;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会话ID
|
||||||
|
*/
|
||||||
|
private String sessionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误码
|
||||||
|
*/
|
||||||
|
private Integer errcode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误消息
|
||||||
|
*/
|
||||||
|
private String errmsg;
|
||||||
|
|
||||||
|
public String toJson() {
|
||||||
|
return WxMpGsonBuilder.create().toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WxMpAiConversationResponse fromJson(String json) {
|
||||||
|
return WxMpGsonBuilder.create().fromJson(json, WxMpAiConversationResponse.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -469,7 +469,11 @@ public interface WxMpApiUrl {
|
|||||||
/**
|
/**
|
||||||
* queryrecoresultfortext.
|
* queryrecoresultfortext.
|
||||||
*/
|
*/
|
||||||
VOICE_QUERY_RESULT_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/voice/queryrecoresultfortext");
|
VOICE_QUERY_RESULT_URL(API_DEFAULT_HOST_URL, "/cgi-bin/media/voice/queryrecoresultfortext"),
|
||||||
|
/**
|
||||||
|
* 智能对话.
|
||||||
|
*/
|
||||||
|
INTELLIGENT_CONVERSATION_URL(API_DEFAULT_HOST_URL, "/cgi-bin/aispeech/conversation");
|
||||||
|
|
||||||
private final String prefix;
|
private final String prefix;
|
||||||
private final String path;
|
private final String path;
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import com.google.inject.Inject;
|
|||||||
import me.chanjar.weixin.common.error.WxErrorException;
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
import me.chanjar.weixin.mp.api.WxMpService;
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
import me.chanjar.weixin.mp.api.test.ApiTestModule;
|
import me.chanjar.weixin.mp.api.test.ApiTestModule;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpAiConversationRequest;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpAiConversationResponse;
|
||||||
import me.chanjar.weixin.mp.enums.AiLangType;
|
import me.chanjar.weixin.mp.enums.AiLangType;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -45,4 +47,30 @@ public class WxMpAiOpenServiceImplTest {
|
|||||||
final String result = this.wxService.getAiOpenService().translate(AiLangType.zh_CN, AiLangType.en_US, "微信文档很坑爹");
|
final String result = this.wxService.getAiOpenService().translate(AiLangType.zh_CN, AiLangType.en_US, "微信文档很坑爹");
|
||||||
assertThat(result).isNotEmpty();
|
assertThat(result).isNotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntelligentConversation() throws WxErrorException {
|
||||||
|
String sessionId = "test_session_" + System.currentTimeMillis();
|
||||||
|
final String result = this.wxService.getAiOpenService().intelligentConversation("你好", sessionId);
|
||||||
|
assertThat(result).isNotEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntelligentConversationWithLang() throws WxErrorException {
|
||||||
|
String sessionId = "test_session_" + System.currentTimeMillis();
|
||||||
|
final String result = this.wxService.getAiOpenService().intelligentConversation("你好,请介绍一下微信", sessionId, AiLangType.zh_CN);
|
||||||
|
assertThat(result).isNotEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntelligentConversationWithRequest() throws WxErrorException {
|
||||||
|
WxMpAiConversationRequest request = new WxMpAiConversationRequest();
|
||||||
|
request.setQuery("微信智能对话功能怎么使用?");
|
||||||
|
request.setSessionId("test_session_bean_" + System.currentTimeMillis());
|
||||||
|
request.setLang(AiLangType.zh_CN);
|
||||||
|
|
||||||
|
final WxMpAiConversationResponse result = this.wxService.getAiOpenService().intelligentConversation(request);
|
||||||
|
assertThat(result).isNotNull();
|
||||||
|
assertThat(result.getReply()).isNotEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user