NapCatQQ source snapshot
Build NapCat Artifacts / Type Check & Test (push) Waiting to run
Release Tag / validate-version (push) Waiting to run

This commit is contained in:
TanTan committed 2026-11-13 09:01:47 +08:00
commit f954252a34
1111 files changed
+139867

No files matched your search

@@ -0,0 +1,58 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { MessageUnique } from 'napcat-common/src/message-unique';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
message_id: Type.Optional(Type.Union([Type.Number(), Type.String()], { description: '消息ID' })),
msg_seq: Type.Optional(Type.String({ description: '消息序号' })),
msg_random: Type.Optional(Type.String({ description: '消息随机数' })),
group_id: Type.Optional(Type.String({ description: '群号' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Any({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class DelEssenceMsg extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.DelEssenceMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '移出精华消息';
override actionDescription = '将一条消息从群精华消息列表中移出';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.DelEssenceMsg.payload;
override returnExample = GroupActionsExamples.DelEssenceMsg.response;
async _handle (payload: PayloadType): Promise<ReturnType> {
// 如果直接提供了 msg_seq, msg_random, group_id,优先使用
if (payload.msg_seq && payload.msg_random && payload.group_id) {
return await this.core.apis.GroupApi.removeGroupEssenceBySeq(
payload.group_id,
payload.msg_random,
payload.msg_seq
);
}
// 如果没有 message_id,则必须提供 msg_seq, msg_random, group_id
if (!payload.message_id) {
throw new Error('必须提供 message_id 或者同时提供 msg_seq, msg_random, group_id');
}
const msg = MessageUnique.getMsgIdAndPeerByShortId(+payload.message_id);
if (!msg) {
const data = this.core.apis.GroupApi.essenceLRU.getValue(+payload.message_id);
if (!data) throw new Error('消息不存在');
const { msg_seq, msg_random, group_id } = JSON.parse(data) as { msg_seq: string, msg_random: string, group_id: string; };
return await this.core.apis.GroupApi.removeGroupEssenceBySeq(group_id, msg_random, msg_seq);
}
return await this.core.apis.GroupApi.removeGroupEssence(
msg.Peer.peerUid,
msg.MsgId
);
}
}
@@ -0,0 +1,33 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
notice_id: Type.String({ description: '公告ID' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Any({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export class DelGroupNotice extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.DelGroupNotice;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '删除群公告';
override actionDescription = '删除群聊中的公告';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.DelGroupNotice.payload;
override returnExample = GroupActionsExamples.DelGroupNotice.response;
async _handle (payload: PayloadType) {
const group = payload.group_id.toString();
const noticeId = payload.notice_id;
return await this.core.apis.GroupApi.deleteGroupBulletin(group, noticeId);
}
}
@@ -0,0 +1,40 @@
import { ActionName } from '@/napcat-onebot/action/router';
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
import { AIVoiceChatType } from 'napcat-core/packet/entities/aiChat';
import { Static, Type } from '@sinclair/typebox';
const PayloadSchema = Type.Object({
character: Type.String({ description: '角色ID' }),
group_id: Type.String({ description: '群号' }),
text: Type.String({ description: '语音文本内容' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.String({ description: '语音URL' });
type ReturnType = Static<typeof ReturnSchema>;
export class GetAiRecord extends GetPacketStatusDepends<PayloadType, ReturnType> {
override actionName = ActionName.GetAiRecord;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取 AI 语音';
override actionDescription = '通过 AI 语音引擎获取指定文本的语音 URL';
override actionTags = ['AI 扩展'];
override payloadExample = {
character: 'ai_char_1',
group_id: '123456',
text: '你好',
};
override returnExample = 'http://example.com/ai_voice.silk';
async _handle (payload: PayloadType) {
const rawRsp = await this.core.apis.PacketApi.pkt.operation.GetAiVoice(+payload.group_id, payload.character, payload.text, AIVoiceChatType.Sound);
if (!rawRsp.msgInfoBody[0]) {
throw new Error('No voice data');
}
return await this.core.apis.PacketApi.pkt.operation.GetGroupPttUrl(+payload.group_id, rawRsp.msgInfoBody[0].index);
}
}
@@ -0,0 +1,46 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Object({
group_id: Type.Number({ description: '群号' }),
group_name: Type.String({ description: '群名称' }),
member_count: Type.Number({ description: '成员数量' }),
max_member_count: Type.Number({ description: '最大成员数量' }),
group_all_shut: Type.Number({ description: '全员禁言状态' }),
group_remark: Type.String({ description: '群备注' }),
}, { description: '群详细信息' });
type ReturnType = Static<typeof ReturnSchema>;
export class GetGroupDetailInfo extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupDetailInfo;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取群详细信息';
override actionDescription = '获取群聊的详细信息,包括成员数、最大成员数等';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.GetGroupDetailInfo.payload;
override returnExample = GroupActionsExamples.GetGroupDetailInfo.response;
async _handle (payload: PayloadType): Promise<ReturnType> {
const data = await this.core.apis.GroupApi.fetchGroupDetail(payload.group_id.toString());
return {
...data,
group_all_shut: data.shutUpAllTimestamp > 0 ? -1 : 0,
group_remark: '',
group_id: +payload.group_id,
group_name: data.groupName,
member_count: data.memberNum,
max_member_count: data.maxMemberNum,
};
}
}
@@ -0,0 +1,132 @@
import { ChatType, Peer } from 'napcat-core';
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { MessageUnique } from 'napcat-common/src/message-unique';
import crypto from 'crypto';
import { Static, Type } from '@sinclair/typebox';
import { NetworkAdapterConfig } from '@/napcat-onebot/config/config';
import { OB11MessageData, OB11MessageDataType } from '@/napcat-onebot/types';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Array(Type.Object({
msg_seq: Type.Number({ description: '消息序号' }),
msg_random: Type.Number({ description: '消息随机数' }),
sender_id: Type.Number({ description: '发送者QQ' }),
sender_nick: Type.String({ description: '发送者昵称' }),
operator_id: Type.Number({ description: '操作者QQ' }),
operator_nick: Type.String({ description: '操作者昵称' }),
message_id: Type.Number({ description: '消息ID' }),
operator_time: Type.Number({ description: '操作时间' }),
content: Type.Array(Type.Any(), { description: '消息内容' }),
}), { description: '精华消息列表' });
type ReturnType = Static<typeof ReturnSchema>;
export class GetGroupEssence extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GoCQHTTP_GetEssenceMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取群精华消息';
override actionDescription = '获取指定群聊中的精华消息列表';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.GetGroupEssence.payload;
override returnExample = GroupActionsExamples.GetGroupEssence.response;
private async msgSeqToMsgId (peer: Peer, msgSeq: string, msgRandom: string) {
const replyMsgList = (await this.core.apis.MsgApi.getMsgsBySeqAndCount(peer, msgSeq, 1, true, true)).msgList.find((msg) => msg.msgSeq === msgSeq && msg.msgRandom === msgRandom);
if (!replyMsgList) {
return undefined;
}
return {
id: MessageUnique.createUniqueMsgId(peer, replyMsgList.msgId),
msg: replyMsgList,
};
}
async _handle (payload: PayloadType, _adapter: string, config: NetworkAdapterConfig): Promise<ReturnType> {
const msglist = (await this.core.apis.WebApi.getGroupEssenceMsgAll(payload.group_id.toString()))
.flatMap((e) => e?.data?.msg_list)
// 在群精华回空的时候会出现[null]的情况~ https://github.com/NapNeko/NapCatQQ/issues/1334
.filter(Boolean);
if (!msglist) {
throw new Error('获取失败');
}
return await Promise.all(msglist.map(async (msg) => {
const msgOriginData = await this.msgSeqToMsgId({
chatType: ChatType.KCHATTYPEGROUP,
peerUid: payload.group_id.toString(),
}, msg.msg_seq.toString(), msg.msg_random.toString());
if (msgOriginData) {
const { id: message_id, msg: rawMessage } = msgOriginData;
const parsed = await this.obContext.apis.MsgApi.parseMessage(rawMessage, config.messagePostFormat);
let content: OB11MessageData[] = [];
if (parsed) {
if (Array.isArray(parsed.message)) {
content = parsed.message;
} else {
content = [{ type: OB11MessageDataType.text, data: { text: parsed.message } }];
}
}
return {
msg_seq: msg.msg_seq,
msg_random: msg.msg_random,
sender_id: +msg.sender_uin,
sender_nick: msg.sender_nick,
operator_id: +msg.add_digest_uin,
operator_nick: msg.add_digest_nick,
message_id,
operator_time: msg.add_digest_time,
content,
};
}
const msgTempData = JSON.stringify({
msg_seq: msg.msg_seq.toString(),
msg_random: msg.msg_random.toString(),
group_id: payload.group_id.toString(),
});
const hash = crypto.createHash('md5').update(msgTempData).digest();
// 设置第一个bit为0 保证shortId为正数
if (hash[0]) {
hash[0] &= 0x7f;
}
const shortId = hash.readInt32BE(0);
this.core.apis.GroupApi.essenceLRU.set(shortId, msgTempData);
return {
msg_seq: msg.msg_seq,
msg_random: msg.msg_random,
sender_id: +msg.sender_uin,
sender_nick: msg.sender_nick,
operator_id: +msg.add_digest_uin,
operator_nick: msg.add_digest_nick,
message_id: shortId,
operator_time: msg.add_digest_time,
content: msg.msg_content.map((msg): OB11MessageData | undefined => {
if (msg.msg_type === 1) {
return {
type: OB11MessageDataType.text,
data: {
text: msg?.text ?? '',
},
};
} else if (msg.msg_type === 3) {
return {
type: OB11MessageDataType.image,
data: {
file: '',
url: msg?.image_url,
},
};
}
return undefined;
}).filter((e): e is OB11MessageData => e !== undefined),
};
}));
}
}
@@ -0,0 +1,62 @@
import { GroupNotifyMsgStatus } from 'napcat-core';
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
const PayloadSchema = Type.Object({}, { description: '群忽略通知负载' });
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Object({
invited_requests: Type.Array(Type.Any(), { description: '邀请请求列表' }),
InvitedRequest: Type.Array(Type.Any(), { description: '邀请请求列表' }),
join_requests: Type.Array(Type.Any(), { description: '加入请求列表' }),
}, { description: '群忽略通知结果' });
type ReturnType = Static<typeof ReturnSchema>;
export class GetGroupIgnoredNotifies extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupIgnoredNotifies;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取群忽略通知';
override actionDescription = '获取被忽略的入群申请和邀请通知';
override actionTags = ['群组接口'];
override payloadExample = {};
override returnExample = {
invited_requests: [],
InvitedRequest: [],
join_requests: [],
};
async _handle (): Promise<ReturnType> {
const SingleScreenNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(false, 50);
const retData: ReturnType = { invited_requests: [], InvitedRequest: [], join_requests: [] };
const notifyPromises = SingleScreenNotifies.map(async (SSNotify) => {
const invitorUin = SSNotify.user1?.uid ? +await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1.uid) : 0;
const actorUin = SSNotify.user2?.uid ? +await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2.uid) : 0;
const commonData = {
request_id: +SSNotify.seq,
invitor_uin: invitorUin,
invitor_nick: SSNotify.user1?.nickName,
group_id: +SSNotify.group?.groupCode,
message: SSNotify?.postscript,
group_name: SSNotify.group?.groupName,
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
actor: actorUin,
requester_nick: SSNotify.user1?.nickName,
};
if (SSNotify.type === 1) {
retData.InvitedRequest.push(commonData);
} else if (SSNotify.type === 7) {
retData.join_requests.push(commonData);
}
});
await Promise.all(notifyPromises);
retData.invited_requests = retData.InvitedRequest;
return retData;
}
}
@@ -0,0 +1,50 @@
import { OB11Construct } from '@/napcat-onebot/helper/data';
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { OB11GroupSchema } from '../schemas';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = OB11GroupSchema;
type ReturnType = Static<typeof ReturnSchema>;
class GetGroupInfo extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupInfo;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取群信息';
override actionDescription = '获取群聊的基本信息';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.GetGroupInfo.payload;
override returnExample = GroupActionsExamples.GetGroupInfo.response;
async _handle (payload: PayloadType) {
const group = (await this.core.apis.GroupApi.getGroups()).find(e => e.groupCode === payload.group_id.toString());
if (!group) {
const data = await this.core.apis.GroupApi.fetchGroupDetail(payload.group_id.toString());
if (data.ownerUid && data.ownerUin === '0') {
data.ownerUin = await this.core.apis.UserApi.getUinByUidV2(data.ownerUid);
}
return {
...data,
group_all_shut: data.shutUpAllTimestamp > 0 ? -1 : 0,
group_remark: '',
group_id: +payload.group_id,
group_name: data.groupName,
member_count: data.memberNum,
max_member_count: data.maxMemberNum,
};
}
return OB11Construct.group(group);
}
}
export default GetGroupInfo;
@@ -0,0 +1,35 @@
import { OB11Construct } from '@/napcat-onebot/helper/data';
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { OB11GroupSchema } from '../schemas';
import { GroupActionsExamples } from '@/napcat-onebot/action/example/GroupActionsExamples';
const PayloadSchema = Type.Object({
no_cache: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否不使用缓存' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Array(OB11GroupSchema, { description: '群列表' });
type ReturnType = Static<typeof ReturnSchema>;
class GetGroupList extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取群列表';
override actionDescription = '获取当前帐号的群聊列表';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.GetGroupList.payload;
override returnExample = GroupActionsExamples.GetGroupList.response;
async _handle (payload: PayloadType) {
return OB11Construct.groups(
await this.core.apis.GroupApi.getGroups(
typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache));
}
}
export default GetGroupList;
@@ -0,0 +1,71 @@
import { OB11Construct } from '@/napcat-onebot/helper/data';
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { OB11GroupMemberSchema } from '../schemas';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: 'QQ号' }),
no_cache: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否不使用缓存' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = OB11GroupMemberSchema;
type ReturnType = Static<typeof ReturnSchema>;
class GetGroupMemberInfo extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupMemberInfo;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取群成员信息';
override actionDescription = '获取群聊中指定成员的信息';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.GetGroupMemberInfo.payload;
override returnExample = GroupActionsExamples.GetGroupMemberInfo.response;
private parseBoolean (value: boolean | string): boolean {
return typeof value === 'string' ? value === 'true' : value;
}
private async getUid (userId: string | number): Promise<string> {
const uid = await this.core.apis.UserApi.getUidByUinV2(userId.toString());
if (!uid) throw new Error(`Uin2Uid Error: 用户ID ${userId} 不存在`);
return uid;
}
private async getGroupMemberInfo (payload: PayloadType, isNocache: boolean) {
const groupId = payload.group_id.toString();
// 全局 UIN -> UID 转换可能与目标群的成员记录不一致,优先按 QQ 号在本群查询。
// getGroupMember 会在缓存未命中时刷新一次,避免冷缓存被误判为成员不存在。
const groupMember = await this.core.apis.GroupApi.getGroupMember(groupId, payload.user_id);
const uid = groupMember?.uid || await this.getUid(payload.user_id);
const [member, info] = await Promise.all([
this.core.apis.GroupApi.getGroupMemberEx(groupId, uid, isNocache),
this.core.apis.UserApi.getUserDetailInfo(uid, isNocache).catch((error) => {
this.core.context.logger.logDebug(`获取群成员补充资料失败, 群号: ${groupId}, QQ号: ${payload.user_id}, 错误: ${error}`);
return undefined;
}),
]);
const baseMember = member ?? groupMember;
if (!baseMember) throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在`);
// 个人资料只补充信息,不能覆盖已确认的群成员身份。
return { ...groupMember, ...baseMember, ...info, uid: baseMember.uid, uin: baseMember.uin };
}
async _handle (payload: PayloadType) {
const isNocache = this.parseBoolean(payload.no_cache ?? true);
const member = await this.getGroupMemberInfo(payload, isNocache);
return OB11Construct.groupMember(payload.group_id.toString(), member);
}
}
export default GetGroupMemberInfo;
@@ -0,0 +1,59 @@
import { OB11Construct } from '@/napcat-onebot/helper/data';
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupMember } from 'napcat-core';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
no_cache: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否不使用缓存' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Array(Type.Any(), { description: '群成员列表' });
type ReturnType = Static<typeof ReturnSchema>;
export class GetGroupMemberList extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupMemberList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取群成员列表';
override actionDescription = '获取群聊中的所有成员列表';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.GetGroupMemberList.payload;
override returnExample = GroupActionsExamples.GetGroupMemberList.response;
async _handle (payload: PayloadType) {
const groupIdStr = payload.group_id.toString();
const noCache = this.parseBoolean(payload.no_cache ?? false);
const groupMembers = await this.getGroupMembers(groupIdStr, noCache);
const _groupMembers = await Promise.all(
Array.from(groupMembers.values()).map(item =>
OB11Construct.groupMember(groupIdStr, item)
)
);
return Array.from(new Map(_groupMembers.map(member => [member.user_id, member])).values());
}
private parseBoolean (value: boolean | string): boolean {
return typeof value === 'string' ? value === 'true' : value;
}
private async getGroupMembers (groupIdStr: string, noCache: boolean): Promise<Map<string, GroupMember>> {
const memberCache = this.core.apis.GroupApi.groupMemberCache;
let groupMembers = memberCache.get(groupIdStr);
if (noCache || !groupMembers) {
const data = this.core.apis.GroupApi.refreshGroupMemberCache(groupIdStr, true).then().catch();
groupMembers = memberCache.get(groupIdStr) || (await data);
if (!groupMembers) {
throw new Error(`Failed to get group member list for group ${groupIdStr}`);
}
}
return groupMembers;
}
}
@@ -0,0 +1,89 @@
import { WebApiGroupNoticeFeed } from 'napcat-core';
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Array(Type.Object({
sender_id: Type.Number({ description: '发送者QQ' }),
publish_time: Type.Number({ description: '发布时间' }),
notice_id: Type.String({ description: '公告ID' }),
message: Type.Object({
text: Type.String({ description: '文本内容' }),
image: Type.Array(Type.Any(), { description: '图片列表' }),
images: Type.Array(Type.Any(), { description: '图片列表' }),
}, { description: '公告内容' }),
settings: Type.Optional(Type.Any({ description: '设置项' })),
read_num: Type.Optional(Type.Number({ description: '阅读数' })),
send_to_new_member: Type.Optional(Type.Boolean({ description: '是否为「发给新成员」公告' })),
pinned: Type.Optional(Type.Boolean({ description: '是否置顶(仅「发给新成员」公告可读到)' })),
}), { description: '群公告列表' });
type ReturnType = Static<typeof ReturnSchema>;
export type ApiGroupNotice = ReturnType[number] & WebApiGroupNoticeFeed;
export class GetGroupNotice extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GoCQHTTP_GetGroupNotice;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取群公告';
override actionDescription = '获取指定群聊中的公告列表';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.GetGroupNotice.payload;
override returnExample = GroupActionsExamples.GetGroupNotice.response;
async _handle (payload: PayloadType) {
const group = payload.group_id.toString();
const ret = await this.core.apis.WebApi.getGroupNotice(group);
if (!ret) {
throw new Error('获取公告失败');
}
const retNotices: ReturnType = [];
const seen = new Set<string>();
// 「发给新成员」类公告只出现在 inst 里,追加在 feeds 之后,保持原有条目的顺序不变
for (const [list, sendToNewMember] of [[ret.feeds, false], [ret.inst, true]] as const) {
for (const retApiNotice of Array.isArray(list) ? list : []) {
if (!retApiNotice || seen.has(retApiNotice.fid)) {
continue;
}
seen.add(retApiNotice.fid);
retNotices.push(this.toNotice(retApiNotice, sendToNewMember));
}
}
return retNotices;
}
private toNotice (retApiNotice: WebApiGroupNoticeFeed, sendToNewMember: boolean): ReturnType[number] {
const image = retApiNotice.msg.pics?.map((pic) => {
return { id: pic.id, height: pic.h, width: pic.w };
}) || [];
const retNotice: ReturnType[number] = {
notice_id: retApiNotice.fid,
sender_id: retApiNotice.u,
publish_time: retApiNotice.pubt,
message: {
text: retApiNotice.msg.text,
image,
images: image,
},
settings: retApiNotice.settings,
read_num: retApiNotice.read_num,
send_to_new_member: sendToNewMember,
};
// 置顶状态只在 inst 条目的 settings.inst_no_pinned 里:0 = 置顶中,1 = 未置顶
const instNoPinned = retApiNotice.settings?.inst_no_pinned;
if (typeof instNoPinned === 'number') {
retNotice.pinned = instNoPinned === 0;
}
return retNotice;
}
}
@@ -0,0 +1,36 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Array(Type.Any(), { description: '禁言成员列表' });
type ReturnType = Static<typeof ReturnSchema>;
export class GetGroupShutList extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.GetGroupShutList;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '获取群禁言列表';
override actionTags = ['群组接口'];
override payloadExample = {
group_id: '123456789',
};
override returnExample = [
{
user_id: 123456789,
nickname: '禁言用户',
shut_up_time: 1734567890,
},
];
async _handle (payload: PayloadType) {
return await this.core.apis.GroupApi.getGroupShutUpMemberList(payload.group_id.toString());
}
}
@@ -0,0 +1,13 @@
import type { GeneralCallResult } from 'napcat-core';
export function assertGroupManagementResults (
operation: string,
results: Array<{ setting: string, result: GeneralCallResult; }>
): void {
const failure = results.find(item => item.result.result !== 0);
if (!failure) return;
throw new Error(
`${operation}失败 Setting: ${failure.setting} ErrCode: ${failure.result.result} ` +
`ErrMsg: ${failure.result.errMsg || '未知错误'}`
);
}
@@ -0,0 +1,41 @@
import { ActionName } from '@/napcat-onebot/action/router';
import { GetPacketStatusDepends } from '@/napcat-onebot/action/packet/GetPacketStatus';
import { AIVoiceChatType } from 'napcat-core/packet/entities/aiChat';
import { Static, Type } from '@sinclair/typebox';
const PayloadSchema = Type.Object({
character: Type.String({ description: '角色ID' }),
group_id: Type.String({ description: '群号' }),
text: Type.String({ description: '语音文本内容' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Object({
message_id: Type.Number({ description: '消息ID' }),
}, { description: '发送结果' });
type ReturnType = Static<typeof ReturnSchema>;
export class SendGroupAiRecord extends GetPacketStatusDepends<PayloadType, ReturnType> {
override actionName = ActionName.SendGroupAiRecord;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '发送群 AI 语音';
override actionDescription = '发送 AI 生成的语音到指定群聊';
override actionTags = ['AI 扩展'];
override payloadExample = {
character: 'ai_char_1',
group_id: '123456',
text: '你好',
};
override returnExample = {};
async _handle (payload: PayloadType) {
await this.core.apis.PacketApi.pkt.operation.GetAiVoice(+payload.group_id, payload.character, payload.text, AIVoiceChatType.Sound);
return {
message_id: 0, // can't get message_id from GetAiVoice
};
}
}
@@ -0,0 +1,26 @@
import { ContextMode, ReturnDataType, SendMsgBase, SendMsgPayload } from '@/napcat-onebot/action/msg/SendMsg';
import { ActionName, BaseCheckResult } from '@/napcat-onebot/action/router';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
// 未检测参数
class SendGroupMsg extends SendMsgBase {
override actionName = ActionName.SendGroupMsg;
override actionSummary = '发送群消息';
override actionDescription = '发送群消息';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SendGroupMsg.payload;
override returnExample = GroupActionsExamples.SendGroupMsg.response;
protected override async check (payload: SendMsgPayload): Promise<BaseCheckResult> {
delete payload.user_id;
payload.message_type = 'group';
return super.check(payload);
}
override async _handle (payload: SendMsgPayload): Promise<ReturnDataType> {
return this.base_handle(payload, ContextMode.Group);
}
}
export default SendGroupMsg;
@@ -0,0 +1,38 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { MessageUnique } from 'napcat-common/src/message-unique';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
message_id: Type.Union([Type.Number(), Type.String()], { description: '消息ID' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Any({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetEssenceMsg extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetEssenceMsg;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '设置精华消息';
override actionDescription = '将一条消息设置为群精华消息';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetEssenceMsg.payload;
override returnExample = GroupActionsExamples.SetEssenceMsg.response;
async _handle (payload: PayloadType) {
const msg = MessageUnique.getMsgIdAndPeerByShortId(+payload.message_id);
if (!msg) {
throw new Error('msg not found');
}
return await this.core.apis.GroupApi.addGroupEssence(
msg.Peer.peerUid,
msg.MsgId
);
}
}
@@ -0,0 +1,66 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { GroupNotify, NTGroupRequestOperateTypes } from 'napcat-core/types';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
flag: Type.String({ description: '请求flag' }),
approve: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否同意' })),
reason: Type.Optional(Type.Union([Type.String({ default: ' ' }), Type.Null()], { description: '拒绝理由' })),
count: Type.Optional(Type.Number({ default: 100, description: '搜索通知数量' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupAddRequest extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupAddRequest;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '处理加群请求';
override actionDescription = '同意或拒绝加群请求或邀请';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupAddRequest.payload;
override returnExample = GroupActionsExamples.SetGroupAddRequest.response;
async _handle (payload: PayloadType): Promise<null> {
const flag = payload.flag.toString();
const approve = payload.approve?.toString() !== 'false';
const reason = payload.reason ?? ' ';
const count = payload.count;
const invite_notify = this.obContext.apis.MsgApi.notifyGroupInvite.get(flag);
const { doubt, notify } = invite_notify
? {
doubt: false,
notify: invite_notify,
}
: await this.findNotify(flag, count);
if (!notify) {
throw new Error('No such request');
}
await this.core.apis.GroupApi.handleGroupRequest(
doubt,
notify,
approve ? NTGroupRequestOperateTypes.KAGREE : NTGroupRequestOperateTypes.KREFUSE,
reason
);
return null;
}
private async findNotify (flag: string, count: number = 100): Promise<{
doubt: boolean,
notify: GroupNotify | undefined;
}> {
let notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(false, count)).find(e => e.seq === flag);
if (!notify) {
notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(true, count)).find(e => e.seq === flag);
return { doubt: true, notify };
}
return { doubt: false, notify };
}
}
@@ -0,0 +1,37 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { NTGroupMemberRole } from 'napcat-core/types';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: '用户QQ' }),
enable: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否设置为管理员' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupAdmin extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupAdmin;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '设置群管理员';
override actionDescription = '设置或取消群聊中的管理员';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupAdmin.payload;
override returnExample = GroupActionsExamples.SetGroupAdmin.response;
async _handle (payload: PayloadType): Promise<null> {
const enable = typeof payload.enable === 'string' ? payload.enable === 'true' : !!payload.enable;
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('get Uid Error');
await this.core.apis.GroupApi.setMemberRole(payload.group_id.toString(), uid, enable ? NTGroupMemberRole.KADMIN : NTGroupMemberRole.KMEMBER);
return null;
}
}
@@ -0,0 +1,47 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
import { NTGroupMemberRole } from '@/napcat-core';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: '用户QQ' }),
duration: Type.Union([Type.Number(), Type.String()], { default: 0, description: '禁言时长(秒)' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupBan extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupBan;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '群组禁言';
override actionDescription = '禁言群聊中的指定成员';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupBan.payload;
override returnExample = GroupActionsExamples.SetGroupBan.response;
async _handle (payload: PayloadType): Promise<null> {
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('uid error');
const member_role = (await this.core.apis.GroupApi.getGroupMemberEx(payload.group_id.toString(), uid, true))?.role;
if (member_role === undefined) throw new Error('user not in group');
if (member_role === NTGroupMemberRole.KOWNER) throw new Error('cannot ban owner');
if (member_role === NTGroupMemberRole.KADMIN) {
const self_role = (await this.core.apis.GroupApi.getGroupMemberEx(payload.group_id.toString(), this.core.selfInfo.uid, true))?.role;
if (self_role === undefined) throw new Error('failed to fetch bot role');
if (self_role !== NTGroupMemberRole.KOWNER) throw new Error('cannot ban admin');
}
// 例如无管理员权限时 result为 120101005 errMsg为 'ERR_NOT_GROUP_ADMIN'
const ret = await this.core.apis.GroupApi.banMember(payload.group_id.toString(),
[{ uid, timeStamp: +payload.duration }]);
if (ret.result !== 0) throw new Error(ret.errMsg);
return null;
}
}
@@ -0,0 +1,51 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { sleep } from '@/napcat-common/src/helper';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: '用户QQ' }),
card: Type.Optional(Type.String({ description: '群名片' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupCard extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupCard;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '设置群名片';
override actionDescription = '设置群聊中指定成员的群名片';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupCard.payload;
override returnExample = GroupActionsExamples.SetGroupCard.response;
async _handle (payload: PayloadType): Promise<null> {
const groupId = payload.group_id.toString();
const userId = payload.user_id.toString();
const card = payload.card || '';
const member = await this.core.apis.GroupApi.getGroupMember(groupId, userId);
if (!member) {
throw new Error(`群(${groupId})成员${userId}不存在`);
}
await this.core.apis.GroupApi.setMemberCard(groupId, member.uid, card);
for (let i = 0; i < 3; i++) {
await sleep(1000);
const updatedMember = await this.core.apis.GroupApi.refreshGroupMemberCachePartial(groupId, member.uid);
if (updatedMember?.cardName === card) {
return null;
}
}
throw new Error('设置群名片未生效');
}
}
@@ -0,0 +1,36 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
user_id: Type.String({ description: '用户QQ' }),
reject_add_request: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否拒绝加群请求' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupKick extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupKick;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '群组踢人';
override actionDescription = '将指定成员踢出群聊';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupKick.payload;
override returnExample = GroupActionsExamples.SetGroupKick.response;
async _handle (payload: PayloadType): Promise<null> {
const rejectReq = payload.reject_add_request?.toString() === 'true';
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('get Uid Error');
await this.core.apis.GroupApi.kickMember(payload.group_id.toString(), [uid], rejectReq);
return null;
}
}
@@ -0,0 +1,38 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
is_dismiss: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否解散' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupLeave extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupLeave;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '退出群组';
override actionDescription = '退出或解散指定群聊';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupLeave.payload;
override returnExample = GroupActionsExamples.SetGroupLeave.response;
async _handle (payload: PayloadType): Promise<null> {
const groupCode = payload.group_id.toString();
// is_dismiss 既可能是布尔值,也可能是字符串 'true'(与 approve 等字段保持一致)
if (payload.is_dismiss === true || payload.is_dismiss === 'true') {
await this.core.apis.GroupApi.destroyGroup(groupCode);
} else {
await this.core.apis.GroupApi.quitGroup(groupCode);
}
return null;
}
}
@@ -0,0 +1,41 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
import { assertGroupManagementResults } from './GroupOperationHelpers';
const MemberInvitePolicySchema = Type.Union([
Type.Literal('disabled'),
Type.Literal('require_approval'),
Type.Literal('no_approval'),
Type.Literal('no_approval_under_100'),
], {
description: '成员邀请策略:禁止、需要管理员审核、无需审核、群成员少于100人时无需审核',
});
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
policy: MemberInvitePolicySchema,
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupMemberInvitePolicy extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupMemberInvitePolicy;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '设置群成员邀请策略';
override actionDescription = '设置是否允许群成员邀请好友进群,以及邀请是否需要管理员审核';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupMemberInvitePolicy.payload;
override returnExample = GroupActionsExamples.SetGroupMemberInvitePolicy.response;
async _handle (payload: PayloadType): Promise<ReturnType> {
const results = await this.core.apis.GroupApi.setGroupMemberInvitePolicy(payload.group_id, payload.policy);
assertGroupManagementResults('设置群成员邀请策略', results);
return null;
}
}
@@ -0,0 +1,43 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
import { assertGroupManagementResults } from './GroupOperationHelpers';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
allow_member_upload_album: Type.Optional(Type.Boolean({ description: '允许成员上传群相册' })),
allow_member_temporary_session: Type.Optional(Type.Boolean({ description: '允许成员发起临时会话' })),
allow_member_create_group: Type.Optional(Type.Boolean({ description: '允许成员发起新的群聊' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupMemberPermissions extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupMemberPermissions;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '设置群成员功能权限';
override actionDescription = '设置群成员上传相册、发起临时会话和发起新群聊的权限;未传入的项目保持不变';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupMemberPermissions.payload;
override returnExample = GroupActionsExamples.SetGroupMemberPermissions.response;
async _handle (payload: PayloadType): Promise<ReturnType> {
const permissions = {
allowMemberUploadAlbum: payload.allow_member_upload_album,
allowMemberTemporarySession: payload.allow_member_temporary_session,
allowMemberCreateGroup: payload.allow_member_create_group,
};
if (Object.values(permissions).every(value => value === undefined)) {
throw new Error('至少需要提供一个群成员功能权限');
}
const results = await this.core.apis.GroupApi.setGroupMemberPermissions(payload.group_id, permissions);
assertGroupManagementResults('设置群成员功能权限', results);
return null;
}
}
@@ -0,0 +1,38 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
group_name: Type.String({ description: '群名称' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupName extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupName;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '设置群名称';
override actionDescription = '修改指定群聊的名称';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupName.payload;
override returnExample = GroupActionsExamples.SetGroupName.response;
async _handle (payload: PayloadType): Promise<null> {
let ret = await this.core.apis.GroupApi.setGroupName(payload.group_id.toString(), payload.group_name);
if (ret.result.toString() === '1287') {
ret = await this.core.apis.GroupApi.setGroupName(payload.group_id.toString(), payload.group_name, true);
}
if (ret.result !== 0) {
throw new Error(`设置群名称失败 ErrCode: ${ret.result} ErrMsg: ${ret.errMsg}`);
}
return null;
}
}
@@ -0,0 +1,35 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
import { assertGroupManagementResults } from './GroupOperationHelpers';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
visible: Type.Boolean({ description: '新成员默认可见最近聊天记录' }),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupNewMemberHistoryVisibility extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupNewMemberHistoryVisibility;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '设置新成员历史消息可见性';
override actionDescription = '设置新入群成员默认是否可以查看最近聊天记录';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupNewMemberHistoryVisibility.payload;
override returnExample = GroupActionsExamples.SetGroupNewMemberHistoryVisibility.response;
async _handle (payload: PayloadType): Promise<ReturnType> {
const results = await this.core.apis.GroupApi.setGroupNewMemberHistoryVisibility(
payload.group_id,
payload.visible
);
assertGroupManagementResults('设置新成员历史消息可见性', results);
return null;
}
}
@@ -0,0 +1,36 @@
import { OneBotAction } from '@/napcat-onebot/action/OneBotAction';
import { ActionName } from '@/napcat-onebot/action/router';
import { Static, Type } from '@sinclair/typebox';
import { GroupActionsExamples } from '../example/GroupActionsExamples';
const PayloadSchema = Type.Object({
group_id: Type.String({ description: '群号' }),
enable: Type.Optional(Type.Union([Type.Boolean(), Type.String()], { description: '是否开启全员禁言' })),
});
type PayloadType = Static<typeof PayloadSchema>;
const ReturnSchema = Type.Null({ description: '操作结果' });
type ReturnType = Static<typeof ReturnSchema>;
export default class SetGroupWholeBan extends OneBotAction<PayloadType, ReturnType> {
override actionName = ActionName.SetGroupWholeBan;
override payloadSchema = PayloadSchema;
override returnSchema = ReturnSchema;
override actionSummary = '全员禁言';
override actionDescription = '开启或关闭指定群聊的全员禁言';
override actionTags = ['群组接口'];
override payloadExample = GroupActionsExamples.SetGroupWholeBan.payload;
override returnExample = GroupActionsExamples.SetGroupWholeBan.response;
async _handle (payload: PayloadType): Promise<null> {
const enable = payload.enable?.toString() !== 'false';
const res = await this.core.apis.GroupApi.banGroup(payload.group_id.toString(), enable);
if (res.result !== 0) {
throw new Error(`SetGroupWholeBan failed: ${res.errMsg} ${res.result}`);
}
return null;
}
}