Skip to content

Commit 8209e13

Browse files
Merge pull request #83 from ashinnotfound/feat/dall-3
Feat/dall-3 & TTS
2 parents 453fc68 + 6aa8874 commit 8209e13

File tree

17 files changed

+369
-285
lines changed

17 files changed

+369
-285
lines changed

README.md

Lines changed: 135 additions & 79 deletions
Large diffs are not rendered by default.

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</parent>
1111
<groupId>com.ashin</groupId>
1212
<artifactId>ChatGPT-YourChatRobot</artifactId>
13-
<version>3.8</version>
13+
<version>3.9</version>
1414
<name>myGPT</name>
1515
<description>快来把你的qq或微信变为chatgpt</description>
1616
<properties>
@@ -50,7 +50,7 @@
5050
<dependency>
5151
<groupId>com.theokanning.openai-gpt3-java</groupId>
5252
<artifactId>service</artifactId>
53-
<version>0.16.1</version>
53+
<version>0.18.2</version>
5454
</dependency>
5555
<dependency>
5656
<groupId>com.knuddels</groupId>

src/main/java/com/ashin/client/QqBotClient.java renamed to src/main/java/com/ashin/client/BotClient.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
package com.ashin.client;
22

3+
import cn.zhouyafeng.itchat4j.Wechat;
4+
import com.ashin.config.KeywordConfig;
35
import com.ashin.config.QqConfig;
6+
import com.ashin.config.WechatConfig;
47
import com.ashin.handler.QqMessageHandler;
8+
import com.ashin.handler.WechatMessageHandler;
9+
import com.ashin.service.InteractService;
10+
import com.ashin.util.BotUtil;
511
import lombok.Getter;
612
import lombok.extern.slf4j.Slf4j;
713
import net.mamoe.mirai.BotFactory;
@@ -14,19 +20,30 @@
1420

1521
@Component
1622
@Slf4j
17-
public class QqBotClient {
18-
19-
@Resource
20-
private QqMessageHandler qqMessageHandler;
23+
public class BotClient {
2124
@Resource
2225
private QqConfig qqConfig;
23-
24-
// qq机器人实例
2526
@Getter
2627
private net.mamoe.mirai.Bot qqBot;
28+
@Resource
29+
private WechatConfig wechatConfig;
30+
@Getter
31+
private Wechat wechatBot;
32+
@Resource
33+
private InteractService interactService;
34+
@Resource
35+
private KeywordConfig keywordConfig;
36+
@Resource
37+
private BotUtil botUtil;
2738

2839
@PostConstruct
2940
public void init() {
41+
//微信
42+
if (wechatConfig.getEnable()){
43+
log.info("正在登录微信,请按提示操作:");
44+
wechatBot = new Wechat(new WechatMessageHandler(interactService, keywordConfig, botUtil), wechatConfig.getQrPath());
45+
wechatBot.start();
46+
}
3047
if (qqConfig.getEnable()) {
3148
//登陆协议有ANDROID_PHONE, ANDROID_PAD, ANDROID_WATCH, IPAD, MACOS
3249
//若登陆失败可尝试更换协议
@@ -39,7 +56,7 @@ public void init() {
3956
qqBot.login();
4057
log.info("成功登录账号为 {} 的qq, 登陆协议为 {}", qqConfig.getAccount(), miraiProtocol);
4158
//订阅监听事件
42-
qqBot.getEventChannel().registerListenerHost(qqMessageHandler);
59+
qqBot.getEventChannel().registerListenerHost(new QqMessageHandler(interactService, qqConfig, keywordConfig, botUtil));
4360
} catch (Exception e) {
4461
log.error("登陆失败, qq账号为 {}, 登陆协议为 {}, 可尝试更换登陆协议, 具体原因: {}", qqConfig.getAccount(), miraiProtocol, e.getMessage());
4562
}

src/main/java/com/ashin/client/WechatBotClient.java

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/main/java/com/ashin/config/GptConfig.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,9 @@ public class GptConfig {
2222
private List<String> basicPrompt;
2323
private List<String> apiKey;
2424
private Long ofSeconds;
25+
private String imageQuality;
26+
private String imageStyle;
27+
private String audioModel;
28+
private String audioVoice;
29+
private Double audioSpeed;
2530
}

src/main/java/com/ashin/config/KeywordConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
@ConfigurationProperties("keyword")
1616
public class KeywordConfig {
1717
private String reset;
18-
private String draw;
18+
private String image;
19+
private String audio;
1920
}

src/main/java/com/ashin/config/QqConfig.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,4 @@ public class QqConfig {
1818
private Long account;
1919
private Boolean acceptNewFriend;
2020
private Boolean acceptNewGroup;
21-
private Boolean returnDrawByURL;
2221
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.ashin.constant;
2+
3+
public enum ChatType {
4+
TEXT,
5+
IMAGE,
6+
AUDIO,
7+
}

src/main/java/com/ashin/entity/bo/ChatBO.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.ashin.entity.bo;
22

3+
import com.ashin.constant.ChatType;
34
import lombok.Data;
45

56
/**
@@ -21,5 +22,5 @@ public class ChatBO {
2122
/**
2223
* 是否ai画图功能
2324
*/
24-
private boolean isAiDraw;
25+
private ChatType chatType;
2526
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.ashin.entity.dto;
2+
3+
import lombok.Data;
4+
5+
import java.io.InputStream;
6+
7+
@Data
8+
public class ChatResultDTO {
9+
String StringResult;
10+
InputStream inputStreamResult;
11+
byte[] bytesResult;
12+
}

src/main/java/com/ashin/exception/ChatException.java

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/main/java/com/ashin/handler/QqMessageHandler.java

Lines changed: 90 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,52 @@
22

33
import com.ashin.config.KeywordConfig;
44
import com.ashin.config.QqConfig;
5+
import com.ashin.constant.ChatType;
56
import com.ashin.entity.bo.ChatBO;
6-
import com.ashin.exception.ChatException;
7+
import com.ashin.entity.dto.ChatResultDTO;
78
import com.ashin.service.InteractService;
89
import com.ashin.util.BotUtil;
9-
import com.ashin.util.ImageUtil;
1010
import lombok.extern.slf4j.Slf4j;
1111
import net.mamoe.mirai.contact.Contact;
12-
import net.mamoe.mirai.contact.MessageTooLargeException;
12+
import net.mamoe.mirai.contact.Friend;
13+
import net.mamoe.mirai.contact.Group;
1314
import net.mamoe.mirai.event.EventHandler;
1415
import net.mamoe.mirai.event.ListenerHost;
1516
import net.mamoe.mirai.event.events.*;
1617
import net.mamoe.mirai.message.data.*;
18+
import net.mamoe.mirai.utils.ExternalResource;
1719
import org.jetbrains.annotations.NotNull;
18-
import org.springframework.stereotype.Component;
19-
import javax.annotation.Resource;
20-
import java.io.File;
20+
21+
import java.io.IOException;
22+
import java.io.InputStream;
2123

2224
/**
2325
* QQ消息处理程序
2426
*
2527
* @author ashinnotfound
2628
* @date 2023/2/1
2729
*/
28-
@Component
2930
@Slf4j
3031
public class QqMessageHandler implements ListenerHost {
31-
@Resource
32-
private InteractService interactService;
33-
@Resource
34-
private QqConfig qqConfig;
35-
@Resource
36-
private KeywordConfig keywordConfig;
37-
@Resource
38-
private BotUtil botUtil;
32+
private final InteractService interactService;
33+
private final QqConfig qqConfig;
34+
private final KeywordConfig keywordConfig;
35+
private final BotUtil botUtil;
36+
37+
public QqMessageHandler(InteractService interactService, QqConfig qqConfig, KeywordConfig keywordConfig, BotUtil botUtil) {
38+
this.interactService = interactService;
39+
this.qqConfig = qqConfig;
40+
this.keywordConfig = keywordConfig;
41+
this.botUtil = botUtil;
42+
}
3943

4044
/**
4145
* 好友消息事件
4246
*
4347
* @param event 事件
4448
*/
4549
@EventHandler
46-
public void onFriendMessageEvent(FriendMessageEvent event){
50+
public void onFriendMessageEvent(FriendMessageEvent event) {
4751
ChatBO chatBO = new ChatBO();
4852
chatBO.setSessionId(String.valueOf(event.getSubject().getId()));
4953
String prompt = event.getMessage().contentToString().trim();
@@ -56,7 +60,7 @@ public void onFriendMessageEvent(FriendMessageEvent event){
5660
* @param event 事件
5761
*/
5862
@EventHandler
59-
public void onGroupMessageEvent(GroupMessageEvent event){
63+
public void onGroupMessageEvent(GroupMessageEvent event) {
6064
ChatBO chatBO = new ChatBO();
6165
chatBO.setSessionId(String.valueOf(event.getSubject().getId()));
6266
if (event.getMessage().contains(new At(event.getBot().getId()))) {
@@ -66,37 +70,80 @@ public void onGroupMessageEvent(GroupMessageEvent event){
6670
response(event, chatBO, prompt);
6771
}
6872
}
73+
6974
private void response(@NotNull MessageEvent event, ChatBO chatBO, String prompt) {
7075
if (keywordConfig.getReset().equals(prompt)) {
7176
//检测到重置会话指令
7277
botUtil.resetPrompt(chatBO.getSessionId());
7378
event.getSubject().sendMessage("重置会话成功");
7479
} else {
75-
String response;
76-
try {
80+
if (prompt.startsWith(keywordConfig.getImage())) {
81+
chatBO.setPrompt(prompt.replaceFirst(keywordConfig.getImage() + " ", ""));
82+
chatBO.setChatType(ChatType.IMAGE);
83+
} else if (prompt.startsWith(keywordConfig.getAudio())) {
84+
chatBO.setPrompt(prompt.replaceFirst(keywordConfig.getAudio() + " ", ""));
85+
chatBO.setChatType(ChatType.AUDIO);
86+
} else {
7787
chatBO.setPrompt(prompt);
78-
chatBO.setAiDraw(prompt.startsWith(keywordConfig.getDraw()));
79-
response = interactService.chat(chatBO);
80-
}catch (ChatException e){
81-
response = e.getMessage();
88+
chatBO.setChatType(ChatType.TEXT);
8289
}
83-
try {
84-
if (chatBO.isAiDraw() && !qqConfig.getReturnDrawByURL()){
85-
File file = ImageUtil.download(response);
86-
Contact.sendImage(event.getSubject(), file);
87-
if (!file.delete()){
88-
log.warn("图片({})删除失败, 请注意存储空间", file.getAbsolutePath());
90+
ChatResultDTO response = interactService.chat(chatBO);
91+
switch (chatBO.getChatType()) {
92+
case TEXT:
93+
event.getSubject().sendMessage(
94+
new MessageChainBuilder()
95+
.append(new QuoteReply(event.getMessage()))
96+
.append(response.getStringResult())
97+
.build()
98+
);
99+
break;
100+
case IMAGE:
101+
if (response.getInputStreamResult() == null) {
102+
event.getSubject().sendMessage(
103+
new MessageChainBuilder()
104+
.append(new QuoteReply(event.getMessage()))
105+
.append("ai画图失败, 以下图片url: ").append(response.getStringResult())
106+
.build()
107+
);
108+
}
109+
try (InputStream inputStream = response.getInputStreamResult()) {
110+
event.getSubject().sendMessage(
111+
new MessageChainBuilder()
112+
.append(new QuoteReply(event.getMessage()))
113+
.append(Contact.uploadImage(event.getSubject(), inputStream))
114+
.build()
115+
);
116+
} catch (IOException e) {
117+
event.getSubject().sendMessage(
118+
new MessageChainBuilder()
119+
.append(new QuoteReply(event.getMessage()))
120+
.append("ai画图失败, 以下图片url: ").append(response.getStringResult())
121+
.build()
122+
);
123+
}
124+
break;
125+
case AUDIO:
126+
if (response.getBytesResult() == null) {
127+
event.getSubject().sendMessage("语音回复失败, 以下为文本回复: " + response.getStringResult());
128+
}
129+
OfflineAudio audio = null;
130+
byte[] audioBytes = response.getBytesResult();
131+
try (ExternalResource externalResource = ExternalResource.create(audioBytes)) {
132+
if (event.getSubject() instanceof Group) {
133+
Group group = (Group) event.getSubject();
134+
audio = group.uploadAudio(externalResource);
135+
} else if (event.getSubject() instanceof Friend) {
136+
Friend user = (Friend) event.getSubject();
137+
audio = user.uploadAudio(externalResource);
138+
}
139+
if (audio != null) {
140+
event.getSubject().sendMessage(audio);
141+
} else {
142+
event.getSubject().sendMessage("语音回复失败, 以下为文本回复: " + response.getStringResult());
143+
}
144+
} catch (IOException e) {
145+
event.getSubject().sendMessage("语音回复失败, 以下为文本回复: " + response.getStringResult());
89146
}
90-
}else {
91-
MessageChain messages = new MessageChainBuilder()
92-
.append(new QuoteReply(event.getMessage()))
93-
.append(response)
94-
.build();
95-
event.getSubject().sendMessage(messages);
96-
}
97-
}catch (MessageTooLargeException e){
98-
//信息太大,无法引用,采用直接回复
99-
event.getSubject().sendMessage(response);
100147
}
101148
}
102149
}
@@ -107,8 +154,8 @@ private void response(@NotNull MessageEvent event, ChatBO chatBO, String prompt)
107154
* @param event 事件
108155
*/
109156
@EventHandler
110-
public void onNewFriendRequestEvent(NewFriendRequestEvent event){
111-
if (qqConfig.getAcceptNewFriend()){
157+
public void onNewFriendRequestEvent(NewFriendRequestEvent event) {
158+
if (qqConfig.getAcceptNewFriend()) {
112159
event.accept();
113160
}
114161
}
@@ -119,8 +166,8 @@ public void onNewFriendRequestEvent(NewFriendRequestEvent event){
119166
* @param event 事件
120167
*/
121168
@EventHandler
122-
public void onNewGroupRequestEvent(BotInvitedJoinGroupRequestEvent event){
123-
if (qqConfig.getAcceptNewGroup()){
169+
public void onNewGroupRequestEvent(BotInvitedJoinGroupRequestEvent event) {
170+
if (qqConfig.getAcceptNewGroup()) {
124171
event.accept();
125172
}
126173
}

0 commit comments

Comments
 (0)