mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
refactor: 统一时间戳为毫秒,优化发送消息逻辑代码
fix: 发送文件的文件名保持原样
This commit is contained in:
parent
c636af0b0e
commit
9faa56ec32
@ -47,6 +47,8 @@ TG群:<https://t.me/+nLZEnpne-pQ1OWFl>
|
||||
- [x] 处理添加好友请求
|
||||
- [x] 处理加群请求
|
||||
- [x] 退群
|
||||
- [ ] 上报加群邀请
|
||||
- [ ] 同意加群邀请
|
||||
- [x] 上报好友消息
|
||||
- [x] 上报添加好友请求
|
||||
- [x] 上报群消息
|
||||
@ -159,6 +161,8 @@ TG群:<https://t.me/+nLZEnpne-pQ1OWFl>
|
||||
- [x] 群管理功能,禁言、踢人,改群名片等
|
||||
- [x] 视频消息
|
||||
- [x] 文件消息
|
||||
- [ ] 上报加群邀请
|
||||
- [ ] 同意加群邀请
|
||||
- [ ] 音乐卡片
|
||||
- [ ] 无头模式
|
||||
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
SendTextElement
|
||||
} from "./types";
|
||||
import {NTQQApi} from "./ntcall";
|
||||
import {encodeSilk, log} from "../common/utils";
|
||||
import {encodeSilk} from "../common/utils";
|
||||
import fs from "fs";
|
||||
|
||||
|
||||
@ -56,7 +56,7 @@ export class SendMsgElementConstructor {
|
||||
}
|
||||
|
||||
static async pic(picPath: string): Promise<SendPicElement> {
|
||||
const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(picPath);
|
||||
const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(picPath, ElementType.PIC);
|
||||
const imageSize = await NTQQApi.getImageSize(picPath);
|
||||
const picElement = {
|
||||
md5HexStr: md5,
|
||||
@ -81,8 +81,14 @@ export class SendMsgElementConstructor {
|
||||
};
|
||||
}
|
||||
|
||||
static async file(filePath: string, isVideo:boolean = false): Promise<SendFileElement> {
|
||||
const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(filePath);
|
||||
static async file(filePath: string, isVideo: boolean = false): Promise<SendFileElement> {
|
||||
let picHeight = 0;
|
||||
let picWidth = 0;
|
||||
if (isVideo) {
|
||||
picHeight = 1024;
|
||||
picWidth = 768;
|
||||
}
|
||||
const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(filePath, ElementType.FILE);
|
||||
let element: SendFileElement = {
|
||||
elementType: ElementType.FILE,
|
||||
elementId: "",
|
||||
@ -90,18 +96,18 @@ export class SendMsgElementConstructor {
|
||||
fileName,
|
||||
"filePath": path,
|
||||
"fileSize": (fileSize).toString(),
|
||||
picHeight,
|
||||
picWidth
|
||||
}
|
||||
}
|
||||
if (isVideo){
|
||||
element.fileElement.picHeight = 1024;
|
||||
element.fileElement.picWidth = 768;
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
static video(filePath: string): Promise<SendFileElement> {
|
||||
return SendMsgElementConstructor.file(filePath, true);
|
||||
}
|
||||
|
||||
static async ptt(pttPath: string): Promise<SendPttElement> {
|
||||
const {converted, path: silkPath, duration} = await encodeSilk(pttPath);
|
||||
// log("生成语音", silkPath, duration);
|
||||
|
@ -1,13 +1,14 @@
|
||||
import {ipcMain} from "electron";
|
||||
import {hookApiCallbacks, ReceiveCmd, registerReceiveHook, removeReceiveHook} from "./hook";
|
||||
import {log} from "../common/utils";
|
||||
import {log, sleep} from "../common/utils";
|
||||
import {
|
||||
ChatType,
|
||||
ElementType,
|
||||
Friend,
|
||||
FriendRequest,
|
||||
Group,
|
||||
GroupMember, GroupMemberRole,
|
||||
GroupMember,
|
||||
GroupMemberRole,
|
||||
GroupNotifies,
|
||||
GroupNotify,
|
||||
GroupRequestOperateTypes,
|
||||
@ -19,6 +20,7 @@ import {
|
||||
import * as fs from "fs";
|
||||
import {addHistoryMsg, friendRequests, groupNotifies, msgHistory, selfInfo} from "../common/data";
|
||||
import {v4 as uuidv4} from "uuid"
|
||||
import path from "path";
|
||||
|
||||
interface IPCReceiveEvent {
|
||||
eventName: string
|
||||
@ -346,7 +348,10 @@ export class NTQQApi {
|
||||
} else {
|
||||
ext = ""
|
||||
}
|
||||
const fileName = `${md5}${ext}`;
|
||||
let fileName = `${path.basename(filePath)}`;
|
||||
if (fileName.indexOf(".") === -1) {
|
||||
fileName += ext;
|
||||
}
|
||||
const mediaPath = await callNTQQApi<string>({
|
||||
methodName: NTQQApiMethod.MEDIA_FILE_PATH,
|
||||
args: [{
|
||||
@ -414,71 +419,57 @@ export class NTQQApi {
|
||||
})
|
||||
}
|
||||
|
||||
static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = false, timeout = 10000) {
|
||||
const sendTimeout = timeout
|
||||
static async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = false, timeout = 10000) {
|
||||
const peerUid = peer.peerUid;
|
||||
|
||||
return new Promise<RawMessage>((resolve, reject) => {
|
||||
const peerUid = peer.peerUid;
|
||||
let usingTime = 0;
|
||||
let success = false;
|
||||
let isTimeout = false;
|
||||
|
||||
const checkSuccess = () => {
|
||||
if (!success) {
|
||||
sendMessagePool[peerUid] = null;
|
||||
isTimeout = true;
|
||||
reject("发送超时")
|
||||
}
|
||||
// 等待上一个相同的peer发送完
|
||||
let checkLastSendUsingTime = 0;
|
||||
const waitLastSend = async () => {
|
||||
if (checkLastSendUsingTime > timeout) {
|
||||
throw ("发送超时")
|
||||
}
|
||||
setTimeout(checkSuccess, sendTimeout);
|
||||
|
||||
const checkLastSend = () => {
|
||||
let lastSending = sendMessagePool[peerUid]
|
||||
if (sendTimeout < usingTime) {
|
||||
sendMessagePool[peerUid] = null;
|
||||
isTimeout = true;
|
||||
reject("发送超时")
|
||||
}
|
||||
if (!!lastSending) {
|
||||
// log("有正在发送的消息,等待中...")
|
||||
usingTime += 500;
|
||||
setTimeout(checkLastSend, 500);
|
||||
} else {
|
||||
log("可以进行发送消息,设置发送成功回调", sendMessagePool)
|
||||
sendMessagePool[peerUid] = (rawMessage: RawMessage) => {
|
||||
sendMessagePool[peerUid] = null;
|
||||
const checkSendComplete = () => {
|
||||
if (isTimeout) {
|
||||
return reject("发送超时")
|
||||
}
|
||||
if (msgHistory[rawMessage.msgId]?.sendStatus == 2) {
|
||||
log(`给${peerUid}发送消息成功`)
|
||||
success = true;
|
||||
resolve(rawMessage);
|
||||
} else {
|
||||
setTimeout(checkSendComplete, 500)
|
||||
}
|
||||
}
|
||||
if (waitComplete) {
|
||||
checkSendComplete();
|
||||
} else {
|
||||
success = true;
|
||||
log(`给${peerUid}发送消息成功`)
|
||||
resolve(rawMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
let lastSending = sendMessagePool[peer.peerUid]
|
||||
if (lastSending) {
|
||||
// log("有正在发送的消息,等待中...")
|
||||
await sleep(500);
|
||||
checkLastSendUsingTime += 500;
|
||||
return await waitLastSend();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
checkLastSend()
|
||||
callNTQQApi({
|
||||
methodName: NTQQApiMethod.SEND_MSG,
|
||||
args: [{
|
||||
msgId: "0",
|
||||
peer, msgElements,
|
||||
msgAttributeInfos: new Map(),
|
||||
}, null]
|
||||
}).then()
|
||||
})
|
||||
}
|
||||
await waitLastSend();
|
||||
|
||||
let sentMessage: RawMessage = null;
|
||||
sendMessagePool[peerUid] = async (rawMessage: RawMessage) => {
|
||||
delete sendMessagePool[peerUid];
|
||||
sentMessage = rawMessage;
|
||||
}
|
||||
|
||||
let checkSendCompleteUsingTime = 0;
|
||||
const checkSendComplete = async (): Promise<RawMessage> => {
|
||||
if (sentMessage && msgHistory[sentMessage.msgId]?.sendStatus == 2) {
|
||||
// log(`给${peerUid}发送消息成功`)
|
||||
return sentMessage;
|
||||
} else {
|
||||
checkSendCompleteUsingTime += 500;
|
||||
if (checkSendCompleteUsingTime > timeout) {
|
||||
throw ("发送超时")
|
||||
}
|
||||
await sleep(500);
|
||||
return await checkSendComplete()
|
||||
}
|
||||
}
|
||||
|
||||
callNTQQApi({
|
||||
methodName: NTQQApiMethod.SEND_MSG,
|
||||
args: [{
|
||||
msgId: "0",
|
||||
peer, msgElements,
|
||||
msgAttributeInfos: new Map(),
|
||||
}, null]
|
||||
}).then()
|
||||
return checkSendComplete();
|
||||
}
|
||||
|
||||
static multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]) {
|
||||
@ -638,7 +629,8 @@ export class NTQQApi {
|
||||
}
|
||||
)
|
||||
}
|
||||
static banGroup(groupQQ: string, shutUp: boolean){
|
||||
|
||||
static banGroup(groupQQ: string, shutUp: boolean) {
|
||||
return callNTQQApi<GeneralCallResult>({
|
||||
methodName: NTQQApiMethod.MUTE_GROUP,
|
||||
args: [
|
||||
@ -676,14 +668,14 @@ export class NTQQApi {
|
||||
})
|
||||
}
|
||||
|
||||
static setGroupName(groupQQ: string, groupName: string){
|
||||
static setGroupName(groupQQ: string, groupName: string) {
|
||||
return callNTQQApi<GeneralCallResult>({
|
||||
methodName: NTQQApiMethod.SET_GROUP_NAME,
|
||||
args:[
|
||||
args: [
|
||||
{
|
||||
groupCode: groupQQ,
|
||||
groupName
|
||||
},null
|
||||
}, null
|
||||
]
|
||||
})
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
case OB11MessageDataType.voice: {
|
||||
const file = sendMsg.data?.file
|
||||
if (file) {
|
||||
const {path, isLocal} = (await uri2local(uuidv4(), file))
|
||||
const {path, isLocal} = (await uri2local(file))
|
||||
if (path) {
|
||||
if (!isLocal) { // 只删除http和base64转过来的文件
|
||||
deleteAfterSentFiles.push(path)
|
||||
|
@ -23,7 +23,7 @@ export class OB11Constructor {
|
||||
const resMsg: OB11Message = {
|
||||
self_id: parseInt(selfInfo.uin),
|
||||
user_id: parseInt(msg.senderUin),
|
||||
time: parseInt(msg.msgTime) || 0,
|
||||
time: parseInt(msg.msgTime) * 1000 || Date.now(), // 13位时间戳,毫秒
|
||||
message_id: msg.msgShortId,
|
||||
real_id: msg.msgId,
|
||||
message_type: msg.chatType == ChatType.group ? "group" : "private",
|
||||
|
@ -10,7 +10,7 @@ export enum EventType {
|
||||
|
||||
|
||||
export abstract class OB11BaseEvent {
|
||||
time = new Date().getTime();
|
||||
time = Date.now();
|
||||
self_id = parseInt(selfInfo.uin);
|
||||
post_type: EventType;
|
||||
}
|
@ -1,10 +1,13 @@
|
||||
import {CONFIG_DIR, isGIF} from "../common/utils";
|
||||
import {v4 as uuidv4} from "uuid";
|
||||
import * as path from 'path';
|
||||
import {OB11MessageData} from "./types";
|
||||
|
||||
const fs = require("fs").promises;
|
||||
|
||||
export async function uri2local(fileName: string, uri: string){
|
||||
export async function uri2local(uri: string, fileName: string=null){
|
||||
if (!fileName){
|
||||
fileName = uuidv4();
|
||||
}
|
||||
let filePath = path.join(CONFIG_DIR, fileName)
|
||||
let url = new URL(uri);
|
||||
let res = {
|
||||
@ -33,6 +36,8 @@ export async function uri2local(fileName: string, uri: string){
|
||||
let blob = await fetchRes.blob();
|
||||
let buffer = await blob.arrayBuffer();
|
||||
try {
|
||||
fileName = path.basename(url.pathname) || fileName
|
||||
filePath = path.join(CONFIG_DIR, fileName)
|
||||
await fs.writeFile(filePath, Buffer.from(buffer));
|
||||
} catch (e: any) {
|
||||
res.errMsg = `${url}下载失败,` + e.toString()
|
||||
|
Loading…
x
Reference in New Issue
Block a user