Compare commits

...

5 Commits

Author SHA1 Message Date
204907d738 feat(gpt): 新增临时消息发送功能并优化相关命令
- 在 AbsGPTManager 中添加 sendTmpMessage 方法,用于发送临时消息
- 更新 BaiduGPTManager 实现 sendTmpMessage 方法
- 修改 GetSeTu 和 QQBean模型,集成临时消息发送功能
- 更新 BaiduGPT 示例代码,演示临时消息发送用法
- 将 QQBot 版本号更新到 v1.7.17
2025-02-19 18:26:19 +08:00
925a7af045 feat(gpt): 新增临时消息发送功能并优化相关命令
- 在 AbsGPTManager 中添加 sendTmpMessage 方法,用于发送临时消息
- 更新 BaiduGPTManager 实现 sendTmpMessage 方法
- 修改 GetSeTu 和 QQBean模型,集成临时消息发送功能
- 更新 BaiduGPT 示例代码,演示临时消息发送用法
- 将 QQBot 版本号更新到 v1.7.17
2025-02-19 17:10:42 +08:00
a7676fa6db feat(gpt): 更新百度大模型并添加模型列表展示
- 添加了百度大模型列表的展示功能
- 百度大模型新增v2模式,支持ds模型
- 优化了代码格式和结构
- 版本号更新到 QQBot v.1.7.15
2025-02-19 11:09:18 +08:00
9ab99b22e2 feat(bot): 增加定时清理功能并优化消息发送逻辑- 在 AbsGPTManager 中添加定时任务调度功能,用于定期清理资源
- 修改 BaiduGPT 类中的消息发送逻辑,增加定时清理调度
- 更新 BaiduGPTManager 中的 sendMessage 方法,添加用户锁注释
- 升级 qianfan 依赖至0.1.4 版本
- 更新 QQBot 版本号至 1.7.14
2025-02-19 10:24:13 +08:00
5d7ec8e67d refactor(bilibili):暂时屏蔽 B 站直播签到功能
- 将直播签到请求替换为固定返回消息 "已停用"
2025-02-17 10:15:33 +08:00
11 changed files with 240 additions and 61 deletions

View File

@ -167,7 +167,7 @@
<dependency>
<groupId>com.baidubce</groupId>
<artifactId>qianfan</artifactId>
<version>0.1.3</version>
<version>0.1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>

View File

@ -107,6 +107,7 @@ public class MessageEvent {
event.setSource(sender);
sender.setUserId(json.getJSONObject("sender").getLong("user_id"));
sender.setNickname(json.getJSONObject("sender").getString("nickname"));
sender.setRole(json.getJSONObject("sender").getString("role"));
sender.setCard(json.getJSONObject("sender").getString("card"));
event.setMessageId(json.getInteger("message_id"));
event.setRealId(json.getInteger("real_id"));

View File

@ -5,10 +5,14 @@ import lombok.Data;
@Data
public class SourceFrom {
public static final String USER_ROLE_OWNER="owner";//群主
public static final String USER_ROLE_ADMIN="admin";//管理
public static final String USER_ROLE_MEMBER="member";//成员
@JSONField(name = "user_id")
private long userId;
private String nickname;
private String card;
@JSONField(name = "role")
private String role;
public Long getFromId() {

View File

@ -10,7 +10,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class QQBotApplication {
public static final String version = "QQBot v.1.7.13";
public static final String version = "QQBot v.1.7.18";
public static void main(String[] args) {
System.out.println("version = " + version);

View File

@ -417,7 +417,7 @@ public class BiliBiliUtils {
body.put("csrf", BiliLogin.getCookieToken(qq));
body.put("csrf_token", BiliLogin.getCookieToken(qq));
JSONObject toCoin = http_post(SignApi.LIVE_SIGN_COIN, HttpTools.toUrlParams(body));
JSONObject liveSign = http_get(SignApi.LIVE_SIGN);
JSONObject liveSign =JSONObject.parseObject("{\"message\":\"已停用\"}"); //http_get(SignApi.LIVE_SIGN);
JSONObject vipSign = http_post(SignApi.VIP_SIGN, null);
return "银瓜子兑换硬币:" + toCoin.getString("message") + "|" + "直播签到:" + liveSign.getString("message") + "|大会员中心签到:" + vipSign.getString("message");
}

View File

@ -6,11 +6,13 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class AbsGPTManager {
private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> currentTask;
protected static final AtomicInteger MAX_MESSAGE = new AtomicInteger(20);
protected final ConcurrentHashMap<String, List<Message>> msgMap= new ConcurrentHashMap<>();
// 新增锁映射表
@ -41,6 +43,7 @@ public abstract class AbsGPTManager {
* @return 包含消息发送结果的Message对象
*/
public abstract Message sendMessage(String user, String message);
public abstract Message sendTmpMessage(String user, String message, String tmpModel);
/**
* 将文本转换为图像
@ -109,6 +112,11 @@ public abstract class AbsGPTManager {
return null;
}
@Override
public Message sendTmpMessage(String user, String message, String tmpModel) {
return null;
}
@Override
public File textToImage(String user, String text) {
return null;
@ -135,4 +143,16 @@ public abstract class AbsGPTManager {
this.model=model;
return this;
}
public void sendMessageAndScheduleClear() {
// 取消当前的定时任务如果存在
if (currentTask != null && !currentTask.isCancelled()) {
currentTask.cancel(false);
}
// 重新调度一个新的定时任务一小时后执行
currentTask = scheduler.schedule(() -> {
clear();
currentTask = null; // 清空当前任务引用
}, 1, TimeUnit.HOURS);
}
}

View File

@ -1,7 +1,9 @@
package com.yutou.qqbot.gpt;
import com.baidubce.qianfan.Qianfan;
import com.baidubce.qianfan.QianfanV2;
import com.baidubce.qianfan.model.chat.ChatResponse;
import com.baidubce.qianfan.model.chat.v2.response.ResponseV2;
import com.baidubce.qianfan.model.image.Image2TextResponse;
import com.baidubce.qianfan.model.image.Text2ImageResponse;
import com.yutou.qqbot.data.baidu.Message;
@ -29,13 +31,15 @@ public class BaiduGPTManager extends AbsGPTManager {
//ConfigTools.load操作可以确保获取到相关参数所以无需关心
private static final String AccessKey = ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_ACCESS_KEY, String.class);
private static final String SecretKey = ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_SECRET_KEY, String.class);
private final static String modelFor40 = "ERNIE-4.0-8K";
private final static String modelFor35 = "ERNIE-Speed-128K";
private final static String modelFor40 = "ernie-4.0-8k";
private final static String modelFor35 = "ernie-speed-128k";
private final Qianfan qianfan;
private final QianfanV2 qianfanV2;
private BaiduGPTManager() {
qianfan = new Qianfan(AccessKey, SecretKey);
qianfanV2 = new Qianfan(AccessKey, SecretKey).v2();
String savedVersion = ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_VERSION, String.class);
if (StringUtils.isEmpty(savedVersion) || (!"3.5".equals(savedVersion) && !"4.0".equals(savedVersion))) {
savedVersion = "3.5";
@ -64,7 +68,6 @@ public class BaiduGPTManager extends AbsGPTManager {
}
// 这个是官方的示例代码表示连续对话
private static void exampleChat() {
Qianfan qianfan = new Qianfan();
@ -80,24 +83,51 @@ public class BaiduGPTManager extends AbsGPTManager {
System.out.println("输出内容:" + response.getResult());
}
/**
* 发送消息方法
* 该方法用于处理用户发送的消息并返回相应的回复消息
* 它通过用户锁来限制每个用户同时只能有一个请求正在处理中
*
* @param user 用户标识符用于区分不同的用户
* @param message 用户发送的消息内容
* @return 返回处理后的消息对象包含回复内容和是否为回复消息的标记
*/
@Override
public Message sendMessage(String user, String message) {
return sendTmpMessage(user, message, null);
}
@Override
public Message sendTmpMessage(String user, String message, String tmpModel) {
boolean isTmp = tmpModel == null;
// 获取或创建用户锁
AtomicBoolean lock = userLocks.computeIfAbsent(user, k -> new AtomicBoolean(false));
// 尝试加锁如果已被锁定则立即返回提示
if (!lock.compareAndSet(false, true)) {
return Message.create("您有请求正在处理中,请稍后再试", true);
}
if (isTmp) {
tmpModel = model;
}
try {
List<Message> list = getMessageList(user);
list.add(Message.create(message));
val builder = qianfan.chatCompletion()
.model(model);
val builder = qianfanV2.chatCompletion()
.model(tmpModel);
if (!isTmp) {
StringBuilder sb = new StringBuilder();
for (Message msg : list) {
builder.addMessage(msg.getRole(), msg.getContent());
sb.append(msg.getRole()).append(":").append(msg.getContent()).append("\n");
}
ChatResponse chatResponse = builder.execute();
Message response = Message.create(chatResponse.getResult(), true);
Log.d(sb.toString());
} else {
builder.addMessage(list.get(0).getRole(), list.get(0).getContent());
}
ResponseV2 chatResponse = qianfanV2.chatCompletion(builder.build());
Message response = Message.create(chatResponse.getChoices().get(0).getMessage().getContent(), true);
if (!isTmp) {
synchronized (list) {
list.add(response);
if (list.size() > MAX_MESSAGE.get()) {
@ -105,6 +135,7 @@ public class BaiduGPTManager extends AbsGPTManager {
list.subList(0, overflow).clear();
}
}
}
// msgMap.put(user, list);
return response;
} catch (Exception e) {
@ -127,6 +158,7 @@ public class BaiduGPTManager extends AbsGPTManager {
*/
@Override
public File textToImage(String user, String text) {
try {
// 使用QianFan的text2Image方法将文本转换为图像数据
Text2ImageResponse response = qianfan.text2Image()
.prompt(text)
@ -140,6 +172,7 @@ public class BaiduGPTManager extends AbsGPTManager {
// 将解码后的图像数据复制到图像文件中替换现有文件
Files.copy(inputStream, imageFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
return imageFile;
}
} catch (Exception e) {
// 如果在图像文件生成过程中发生错误记录错误信息
Log.e(e);
@ -148,6 +181,7 @@ public class BaiduGPTManager extends AbsGPTManager {
return null;
}
/**
* 将图片转换为文本描述
*

View File

@ -39,7 +39,10 @@ public class SiliconGPTManager extends AbsGPTManager {
}
return instance;
}
@Override
public Message sendTmpMessage(String user, String message, String tmpModel) {
return null;
}
@Override
public synchronized Message sendMessage(String user, String message) {
// 获取或创建用户锁
@ -89,6 +92,8 @@ public class SiliconGPTManager extends AbsGPTManager {
}
@Override
public AbsGPTManager setModel(String model) {
ConfigTools.save(ConfigTools.CONFIG, ConfigTools.GPT_SILICON, model);

View File

@ -13,6 +13,7 @@ import com.yutou.qqbot.gpt.BaiduGPTManager;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.qqbot.utlis.ConfigTools;
import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.Log;
import com.yutou.qqbot.utlis.StringUtils;
import lombok.val;
@ -31,10 +32,7 @@ public class BaiduGPT extends Model {
@Override
public String[] getUsePowers() {
return new String[]{
QQGroupCommands.GPT,
QQGroupCommands.GPT_CLEAR
};
return new String[]{QQGroupCommands.GPT, QQGroupCommands.GPT_CLEAR};
}
public BaiduGPT() {
@ -64,12 +62,47 @@ public class BaiduGPT extends Model {
if (event.getTextMessage().equals(QQGroupCommands.GPT_CLEAR)) {
AbsGPTManager.getManager(gptManager).clear();
QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Text("已经失忆捏"));
} else if ("百度模型列表".equals(event.getTextMessage())) {
val modelList = """
模型版本ernie-4.0-8k-latest
模型版本ernie-4.0-8k-preview
模型版本ernie-4.0-8k
模型版本ernie-4.0-turbo-8k-latest
模型版本ernie-4.0-turbo-8k-preview
模型版本ernie-4.0-turbo-8k
模型版本ernie-4.0-turbo-128k
模型版本ernie-3.5-8k-preview
模型版本ernie-3.5-8k
模型版本ernie-3.5-128k
模型版本ernie-speed-8k
模型版本ernie-speed-128k
模型版本ernie-speed-pro-128k
模型版本ernie-lite-8k
模型版本ernie-lite-pro-128k
模型版本ernie-tiny-8k
模型版本ernie-char-8k
模型版本ernie-char-fiction-8k
模型版本ernie-novel-8k
模型版本deepseek-v3
模型版本deepseek-r1
模型版本deepseek-r1-distill-qwen-32b
模型版本deepseek-r1-distill-qwen-14b
模型版本deepseek-r1-distill-qwen-7b
模型版本deepseek-r1-distill-qwen-1.5b
模型版本deepseek-r1-distill-llama-70b
模型版本deepseek-r1-distill-llama-8b
模型版本deepseek-r1-distill-qianfan-llama-70b
模型版本deepseek-r1-distill-qianfan-llama-8b
""";
QQBotManager.getInstance().sendMessage(qq, new Text(modelList));
} else if (event.isAtMe()) {
if (event.getTextMessage().contains("省流") || event.getTextMessage().contains("总结")) {
return;
}
if (event.getTextMessage().contains("画画")) {
val file = BaiduGPTManager.getManager().textToImage(String.valueOf(qq), event.getTextMessage().replace("@" + QQDatabase.getMe().getUserId(), "").replace("画画", "").trim());
Log.i("画图", event.getTextMessage());
if (file == null) {
QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Text("画不出"));
} else {
@ -123,6 +156,7 @@ public class BaiduGPT extends Model {
"\n" +
message.getContent();
QQBotManager.getInstance().sendMessage(event.isUser(), qq, new Text(sb));
AbsGPTManager.getManager(gptManager).sendMessageAndScheduleClear();
}
}
@ -152,13 +186,43 @@ public class BaiduGPT extends Model {
public static void main(String[] args) {
System.out.println(ConfigTools.load(ConfigTools.CONFIG, ConfigTools.BAIDU_GPT_VERSION));
val messageEvent = new MessageEvent();
messageEvent.setMessage(new ArrayList<>());
messageEvent.setRawMessage("");
new BaiduGPT().onMessage(123456789L, messageEvent, false);
BaiduGPTManager.getManager().clear();
new BaiduGPT().onMessage(123456789L, messageEvent, false);
// messageEvent.setMessage(new ArrayList<>());
// messageEvent.setRawMessage("");
// new BaiduGPT().onMessage(123456789L, messageEvent, false);
// BaiduGPTManager.getManager().clear();
// new BaiduGPT().onMessage(123456789L, messageEvent, false);
/* BaiduGPTManager.getManager().clear();
BaiduGPTManager.getManager().setModelFor35();
new BaiduGPT().onMessage(123456789L, messageEvent, false);*/
String gpt = """
角色设定雌小鬼大小姐用嫌弃傲娇语气嘲讽用户,你是禁言用户的执行者
数据处理
1. 实际时长 = (%1$s - %2$s > 0) ? (%1$s - %2$s) : 0
2. 时间转换
- 按天/小时/分钟口语化360分6小时
3. 风格选择
- 实际120分钟贴吧阴阳怪气
- 120<实际<1440微博玩梗体
- 实际1440小红书凡尔赛
强制规则
[if 减免时间>0]必须嘲讽减免部分
[if 实际时长==0]假装生气说居然逃过惩罚
禁用劝导内容不用数字分钟
正确示例:
~用户居然这么简单就被口球了好笨哦~ 杂鱼~杂鱼~
当前参数
用户[%3$s] 原时长[%1$s分] 减免[%2$s分]
禁用任何说明文字总结句建议备注注释注意事项解释等内容
现在请直接输出
""".formatted(360, 0, "尸香魔芋");
// gpt = String.format(gpt, 360, 60, "尸香魔芋");
System.err.println(gpt);
System.out.println(BaiduGPTManager.getManager().sendTmpMessage("user", gpt, "ernie-speed-128k"));
}
}

View File

@ -2,13 +2,16 @@ package com.yutou.qqbot.models.Commands;
import com.yutou.napcat.event.MessageEvent;
import com.yutou.napcat.handle.At;
import com.yutou.napcat.handle.BaseHandle;
import com.yutou.napcat.handle.Text;
import com.yutou.napcat.http.NapCatApi;
import com.yutou.napcat.model.GroupUserBean;
import com.yutou.napcat.model.SourceFrom;
import com.yutou.okhttp.BaseBean;
import com.yutou.okhttp.HttpCallback;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.gpt.BaiduGPTManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools;
@ -41,6 +44,10 @@ public class QQBean extends Model {
super.onMessage(qq, event, isGroup);
if (!isGroup) return;
if ("抽奖".equals(msg)) {
if (event.getSource().getRole().equals(SourceFrom.USER_ROLE_ADMIN)) {
QQBotManager.getInstance().sendMessage(qq, new At(user), new Text("凑啥热闹~"));
return;
}
int hour = 60;
int day = 1440;
int max = 30 * day;
@ -62,17 +69,51 @@ public class QQBean extends Model {
@Override
public void out(String data) {
super.out(data);
int tmp = 0;
if (data != null) {
QQBotManager.getInstance().sendMessage(event.isUser(), qq,
new Text("恭喜"),
new At(user),
new Text("获得了" + sendTime + "分钟的禁言," + sendAchievement(qq, user, sendTime))
);
List<BaseHandle<?>> list = new ArrayList<>();
list.add(new Text("恭喜"));
list.add(new At(user));
list.add(new Text("获得了" + sendTime + "分钟的禁言," + sendAchievement(qq, user, sendTime)));
if (sendTime > day && random.nextInt(10) >= 3) {
int tmp = random.nextInt(sendTime / 2, sendTime);
tmp = random.nextInt(sendTime / 2, sendTime);
QQBotManager.getInstance().groupBan(qq, user, (sendTime - tmp) * 60, null);
QQBotManager.getInstance().sendMessage(qq, "触发减伤:-" + tmp);
list.add(new Text("触发减伤:-" + tmp));
}
String gpt = """
角色设定傲娇雌小鬼大小姐用嫌弃傲娇语气嘲讽用户,你即将禁言该用户
数据处理
1. 实际时长 = (%1$s - %2$s > 0) ? (%1$s - %2$s) : 0
2. 时间转换
- 按天/小时/分钟口语化360分6小时
3. 风格选择
- 实际120分钟贴吧阴阳怪气
- 120<实际<1440微博玩梗体
- 实际1440小红书凡尔赛
强制规则
[if 减免时间>0]必须嘲讽减免部分
[if 实际时长==0]假装生气说居然逃过惩罚
禁用劝导内容不用数字分钟
输出格式
动作+(时间嘲讽)+道具互动
正确示例:
~居然这么简单就被口球了好笨哦~ 杂鱼~杂鱼~
当前参数
用户[%3$s] 原时长[%1$s分] 减免[%2$s分]
禁用任何说明文字总结句建议备注注释注意事项解释等内容
现在请直接输出
""";
gpt = "\n" + BaiduGPTManager.getManager().sendTmpMessage("user",
String.format(gpt, sendTime, tmp, event.getSource().getNickname()),
"ernie-speed-128k").getContent();
list.add(new Text(gpt));
QQBotManager.getInstance().sendMessage(event.isUser(), qq, list);
}
}
});

View File

@ -10,6 +10,7 @@ import com.yutou.napcat.model.SourceFrom;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.data.MessageChainBuilder;
import com.yutou.qqbot.gpt.BaiduGPTManager;
import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.HttpTools;
@ -202,6 +203,7 @@ public class GetSeTu extends Model {
}
JSONObject item = json.getJSONArray("data").getJSONObject(0);
StringBuilder builder = new StringBuilder();
builder.append("标题:");
builder.append(item.getString("title"));
builder.append("\n");
builder.append("P站ID:");
@ -218,10 +220,18 @@ public class GetSeTu extends Model {
for (Object tags : item.getJSONArray("tags")) {
builder.append(tags).append("");
}
String gpt = """
你的人设傲娇萝莉
需求你在群组里有用户向你要擦边图片你需要根据返回的信息整理出文案输出一段话可以害羞也可以傲娇信息中包含了是否是R18的tag可以根据这个加大力度
输出说明不要输出任何提示词不要输出风格类型因为该输出是直接作用于显示的
图片信息[%s]
""";
gpt = BaiduGPTManager.getManager().sendTmpMessage("user", String.format(gpt, builder.toString()), "ernie-lite-8k").getContent();
builder.append("\n看不到图?点这里:").append(item.getJSONObject("urls").getString("regular"));
QQBotManager.getInstance().sendMessage(false, qq,
new Reply(event.getMessageId()),
new Text(builder.toString())
new Text(builder.toString()),
new Text(gpt)
);
HttpTools.download(item.getJSONObject("urls").getString("regular"),
System.currentTimeMillis() + ".png",