Skip to content

Commit

Permalink
Merge pull request #75 from ashinnotfound/feat/image
Browse files Browse the repository at this point in the history
Feat/image
  • Loading branch information
ashinnotfound authored Nov 10, 2023
2 parents 27cf436 + 306cf0b commit 63ee01a
Show file tree
Hide file tree
Showing 15 changed files with 183 additions and 59 deletions.
38 changes: 25 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# ChatGPT-YourChatRobot

> ### NEWS: 正在尝试接入OPENAI的ai画图功能([DALL·E模型](https://platform.openai.com/docs/models/dall-e))
> ### NEWS: 已接入OPENAI的ai画图功能([DALL·E模型](https://platform.openai.com/docs/models/dall-e))
> - 无需为此功能额外配置apikey,使用原先的即可
> - 可先在feat/image分支或release里的beta版试用
> - --- 2023.8.10
>
> <img src="https://cdn.jsdelivr.net/gh/ashinnotfound/ImageHosting/img/f5cb7fb04594b894edf8d614ca3fe5f.jpg" style="zoom:25%;" /><img src="https://cdn.jsdelivr.net/gh/ashinnotfound/ImageHosting/img/28894abd84617a4efca4ddf9c3abc99.jpg" style="zoom:25%;" />
> - 默认指令 “ai画图” 可在配置选项修改,亦可修改返回图片方式(限qq机器人)
> ![](https://cdn.jsdelivr.net/gh/ashinnotfound/ImageHosting/img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-11-10%20133117.png)![](https://cdn.jsdelivr.net/gh/ashinnotfound/ImageHosting/img/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202023-11-10%20132601.png)
> --- 2023.11.10
## 简介

Expand All @@ -29,6 +28,8 @@ qq机器人实现基于[TheoKanning/openai-java](https://github.com/TheoKanning/

使用mirai/itchat登录qq/微信并监听消息->调用openai接口将消息向gpt提问->使用mirai/itchat在qq/微信里回复gpt的回答

其中ai画图采用[DALL·E模型](https://platform.openai.com/docs/models/dall-e)[generation方法](https://platform.openai.com/docs/guides/images/generations)

## 使用

❤❤❤ 开箱即用!!! ❤❤❤
Expand All @@ -48,7 +49,6 @@ qq机器人实现基于[TheoKanning/openai-java](https://github.com/TheoKanning/
并把它们配置在application.yml里:

```
//这是application.yml文件
proxy:
# 代理配置
# 国内墙了gpt的api,所以得用代理,一般你使用的代理软件会有相关信息,例子:
Expand All @@ -65,6 +65,8 @@ gpt:
maxToken: 2048
# 信息熵 越高回答越随机(Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.---via OPENAI)
temperature: 0.5
# 最大请求时间 超时自动中断请求
ofSeconds: 10000
# 基础提问 支持多个提问 可用来设定人格(对应api中的system角色)
basicPrompt:
- "用中文回答我的问题"
Expand All @@ -75,25 +77,31 @@ gpt:
qq:
# 是否使用qq true/false
enable: true
# 登陆方法:1.密码登录 2.扫码登录(推荐)
method: 2
# qq账号密码(扫码登录则无需填写账号密码)
# 登陆方法:true扫码登录(推荐) false密码登录
loginByQRCode: true
# qq账号密码
account:
# (扫码登录则无需填写密码)
password:
# 是否自动同意好友申请
acceptNewFriend: false
# 是否自动同意被邀请入群
acceptNewGroup: false
# 重置会话指令
resetWord: "重置会话"
# ai画图时返回方法: true链接(更快) false图片
returnDrawByURL: true
wechat:
# 是否使用微信 true/false
enable: false
# 生成的登录二维码路径 默认与项目同级
qrPath: "./"
keyword:
# 重置会话指令
resetWord: "重置会话"
reset: "重置会话"
# ai画图指令(DALL·E模型 https://platform.openai.com/docs/models/dall-e)
# generation 根据关键词生成图片(https://platform.openai.com/docs/guides/images/generations)
draw: "ai画图"
```

3. 然后 run!!!😁😁😁
Expand Down Expand Up @@ -130,7 +138,11 @@ tips:机器人响应速度与你的网络环境挂钩。
<details>

<summary></summary>


### v3.8 (NOV 10, 2023)
- 把之前写的([DALL·E模型](https://platform.openai.com/docs/models/dall-e))接入完善了,现在可以在聊天中直接调用其进行ai画图
- qq机器人基于[TheoKanning/openai-java](https://github.com/TheoKanning/openai-java)[mamoe/mirai](https://github.com/mamoe/mirai.git)
- 微信机器人基于[TheoKanning/openai-java](https://github.com/TheoKanning/openai-java)[wxmbaci/itchat4j-uos](https://github.com/wxmbaci/itchat4j-uos)
### v3.7 (Aug 8, 2023)
- 最近有空能闲下来看看这个项目,主要更新了项目依赖、优化了下代码结构、增加了token消耗的计算、优化了bot交互返回信息
- qq机器人基于[TheoKanning/openai-java](https://github.com/TheoKanning/openai-java)[mamoe/mirai](https://github.com/mamoe/mirai.git)
Expand Down
12 changes: 6 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<groupId>com.ashin</groupId>
<artifactId>ChatGPT-YourChatRobot</artifactId>
<version>3.7</version>
<version>3.8</version>
<name>myGPT</name>
<description>快来把你的qq或微信变为chatgpt</description>
<properties>
Expand All @@ -36,15 +36,15 @@
<dependency>
<groupId>net.mamoe</groupId>
<artifactId>mirai-core-jvm</artifactId>
<version>2.15.0</version>
<version>2.16.0</version>
</dependency>
<!-- 临时修复qq登录组件 -->
<!-- 临时修复qq登录组件 https://github.com/cssxsh/fix-protocol-version.git -->
<dependency>
<groupId>mirai</groupId>
<artifactId>fix-protocol</artifactId>
<version>1.9.11</version>
<version>1.12.0</version>
<scope>system</scope>
<systemPath>${pom.basedir}/src/main/resources/fix-protocol-version-1.9.11.mirai2.jar</systemPath>
<systemPath>${pom.basedir}/src/main/resources/fix-protocol-version-1.12.0.mirai2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.asynchttpclient</groupId>
Expand All @@ -63,7 +63,7 @@
<dependency>
<groupId>com.theokanning.openai-gpt3-java</groupId>
<artifactId>service</artifactId>
<version>0.15.0</version>
<version>0.16.1</version>
</dependency>
<dependency>
<groupId>com.knuddels</groupId>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/ashin/client/GptClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void init() {
for (String apiKey : gptConfig.getApiKey()) {
apiKey = apiKey.trim();
if (!apiKey.isEmpty()) {
openAiServiceList.add(new OpenAiService(apiKey, Duration.ofSeconds(1000)));
openAiServiceList.add(new OpenAiService(apiKey, Duration.ofSeconds(gptConfig.getOfSeconds())));
log.info("apiKey为 {} 的账号初始化成功", apiKey);
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/com/ashin/client/QqBotClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,24 @@ public void init() {
//登录 登陆协议有ANDROID_PHONE, ANDROID_PAD, ANDROID_WATCH, IPAD, MACOS
try {
log.info("正在登录qq,请按提示操作:");
if (qqConfig.getMethod() == 1) {
if (qqConfig.getLoginByQRCode()) {
//扫码登陆
qqBot = BotFactory.INSTANCE.newBot(qqConfig.getAccount(), BotAuthorization.byQRCode(), configuration -> configuration.setProtocol(BotConfiguration.MiraiProtocol.ANDROID_WATCH));
} else {
//密码登录
qqBot = BotFactory.INSTANCE.newBot(qqConfig.getAccount(), qqConfig.getPassword().trim(), new BotConfiguration() {{
setProtocol(BotConfiguration.MiraiProtocol.ANDROID_PAD);
}});
//使用临时修复插件
FixProtocolVersion.update();
} else {
//扫码登陆
qqBot = BotFactory.INSTANCE.newBot(qqConfig.getAccount(), BotAuthorization.byQRCode(), configuration -> configuration.setProtocol(BotConfiguration.MiraiProtocol.ANDROID_WATCH));
}

qqBot.login();
log.info("成功登录账号为 {} 的qq, 登陆方式为 {}", qqConfig.getAccount(), qqConfig.getMethod() == 1 ? "密码登录" : "扫码登陆");
log.info("成功登录账号为 {} 的qq, 登陆方式为 {}", qqConfig.getAccount(), qqConfig.getLoginByQRCode() ? "扫码登陆" : "密码登录");
//订阅监听事件
qqBot.getEventChannel().registerListenerHost(qqMessageHandler);
} catch (Exception e) {
log.error("登陆失败,qq账号为 {}, 登陆方式为 {} ,原因:{}", qqConfig.getAccount(), qqConfig.getMethod() == 1 ? "密码登录" : "扫码登陆", e.getMessage());
log.error("登陆失败,qq账号为 {}, 登陆方式为 {} ,原因:{}", qqConfig.getAccount(), qqConfig.getLoginByQRCode() ? "扫码登陆" : "密码登录", e.getMessage());
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/ashin/config/GptConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ public class GptConfig {
private Double temperature;
private List<String> basicPrompt;
private List<String> apiKey;
private Long ofSeconds;
}
19 changes: 19 additions & 0 deletions src/main/java/com/ashin/config/KeywordConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.ashin.config;

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

/**
* 关键字配置
*
* @author ashinnotfound
* @date 2023/08/10
*/
@Data
@Component
@ConfigurationProperties("keyword")
public class KeywordConfig {
private String reset;
private String draw;
}
4 changes: 2 additions & 2 deletions src/main/java/com/ashin/config/QqConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
@ConfigurationProperties("qq")
public class QqConfig {
private Boolean enable;
private Integer method;
private Boolean loginByQRCode;
private Long account;
private String password;
private Boolean acceptNewFriend;
private Boolean acceptNewGroup;
private String resetWord;
private Boolean returnDrawByURL;
}
1 change: 0 additions & 1 deletion src/main/java/com/ashin/config/WechatConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@
public class WechatConfig {
private Boolean enable;
private String qrPath;
private String resetWord;
}
4 changes: 4 additions & 0 deletions src/main/java/com/ashin/entity/bo/ChatBO.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ public class ChatBO {
* 问题
*/
private String prompt;
/**
* 是否ai画图功能
*/
private boolean isAiDraw;
}
34 changes: 24 additions & 10 deletions src/main/java/com/ashin/handler/QqMessageHandler.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
package com.ashin.handler;

import com.ashin.config.KeywordConfig;
import com.ashin.config.QqConfig;
import com.ashin.entity.bo.ChatBO;
import com.ashin.exception.ChatException;
import com.ashin.service.InteractService;
import com.ashin.util.BotUtil;
import com.ashin.util.ImageUtil;
import lombok.extern.slf4j.Slf4j;
import net.mamoe.mirai.contact.Contact;
import net.mamoe.mirai.contact.MessageTooLargeException;
import net.mamoe.mirai.event.EventHandler;
import net.mamoe.mirai.event.ListenerHost;
import net.mamoe.mirai.event.events.*;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.message.data.MessageChain;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.QuoteReply;
import net.mamoe.mirai.message.data.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.File;

/**
* QQ消息处理程序
Expand All @@ -24,12 +26,15 @@
* @date 2023/2/1
*/
@Component
@Slf4j
public class QqMessageHandler implements ListenerHost {
@Resource
private InteractService interactService;
@Resource
private QqConfig qqConfig;
@Resource
private KeywordConfig keywordConfig;
@Resource
private BotUtil botUtil;

/**
Expand Down Expand Up @@ -62,24 +67,33 @@ public void onGroupMessageEvent(GroupMessageEvent event){
}
}
private void response(@NotNull MessageEvent event, ChatBO chatBO, String prompt) {
if (qqConfig.getResetWord().equals(prompt)) {
if (keywordConfig.getReset().equals(prompt)) {
//检测到重置会话指令
botUtil.resetPrompt(chatBO.getSessionId());
event.getSubject().sendMessage("重置会话成功");
} else {
String response;
try {
chatBO.setPrompt(prompt);
chatBO.setAiDraw(prompt.startsWith(keywordConfig.getDraw()));
response = interactService.chat(chatBO);
}catch (ChatException e){
response = e.getMessage();
}
try {
MessageChain messages = new MessageChainBuilder()
.append(new QuoteReply(event.getMessage()))
.append(response)
.build();
event.getSubject().sendMessage(messages);
if (chatBO.isAiDraw() && !qqConfig.getReturnDrawByURL()){
File file = ImageUtil.download(response);
Contact.sendImage(event.getSubject(), file);
if (!file.delete()){
log.warn("图片({})删除失败, 请注意存储空间", file.getAbsolutePath());
}
}else {
MessageChain messages = new MessageChainBuilder()
.append(new QuoteReply(event.getMessage()))
.append(response)
.build();
event.getSubject().sendMessage(messages);
}
}catch (MessageTooLargeException e){
//信息太大,无法引用,采用直接回复
event.getSubject().sendMessage(response);
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/com/ashin/handler/WechatMessageHandler.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.ashin.handler;

import com.ashin.config.WechatConfig;
import com.ashin.config.KeywordConfig;
import com.ashin.entity.bo.ChatBO;
import com.ashin.exception.ChatException;
import com.ashin.service.InteractService;
Expand All @@ -23,7 +23,7 @@ public class WechatMessageHandler implements IMsgHandlerFace {
@Resource
private InteractService interactService;
@Resource
private WechatConfig wechatConfig;
private KeywordConfig keywordConfig;
@Resource
private BotUtil botUtil;

Expand All @@ -45,13 +45,14 @@ public String textMsgHandle(BaseMsg baseMsg) {
}

private String textResponse(String userName, String content) {
if (wechatConfig.getResetWord().equals(content)){
if (keywordConfig.getReset().equals(content)){
botUtil.resetPrompt(userName);
return "重置会话成功";
}else {
ChatBO chatBO = new ChatBO();
chatBO.setPrompt(content);
chatBO.setSessionId(userName);
chatBO.setAiDraw(content.startsWith(keywordConfig.getDraw()));
String response;
try {
response = interactService.chat(chatBO);
Expand Down
Loading

0 comments on commit 63ee01a

Please sign in to comment.