diff --git a/packages/engine-chronocat-api/src/api/guild/member/mute.ts b/packages/engine-chronocat-api/src/api/guild/member/mute.ts new file mode 100644 index 0000000..34a7a34 --- /dev/null +++ b/packages/engine-chronocat-api/src/api/guild/member/mute.ts @@ -0,0 +1,19 @@ +import type { ChronocatContext, GuildMemberMutePayload } from '@chronocat/shell' +import { setMemberShutUp } from '../../../definitions/groupService' + +export const buildGuildMemberMute = + (ctx: ChronocatContext) => + async ({ channel_id, user_id, duration }: GuildMemberMutePayload) => { + await setMemberShutUp({ + groupCode: channel_id, + + memList: [ + { + uid: ctx.chronocat.uix.getUid(user_id), + timeStamp: Math.floor(duration / 1000), + }, + ], + }) + + return {} + } diff --git a/packages/engine-chronocat-api/src/index.ts b/packages/engine-chronocat-api/src/index.ts index ddb3b80..4ffded1 100644 --- a/packages/engine-chronocat-api/src/index.ts +++ b/packages/engine-chronocat-api/src/index.ts @@ -14,6 +14,7 @@ import { buildGuildList } from './api/guild/list' import { buildGuildMemberGet } from './api/guild/member/get' import { buildGuildMemberKick } from './api/guild/member/kick' import { buildGuildMemberList } from './api/guild/member/list' +import { buildGuildMemberMute } from './api/guild/member/mute' import { buildGuildRemove } from './api/guild/remove' import { buildAssetsGet } from './api/internal/assets/get' import { qfaceGet, qfaceList } from './api/internal/qface' @@ -56,6 +57,7 @@ export const apply = async (ctx: ChronocatContext) => { register('guild.member.get', buildGuildMemberGet(ctx)) register('guild.member.list', buildGuildMemberList(ctx)) register('guild.member.kick', buildGuildMemberKick(ctx)) + register('guild.member.mute', buildGuildMemberMute(ctx)) register('message.create', buildMessageCreate(ctx)) register('chronocat.internal.message.create.forward', buildMessageCreate(ctx)) register('message.get', buildMessageGet(ctx)) diff --git a/packages/shell/src/satori/routes/guild/member/mute.ts b/packages/shell/src/satori/routes/guild/member/mute.ts new file mode 100644 index 0000000..841f2e6 --- /dev/null +++ b/packages/shell/src/satori/routes/guild/member/mute.ts @@ -0,0 +1,30 @@ +import type { GuildMemberMutePayload } from '../../../types' +import type { RouteContext } from '../../types' + +export const guildMemberMute = async ({ + cctx, + path, + req, + res, + json, +}: RouteContext) => { + const payload = (await json()) as GuildMemberMutePayload + + const validateResult = await cctx.chronocat.validate( + 'GuildMemberMutePayload', + )(payload) + + if (validateResult) { + const err = `解析 ${path} 请求时出现问题,来自 ${req.socket.remoteAddress}。${validateResult}` + + cctx.chronocat.l.error(err, { + code: 400, + }) + + res.writeHead(400) + res.end(`400 bad request\n${err}`) + return + } + + return await cctx.chronocat.api['guild.member.mute'](payload) +} diff --git a/packages/shell/src/satori/routes/index.ts b/packages/shell/src/satori/routes/index.ts index 769b76f..ae54a2c 100644 --- a/packages/shell/src/satori/routes/index.ts +++ b/packages/shell/src/satori/routes/index.ts @@ -11,6 +11,7 @@ import { guildList } from './guild/list' import { guildMemberGet } from './guild/member/get' import { guildMemberKick } from './guild/member/kick' import { guildMemberList } from './guild/member/list' +import { guildMemberMute } from './guild/member/mute' import { guildRemove } from './guild/remove' import { loginGet } from './login/get' import { messageCreate } from './message/create' @@ -39,6 +40,7 @@ const routesIntl = { 'guild.member.list': guildMemberList, 'guild.member.kick': guildMemberKick, 'guild.member.approve': notImplemented, + 'guild.member.mute': guildMemberMute, 'guild.member.role.set': notImplemented, 'guild.member.role.unset': notImplemented, 'guild.role.list': notImplemented, diff --git a/packages/shell/src/satori/types/satoriPayloadEntity.ts b/packages/shell/src/satori/types/satoriPayloadEntity.ts index 8058799..f85f00b 100644 --- a/packages/shell/src/satori/types/satoriPayloadEntity.ts +++ b/packages/shell/src/satori/types/satoriPayloadEntity.ts @@ -102,6 +102,27 @@ export interface ChannelMemberMutePayload { duration: number } +export interface GuildMemberMutePayload { + channel_id: string + user_id: string + + /** + * @title 禁言时长 + * + * @description 禁言的时长,单位为毫秒。0 + * 表示解除禁言。应当小于 30 天(259,200,000 + * 毫秒)。目前会对向下取整到秒。 + */ + duration: number + + /** + * @title 说明信息 + * + * @description 禁言群组成员的说明。目前会忽略此字段。 + */ + comment?: string +} + export interface ChannelListPayload extends Next { guild_id: string } diff --git a/packages/shell/src/satori/types/satoriPayloadRich.ts b/packages/shell/src/satori/types/satoriPayloadRich.ts index 9cb3ad2..ba6bfc4 100644 --- a/packages/shell/src/satori/types/satoriPayloadRich.ts +++ b/packages/shell/src/satori/types/satoriPayloadRich.ts @@ -15,6 +15,7 @@ export type { GuildMemberKickPayload, GuildMemberListPayload, GuildMemberListResponse, + GuildMemberMutePayload, GuildRemovePayload, MessageDeletePayload, MessageGetPayload, diff --git a/packages/shell/src/types.ts b/packages/shell/src/types.ts index ea098e2..cfd123b 100644 --- a/packages/shell/src/types.ts +++ b/packages/shell/src/types.ts @@ -21,6 +21,7 @@ import type { GuildMemberKickPayload, GuildMemberListPayload, GuildMemberListResponse, + GuildMemberMutePayload, GuildRemovePayload, Login, Message, @@ -113,6 +114,7 @@ export interface SatoriMethods { 'guild.member.get': [[GuildMemberGetPayload], GuildMember] 'guild.member.list': [[GuildMemberListPayload], GuildMemberListResponse] 'guild.member.kick': [[GuildMemberKickPayload], Record] + 'guild.member.mute': [[GuildMemberMutePayload], Record] 'message.create': [ [MessageCreatePayload, ChronocatSatoriServerConfig],