1
0
mirror of synced 2025-12-21 16:38:01 +08:00

Implement WeChat Intelligent Conversation support in MP module

Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-09-24 15:27:35 +00:00
parent dec2c188f3
commit 27de971e8c
6 changed files with 222 additions and 1 deletions

View File

@@ -3,6 +3,8 @@ package me.chanjar.weixin.mp.api;
import java.io.File;
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;
/**
@@ -76,4 +78,49 @@ public interface WxMpAiOpenService {
* @throws WxErrorException the wx error exception
*/
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;
}

View File

@@ -1,5 +1,6 @@
package me.chanjar.weixin.mp.api.impl;
import com.google.gson.JsonObject;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.enums.WxType;
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.mp.api.WxMpAiOpenService;
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.util.requestexecuter.voice.VoiceUploadRequestExecutor;
@@ -70,4 +73,59 @@ public class WxMpAiOpenServiceImpl implements WxMpAiOpenService {
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;
}
}

View File

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

View File

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

View File

@@ -469,7 +469,11 @@ public interface WxMpApiUrl {
/**
* 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 path;

View File

@@ -8,6 +8,8 @@ import com.google.inject.Inject;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
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 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, "微信文档很坑爹");
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();
}
}