diff --git a/src/main/java/com/ashin/client/BotClient.java b/src/main/java/com/ashin/client/BotClient.java index 40acb95..c2a8fdb 100644 --- a/src/main/java/com/ashin/client/BotClient.java +++ b/src/main/java/com/ashin/client/BotClient.java @@ -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; @@ -32,6 +33,8 @@ public class BotClient { @Resource private InteractService interactService; @Resource + private TriggerService triggerService; + @Resource private KeywordConfig keywordConfig; @Resource private BotUtil botUtil; @@ -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()) { @@ -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()); } diff --git a/src/main/java/com/ashin/config/TriggerConfig.java b/src/main/java/com/ashin/config/TriggerConfig.java new file mode 100644 index 0000000..5bc08d4 --- /dev/null +++ b/src/main/java/com/ashin/config/TriggerConfig.java @@ -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 triggers; + @PostConstruct + public void init() { + System.out.println("TriggerConfig initialized. Triggers: " + triggers); + } +} diff --git a/src/main/java/com/ashin/handler/QqMessageHandler.java b/src/main/java/com/ashin/handler/QqMessageHandler.java index 60f3ce8..bc6bbdf 100644 --- a/src/main/java/com/ashin/handler/QqMessageHandler.java +++ b/src/main/java/com/ashin/handler/QqMessageHandler.java @@ -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; @@ -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; } /** @@ -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); + } } /** @@ -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() + ); + } } } @@ -171,4 +198,4 @@ public void onNewGroupRequestEvent(BotInvitedJoinGroupRequestEvent event) { event.accept(); } } -} \ No newline at end of file +} diff --git a/src/main/java/com/ashin/handler/WechatMessageHandler.java b/src/main/java/com/ashin/handler/WechatMessageHandler.java index 73c8674..1396e3d 100644 --- a/src/main/java/com/ashin/handler/WechatMessageHandler.java +++ b/src/main/java/com/ashin/handler/WechatMessageHandler.java @@ -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; @@ -17,12 +18,14 @@ */ 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; } @@ -30,17 +33,20 @@ public WechatMessageHandler(InteractService interactService, KeywordConfig keywo 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) { diff --git a/src/main/java/com/ashin/service/TriggerService.java b/src/main/java/com/ashin/service/TriggerService.java new file mode 100644 index 0000000..f4754ac --- /dev/null +++ b/src/main/java/com/ashin/service/TriggerService.java @@ -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 triggers = triggerConfig.getTriggers(); + + return triggers.entrySet() + .stream() + .filter(entry -> input.contains(entry.getKey())) + .findFirst() + .map(Map.Entry::getValue) + .orElse(null); + } + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 95347c9..716ad29 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -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!"