mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
commit
36d990e328
@ -4,7 +4,7 @@
|
|||||||
"name": "LLOneBot",
|
"name": "LLOneBot",
|
||||||
"slug": "LLOneBot",
|
"slug": "LLOneBot",
|
||||||
"description": "实现 OneBot 11 协议,用于 QQ 机器人开发",
|
"description": "实现 OneBot 11 协议,用于 QQ 机器人开发",
|
||||||
"version": "3.33.9",
|
"version": "3.33.10",
|
||||||
"icon": "./icon.webp",
|
"icon": "./icon.webp",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/cors": "^2.8.17",
|
"@types/cors": "^2.8.17",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^5.0.0",
|
||||||
"@types/fluent-ffmpeg": "^2.1.26",
|
"@types/fluent-ffmpeg": "^2.1.26",
|
||||||
"@types/node": "^20.14.15",
|
"@types/node": "^20.14.15",
|
||||||
"@types/ws": "^8.5.12",
|
"@types/ws": "^8.5.12",
|
||||||
@ -40,7 +40,7 @@
|
|||||||
"electron-vite": "^2.3.0",
|
"electron-vite": "^2.3.0",
|
||||||
"protobufjs-cli": "^1.1.3",
|
"protobufjs-cli": "^1.1.3",
|
||||||
"typescript": "^5.6.2",
|
"typescript": "^5.6.2",
|
||||||
"vite": "^5.4.7",
|
"vite": "^5.4.8",
|
||||||
"vite-plugin-cp": "^4.0.8"
|
"vite-plugin-cp": "^4.0.8"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.5.0"
|
"packageManager": "yarn@4.5.0"
|
||||||
|
@ -8,7 +8,8 @@ import {
|
|||||||
GetFileListParam,
|
GetFileListParam,
|
||||||
PublishGroupBulletinReq,
|
PublishGroupBulletinReq,
|
||||||
GroupAllInfo,
|
GroupAllInfo,
|
||||||
GroupFileInfo
|
GroupFileInfo,
|
||||||
|
GroupBulletinListResult
|
||||||
} from '../types'
|
} from '../types'
|
||||||
import { invoke, NTClass, NTMethod } from '../ntcall'
|
import { invoke, NTClass, NTMethod } from '../ntcall'
|
||||||
import { GeneralCallResult } from '../services'
|
import { GeneralCallResult } from '../services'
|
||||||
@ -347,4 +348,33 @@ export class NTQQGroupApi extends Service {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getGroupBulletinList(groupCode: string) {
|
||||||
|
invoke('nodeIKernelGroupListener/onGetGroupBulletinListResult', [], { registerEvent: true })
|
||||||
|
const ntUserApi = this.ctx.get('ntUserApi')!
|
||||||
|
const psKey = (await ntUserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!
|
||||||
|
return await invoke<{
|
||||||
|
groupCode: string
|
||||||
|
context: string
|
||||||
|
result: GroupBulletinListResult
|
||||||
|
}>(
|
||||||
|
'nodeIKernelGroupService/getGroupBulletinList',
|
||||||
|
[{
|
||||||
|
groupCode,
|
||||||
|
psKey,
|
||||||
|
context: '',
|
||||||
|
req: {
|
||||||
|
startIndex: -1,
|
||||||
|
num: 20,
|
||||||
|
needInstructionsForJoinGroup: 1,
|
||||||
|
needPublisherInfo: 1
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
{
|
||||||
|
cbCmd: 'nodeIKernelGroupListener/onGetGroupBulletinListResult',
|
||||||
|
cmdCB: payload => payload.groupCode === groupCode,
|
||||||
|
afterFirstCmd: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@ export interface Group {
|
|||||||
hasModifyConfGroupName: boolean
|
hasModifyConfGroupName: boolean
|
||||||
remarkName: string
|
remarkName: string
|
||||||
hasMemo: boolean
|
hasMemo: boolean
|
||||||
groupShutupExpireTime: string //"0",
|
groupShutupExpireTime: string
|
||||||
personShutupExpireTime: string //"0",
|
personShutupExpireTime: string
|
||||||
discussToGroupUin: string //"0",
|
discussToGroupUin: string
|
||||||
discussToGroupMaxMsgSeq: number
|
discussToGroupMaxMsgSeq: number
|
||||||
discussToGroupTime: number
|
discussToGroupTime: number
|
||||||
groupFlagExt: number //1073938496,
|
groupFlagExt: number //1073938496,
|
||||||
@ -32,8 +32,8 @@ export interface Group {
|
|||||||
groupCreditLevel: number //0,
|
groupCreditLevel: number //0,
|
||||||
groupFlagExt3: number //0,
|
groupFlagExt3: number //0,
|
||||||
groupOwnerId: {
|
groupOwnerId: {
|
||||||
memberUin: string //"0",
|
memberUin: string
|
||||||
memberUid: string //"u_fbf8N7aeuZEnUiJAbQ9R8Q"
|
memberUid: string
|
||||||
}
|
}
|
||||||
members: GroupMember[] // 原始数据是没有这个的,为了方便自己加了这个字段
|
members: GroupMember[] // 原始数据是没有这个的,为了方便自己加了这个字段
|
||||||
createTime: string
|
createTime: string
|
||||||
@ -120,3 +120,55 @@ export interface GroupAllInfo {
|
|||||||
joinGroupAuth: string
|
joinGroupAuth: string
|
||||||
isAllowModifyConfGroupName: number
|
isAllowModifyConfGroupName: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GroupBulletinListResult {
|
||||||
|
groupCode: string
|
||||||
|
srvCode: number
|
||||||
|
readOnly: number
|
||||||
|
role: number
|
||||||
|
inst: unknown[]
|
||||||
|
feeds: {
|
||||||
|
uin: string
|
||||||
|
feedId: string
|
||||||
|
publishTime: string
|
||||||
|
msg: {
|
||||||
|
text: string
|
||||||
|
textFace: string
|
||||||
|
pics: {
|
||||||
|
id: string
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
}[]
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
type: number
|
||||||
|
fn: number
|
||||||
|
cn: number
|
||||||
|
vn: number
|
||||||
|
settings: {
|
||||||
|
isShowEditCard: number
|
||||||
|
remindTs: number
|
||||||
|
tipWindowType: number
|
||||||
|
confirmRequired: number
|
||||||
|
}
|
||||||
|
pinned: number
|
||||||
|
readNum: number
|
||||||
|
is_read: number
|
||||||
|
is_all_confirm: number
|
||||||
|
}[]
|
||||||
|
groupInfo: {
|
||||||
|
groupCode: string
|
||||||
|
classId: number
|
||||||
|
}
|
||||||
|
gln: number
|
||||||
|
tst: number
|
||||||
|
publisherInfos: {
|
||||||
|
uin: string
|
||||||
|
nick: string
|
||||||
|
avatar: string
|
||||||
|
}[]
|
||||||
|
server_time: string
|
||||||
|
svrt: string
|
||||||
|
nextIndex: number
|
||||||
|
jointime: string
|
||||||
|
}
|
||||||
|
48
src/onebot11/action/go-cqhttp/GetGroupNotice.ts
Normal file
48
src/onebot11/action/go-cqhttp/GetGroupNotice.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { BaseAction, Schema } from '../BaseAction'
|
||||||
|
import { ActionName } from '../types'
|
||||||
|
|
||||||
|
interface Payload {
|
||||||
|
group_id: number | string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Notice {
|
||||||
|
sender_id: number
|
||||||
|
publish_time: number
|
||||||
|
message: {
|
||||||
|
text: string
|
||||||
|
images: {
|
||||||
|
height: string
|
||||||
|
width: string
|
||||||
|
id: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GetGroupNotice extends BaseAction<Payload, Notice[]> {
|
||||||
|
actionName = ActionName.GoCQHTTP_GetGroupNotice
|
||||||
|
payloadSchema = Schema.object({
|
||||||
|
group_id: Schema.union([Number, String]).required()
|
||||||
|
})
|
||||||
|
|
||||||
|
protected async _handle(payload: Payload) {
|
||||||
|
const data = await this.ctx.ntGroupApi.getGroupBulletinList(payload.group_id.toString())
|
||||||
|
const result: Notice[] = []
|
||||||
|
for (const feed of data.result.feeds) {
|
||||||
|
result.push({
|
||||||
|
sender_id: +feed.uin,
|
||||||
|
publish_time: +feed.publishTime,
|
||||||
|
message: {
|
||||||
|
text: feed.msg.text,
|
||||||
|
images: feed.msg.pics.map(image => {
|
||||||
|
return {
|
||||||
|
height: String(image.height),
|
||||||
|
width: String(image.width),
|
||||||
|
id: image.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,8 @@ import { convertMessage2List, createSendElements, sendMsg, createPeer, CreatePee
|
|||||||
interface Payload {
|
interface Payload {
|
||||||
user_id?: string | number
|
user_id?: string | number
|
||||||
group_id?: string | number
|
group_id?: string | number
|
||||||
messages: OB11MessageNode[]
|
messages?: OB11MessageNode[]
|
||||||
|
message?: OB11MessageNode[]
|
||||||
message_type?: 'group' | 'private'
|
message_type?: 'group' | 'private'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,15 +21,20 @@ interface Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class SendForwardMsg extends BaseAction<Payload, Response> {
|
export class SendForwardMsg extends BaseAction<Payload, Response> {
|
||||||
actionName = ActionName.GoCQHTTP_SendForwardMsg
|
actionName = ActionName.SendForwardMsg
|
||||||
payloadSchema = Schema.object({
|
payloadSchema = Schema.object({
|
||||||
user_id: Schema.union([Number, String]),
|
user_id: Schema.union([Number, String]),
|
||||||
group_id: Schema.union([Number, String]),
|
group_id: Schema.union([Number, String]),
|
||||||
messages: Schema.array(Schema.any()).required(),
|
messages: Schema.array(Schema.any()),
|
||||||
|
message: Schema.array(Schema.any()),
|
||||||
message_type: Schema.union(['group', 'private'])
|
message_type: Schema.union(['group', 'private'])
|
||||||
})
|
})
|
||||||
|
|
||||||
protected async _handle(payload: Payload) {
|
protected async _handle(payload: Payload) {
|
||||||
|
const messages = payload.messages ?? payload.message
|
||||||
|
if (!messages) {
|
||||||
|
throw new Error('未指定消息内容')
|
||||||
|
}
|
||||||
let contextMode = CreatePeerMode.Normal
|
let contextMode = CreatePeerMode.Normal
|
||||||
if (payload.message_type === 'group') {
|
if (payload.message_type === 'group') {
|
||||||
contextMode = CreatePeerMode.Group
|
contextMode = CreatePeerMode.Group
|
||||||
@ -36,7 +42,7 @@ export class SendForwardMsg extends BaseAction<Payload, Response> {
|
|||||||
contextMode = CreatePeerMode.Private
|
contextMode = CreatePeerMode.Private
|
||||||
}
|
}
|
||||||
const peer = await createPeer(this.ctx, payload, contextMode)
|
const peer = await createPeer(this.ctx, payload, contextMode)
|
||||||
const msg = await this.handleForwardNode(peer, payload.messages)
|
const msg = await this.handleForwardNode(peer, messages)
|
||||||
const msgShortId = this.ctx.store.createMsgShortId({ chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId)
|
const msgShortId = this.ctx.store.createMsgShortId({ chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId)
|
||||||
return { message_id: msgShortId }
|
return { message_id: msgShortId }
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { ActionName } from '../types'
|
|||||||
interface Payload {
|
interface Payload {
|
||||||
group_id: number | string
|
group_id: number | string
|
||||||
user_id: number | string
|
user_id: number | string
|
||||||
duration: number
|
duration: number | string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class SetGroupBan extends BaseAction<Payload, null> {
|
export default class SetGroupBan extends BaseAction<Payload, null> {
|
||||||
@ -12,7 +12,7 @@ export default class SetGroupBan extends BaseAction<Payload, null> {
|
|||||||
payloadSchema = Schema.object({
|
payloadSchema = Schema.object({
|
||||||
group_id: Schema.union([Number, String]).required(),
|
group_id: Schema.union([Number, String]).required(),
|
||||||
user_id: Schema.union([Number, String]).required(),
|
user_id: Schema.union([Number, String]).required(),
|
||||||
duration: Schema.number().default(30 * 60)
|
duration: Schema.union([Number, String]).default(30 * 60)
|
||||||
})
|
})
|
||||||
|
|
||||||
protected async _handle(payload: Payload): Promise<null> {
|
protected async _handle(payload: Payload): Promise<null> {
|
||||||
@ -21,7 +21,7 @@ export default class SetGroupBan extends BaseAction<Payload, null> {
|
|||||||
const uid = await this.ctx.ntUserApi.getUidByUin(uin, groupCode)
|
const uid = await this.ctx.ntUserApi.getUidByUin(uin, groupCode)
|
||||||
if (!uid) throw new Error('无法获取用户信息')
|
if (!uid) throw new Error('无法获取用户信息')
|
||||||
await this.ctx.ntGroupApi.banMember(groupCode, [
|
await this.ctx.ntGroupApi.banMember(groupCode, [
|
||||||
{ uid, timeStamp: payload.duration },
|
{ uid, timeStamp: +payload.duration },
|
||||||
])
|
])
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,7 @@ import { GetFriendWithCategory } from './llonebot/GetFriendWithCategory'
|
|||||||
import { UploadGroupFile } from './go-cqhttp/UploadGroupFile'
|
import { UploadGroupFile } from './go-cqhttp/UploadGroupFile'
|
||||||
import { UploadPrivateFile } from './go-cqhttp/UploadPrivateFile'
|
import { UploadPrivateFile } from './go-cqhttp/UploadPrivateFile'
|
||||||
import { GetGroupFileUrl } from './go-cqhttp/GetGroupFileUrl'
|
import { GetGroupFileUrl } from './go-cqhttp/GetGroupFileUrl'
|
||||||
|
import { GetGroupNotice } from './go-cqhttp/GetGroupNotice'
|
||||||
|
|
||||||
export function initActionMap(adapter: Adapter) {
|
export function initActionMap(adapter: Adapter) {
|
||||||
const actionHandlers = [
|
const actionHandlers = [
|
||||||
@ -144,7 +145,8 @@ export function initActionMap(adapter: Adapter) {
|
|||||||
new GetGroupRootFiles(adapter),
|
new GetGroupRootFiles(adapter),
|
||||||
new SendGroupNotice(adapter),
|
new SendGroupNotice(adapter),
|
||||||
new GetGroupFilesByFolder(adapter),
|
new GetGroupFilesByFolder(adapter),
|
||||||
new GetGroupFileUrl(adapter)
|
new GetGroupFileUrl(adapter),
|
||||||
|
new GetGroupNotice(adapter),
|
||||||
]
|
]
|
||||||
const actionMap = new Map<string, BaseAction<any, unknown>>()
|
const actionMap = new Map<string, BaseAction<any, unknown>>()
|
||||||
for (const action of actionHandlers) {
|
for (const action of actionHandlers) {
|
||||||
|
@ -24,6 +24,7 @@ export enum ActionName {
|
|||||||
FetchEmojiLike = 'fetch_emoji_like',
|
FetchEmojiLike = 'fetch_emoji_like',
|
||||||
FetchCustomFace = 'fetch_custom_face',
|
FetchCustomFace = 'fetch_custom_face',
|
||||||
GetFriendMsgHistory = 'get_friend_msg_history',
|
GetFriendMsgHistory = 'get_friend_msg_history',
|
||||||
|
SendForwardMsg = 'send_forward_msg',
|
||||||
// onebot 11
|
// onebot 11
|
||||||
SendLike = 'send_like',
|
SendLike = 'send_like',
|
||||||
GetLoginInfo = 'get_login_info',
|
GetLoginInfo = 'get_login_info',
|
||||||
@ -58,7 +59,6 @@ export enum ActionName {
|
|||||||
ForwardFriendSingleMsg = 'forward_friend_single_msg',
|
ForwardFriendSingleMsg = 'forward_friend_single_msg',
|
||||||
ForwardGroupSingleMsg = 'forward_group_single_msg',
|
ForwardGroupSingleMsg = 'forward_group_single_msg',
|
||||||
// 以下为go-cqhttp api
|
// 以下为go-cqhttp api
|
||||||
GoCQHTTP_SendForwardMsg = 'send_forward_msg',
|
|
||||||
GoCQHTTP_SendGroupForwardMsg = 'send_group_forward_msg',
|
GoCQHTTP_SendGroupForwardMsg = 'send_group_forward_msg',
|
||||||
GoCQHTTP_SendPrivateForwardMsg = 'send_private_forward_msg',
|
GoCQHTTP_SendPrivateForwardMsg = 'send_private_forward_msg',
|
||||||
GoCQHTTP_GetStrangerInfo = 'get_stranger_info',
|
GoCQHTTP_GetStrangerInfo = 'get_stranger_info',
|
||||||
@ -82,5 +82,6 @@ export enum ActionName {
|
|||||||
GoCQHTTP_GetGroupRootFiles = 'get_group_root_files',
|
GoCQHTTP_GetGroupRootFiles = 'get_group_root_files',
|
||||||
GoCQHTTP_SendGroupNotice = '_send_group_notice',
|
GoCQHTTP_SendGroupNotice = '_send_group_notice',
|
||||||
GoCQHTTP_GetGroupFilesByFolder = 'get_group_files_by_folder',
|
GoCQHTTP_GetGroupFilesByFolder = 'get_group_files_by_folder',
|
||||||
GoCQHTTP_GetGroupFileUrl = 'get_group_file_url'
|
GoCQHTTP_GetGroupFileUrl = 'get_group_file_url',
|
||||||
|
GoCQHTTP_GetGroupNotice = '_get_group_notice',
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import {
|
|||||||
GroupNotifyType,
|
GroupNotifyType,
|
||||||
RawMessage,
|
RawMessage,
|
||||||
BuddyReqType,
|
BuddyReqType,
|
||||||
Peer,
|
|
||||||
FriendRequest,
|
FriendRequest,
|
||||||
GroupMember,
|
GroupMember,
|
||||||
GroupMemberRole,
|
GroupMemberRole,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import http from 'node:http'
|
import http from 'node:http'
|
||||||
import cors from 'cors'
|
import cors from 'cors'
|
||||||
import crypto from 'node:crypto'
|
import crypto from 'node:crypto'
|
||||||
import express, { Express, Request, Response } from 'express'
|
import express, { Express, Request, Response, NextFunction } from 'express'
|
||||||
import { BaseAction } from '../action/BaseAction'
|
import { BaseAction } from '../action/BaseAction'
|
||||||
import { Context } from 'cordis'
|
import { Context } from 'cordis'
|
||||||
import { llonebotError, selfInfo } from '@/common/globalVars'
|
import { llonebotError, selfInfo } from '@/common/globalVars'
|
||||||
@ -76,7 +76,7 @@ class OB11Http {
|
|||||||
Object.assign(this.config, config)
|
Object.assign(this.config, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
private authorize(req: Request, res: Response, next: () => void) {
|
private authorize(req: Request, res: Response, next: NextFunction) {
|
||||||
const serverToken = this.config.token
|
const serverToken = this.config.token
|
||||||
if (!serverToken) return next()
|
if (!serverToken) return next()
|
||||||
|
|
||||||
@ -95,12 +95,13 @@ class OB11Http {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (clientToken !== serverToken) {
|
if (clientToken !== serverToken) {
|
||||||
return res.status(403).json({ message: 'token verify failed!' })
|
res.status(403).json({ message: 'token verify failed!' })
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
next()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleRequest(req: Request, res: Response, next: () => void) {
|
private async handleRequest(req: Request, res: Response, next: NextFunction) {
|
||||||
if (req.path === '/') return next()
|
if (req.path === '/') return next()
|
||||||
let payload = req.body
|
let payload = req.body
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
|
@ -1 +1 @@
|
|||||||
export const version = '3.33.9'
|
export const version = '3.33.10'
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
"module": "CommonJS",
|
"module": "CommonJS",
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"isolatedModules": true,
|
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user