mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
feat: 群文件上传事件
feat: 群文件上传接口
This commit is contained in:
parent
178c32053b
commit
ed681b8adf
@ -9,7 +9,7 @@
|
|||||||
"build-mac": "npm run build && npm run deploy-mac",
|
"build-mac": "npm run build && npm run deploy-mac",
|
||||||
"deploy-mac": "cp -r dist/* ~/Library/Containers/com.tencent.qq/Data/LiteLoaderQQNT/plugins/LLOneBot/",
|
"deploy-mac": "cp -r dist/* ~/Library/Containers/com.tencent.qq/Data/LiteLoaderQQNT/plugins/LLOneBot/",
|
||||||
"build-win": "npm run build && npm run deploy-win",
|
"build-win": "npm run build && npm run deploy-win",
|
||||||
"deploy-win": "cmd /c \"xcopy /S /Y dist\\* %USERPROFILE%\\documents\\LiteLoaderQQNT\\plugins\\LLOneBot\\\""
|
"deploy-win": "cmd /c \"xcopy /C /S /Y dist\\* %USERPROFILE%\\documents\\LiteLoaderQQNT\\plugins\\LLOneBot\\\""
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
@ -206,7 +206,7 @@ export async function encodeSilk(filePath: string) {
|
|||||||
if (ffmpegPath) {
|
if (ffmpegPath) {
|
||||||
ffmpeg.setFfmpegPath(ffmpegPath);
|
ffmpeg.setFfmpegPath(ffmpegPath);
|
||||||
}
|
}
|
||||||
ffmpeg(filePath).toFormat("wav").on('end', function () {
|
ffmpeg(filePath).toFormat("wav").audioChannels(2).on('end', function () {
|
||||||
log('wav转换完成');
|
log('wav转换完成');
|
||||||
})
|
})
|
||||||
.on('error', function (err) {
|
.on('error', function (err) {
|
||||||
@ -221,11 +221,12 @@ export async function encodeSilk(filePath: string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
// const sampleRate = await getAudioSampleRate(filePath) || 0;
|
// const sampleRate = await getAudioSampleRate(filePath) || 0;
|
||||||
|
// log("音频采样率", sampleRate)
|
||||||
const pcm = fs.readFileSync(filePath);
|
const pcm = fs.readFileSync(filePath);
|
||||||
const silk = await encode(pcm, 0);
|
const silk = await encode(pcm, 0);
|
||||||
fs.writeFileSync(pttPath, silk.data);
|
fs.writeFileSync(pttPath, silk.data);
|
||||||
fs.unlink(wavPath, (err) => {
|
// fs.unlink(wavPath, (err) => {
|
||||||
});
|
// });
|
||||||
log(`语音文件${filePath}转换成功!`, pttPath)
|
log(`语音文件${filePath}转换成功!`, pttPath)
|
||||||
return {
|
return {
|
||||||
converted: true,
|
converted: true,
|
||||||
@ -260,7 +261,7 @@ export async function encodeSilk(filePath: string) {
|
|||||||
export async function getVideoInfo(filePath: string) {
|
export async function getVideoInfo(filePath: string) {
|
||||||
const size = fs.statSync(filePath).size;
|
const size = fs.statSync(filePath).size;
|
||||||
return new Promise<{ width: number, height: number, time: number, format: string, size: number, filePath: string }>((resolve, reject) => {
|
return new Promise<{ width: number, height: number, time: number, format: string, size: number, filePath: string }>((resolve, reject) => {
|
||||||
ffmpeg.ffprobe(filePath, (err, metadata) => {
|
ffmpeg(filePath).ffprobe( (err, metadata) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
@ -282,6 +283,7 @@ export async function getVideoInfo(filePath: string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function encodeMp4(filePath: string) {
|
export async function encodeMp4(filePath: string) {
|
||||||
let videoInfo = await getVideoInfo(filePath);
|
let videoInfo = await getVideoInfo(filePath);
|
||||||
log("视频信息", videoInfo)
|
log("视频信息", videoInfo)
|
||||||
|
@ -121,7 +121,7 @@ export class SendMsgElementConstructor {
|
|||||||
thumb = pathLib.dirname(thumb)
|
thumb = pathLib.dirname(thumb)
|
||||||
// log("thumb 目录", thumb)
|
// log("thumb 目录", thumb)
|
||||||
const videoInfo = await getVideoInfo(path);
|
const videoInfo = await getVideoInfo(path);
|
||||||
// log("视频信息", videoInfo)
|
log("视频信息", videoInfo)
|
||||||
const createThumb = new Promise<string>((resolve, reject) => {
|
const createThumb = new Promise<string>((resolve, reject) => {
|
||||||
const thumbFileName = `${md5}_0.png`
|
const thumbFileName = `${md5}_0.png`
|
||||||
ffmpeg(filePath)
|
ffmpeg(filePath)
|
||||||
|
@ -48,6 +48,7 @@ export enum NTQQApiClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum NTQQApiMethod {
|
export enum NTQQApiMethod {
|
||||||
|
SET_HEADER = "nodeIKernelProfileService/setHeader",
|
||||||
LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike",
|
LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike",
|
||||||
SELF_INFO = "fetchAuthData",
|
SELF_INFO = "fetchAuthData",
|
||||||
FRIENDS = "nodeIKernelBuddyService/getBuddyList",
|
FRIENDS = "nodeIKernelBuddyService/getBuddyList",
|
||||||
@ -202,7 +203,12 @@ interface GeneralCallResult {
|
|||||||
|
|
||||||
|
|
||||||
export class NTQQApi {
|
export class NTQQApi {
|
||||||
// static likeFriend = defineNTQQApi<void>(NTQQApiChannel.IPC_UP_2, NTQQApiClass.NT_API, NTQQApiMethod.LIKE_FRIEND)
|
static async setHeader(path: string){
|
||||||
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
|
methodName: NTQQApiMethod.SET_HEADER,
|
||||||
|
args: [path]
|
||||||
|
})
|
||||||
|
}
|
||||||
static async likeFriend(uid: string, count = 1) {
|
static async likeFriend(uid: string, count = 1) {
|
||||||
return await callNTQQApi<GeneralCallResult>({
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
methodName: NTQQApiMethod.LIKE_FRIEND,
|
methodName: NTQQApiMethod.LIKE_FRIEND,
|
||||||
@ -728,8 +734,9 @@ export class NTQQApi {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static async call(cmdName: string, args: any[],) {
|
static async call(className: NTQQApiClass, cmdName: string, args: any[],) {
|
||||||
return await callNTQQApi<GeneralCallResult>({
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
|
className,
|
||||||
methodName: cmdName,
|
methodName: cmdName,
|
||||||
args: [
|
args: [
|
||||||
...args,
|
...args,
|
||||||
|
37
src/onebot11/action/go-cqhttp/UploadGroupFile.ts
Normal file
37
src/onebot11/action/go-cqhttp/UploadGroupFile.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import BaseAction from "../BaseAction";
|
||||||
|
import {getGroup} from "../../../common/data";
|
||||||
|
import {ActionName} from "../types";
|
||||||
|
import {SendMsgElementConstructor} from "../../../ntqqapi/constructor";
|
||||||
|
import {ChatType, SendFileElement} from "../../../ntqqapi/types";
|
||||||
|
import {NTQQApi} from "../../../ntqqapi/ntcall";
|
||||||
|
import {uri2local} from "../../utils";
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
interface Payload{
|
||||||
|
group_id: number
|
||||||
|
file: string
|
||||||
|
name: string
|
||||||
|
folder: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class GoCQHTTPUploadGroupFile extends BaseAction<Payload, null> {
|
||||||
|
actionName = ActionName.GoCQHTTP_UploadGroupFile
|
||||||
|
|
||||||
|
protected async _handle(payload: Payload): Promise<null> {
|
||||||
|
const group = await getGroup(payload.group_id.toString());
|
||||||
|
if (!group){
|
||||||
|
throw new Error(`群组${payload.group_id}不存在`)
|
||||||
|
}
|
||||||
|
let file = payload.file;
|
||||||
|
if (fs.existsSync(file)){
|
||||||
|
file = `file://${file}`
|
||||||
|
}
|
||||||
|
const downloadResult = await uri2local(file);
|
||||||
|
if (downloadResult.errMsg){
|
||||||
|
throw new Error(downloadResult.errMsg)
|
||||||
|
}
|
||||||
|
let sendFileEle: SendFileElement = await SendMsgElementConstructor.file(downloadResult.path, payload.name);
|
||||||
|
await NTQQApi.sendMsg({chatType: ChatType.group, peerUid: group.groupCode}, [sendFileEle]);
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,7 @@ import GetImage from "./GetImage";
|
|||||||
import GetRecord from "./GetRecord";
|
import GetRecord from "./GetRecord";
|
||||||
import GoCQHTTPMarkMsgAsRead from "./MarkMsgAsRead";
|
import GoCQHTTPMarkMsgAsRead from "./MarkMsgAsRead";
|
||||||
import CleanCache from "./CleanCache";
|
import CleanCache from "./CleanCache";
|
||||||
|
import GoCQHTTPUploadGroupFile from "./go-cqhttp/UploadGroupFile";
|
||||||
|
|
||||||
export const actionHandlers = [
|
export const actionHandlers = [
|
||||||
new Debug(),
|
new Debug(),
|
||||||
@ -65,6 +66,7 @@ export const actionHandlers = [
|
|||||||
new GoCQHTTPGetStrangerInfo(),
|
new GoCQHTTPGetStrangerInfo(),
|
||||||
new GetGuildList(),
|
new GetGuildList(),
|
||||||
new GoCQHTTPMarkMsgAsRead(),
|
new GoCQHTTPMarkMsgAsRead(),
|
||||||
|
new GoCQHTTPUploadGroupFile(),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -49,4 +49,5 @@ export enum ActionName {
|
|||||||
GoCQHTTP_GetStrangerInfo = "get_stranger_info",
|
GoCQHTTP_GetStrangerInfo = "get_stranger_info",
|
||||||
GetGuildList = "get_guild_list",
|
GetGuildList = "get_guild_list",
|
||||||
GoCQHTTP_MarkMsgAsRead = "mark_msg_as_read",
|
GoCQHTTP_MarkMsgAsRead = "mark_msg_as_read",
|
||||||
|
GoCQHTTP_UploadGroupFile = "upload_group_file",
|
||||||
}
|
}
|
@ -27,6 +27,8 @@ import {encodeCQCode} from "./cqcode";
|
|||||||
import {dbUtil} from "../common/db";
|
import {dbUtil} from "../common/db";
|
||||||
import {OB11GroupIncreaseEvent} from "./event/notice/OB11GroupIncreaseEvent";
|
import {OB11GroupIncreaseEvent} from "./event/notice/OB11GroupIncreaseEvent";
|
||||||
import {OB11GroupBanEvent} from "./event/notice/OB11GroupBanEvent";
|
import {OB11GroupBanEvent} from "./event/notice/OB11GroupBanEvent";
|
||||||
|
import {OB11GroupUploadNoticeEvent} from "./event/notice/OB11GroupUploadNoticeEvent";
|
||||||
|
import {OB11GroupNoticeEvent} from "./event/notice/OB11GroupNoticeEvent";
|
||||||
|
|
||||||
|
|
||||||
export class OB11Constructor {
|
export class OB11Constructor {
|
||||||
@ -244,7 +246,10 @@ export class OB11Constructor {
|
|||||||
return resMsg;
|
return resMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async GroupEvent(msg: RawMessage): Promise<OB11GroupIncreaseEvent> {
|
static async GroupEvent(msg: RawMessage): Promise<OB11GroupNoticeEvent> {
|
||||||
|
if (msg.chatType !== ChatType.group) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (let element of msg.elements) {
|
for (let element of msg.elements) {
|
||||||
const groupElement = element.grayTipElement?.groupElement
|
const groupElement = element.grayTipElement?.groupElement
|
||||||
if (groupElement) {
|
if (groupElement) {
|
||||||
@ -289,6 +294,9 @@ export class OB11Constructor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (element.fileElement){
|
||||||
|
return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), {id: element.fileElement.fileName, name: element.fileElement.fileName, size: parseInt(element.fileElement.fileSize)})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
src/onebot11/event/notice/OB11GroupUploadNoticeEvent.ts
Normal file
19
src/onebot11/event/notice/OB11GroupUploadNoticeEvent.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import {OB11GroupNoticeEvent} from "./OB11GroupNoticeEvent";
|
||||||
|
|
||||||
|
export interface GroupUploadFile{
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
size: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export class OB11GroupUploadNoticeEvent extends OB11GroupNoticeEvent {
|
||||||
|
notice_type = "group_upload"
|
||||||
|
file: GroupUploadFile
|
||||||
|
|
||||||
|
constructor(groupId: number, userId: number, file: GroupUploadFile) {
|
||||||
|
super();
|
||||||
|
this.group_id = groupId;
|
||||||
|
this.user_id = userId;
|
||||||
|
this.file = file
|
||||||
|
}
|
||||||
|
}
|
@ -90,7 +90,7 @@ async function onSettingWindowCreated(view: Element) {
|
|||||||
], 'ob11.messagePostFormat', config.ob11.messagePostFormat),
|
], 'ob11.messagePostFormat', config.ob11.messagePostFormat),
|
||||||
),
|
),
|
||||||
SettingItem(
|
SettingItem(
|
||||||
'ffmpeg 路径, 用于发送语音时进行转码', `<span id="config-ffmpeg-path-text">${!isEmpty(config.ffmpeg) ? config.ffmpeg : '未指定'}</span>`,
|
'ffmpeg 路径, 发送语音、视频需要,同时保证ffprobe和ffmpeg在一起', `<span id="config-ffmpeg-path-text">${!isEmpty(config.ffmpeg) ? config.ffmpeg : '未指定'}</span>`,
|
||||||
SettingButton('选择', 'config-ffmpeg-select'),
|
SettingButton('选择', 'config-ffmpeg-select'),
|
||||||
),
|
),
|
||||||
SettingItem(
|
SettingItem(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user