mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-12-19 13:10:16 +08:00
Add group album media actions and API integration
Introduces new OneBot actions for group album media: listing, commenting, liking, and deleting. Adds supporting API methods and data structures for album media operations in NTQQWebApi and NodeIKernelAlbumService. Updates action router and index to register new actions.
This commit is contained in:
parent
f5052935bd
commit
75d26465f1
@ -12,6 +12,7 @@ import { createReadStream, readFileSync, statSync } from 'node:fs';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { basename } from 'node:path';
|
||||
import { qunAlbumControl } from '../data/webapi';
|
||||
import { createAlbumCommentRequest, createAlbumFeedPublish, createAlbumMediaFeed } from '../data/album';
|
||||
export class NTQQWebApi {
|
||||
context: InstanceContext;
|
||||
core: NapCatCore;
|
||||
@ -443,4 +444,73 @@ export class NTQQWebApi {
|
||||
if (!session) throw new Error('创建群相册会话失败');
|
||||
await this.uploadQunAlbumSlice(path, session, skey, pskey, uin, 16384);
|
||||
}
|
||||
async getAlbumMediaListByNTQQ(gc: string, albumId: string, attach_info: string = '') {
|
||||
return (await this.context.session.getAlbumService().getMediaList({
|
||||
qun_id: gc,
|
||||
attach_info: attach_info,
|
||||
seq: 0,
|
||||
request_time_line: {
|
||||
request_invoke_time: "0"
|
||||
},
|
||||
album_id: albumId,
|
||||
lloc: '',
|
||||
batch_id: ''
|
||||
})).response;
|
||||
}
|
||||
|
||||
async doAlbumMediaPlainCommentByNTQQ(
|
||||
qunId: string,
|
||||
albumId: string,
|
||||
lloc: string,
|
||||
content: string) {
|
||||
const random_seq = Math.floor(Math.random() * 9000) + 1000;
|
||||
const uin = this.core.selfInfo.uin || '10001';
|
||||
//16位number数字
|
||||
const client_key = Date.now() * 1000
|
||||
return await this.context.session.getAlbumService().doQunComment(
|
||||
random_seq, {
|
||||
map_info: [],
|
||||
map_bytes_info: [],
|
||||
map_user_account: []
|
||||
},
|
||||
qunId,
|
||||
2,
|
||||
createAlbumMediaFeed(uin, albumId, lloc),
|
||||
createAlbumCommentRequest(uin, content, client_key)
|
||||
);
|
||||
}
|
||||
|
||||
async deleteAlbumMediaByNTQQ(
|
||||
qunId: string,
|
||||
albumId: string,
|
||||
lloc: string) {
|
||||
const random_seq = Math.floor(Math.random() * 9000) + 1000;
|
||||
return await this.context.session.getAlbumService().deleteMedias(
|
||||
random_seq,
|
||||
qunId,
|
||||
albumId,
|
||||
[lloc],
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
async doAlbumMediaLikeByNTQQ(
|
||||
qunId: string,
|
||||
albumId: string,
|
||||
lloc: string,
|
||||
id: string) {
|
||||
const random_seq = Math.floor(Math.random() * 9000) + 1000;
|
||||
const uin = this.core.selfInfo.uin || '10001';
|
||||
return await this.context.session.getAlbumService().doQunLike(
|
||||
random_seq, {
|
||||
map_info: [],
|
||||
map_bytes_info: [],
|
||||
map_user_account: []
|
||||
}, {
|
||||
id: id,
|
||||
status: 1
|
||||
},
|
||||
createAlbumFeedPublish(qunId, uin, albumId, lloc)
|
||||
)
|
||||
}
|
||||
}
|
||||
221
src/core/data/album.ts
Normal file
221
src/core/data/album.ts
Normal file
@ -0,0 +1,221 @@
|
||||
/**
|
||||
* 群相册列表请求参数接口
|
||||
*/
|
||||
export interface AlbumListRequest {
|
||||
qun_id: string;
|
||||
attach_info: string;
|
||||
seq: number;
|
||||
request_time_line: {
|
||||
request_invoke_time: string;
|
||||
};
|
||||
album_id: string;
|
||||
lloc: string;
|
||||
batch_id: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建群相册列表请求参数
|
||||
* @param qunId 群号
|
||||
* @param albumId 相册ID
|
||||
* @param seq 请求序列号,默认值为0
|
||||
* @returns 请求参数对象
|
||||
*/
|
||||
export function createAlbumListRequest(
|
||||
qunId: string,
|
||||
albumId: string,
|
||||
seq: number = 0
|
||||
): AlbumListRequest {
|
||||
return {
|
||||
qun_id: qunId,
|
||||
attach_info: "",
|
||||
seq: seq,
|
||||
request_time_line: {
|
||||
request_invoke_time: "0"
|
||||
},
|
||||
album_id: albumId,
|
||||
lloc: "",
|
||||
batch_id: ""
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 相册媒体项请求接口
|
||||
*/
|
||||
export interface AlbumMediaFeed {
|
||||
cell_common: {
|
||||
time: string;
|
||||
};
|
||||
cell_user_info: {
|
||||
user: {
|
||||
uin: string;
|
||||
};
|
||||
};
|
||||
cell_media: {
|
||||
album_id: string;
|
||||
batch_id: string;
|
||||
media_items: Array<{
|
||||
image: {
|
||||
lloc: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建相册媒体请求参数
|
||||
* @param uin 用户QQ号
|
||||
* @param albumId 相册ID
|
||||
* @param lloc
|
||||
* @returns 媒体请求参数对象
|
||||
*/
|
||||
export function createAlbumMediaFeed(
|
||||
uin: string,
|
||||
albumId: string,
|
||||
lloc: string
|
||||
): AlbumMediaFeed {
|
||||
return {
|
||||
cell_common: {
|
||||
time: ""
|
||||
},
|
||||
cell_user_info: {
|
||||
user: {
|
||||
uin: uin
|
||||
}
|
||||
},
|
||||
cell_media: {
|
||||
album_id: albumId,
|
||||
batch_id: "",
|
||||
media_items: [{
|
||||
image: {
|
||||
lloc: lloc
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 相册评论内容接口
|
||||
*/
|
||||
export interface AlbumCommentContent {
|
||||
type: number;
|
||||
content: string;
|
||||
who: number;
|
||||
uid: string;
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 相册评论请求接口
|
||||
*/
|
||||
export interface AlbumCommentReplyContent {
|
||||
client_key: number;
|
||||
content: AlbumCommentContent[];
|
||||
user: {
|
||||
uin: string;
|
||||
};
|
||||
}
|
||||
export enum RichMsgType {
|
||||
KRICHMSGTYPEPLAINTEXT,
|
||||
KRICHMSGTYPEAT,
|
||||
KRICHMSGTYPEURL,
|
||||
KRICHMSGTYPEMEDIA
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建相册评论请求参数
|
||||
* @param uin 用户QQ号
|
||||
* @param content 评论内容
|
||||
* @param client_key 客户端鉴权密钥
|
||||
* @returns 评论请求参数对象
|
||||
*/
|
||||
export function createAlbumCommentRequest(
|
||||
uin: string,
|
||||
content: string,
|
||||
client_key: number
|
||||
): AlbumCommentReplyContent {
|
||||
return {
|
||||
client_key: client_key,
|
||||
//暂时只支持纯文本吧
|
||||
content: [{
|
||||
type: RichMsgType.KRICHMSGTYPEPLAINTEXT,
|
||||
content: content,
|
||||
who: 0,
|
||||
uid: "",
|
||||
name: "",
|
||||
url: ""
|
||||
}],
|
||||
user: {
|
||||
uin: uin
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export interface AlbumFeedLikePublish {
|
||||
cell_common: {
|
||||
time: number;
|
||||
feed_id: string;
|
||||
};
|
||||
cell_user_info: {
|
||||
user: {
|
||||
uin: string;
|
||||
};
|
||||
};
|
||||
cell_media: {
|
||||
album_id: string;
|
||||
batch_id: number;
|
||||
media_items: Array<{
|
||||
type: number;
|
||||
image: {
|
||||
lloc: string;
|
||||
sloc: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
cell_qun_info: {
|
||||
qun_id: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建相册动态发布请求参数
|
||||
* @param qunId 群号
|
||||
* @param uin 用户QQ号
|
||||
* @param albumId 相册ID
|
||||
* @param lloc 信息
|
||||
* @param sloc 信息(可选,默认与lloc相同)
|
||||
* @returns 动态发布请求参数对象
|
||||
*/
|
||||
export function createAlbumFeedPublish(
|
||||
qunId: string,
|
||||
uin: string,
|
||||
albumId: string,
|
||||
lloc: string,
|
||||
sloc?: string
|
||||
): AlbumFeedLikePublish {
|
||||
return {
|
||||
cell_common: {
|
||||
time: Date.now(),
|
||||
feed_id: ""
|
||||
},
|
||||
cell_user_info: {
|
||||
user: {
|
||||
uin: uin
|
||||
}
|
||||
},
|
||||
cell_media: {
|
||||
album_id: albumId,
|
||||
batch_id: 0,
|
||||
media_items: [{
|
||||
type: 0,
|
||||
image: {
|
||||
lloc: lloc,
|
||||
sloc: sloc || lloc
|
||||
}
|
||||
}]
|
||||
},
|
||||
cell_qun_info: {
|
||||
qun_id: qunId
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
import { AlbumCommentReplyContent, AlbumFeedLikePublish, AlbumListRequest, AlbumMediaFeed } from "../data/album";
|
||||
|
||||
export interface NodeIKernelAlbumService {
|
||||
|
||||
setAlbumServiceInfo(...args: unknown[]): unknown;// needs 3 arguments
|
||||
@ -19,7 +21,7 @@ export interface NodeIKernelAlbumService {
|
||||
trace_id: string,
|
||||
is_from_cache: boolean,
|
||||
request_time_line: unknown,
|
||||
album_list: Array<unknown>,
|
||||
album_list: Array<{ name: string, album_id: string }>,
|
||||
attach_info: string,
|
||||
has_more: boolean,
|
||||
right: unknown,
|
||||
@ -32,11 +34,19 @@ export interface NodeIKernelAlbumService {
|
||||
|
||||
addAlbum(...args: unknown[]): unknown;// needs 2 arguments
|
||||
|
||||
deleteMedias(...args: unknown[]): unknown;// needs 4 arguments
|
||||
deleteMedias(seq: number, group_code: string, album_id: string, media_ids: string[], ban_ids: unknown[]): Promise<unknown>;// needs 4 arguments
|
||||
|
||||
modifyAlbum(...args: unknown[]): unknown;// needs 3 arguments
|
||||
|
||||
getMediaList(...args: unknown[]): unknown;// needs 1 arguments
|
||||
getMediaList(param: AlbumListRequest): Promise<{
|
||||
response: {
|
||||
seq: number,
|
||||
result: number,
|
||||
errMs: string,//没错就是errMs不是errMsg
|
||||
trace_id: string,
|
||||
request_time_line: unknown,
|
||||
}
|
||||
}>;// needs 1 arguments
|
||||
|
||||
quoteToQzone(...args: unknown[]): unknown;// needs 1 arguments
|
||||
|
||||
@ -55,12 +65,36 @@ export interface NodeIKernelAlbumService {
|
||||
getQunLikes(...args: unknown[]): unknown;// needs 4 arguments
|
||||
|
||||
deleteQunFeed(...args: unknown[]): unknown;// needs 1 arguments
|
||||
|
||||
doQunComment(...args: unknown[]): unknown;// needs 6 arguments
|
||||
//seq random
|
||||
//stCommonExt {"map_info":[],"map_bytes_info":[],"map_user_account":[]}
|
||||
//qunId string
|
||||
doQunComment(seq: number, ext: {
|
||||
map_info: unknown[],
|
||||
map_bytes_info: unknown[],
|
||||
map_user_account: unknown[]
|
||||
},
|
||||
qunId: string,
|
||||
commentType: number,
|
||||
feed: AlbumMediaFeed,
|
||||
content: AlbumCommentReplyContent,
|
||||
): Promise<unknown>;// needs 6 arguments
|
||||
|
||||
doQunReply(...args: unknown[]): unknown;// needs 7 arguments
|
||||
|
||||
doQunLike(...args: unknown[]): unknown;// needs 5 arguments
|
||||
doQunLike(
|
||||
seq: number,
|
||||
ext: {
|
||||
map_info: unknown[],
|
||||
map_bytes_info: unknown[],
|
||||
map_user_account: unknown[]
|
||||
},
|
||||
param: {
|
||||
//{"id":"421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|V5bCgAxMDEyOTU5MjU3e*KqaLVYdic!^||^421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|17560336594^||^1","status":1}
|
||||
id: string,
|
||||
status: number
|
||||
},
|
||||
like: AlbumFeedLikePublish
|
||||
): Promise<unknown>;// needs 5 arguments
|
||||
|
||||
getRedPoints(...args: unknown[]): unknown;// needs 3 arguments
|
||||
|
||||
|
||||
24
src/onebot/action/extends/DelGroupAlbumMedia.ts
Normal file
24
src/onebot/action/extends/DelGroupAlbumMedia.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||
import { ActionName } from '@/onebot/action/router';
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
|
||||
const SchemaData = Type.Object({
|
||||
group_id: Type.String(),
|
||||
album_id: Type.String(),
|
||||
lloc: Type.String()
|
||||
});
|
||||
|
||||
type Payload = Static<typeof SchemaData>;
|
||||
|
||||
export class DelGroupAlbumMedia extends OneBotAction<Payload, unknown> {
|
||||
override actionName = ActionName.DelGroupAlbumMedia;
|
||||
override payloadSchema = SchemaData;
|
||||
|
||||
async _handle(payload: Payload) {
|
||||
return await this.core.apis.WebApi.deleteAlbumMediaByNTQQ(
|
||||
payload.group_id,
|
||||
payload.album_id,
|
||||
payload.lloc
|
||||
);
|
||||
}
|
||||
}
|
||||
26
src/onebot/action/extends/DoGroupAlbumComment.ts
Normal file
26
src/onebot/action/extends/DoGroupAlbumComment.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||
import { ActionName } from '@/onebot/action/router';
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
|
||||
const SchemaData = Type.Object({
|
||||
group_id: Type.String(),
|
||||
album_id: Type.String(),
|
||||
lloc: Type.String(),
|
||||
content: Type.String(),
|
||||
});
|
||||
|
||||
type Payload = Static<typeof SchemaData>;
|
||||
|
||||
export class DoGroupAlbumComment extends OneBotAction<Payload, unknown> {
|
||||
override actionName = ActionName.DoGroupAlbumComment;
|
||||
override payloadSchema = SchemaData;
|
||||
|
||||
async _handle(payload: Payload) {
|
||||
return await this.core.apis.WebApi.doAlbumMediaPlainCommentByNTQQ(
|
||||
payload.group_id,
|
||||
payload.album_id,
|
||||
payload.lloc,
|
||||
payload.content
|
||||
);
|
||||
}
|
||||
}
|
||||
24
src/onebot/action/extends/GetGroupAlbumMediaList.ts
Normal file
24
src/onebot/action/extends/GetGroupAlbumMediaList.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||
import { ActionName } from '@/onebot/action/router';
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
|
||||
const SchemaData = Type.Object({
|
||||
group_id: Type.String(),
|
||||
album_id: Type.String(),
|
||||
attach_info: Type.String({ default: "" }),
|
||||
});
|
||||
|
||||
type Payload = Static<typeof SchemaData>;
|
||||
|
||||
export class GetGroupAlbumMediaList extends OneBotAction<Payload, unknown> {
|
||||
override actionName = ActionName.GetGroupAlbumMediaList;
|
||||
override payloadSchema = SchemaData;
|
||||
|
||||
async _handle(payload: Payload) {
|
||||
return await this.core.apis.WebApi.getAlbumMediaListByNTQQ(
|
||||
payload.group_id,
|
||||
payload.album_id,
|
||||
payload.attach_info
|
||||
);
|
||||
}
|
||||
}
|
||||
27
src/onebot/action/extends/SetGroupAlbumMediaLike.ts
Normal file
27
src/onebot/action/extends/SetGroupAlbumMediaLike.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||
import { ActionName } from '@/onebot/action/router';
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
|
||||
const SchemaData = Type.Object({
|
||||
group_id: Type.String(),
|
||||
album_id: Type.String(),
|
||||
lloc: Type.String(),
|
||||
id: Type.String(),//421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|V5bCgAxMDEyOTU5MjU3.PyqaPndPxg!^||^421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|17560363448^||^1
|
||||
set: Type.Boolean({default: true})//true=点赞 false=取消点赞 未实现
|
||||
});
|
||||
|
||||
type Payload = Static<typeof SchemaData>;
|
||||
|
||||
export class SetGroupAlbumMediaLike extends OneBotAction<Payload, unknown> {
|
||||
override actionName = ActionName.SetGroupAlbumMediaLike;
|
||||
override payloadSchema = SchemaData;
|
||||
|
||||
async _handle(payload: Payload) {
|
||||
return await this.core.apis.WebApi.doAlbumMediaLikeByNTQQ(
|
||||
payload.group_id,
|
||||
payload.album_id,
|
||||
payload.lloc,
|
||||
payload.id
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -126,10 +126,18 @@ import { GetCollectionList } from './extends/GetCollectionList';
|
||||
import { SetGroupTodo } from './packet/SetGroupTodo';
|
||||
import { GetQunAlbumList } from './extends/GetQunAlbumList';
|
||||
import { UploadImageToQunAlbum } from './extends/UploadImageToQunAlbum';
|
||||
import { DoGroupAlbumComment } from './extends/DoGroupAlbumComment';
|
||||
import { GetGroupAlbumMediaList } from './extends/GetGroupAlbumMediaList';
|
||||
import { SetGroupAlbumMediaLike } from './extends/SetGroupAlbumMediaLike';
|
||||
import { DelGroupAlbumMedia } from './extends/DelGroupAlbumMedia';
|
||||
|
||||
export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore) {
|
||||
|
||||
const actionHandlers = [
|
||||
new DelGroupAlbumMedia(obContext, core),
|
||||
new SetGroupAlbumMediaLike(obContext, core),
|
||||
new DoGroupAlbumComment(obContext, core),
|
||||
new GetGroupAlbumMediaList(obContext, core),
|
||||
new GetQunAlbumList(obContext, core),
|
||||
new UploadImageToQunAlbum(obContext, core),
|
||||
new SetGroupTodo(obContext, core),
|
||||
|
||||
@ -10,6 +10,10 @@ export interface InvalidCheckResult {
|
||||
}
|
||||
|
||||
export const ActionName = {
|
||||
DelGroupAlbumMedia: 'del_group_album_media',
|
||||
SetGroupAlbumMediaLike: 'set_group_album_media_like',
|
||||
DoGroupAlbumComment: 'do_group_album_comment',
|
||||
GetGroupAlbumMediaList: 'get_group_album_media_list',
|
||||
UploadImageToQunAlbum: 'upload_image_to_qun_album',
|
||||
GetQunAlbumList: 'get_qun_album_list',
|
||||
SetGroupTodo: 'set_group_todo',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user