mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
feat: SendGroupNotice
This commit is contained in:
parent
18d253edf6
commit
02e5222f92
@ -1,5 +1,6 @@
|
||||
import { RequestUtil } from '@/common/utils/request'
|
||||
import { Service, Context } from 'cordis'
|
||||
import { Dict } from 'cosmokit'
|
||||
|
||||
declare module 'cordis' {
|
||||
interface Context {
|
||||
@ -49,56 +50,6 @@ interface WebApiGroupMemberRet {
|
||||
extmode: number
|
||||
}
|
||||
|
||||
export interface WebApiGroupNoticeFeed {
|
||||
u: number//发送者
|
||||
fid: string//fid
|
||||
pubt: number//时间
|
||||
msg: {
|
||||
text: string
|
||||
text_face: string
|
||||
title: string,
|
||||
pics?: {
|
||||
id: string,
|
||||
w: string,
|
||||
h: string
|
||||
}[]
|
||||
}
|
||||
type: number
|
||||
fn: number
|
||||
cn: number
|
||||
vn: number
|
||||
settings: {
|
||||
is_show_edit_card: number
|
||||
remind_ts: number
|
||||
tip_window_type: number
|
||||
confirm_required: number
|
||||
}
|
||||
read_num: number
|
||||
is_read: number
|
||||
is_all_confirm: number
|
||||
}
|
||||
|
||||
export interface WebApiGroupNoticeRet {
|
||||
ec: number
|
||||
em: string
|
||||
ltsm: number
|
||||
srv_code: number
|
||||
read_only: number
|
||||
role: number
|
||||
feeds: WebApiGroupNoticeFeed[]
|
||||
group: {
|
||||
group_id: number
|
||||
class_ext: number
|
||||
}
|
||||
sta: number,
|
||||
gln: number
|
||||
tst: number,
|
||||
ui: any
|
||||
server_time: number
|
||||
svrt: number
|
||||
ad: number
|
||||
}
|
||||
|
||||
interface GroupEssenceMsg {
|
||||
group_code: string
|
||||
msg_seq: number
|
||||
@ -124,6 +75,30 @@ export interface GroupEssenceMsgRet {
|
||||
}
|
||||
}
|
||||
|
||||
interface SetGroupNoticeParams {
|
||||
groupCode: string
|
||||
content: string
|
||||
pinned: number
|
||||
type: number
|
||||
isShowEditCard: number
|
||||
tipWindowType: number
|
||||
confirmRequired: number
|
||||
picId: string
|
||||
imgWidth?: number
|
||||
imgHeight?: number
|
||||
}
|
||||
|
||||
interface SetGroupNoticeRet {
|
||||
ec: number
|
||||
em: string
|
||||
id: number
|
||||
ltsm: number
|
||||
new_fid: string
|
||||
read_only: number
|
||||
role: number
|
||||
srv_code: number
|
||||
}
|
||||
|
||||
export class NTQQWebApi extends Service {
|
||||
static inject = ['ntUserApi']
|
||||
|
||||
@ -134,7 +109,7 @@ export class NTQQWebApi extends Service {
|
||||
async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> {
|
||||
const memberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>()
|
||||
const cookieObject = await this.ctx.ntUserApi.getCookies('qun.qq.com')
|
||||
const cookieStr = Object.entries(cookieObject).map(([key, value]) => `${key}=${value}`).join('; ')
|
||||
const cookieStr = this.cookieToString(cookieObject)
|
||||
const retList: Promise<WebApiGroupMemberRet>[] = []
|
||||
const params = new URLSearchParams({
|
||||
st: '0',
|
||||
@ -173,49 +148,47 @@ export class NTQQWebApi extends Service {
|
||||
}
|
||||
|
||||
genBkn(sKey: string) {
|
||||
sKey = sKey || '';
|
||||
let hash = 5381;
|
||||
|
||||
sKey = sKey || ''
|
||||
let hash = 5381
|
||||
for (let i = 0; i < sKey.length; i++) {
|
||||
const code = sKey.charCodeAt(i);
|
||||
hash = hash + (hash << 5) + code;
|
||||
const code = sKey.charCodeAt(i)
|
||||
hash = hash + (hash << 5) + code
|
||||
}
|
||||
|
||||
return (hash & 0x7FFFFFFF).toString();
|
||||
return (hash & 0x7FFFFFFF).toString()
|
||||
}
|
||||
|
||||
//实现未缓存 考虑2h缓存
|
||||
async getGroupHonorInfo(groupCode: string, getType: WebHonorType) {
|
||||
const getDataInternal = async (Internal_groupCode: string, Internal_type: number) => {
|
||||
let url = 'https://qun.qq.com/interactive/honorlist?gc=' + Internal_groupCode + '&type=' + Internal_type.toString();
|
||||
let res = '';
|
||||
let resJson;
|
||||
let url = 'https://qun.qq.com/interactive/honorlist?gc=' + Internal_groupCode + '&type=' + Internal_type.toString()
|
||||
let res = ''
|
||||
let resJson
|
||||
try {
|
||||
res = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': cookieStr });
|
||||
const match = res.match(/window\.__INITIAL_STATE__=(.*?);/);
|
||||
res = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': cookieStr })
|
||||
const match = res.match(/window\.__INITIAL_STATE__=(.*?);/)
|
||||
if (match) {
|
||||
resJson = JSON.parse(match[1].trim());
|
||||
resJson = JSON.parse(match[1].trim())
|
||||
}
|
||||
if (Internal_type === 1) {
|
||||
return resJson?.talkativeList;
|
||||
return resJson?.talkativeList
|
||||
} else {
|
||||
return resJson?.actorList;
|
||||
return resJson?.actorList
|
||||
}
|
||||
} catch (e) {
|
||||
this.ctx.logger.error('获取当前群荣耀失败', url, e);
|
||||
this.ctx.logger.error('获取当前群荣耀失败', url, e)
|
||||
}
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
|
||||
let HonorInfo: any = { group_id: groupCode };
|
||||
let HonorInfo: any = { group_id: groupCode }
|
||||
const cookieObject = await this.ctx.ntUserApi.getCookies('qun.qq.com')
|
||||
const cookieStr = Object.entries(cookieObject).map(([key, value]) => `${key}=${value}`).join('; ')
|
||||
const cookieStr = this.cookieToString(cookieObject)
|
||||
|
||||
if (getType === WebHonorType.TALKACTIVE || getType === WebHonorType.ALL) {
|
||||
try {
|
||||
let RetInternal = await getDataInternal(groupCode, 1);
|
||||
let RetInternal = await getDataInternal(groupCode, 1)
|
||||
if (!RetInternal) {
|
||||
throw new Error('获取龙王信息失败');
|
||||
throw new Error('获取龙王信息失败')
|
||||
}
|
||||
HonorInfo.current_talkative = {
|
||||
user_id: RetInternal[0]?.uin,
|
||||
@ -232,17 +205,17 @@ export class NTQQWebApi extends Service {
|
||||
description: talkative_ele?.desc,
|
||||
day_count: 0,
|
||||
nickname: talkative_ele?.name
|
||||
});
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
this.ctx.logger.error(e);
|
||||
this.ctx.logger.error(e)
|
||||
}
|
||||
}
|
||||
if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) {
|
||||
try {
|
||||
let RetInternal = await getDataInternal(groupCode, 2);
|
||||
let RetInternal = await getDataInternal(groupCode, 2)
|
||||
if (!RetInternal) {
|
||||
throw new Error('获取群聊之火失败');
|
||||
throw new Error('获取群聊之火失败')
|
||||
}
|
||||
HonorInfo.performer_list = [];
|
||||
for (const performer_ele of RetInternal) {
|
||||
@ -251,54 +224,86 @@ export class NTQQWebApi extends Service {
|
||||
nickname: performer_ele?.name,
|
||||
avatar: performer_ele?.avatar,
|
||||
description: performer_ele?.desc
|
||||
});
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
this.ctx.logger.error(e);
|
||||
this.ctx.logger.error(e)
|
||||
}
|
||||
}
|
||||
if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) {
|
||||
try {
|
||||
let RetInternal = await getDataInternal(groupCode, 3);
|
||||
let RetInternal = await getDataInternal(groupCode, 3)
|
||||
if (!RetInternal) {
|
||||
throw new Error('获取群聊炽焰失败');
|
||||
throw new Error('获取群聊炽焰失败')
|
||||
}
|
||||
HonorInfo.legend_list = [];
|
||||
HonorInfo.legend_list = []
|
||||
for (const legend_ele of RetInternal) {
|
||||
HonorInfo.legend_list.push({
|
||||
user_id: legend_ele?.uin,
|
||||
nickname: legend_ele?.name,
|
||||
avatar: legend_ele?.avatar,
|
||||
desc: legend_ele?.description
|
||||
});
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
this.ctx.logger.error('获取群聊炽焰失败', e);
|
||||
this.ctx.logger.error('获取群聊炽焰失败', e)
|
||||
}
|
||||
}
|
||||
if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) {
|
||||
try {
|
||||
let RetInternal = await getDataInternal(groupCode, 6);
|
||||
let RetInternal = await getDataInternal(groupCode, 6)
|
||||
if (!RetInternal) {
|
||||
throw new Error('获取快乐源泉失败');
|
||||
throw new Error('获取快乐源泉失败')
|
||||
}
|
||||
HonorInfo.emotion_list = [];
|
||||
HonorInfo.emotion_list = []
|
||||
for (const emotion_ele of RetInternal) {
|
||||
HonorInfo.emotion_list.push({
|
||||
user_id: emotion_ele?.uin,
|
||||
nickname: emotion_ele?.name,
|
||||
avatar: emotion_ele?.avatar,
|
||||
desc: emotion_ele?.description
|
||||
});
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
this.ctx.logger.error('获取快乐源泉失败', e);
|
||||
this.ctx.logger.error('获取快乐源泉失败', e)
|
||||
}
|
||||
}
|
||||
//冒尖小春笋好像已经被tx扬了
|
||||
if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) {
|
||||
HonorInfo.strong_newbie_list = [];
|
||||
HonorInfo.strong_newbie_list = []
|
||||
}
|
||||
return HonorInfo;
|
||||
return HonorInfo
|
||||
}
|
||||
|
||||
async setGroupNotice(params: SetGroupNoticeParams): Promise<SetGroupNoticeRet> {
|
||||
const cookieObject = await this.ctx.ntUserApi.getCookies('qun.qq.com')
|
||||
const settings = JSON.stringify({
|
||||
is_show_edit_card: params.isShowEditCard,
|
||||
tip_window_type: params.tipWindowType,
|
||||
confirm_required: params.confirmRequired
|
||||
})
|
||||
|
||||
return await RequestUtil.HttpGetJson<SetGroupNoticeRet>(
|
||||
`https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?${new URLSearchParams({
|
||||
bkn: this.genBkn(cookieObject.skey),
|
||||
qid: params.groupCode,
|
||||
text: params.content,
|
||||
pinned: params.pinned.toString(),
|
||||
type: params.type.toString(),
|
||||
settings: settings,
|
||||
...(params.picId !== '' && {
|
||||
pic: params.picId,
|
||||
imgWidth: params.imgWidth?.toString(),
|
||||
imgHeight: params.imgHeight?.toString(),
|
||||
})
|
||||
})}`,
|
||||
'POST',
|
||||
'',
|
||||
{ 'Cookie': this.cookieToString(cookieObject) }
|
||||
)
|
||||
}
|
||||
|
||||
private cookieToString(cookieObject: Dict) {
|
||||
return Object.entries(cookieObject).map(([key, value]) => `${key}=${value}`).join('; ')
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ declare module 'cordis' {
|
||||
}
|
||||
|
||||
class Core extends Service {
|
||||
static inject = ['ntMsgApi', 'ntFileApi', 'ntFileCacheApi', 'ntFriendApi', 'ntGroupApi', 'ntUserApi', 'ntWindowApi']
|
||||
static inject = ['ntMsgApi', 'ntFriendApi', 'ntGroupApi']
|
||||
|
||||
constructor(protected ctx: Context, public config: Core.Config) {
|
||||
super(ctx, 'app', true)
|
||||
|
37
src/onebot11/action/go-cqhttp/SendGroupNotice.ts
Normal file
37
src/onebot11/action/go-cqhttp/SendGroupNotice.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import BaseAction from '../BaseAction'
|
||||
import { ActionName } from '../types'
|
||||
|
||||
interface Payload {
|
||||
group_id: number | string
|
||||
content: string
|
||||
image?: string
|
||||
pinned?: number | string //扩展
|
||||
confirm_required?: number | string //扩展
|
||||
}
|
||||
|
||||
export class SendGroupNotice extends BaseAction<Payload, null> {
|
||||
actionName = ActionName.GoCQHTTP_SendGroupNotice
|
||||
|
||||
async _handle(payload: Payload) {
|
||||
const type = 1
|
||||
const isShowEditCard = 0
|
||||
const tipWindowType = 0
|
||||
const pinned = Number(payload.pinned ?? 0)
|
||||
const confirmRequired = Number(payload.confirm_required ?? 1)
|
||||
|
||||
const result = await this.ctx.ntWebApi.setGroupNotice({
|
||||
groupCode: payload.group_id.toString(),
|
||||
content: payload.content,
|
||||
pinned,
|
||||
type,
|
||||
isShowEditCard,
|
||||
tipWindowType,
|
||||
confirmRequired,
|
||||
picId: ''
|
||||
})
|
||||
if (result.ec !== 0) {
|
||||
throw new Error(`设置群公告失败, 错误信息: ${result.em}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
@ -61,6 +61,7 @@ import { DelGroupFolder } from './go-cqhttp/DelGroupFolder'
|
||||
import { GetGroupAtAllRemain } from './go-cqhttp/GetGroupAtAllRemain'
|
||||
import { GetGroupRootFiles } from './go-cqhttp/GetGroupRootFiles'
|
||||
import { SetOnlineStatus } from './llonebot/SetOnlineStatus'
|
||||
import { SendGroupNotice } from './go-cqhttp/SendGroupNotice'
|
||||
|
||||
export function initActionMap(adapter: Adapter) {
|
||||
const actionHandlers = [
|
||||
@ -128,7 +129,8 @@ export function initActionMap(adapter: Adapter) {
|
||||
new CreateGroupFileFolder(adapter),
|
||||
new DelGroupFolder(adapter),
|
||||
new GetGroupAtAllRemain(adapter),
|
||||
new GetGroupRootFiles(adapter)
|
||||
new GetGroupRootFiles(adapter),
|
||||
new SendGroupNotice(adapter)
|
||||
]
|
||||
const actionMap = new Map<string, BaseAction<any, any>>()
|
||||
for (const action of actionHandlers) {
|
||||
|
@ -79,5 +79,6 @@ export enum ActionName {
|
||||
GoCQHTTP_CreateGroupFileFolder = 'create_group_file_folder',
|
||||
GoCQHTTP_DelGroupFolder = 'delete_group_folder',
|
||||
GoCQHTTP_GetGroupAtAllRemain = 'get_group_at_all_remain',
|
||||
GoCQHTTP_GetGroupRootFiles = 'get_group_root_files'
|
||||
GoCQHTTP_GetGroupRootFiles = 'get_group_root_files',
|
||||
GoCQHTTP_SendGroupNotice = '_send_group_notice',
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ declare module 'cordis' {
|
||||
}
|
||||
|
||||
class OneBot11Adapter extends Service {
|
||||
static inject = ['ntMsgApi', 'ntFileApi', 'ntFileCacheApi', 'ntFriendApi', 'ntGroupApi', 'ntUserApi', 'ntWindowApi']
|
||||
static inject = ['ntMsgApi', 'ntFileApi', 'ntFileCacheApi', 'ntFriendApi', 'ntGroupApi', 'ntUserApi', 'ntWindowApi', 'ntWebApi']
|
||||
|
||||
public messages: Map<string, RawMessage> = new Map()
|
||||
public startTime = 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user