Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

新增“关键词回复功能” #86

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/main/java/com/ashin/client/BotClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.ashin.handler.QqMessageHandler;
import com.ashin.handler.WechatMessageHandler;
import com.ashin.service.InteractService;
import com.ashin.service.TriggerService;
import com.ashin.util.BotUtil;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -32,6 +33,8 @@ public class BotClient {
@Resource
private InteractService interactService;
@Resource
private TriggerService triggerService;
@Resource
private KeywordConfig keywordConfig;
@Resource
private BotUtil botUtil;
Expand All @@ -41,7 +44,7 @@ public void init() {
//微信
if (wechatConfig.getEnable()){
log.info("正在登录微信,请按提示操作:");
wechatBot = new Wechat(new WechatMessageHandler(interactService, keywordConfig, botUtil), wechatConfig.getQrPath());
wechatBot = new Wechat(new WechatMessageHandler(interactService, keywordConfig, triggerService, botUtil), wechatConfig.getQrPath());
wechatBot.start();
}
if (qqConfig.getEnable()) {
Expand All @@ -56,7 +59,7 @@ public void init() {
qqBot.login();
log.info("成功登录账号为 {} 的qq, 登陆协议为 {}", qqConfig.getAccount(), miraiProtocol);
//订阅监听事件
qqBot.getEventChannel().registerListenerHost(new QqMessageHandler(interactService, qqConfig, keywordConfig, botUtil));
qqBot.getEventChannel().registerListenerHost(new QqMessageHandler(interactService, qqConfig, keywordConfig, botUtil, triggerService));
} catch (Exception e) {
log.error("登陆失败, qq账号为 {}, 登陆协议为 {}, 可尝试更换登陆协议, 具体原因: {}", qqConfig.getAccount(), miraiProtocol, e.getMessage());
}
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/com/ashin/config/TriggerConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.ashin.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
* 关键词回复配置
* @author InwardfFlow
* @date 2023/12/13
*/

@Data
@Component
@ConfigurationProperties("trigger")
public class TriggerConfig {
private Map<String, String> triggers;
@PostConstruct
public void init() {
System.out.println("TriggerConfig initialized. Triggers: " + triggers);
}
}
39 changes: 33 additions & 6 deletions src/main/java/com/ashin/handler/QqMessageHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.ashin.entity.bo.ChatBO;
import com.ashin.entity.dto.ChatResultDTO;
import com.ashin.service.InteractService;
import com.ashin.service.TriggerService;
import com.ashin.util.BotUtil;
import lombok.extern.slf4j.Slf4j;
import net.mamoe.mirai.contact.Contact;
Expand All @@ -30,15 +31,17 @@
@Slf4j
public class QqMessageHandler implements ListenerHost {
private final InteractService interactService;
private final TriggerService triggerService;
private final QqConfig qqConfig;
private final KeywordConfig keywordConfig;
private final BotUtil botUtil;

public QqMessageHandler(InteractService interactService, QqConfig qqConfig, KeywordConfig keywordConfig, BotUtil botUtil) {
public QqMessageHandler(InteractService interactService, QqConfig qqConfig, KeywordConfig keywordConfig, BotUtil botUtil, TriggerService triggerService) {
this.interactService = interactService;
this.qqConfig = qqConfig;
this.keywordConfig = keywordConfig;
this.botUtil = botUtil;
this.triggerService = triggerService;
}

/**
Expand All @@ -51,7 +54,18 @@ public void onFriendMessageEvent(FriendMessageEvent event) {
ChatBO chatBO = new ChatBO();
chatBO.setSessionId(String.valueOf(event.getSubject().getId()));
String prompt = event.getMessage().contentToString().trim();
response(event, chatBO, prompt);
String triggerResponse = triggerService.getResponse(prompt);
// 检测用户发送的内容是否触发关键词
if (triggerResponse != null) {
event.getSubject().sendMessage(
new MessageChainBuilder()
.append(new QuoteReply(event.getMessage()))
.append(triggerResponse)
.build()
);
} else {
response(event, chatBO, prompt);
}
}

/**
Expand All @@ -63,11 +77,24 @@ public void onFriendMessageEvent(FriendMessageEvent event) {
public void onGroupMessageEvent(GroupMessageEvent event) {
ChatBO chatBO = new ChatBO();
chatBO.setSessionId(String.valueOf(event.getSubject().getId()));

// 去除@再提问
String prompt = event.getMessage().contentToString().replace("@" + event.getBot().getId(), "").trim();

// 若存在@机器人的消息,就向ChatGPT提问
if (event.getMessage().contains(new At(event.getBot().getId()))) {
//存在@机器人的消息就向ChatGPT提问
//去除@再提问
String prompt = event.getMessage().contentToString().replace("@" + event.getBot().getId(), "").trim();
response(event, chatBO, prompt);
} else {
// 检测用户发送的内容是否触发关键词
String triggerResponse = triggerService.getResponse(prompt);
if (triggerResponse != null) {
event.getSubject().sendMessage(
new MessageChainBuilder()
.append(new QuoteReply(event.getMessage()))
.append(triggerResponse)
.build()
);
}
}
}

Expand Down Expand Up @@ -171,4 +198,4 @@ public void onNewGroupRequestEvent(BotInvitedJoinGroupRequestEvent event) {
event.accept();
}
}
}
}
22 changes: 14 additions & 8 deletions src/main/java/com/ashin/handler/WechatMessageHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.ashin.constant.ChatType;
import com.ashin.entity.bo.ChatBO;
import com.ashin.service.InteractService;
import com.ashin.service.TriggerService;
import com.ashin.util.BotUtil;
import cn.zhouyafeng.itchat4j.beans.BaseMsg;
import cn.zhouyafeng.itchat4j.core.Core;
Expand All @@ -17,30 +18,35 @@
*/
public class WechatMessageHandler implements IMsgHandlerFace {
private final InteractService interactService;
private final TriggerService triggerService;
private final KeywordConfig keywordConfig;
private final BotUtil botUtil;

public WechatMessageHandler(InteractService interactService, KeywordConfig keywordConfig, BotUtil botUtil) {
public WechatMessageHandler(InteractService interactService, KeywordConfig keywordConfig, TriggerService triggerService, BotUtil botUtil) {
this.interactService = interactService;
this.keywordConfig = keywordConfig;
this.triggerService = triggerService;
this.botUtil = botUtil;
}

@Override
public String textMsgHandle(BaseMsg baseMsg) {
//如果是在群聊
if (baseMsg.isGroupMsg()){
//去除@再提问
String prompt = baseMsg.getText().replace("@"+ Core.getInstance().getNickName() + " ", "").trim();
//存在@机器人的消息就向ChatGPT提问
if (baseMsg.getText().contains("@"+ Core.getInstance().getNickName())){
//去除@再提问
String prompt = baseMsg.getText().replace("@"+ Core.getInstance().getNickName() + " ", "").trim();
return textResponse(baseMsg.getFromUserName(), prompt);
String triggerResponse = triggerService.getResponse(prompt);
return (triggerResponse == null) ? textResponse(baseMsg.getFromUserName(), prompt) : triggerResponse;
} else {
return triggerService.getResponse(baseMsg.getText());
}
}else {
//不是在群聊 则直接回复
return textResponse(baseMsg.getFromUserName(), baseMsg.getText());
} else {
// 不是在群聊 则直接回复
String triggerResponse = triggerService.getResponse(baseMsg.getText());
return (triggerResponse == null) ? textResponse(baseMsg.getFromUserName(), baseMsg.getText()) : triggerResponse;
}
return null;
}

private String textResponse(String userName, String content) {
Expand Down
43 changes: 43 additions & 0 deletions src/main/java/com/ashin/service/TriggerService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.ashin.service;

import com.ashin.config.TriggerConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
* 关键词回复服务
* @author InwardFlow
* @date 2023/12/13
*/

@Slf4j
@Service
public class TriggerService {
private final TriggerConfig triggerConfig;

@Autowired
public TriggerService(TriggerConfig triggerConfig) {
this.triggerConfig = triggerConfig;
log.debug("TriggerConfig: {}", triggerConfig); // 添加日志
}

/**
* 关键词回复
* @param input 输入
* @return 输出,如果不触发关键词返回null,触发了就直接返回输出内容
*/
public String getResponse(String input) {
Map<String, String> triggers = triggerConfig.getTriggers();

return triggers.entrySet()
.stream()
.filter(entry -> input.contains(entry.getKey()))
.findFirst()
.map(Map.Entry::getValue)
.orElse(null);
}

}
7 changes: 7 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,10 @@ keyword:
image: "ai画图"
# ai语音指令(TTS模型 https://platform.openai.com/docs/api-reference/audio)
audio: "ai语音"

trigger:
# TODO: 后续可能会添加一个 enable 配置项
triggers:
# 注意,在yaml中,请按这个格式 "[中文]"编辑中文关键词
"[你好]": "你好,我是智能聊天机器人,请问有什么可以帮助你的吗?"
"[hello]": "Hello, I'm YourChatRobot. Nice to meet you!"