mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
feat
This commit is contained in:
parent
9ecfb6ea0c
commit
1bcdbba29a
@ -4,6 +4,7 @@ import path from 'node:path'
|
|||||||
import { TEMP_DIR } from '../globalVars'
|
import { TEMP_DIR } from '../globalVars'
|
||||||
import { randomUUID, createHash } from 'node:crypto'
|
import { randomUUID, createHash } from 'node:crypto'
|
||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
|
import { fileTypeFromFile } from 'file-type'
|
||||||
|
|
||||||
export function isGIF(path: string) {
|
export function isGIF(path: string) {
|
||||||
const buffer = Buffer.alloc(4)
|
const buffer = Buffer.alloc(4)
|
||||||
@ -116,7 +117,7 @@ type Uri2LocalRes = {
|
|||||||
isLocal: boolean
|
isLocal: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function uri2local(uri: string, filename?: string): Promise<Uri2LocalRes> {
|
export async function uri2local(uri: string, filename?: string, needExt?: boolean): Promise<Uri2LocalRes> {
|
||||||
const { type } = checkUriType(uri)
|
const { type } = checkUriType(uri)
|
||||||
|
|
||||||
if (type === FileUriType.FileURL) {
|
if (type === FileUriType.FileURL) {
|
||||||
@ -139,8 +140,14 @@ export async function uri2local(uri: string, filename?: string): Promise<Uri2Loc
|
|||||||
} else {
|
} else {
|
||||||
filename ??= randomUUID()
|
filename ??= randomUUID()
|
||||||
}
|
}
|
||||||
const filePath = path.join(TEMP_DIR, filename)
|
let filePath = path.join(TEMP_DIR, filename)
|
||||||
await fsPromise.writeFile(filePath, res.data)
|
await fsPromise.writeFile(filePath, res.data)
|
||||||
|
if (needExt && !path.extname(filePath)) {
|
||||||
|
const ext = (await fileTypeFromFile(filePath))?.ext
|
||||||
|
filename += `.${ext}`
|
||||||
|
await fsPromise.rename(filePath, `${filePath}.${ext}`)
|
||||||
|
filePath = `${filePath}.${ext}`
|
||||||
|
}
|
||||||
return { success: true, errMsg: '', fileName: filename, path: filePath, isLocal: false }
|
return { success: true, errMsg: '', fileName: filename, path: filePath, isLocal: false }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const errMsg = `${uri} 下载失败, ${(e as Error).message}`
|
const errMsg = `${uri} 下载失败, ${(e as Error).message}`
|
||||||
@ -150,9 +157,15 @@ export async function uri2local(uri: string, filename?: string): Promise<Uri2Loc
|
|||||||
|
|
||||||
if (type === FileUriType.OneBotBase64) {
|
if (type === FileUriType.OneBotBase64) {
|
||||||
filename ??= randomUUID()
|
filename ??= randomUUID()
|
||||||
const filePath = path.join(TEMP_DIR, filename)
|
let filePath = path.join(TEMP_DIR, filename)
|
||||||
const base64 = uri.replace(/^base64:\/\//, '')
|
const base64 = uri.replace(/^base64:\/\//, '')
|
||||||
await fsPromise.writeFile(filePath, base64, 'base64')
|
await fsPromise.writeFile(filePath, base64, 'base64')
|
||||||
|
if (needExt) {
|
||||||
|
const ext = (await fileTypeFromFile(filePath))?.ext
|
||||||
|
filename += `.${ext}`
|
||||||
|
await fsPromise.rename(filePath, `${filePath}.${ext}`)
|
||||||
|
filePath = `${filePath}.${ext}`
|
||||||
|
}
|
||||||
return { success: true, errMsg: '', fileName: filename, path: filePath, isLocal: false }
|
return { success: true, errMsg: '', fileName: filename, path: filePath, isLocal: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,8 +175,14 @@ export async function uri2local(uri: string, filename?: string): Promise<Uri2Loc
|
|||||||
if (capture) {
|
if (capture) {
|
||||||
filename ??= randomUUID()
|
filename ??= randomUUID()
|
||||||
const [, _type, base64] = capture
|
const [, _type, base64] = capture
|
||||||
const filePath = path.join(TEMP_DIR, filename)
|
let filePath = path.join(TEMP_DIR, filename)
|
||||||
await fsPromise.writeFile(filePath, base64, 'base64')
|
await fsPromise.writeFile(filePath, base64, 'base64')
|
||||||
|
if (needExt) {
|
||||||
|
const ext = (await fileTypeFromFile(filePath))?.ext
|
||||||
|
filename += `.${ext}`
|
||||||
|
await fsPromise.rename(filePath, `${filePath}.${ext}`)
|
||||||
|
filePath = `${filePath}.${ext}`
|
||||||
|
}
|
||||||
return { success: true, errMsg: '', fileName: filename, path: filePath, isLocal: false }
|
return { success: true, errMsg: '', fileName: filename, path: filePath, isLocal: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ function onLoad() {
|
|||||||
|
|
||||||
// 创建窗口时触发
|
// 创建窗口时触发
|
||||||
function onBrowserWindowCreated(window: BrowserWindow) {
|
function onBrowserWindowCreated(window: BrowserWindow) {
|
||||||
if (![2, 4].includes(window.id)) {
|
if (![2, 4, 6].includes(window.id)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (window.id === 2) {
|
if (window.id === 2) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ReceiveCmdS } from '../hook'
|
import { ReceiveCmdS } from '../hook'
|
||||||
import { Group, GroupMember, GroupMemberRole, GroupNotifies, GroupRequestOperateTypes, GetFileListParam } from '../types'
|
import { Group, GroupMember, GroupMemberRole, GroupNotifies, GroupRequestOperateTypes, GetFileListParam, PublishGroupBulletinReq } from '../types'
|
||||||
import { invoke, NTClass, NTMethod } from '../ntcall'
|
import { invoke, NTClass, NTMethod } from '../ntcall'
|
||||||
import { GeneralCallResult } from '../services'
|
import { GeneralCallResult } from '../services'
|
||||||
import { NTQQWindows } from './window'
|
import { NTQQWindows } from './window'
|
||||||
@ -288,4 +288,16 @@ export class NTQQGroupApi extends Service {
|
|||||||
)
|
)
|
||||||
return data.fileInfo.item
|
return data.fileInfo.item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async publishGroupBulletin(groupCode: string, req: PublishGroupBulletinReq) {
|
||||||
|
const ntUserApi = this.ctx.get('ntUserApi')!
|
||||||
|
const psKey = (await ntUserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!
|
||||||
|
return await invoke('nodeIKernelGroupService/publishGroupBulletin', [{ groupCode, psKey, req }, null])
|
||||||
|
}
|
||||||
|
|
||||||
|
async uploadGroupBulletinPic(groupCode: string, path: string) {
|
||||||
|
const ntUserApi = this.ctx.get('ntUserApi')!
|
||||||
|
const psKey = (await ntUserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!
|
||||||
|
return await invoke('nodeIKernelGroupService/uploadGroupBulletinPic', [{ groupCode, psKey, path }, null])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,10 @@ export class NTQQUserApi extends Service {
|
|||||||
return cookies
|
return cookies
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getPSkey(domains: string[]) {
|
||||||
|
return await invoke('nodeIKernelTipOffService/getPskey', [{ domains, isForNewPCQQ: true }, null])
|
||||||
|
}
|
||||||
|
|
||||||
genBkn(sKey: string) {
|
genBkn(sKey: string) {
|
||||||
sKey = sKey || ''
|
sKey = sKey || ''
|
||||||
let hash = 5381
|
let hash = 5381
|
||||||
|
@ -30,7 +30,7 @@ declare module 'cordis' {
|
|||||||
'nt/message-sent': (input: RawMessage[]) => void
|
'nt/message-sent': (input: RawMessage[]) => void
|
||||||
'nt/group-notify': (input: GroupNotify[]) => void
|
'nt/group-notify': (input: GroupNotify[]) => void
|
||||||
'nt/friend-request': (input: FriendRequest[]) => void
|
'nt/friend-request': (input: FriendRequest[]) => void
|
||||||
'nt/group-member-info-updated': (input: { groupCode: string; members: GroupMember[] }) => void
|
'nt/group-member-info-updated': (input: { groupCode: string, members: GroupMember[] }) => void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,11 +202,12 @@ export interface NodeIKernelGroupService {
|
|||||||
|
|
||||||
publishInstructionForNewcomers(groupCode: string, arg: unknown): void
|
publishInstructionForNewcomers(groupCode: string, arg: unknown): void
|
||||||
|
|
||||||
uploadGroupBulletinPic(groupCode: string, pskey: string, imagePath: string): Promise<GeneralCallResult & {
|
uploadGroupBulletinPic(groupCode: string, pskey: string, imagePath: string): Promise<{
|
||||||
errCode: number
|
errCode: number
|
||||||
|
errMsg: string
|
||||||
picInfo?: {
|
picInfo?: {
|
||||||
id: string,
|
id: string
|
||||||
width: number,
|
width: number
|
||||||
height: number
|
height: number
|
||||||
}
|
}
|
||||||
}>
|
}>
|
||||||
|
@ -65,3 +65,15 @@ export interface GroupMember {
|
|||||||
joinTime: string
|
joinTime: string
|
||||||
lastSpeakTime: string
|
lastSpeakTime: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PublishGroupBulletinReq {
|
||||||
|
text: string
|
||||||
|
picInfo?: {
|
||||||
|
id: string
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
oldFeedsId: ''
|
||||||
|
pinned: number
|
||||||
|
confirmRequired: number
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
import BaseAction from '../BaseAction'
|
import BaseAction from '../BaseAction'
|
||||||
import { ActionName } from '../types'
|
import { ActionName } from '../types'
|
||||||
|
import { unlink } from 'fs/promises'
|
||||||
|
import { checkFileReceived, uri2local } from '@/common/utils/file'
|
||||||
|
|
||||||
interface Payload {
|
interface Payload {
|
||||||
group_id: number | string
|
group_id: number | string
|
||||||
@ -13,24 +15,36 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
|
|||||||
actionName = ActionName.GoCQHTTP_SendGroupNotice
|
actionName = ActionName.GoCQHTTP_SendGroupNotice
|
||||||
|
|
||||||
async _handle(payload: Payload) {
|
async _handle(payload: Payload) {
|
||||||
const type = 1
|
const groupCode = payload.group_id.toString()
|
||||||
const isShowEditCard = 0
|
|
||||||
const tipWindowType = 0
|
|
||||||
const pinned = Number(payload.pinned ?? 0)
|
const pinned = Number(payload.pinned ?? 0)
|
||||||
const confirmRequired = Number(payload.confirm_required ?? 1)
|
const confirmRequired = Number(payload.confirm_required ?? 1)
|
||||||
|
|
||||||
const result = await this.ctx.ntWebApi.setGroupNotice({
|
let picInfo: { id: string, width: number, height: number } | undefined
|
||||||
groupCode: payload.group_id.toString(),
|
if (payload.image) {
|
||||||
content: payload.content,
|
const { path, isLocal, success, errMsg } = await uri2local(payload.image, undefined, true)
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(`设置群公告失败, 错误信息: uri2local: ${errMsg}`)
|
||||||
|
}
|
||||||
|
await checkFileReceived(path, 5000) // 文件不存在QQ会崩溃,需要提前判断
|
||||||
|
const result = await this.ctx.ntGroupApi.uploadGroupBulletinPic(groupCode, path)
|
||||||
|
if (result.errCode !== 0) {
|
||||||
|
throw new Error(`设置群公告失败, 错误信息: uploadGroupBulletinPic: ${result.errMsg}`)
|
||||||
|
}
|
||||||
|
if (!isLocal) {
|
||||||
|
unlink(path)
|
||||||
|
}
|
||||||
|
picInfo = result.picInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await this.ctx.ntGroupApi.publishGroupBulletin(groupCode, {
|
||||||
|
text: encodeURIComponent(payload.content),
|
||||||
|
oldFeedsId: '',
|
||||||
pinned,
|
pinned,
|
||||||
type,
|
|
||||||
isShowEditCard,
|
|
||||||
tipWindowType,
|
|
||||||
confirmRequired,
|
confirmRequired,
|
||||||
picId: ''
|
picInfo
|
||||||
})
|
})
|
||||||
if (result.ec !== 0) {
|
if (res.result !== 0) {
|
||||||
throw new Error(`设置群公告失败, 错误信息: ${result.em}`)
|
throw new Error(`设置群公告失败, 错误信息: ${res.errMsg}`)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user