Skip to content

Commit 70c0c1c

Browse files
committed
feat(file): 新增文件消息功能
- 添加 FileMsg 类作为文件消息的父类 - 实现 Image、Audio 和 Video 类继承 FileMsg - 修改版本号为 1.5.2 - 更新相关接口和实现类以支持文件消息
1 parent 023654e commit 70c0c1c

17 files changed

Lines changed: 262 additions & 138 deletions

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>io.github.kloping</groupId>
88
<artifactId>bot-qqpd-java</artifactId>
9-
<version>1.5.2-L3</version>
9+
<version>1.5.2</version>
1010

1111
<packaging>jar</packaging>
1212
<name>bot-qqpd-java</name>

src/main/java/io/github/kloping/qqbot/Starter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import io.github.kloping.judge.Judge;
55
import io.github.kloping.qqbot.entities.Bot;
66
import io.github.kloping.qqbot.impl.ListenerHost;
7-
import io.github.kloping.qqbot.interfaces.ImageUploadInterceptor;
7+
import io.github.kloping.qqbot.interfaces.FileUploadInterceptor;
88
import io.github.kloping.qqbot.network.Events;
99
import io.github.kloping.qqbot.network.WebSocketListener;
1010
import io.github.kloping.qqbot.network.WssWorker;
@@ -204,7 +204,7 @@ public static class Config {
204204
*/
205205
private String webhookpath = "/webhook0";
206206
private Set<ListenerHost> listenerHosts = new HashSet<>();
207-
private ImageUploadInterceptor interceptor0;
207+
private FileUploadInterceptor interceptor0;
208208
private WebSocketListener webSocketListener;
209209

210210
/**
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.github.kloping.qqbot.entities.ex;
2+
3+
import lombok.experimental.Accessors;
4+
5+
/**
6+
* 语音消息 仅支持silk格式
7+
* <br>发送到频道时url必须备案(少数情况不需要
8+
* <br>可使用 bytes发送
9+
*
10+
* @author github.kloping
11+
*/
12+
@Accessors(chain = true)
13+
public class Audio extends FileMsg {
14+
15+
public Audio(byte[] bytes) {
16+
super(bytes, FileType.AUDIO);
17+
}
18+
19+
public Audio(String url) {
20+
super(url, FileType.AUDIO);
21+
}
22+
23+
public Audio(byte[] bytes, String name) {
24+
super(bytes, FileType.AUDIO);
25+
this.name = name;
26+
}
27+
28+
public Audio(String url, String name) {
29+
super(url, FileType.AUDIO);
30+
this.name = name;
31+
}
32+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package io.github.kloping.qqbot.entities.ex;
2+
3+
import io.github.kloping.judge.Judge;
4+
import io.github.kloping.qqbot.api.SendAble;
5+
import io.github.kloping.qqbot.api.SenderAndCidMidGetter;
6+
import io.github.kloping.qqbot.api.SenderV2;
7+
import io.github.kloping.qqbot.entities.ex.enums.EnvType;
8+
import io.github.kloping.qqbot.entities.qqpd.Channel;
9+
import io.github.kloping.qqbot.entities.qqpd.message.RawMessage;
10+
import io.github.kloping.qqbot.http.data.Result;
11+
import io.github.kloping.qqbot.http.data.V2MsgData;
12+
import io.github.kloping.qqbot.http.data.V2Result;
13+
import io.github.kloping.qqbot.impl.MessagePacket;
14+
import lombok.Getter;
15+
import lombok.Setter;
16+
import lombok.experimental.Accessors;
17+
import org.jsoup.helper.HttpConnection;
18+
19+
import java.io.ByteArrayInputStream;
20+
import java.util.Base64;
21+
22+
import static io.github.kloping.qqbot.entities.qqpd.Channel.SEND_FORM_DATA_HEADERS;
23+
import static io.github.kloping.qqbot.entities.qqpd.Channel.SEND_MESSAGE_HEADERS;
24+
25+
26+
/**
27+
* 文件消息 父类
28+
* <br>发送到频道时url必须备案(少数情况不需要
29+
* <br>可使用 bytes发送
30+
*
31+
* @author github kloping
32+
* @date 2025/9/1-21:55
33+
*/
34+
@Getter
35+
@Accessors(chain = true)
36+
public abstract class FileMsg implements SendAble {
37+
/**
38+
* <td> 媒体类型:1 图片,2 视频,3 语音,4 文件(暂不开放)<br>资源格式要求<br>图片:png/jpg,视频:mp4,语音:silk</td>
39+
*/
40+
public enum FileType {
41+
IMAGE(1), VIDEO(2), AUDIO(3), FILE(4);
42+
final int value;
43+
44+
FileType(int value) {
45+
this.value = value;
46+
}
47+
48+
}
49+
50+
private Integer file_type = 1;
51+
@Setter
52+
private String type;
53+
@Setter
54+
protected String url;
55+
@Setter
56+
protected byte[] bytes;
57+
@Setter
58+
protected String name;
59+
60+
private FileMsg(FileType fileType) {
61+
this.file_type = fileType.value;
62+
switch (fileType) {
63+
case IMAGE:
64+
type = "png";
65+
break;
66+
case VIDEO:
67+
type = "mp4";
68+
break;
69+
case AUDIO:
70+
type = "silk";
71+
break;
72+
}
73+
}
74+
75+
protected FileMsg(byte[] bytes, FileType fileType) {
76+
this(fileType);
77+
this.bytes = bytes;
78+
}
79+
80+
protected FileMsg(String url, FileType fileType) {
81+
this(fileType);
82+
this.url = url;
83+
}
84+
85+
public FileMsg(Integer file_type, String type, String url, byte[] bytes, String name) {
86+
this.file_type = file_type;
87+
this.type = type;
88+
this.url = url;
89+
this.bytes = bytes;
90+
this.name = name;
91+
}
92+
93+
@Override
94+
public Result send(SenderAndCidMidGetter er) {
95+
if (er.getEnvType() == EnvType.GUILD) {
96+
if (getBytes() != null) {
97+
BaseKeyVals keyVals = new BaseKeyVals();
98+
if (er.getMid() != null) {
99+
HttpConnection.KeyVal v0 = HttpConnection.KeyVal.create("msg_id", er.getMid());
100+
v0.contentType("text/plain");
101+
keyVals.add(v0);
102+
}
103+
HttpConnection.KeyVal v1 = HttpConnection.KeyVal.create("file_image", name);
104+
v1.inputStream(new ByteArrayInputStream(bytes));
105+
v1.contentType(type);
106+
keyVals.add(v1);
107+
return new Result<>(er.getBot().messageBase.send(er.getCid(), SEND_FORM_DATA_HEADERS, keyVals));
108+
}
109+
MessagePacket packet = new MessagePacket();
110+
if (Judge.isNotEmpty(getUrl())) packet.setImage(getUrl());
111+
return er.send(packet);
112+
} else {
113+
SenderV2 v2 = (SenderV2) er;
114+
RawMessage.filePrepare(this, er.getBot());
115+
V2Result result = null;
116+
if (Judge.isNotEmpty(getUrl())) {
117+
result = v2.getV2().sendFile(er.getCid(), String.format("{\"file_type\": %s,\"url\": \"%s\",\"srv_send_msg\": false}", getFile_type(), getUrl()), Channel.SEND_MESSAGE_HEADERS);
118+
} else {
119+
result = v2.getV2().sendFile(er.getCid(), String.format("{\"file_type\": %s,\"file_data\": \"%s\",\"srv_send_msg\": false}", getFile_type(), Base64.getEncoder().encodeToString(bytes)), Channel.SEND_MESSAGE_HEADERS);
120+
}
121+
result.logFileInfo(er.getBot().logger, this);
122+
V2MsgData data = new V2MsgData();
123+
data.setMsg_type(7);
124+
if (Judge.isNotEmpty(er.getMid())) data.setMsg_id(er.getMid());
125+
data.setMedia(new V2MsgData.Media(result.getFile_info()));
126+
data.setMsg_seq(v2.getMsgSeq());
127+
return new Result<V2Result>(v2.getV2().send(er.getCid(), data.toString(), SEND_MESSAGE_HEADERS));
128+
}
129+
}
130+
}
Lines changed: 11 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,32 @@
11
package io.github.kloping.qqbot.entities.ex;
22

3-
import io.github.kloping.judge.Judge;
4-
import io.github.kloping.qqbot.api.SendAble;
5-
import io.github.kloping.qqbot.api.SenderAndCidMidGetter;
6-
import io.github.kloping.qqbot.api.SenderV2;
7-
import io.github.kloping.qqbot.entities.ex.enums.EnvType;
8-
import io.github.kloping.qqbot.entities.qqpd.Channel;
9-
import io.github.kloping.qqbot.entities.qqpd.message.RawMessage;
10-
import io.github.kloping.qqbot.http.data.Result;
11-
import io.github.kloping.qqbot.http.data.V2MsgData;
12-
import io.github.kloping.qqbot.http.data.V2Result;
13-
import io.github.kloping.qqbot.impl.MessagePacket;
14-
import lombok.Data;
153
import lombok.experimental.Accessors;
16-
import org.jsoup.helper.HttpConnection;
17-
18-
import java.io.ByteArrayInputStream;
19-
import java.util.Base64;
20-
import java.util.UUID;
21-
22-
import static io.github.kloping.qqbot.entities.qqpd.Channel.SEND_FORM_DATA_HEADERS;
23-
import static io.github.kloping.qqbot.entities.qqpd.Channel.SEND_MESSAGE_HEADERS;
244

255
/**
6+
* 图片消息 支持jpg/png
7+
* <br>发送到频道时url必须备案(少数情况不需要
8+
* <br>可使用 bytes发送
269
*
27-
* 发送到频道时url必须备案(少数情况不需要
2810
* @author github.kloping
2911
*/
30-
@Data
3112
@Accessors(chain = true)
32-
public class Image implements SendAble {
33-
private String url;
34-
private byte[] bytes;
35-
private String type = "image/jpeg";
36-
private String name = UUID.randomUUID() + ".jpg";
37-
38-
/**
39-
* 仅用于qq群发送
40-
* <td> 媒体类型:1 图片,2 视频,3 语音,4 文件(暂不开放)<br>资源格式要求<br>图片:png/jpg,视频:mp4,语音:silk</td>
41-
*/
42-
private Integer file_type = 1;
13+
public class Image extends FileMsg {
4314

4415
public Image(byte[] bytes) {
45-
this.bytes = bytes;
16+
super(bytes, FileType.IMAGE);
4617
}
4718

4819
public Image(String url) {
49-
this.url = url;
50-
}
51-
52-
public Image(String url, Integer file_type) {
53-
this.url = url;
54-
this.file_type = file_type;
55-
}
56-
57-
public Image(byte[] bytes, String type) {
58-
this.bytes = bytes;
59-
this.type = type;
20+
super(url, FileType.IMAGE);
6021
}
6122

62-
public Image(byte[] bytes, String type, String name) {
63-
this.bytes = bytes;
64-
this.type = type;
23+
public Image(byte[] bytes, String name) {
24+
super(bytes, FileType.IMAGE);
6525
this.name = name;
6626
}
6727

68-
@Override
69-
public Result send(SenderAndCidMidGetter er) {
70-
if (er.getEnvType() == EnvType.GUILD) {
71-
if (getBytes() != null) {
72-
BaseKeyVals keyVals = new BaseKeyVals();
73-
if (er.getMid() != null) {
74-
HttpConnection.KeyVal v0 = HttpConnection.KeyVal.create("msg_id", er.getMid());
75-
v0.contentType("text/plain");
76-
keyVals.add(v0);
77-
}
78-
HttpConnection.KeyVal v1 = HttpConnection.KeyVal.create("file_image", name);
79-
v1.inputStream(new ByteArrayInputStream(bytes));
80-
v1.contentType(type);
81-
keyVals.add(v1);
82-
return new Result<>(er.getBot().messageBase.send(er.getCid(), SEND_FORM_DATA_HEADERS, keyVals));
83-
}
84-
MessagePacket packet = new MessagePacket();
85-
if (Judge.isNotEmpty(getUrl())) packet.setImage(getUrl());
86-
return er.send(packet);
87-
} else {
88-
SenderV2 v2 = (SenderV2) er;
89-
RawMessage.imagePrepare(this, er.getBot());
90-
V2Result result = null;
91-
if (Judge.isNotEmpty(getUrl())) {
92-
result = v2.getV2().sendFile(er.getCid(), String.format("{\"file_type\": %s,\"url\": \"%s\",\"srv_send_msg\": false}", getFile_type(), getUrl()), Channel.SEND_MESSAGE_HEADERS);
93-
} else {
94-
result = v2.getV2().sendFile(er.getCid(), String.format("{\"file_type\": %s,\"file_data\": \"%s\",\"srv_send_msg\": false}", getFile_type(), Base64.getEncoder().encodeToString(bytes)), Channel.SEND_MESSAGE_HEADERS);
95-
}
96-
result.logFileInfo(er.getBot().logger, this);
97-
V2MsgData data = new V2MsgData();
98-
data.setMsg_type(7);
99-
if (Judge.isNotEmpty(er.getMid())) data.setMsg_id(er.getMid());
100-
data.setMedia(new V2MsgData.Media(result.getFile_info()));
101-
data.setMsg_seq(v2.getMsgSeq());
102-
return new Result<V2Result>(v2.getV2().send(er.getCid(), data.toString(), SEND_MESSAGE_HEADERS));
103-
}
28+
public Image(String url, String name) {
29+
super(url, FileType.IMAGE);
30+
this.name = name;
10431
}
10532
}

src/main/java/io/github/kloping/qqbot/entities/ex/MessagePre.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222
@Data
2323
public class MessagePre implements SendAble {
2424
private String content = "";
25-
private Image image;
25+
private FileMsg fileMsg;
2626
private String replyId;
2727

2828
@Override
2929
public Result<ActionResult> send(SenderAndCidMidGetter er) {
30-
if (image != null) {
31-
if (image.getBytes() != null) {
30+
if (fileMsg != null) {
31+
if (fileMsg.getBytes() != null) {
3232
BaseKeyVals keyVals = new BaseKeyVals();
3333
if (er.getMid() != null) {
3434
HttpConnection.KeyVal v0 = HttpConnection.KeyVal.create("msg_id", er.getMid());
@@ -40,8 +40,8 @@ public Result<ActionResult> send(SenderAndCidMidGetter er) {
4040
v1.contentType("text/plain");
4141
keyVals.add(v1);
4242
}
43-
HttpConnection.KeyVal v1 = HttpConnection.KeyVal.create("file_image", image.getName(), new ByteArrayInputStream(image.getBytes()));
44-
v1.contentType(image.getType());
43+
HttpConnection.KeyVal v1 = HttpConnection.KeyVal.create("file_image", fileMsg.getName(), new ByteArrayInputStream(fileMsg.getBytes()));
44+
v1.contentType(fileMsg.getType());
4545
keyVals.add(v1);
4646
if (er instanceof Dms) {
4747
Dms dms = (Dms) er;
@@ -52,14 +52,14 @@ public Result<ActionResult> send(SenderAndCidMidGetter er) {
5252
} else return new Result<>(er.getBot().messageBase.send(er.getCid(), SEND_FORM_DATA_HEADERS, keyVals));
5353
}
5454
}
55-
return getActionResult(er, image, content, replyId);
55+
return getActionResult(er, fileMsg, content, replyId);
5656
}
5757

58-
public static Result<ActionResult> getActionResult(SenderAndCidMidGetter er, Image image, String content, String replyId) {
58+
public static Result<ActionResult> getActionResult(SenderAndCidMidGetter er, FileMsg fileMsg, String content, String replyId) {
5959
MessagePacket packet = new MessagePacket();
6060
if (Judge.isNotEmpty(replyId)) packet.setReplyId(replyId);
6161
if (Judge.isNotEmpty(content)) packet.setContent(content);
62-
if (image != null && Judge.isNotEmpty(image.getUrl())) packet.setImage(image.getUrl());
62+
if (fileMsg != null && Judge.isNotEmpty(fileMsg.getUrl())) packet.setImage(fileMsg.getUrl());
6363
return er.send(packet);
6464
}
6565
}

src/main/java/io/github/kloping/qqbot/entities/ex/MessagePreBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ public MessagePreBuilder append(String text) {
1717
return this;
1818
}
1919

20-
public MessagePreBuilder append(Image image) {
21-
pre.setImage(image);
20+
public MessagePreBuilder append(FileMsg fileMsg) {
21+
pre.setFileMsg(fileMsg);
2222
empty = false;
2323
return this;
2424
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.github.kloping.qqbot.entities.ex;
2+
3+
import lombok.experimental.Accessors;
4+
5+
/**
6+
* 视频消息 仅支持mp4格式
7+
* <br>发送到频道时url必须备案(少数情况不需要
8+
* <br>可使用 bytes发送
9+
*
10+
* @author github.kloping
11+
*/
12+
@Accessors(chain = true)
13+
public class Video extends FileMsg {
14+
15+
public Video(byte[] bytes) {
16+
super(bytes, FileType.VIDEO);
17+
}
18+
19+
public Video(String url) {
20+
super(url, FileType.VIDEO);
21+
}
22+
23+
public Video(byte[] bytes, String name) {
24+
super(bytes, FileType.VIDEO);
25+
this.name = name;
26+
}
27+
28+
public Video(String url, String name) {
29+
super(url, FileType.VIDEO);
30+
this.name = name;
31+
}
32+
}

0 commit comments

Comments
 (0)