refactor: simplify codebase with unified patterns and reduced duplication
- unify ChatConfigService setters into generic setPermission method - replace PermissionService switch statements with data-driven checkers map - deduplicate config.ts callback handlers via loop-based registration (414→254 lines) - extract shared updateChatCommands utility from role-add/role-delete - add proper generics to chunk utility, fix mention loop indexing - extract isHiddenAdmin helper and ANONYMOUS_ADMIN_ID constant in perms - remove debug console.logs, standardize arrow exports and type imports - add roleAdminPermission schema and migration
This commit is contained in:
parent
1eb2200fbe
commit
85c7410ffb
21 changed files with 638 additions and 364 deletions
|
|
@ -2,20 +2,17 @@ import type { BotType } from '@/bot/index.js'
|
|||
import { bold, format } from 'gramio'
|
||||
import { isChatAdmin, refreshAdminCache } from '@/bot/utilities/perms.js'
|
||||
|
||||
export default function (bot: BotType) {
|
||||
// Command to refresh admin cache
|
||||
export default (bot: BotType) => {
|
||||
bot.command('reload', async (ctx) => {
|
||||
if (!['group', 'supergroup'].includes(ctx.chat.type)) {
|
||||
return ctx.reply('This command can only be used in groups or supergroups')
|
||||
}
|
||||
|
||||
// Any admin can refresh cache
|
||||
const isAdmin = await isChatAdmin(ctx.chat.id, ctx.from.id)
|
||||
if (!isAdmin) {
|
||||
return ctx.reply('This command can only be used by admins')
|
||||
}
|
||||
|
||||
// Refresh the admin cache for this chat
|
||||
refreshAdminCache(ctx.chat.id)
|
||||
|
||||
return ctx.reply(
|
||||
|
|
|
|||
|
|
@ -1,43 +1,81 @@
|
|||
import type { BotType } from '@/bot/index.js'
|
||||
import { bold, format, InlineKeyboard, italic } from 'gramio'
|
||||
import { isChatAdmin, isChatOwner } from '@/bot/utilities/perms.js'
|
||||
import { ChatConfigService, type RoleManagePermission, type RoleMentionPermission } from '@/shared/services/chatConfig.js'
|
||||
import { ChatConfigService, type ChatConfig, type RoleAdminPermission, type RoleManagePermission, type RoleMentionPermission } from '@/shared/services/chatConfig.js'
|
||||
import { PermissionService } from '@/shared/services/permission.js'
|
||||
import { bot } from '@/bot/index.js'
|
||||
|
||||
// Shared keyboard builders for consistent UI
|
||||
const MANAGE_PERMISSION_OPTIONS: { value: RoleManagePermission, label: string }[] = [
|
||||
{ value: 'everyone', label: 'Everyone' },
|
||||
{ value: 'all_admins', label: 'All Admins' },
|
||||
{ value: 'admin_can_promote_members', label: 'Admins: Promote Members' },
|
||||
{ value: 'admin_can_change_info', label: 'Admins: Change Info' },
|
||||
{ value: 'admin_can_manage_chat', label: 'Admins: Manage Chat' },
|
||||
{ value: 'only_owner', label: 'Only Owner' },
|
||||
]
|
||||
type PermissionType = 'manage' | 'mention' | 'admin'
|
||||
|
||||
const MENTION_PERMISSION_OPTIONS: { value: RoleMentionPermission, label: string }[] = [
|
||||
{ value: 'everyone', label: 'Everyone' },
|
||||
{ value: 'all_admins', label: 'All Admins' },
|
||||
{ value: 'only_owner', label: 'Only Owner' },
|
||||
]
|
||||
|
||||
function buildManageKeyboard(currentValue: RoleManagePermission): InlineKeyboard {
|
||||
const keyboard = new InlineKeyboard()
|
||||
for (const option of MANAGE_PERMISSION_OPTIONS) {
|
||||
const isSelected = option.value === currentValue
|
||||
const label = isSelected ? `✓ ${option.label}` : option.label
|
||||
keyboard.text(label, `config:manage:${option.value}`).row()
|
||||
}
|
||||
keyboard.text('« Back to Config', 'config:back')
|
||||
return keyboard
|
||||
interface PermissionOption<T> {
|
||||
value: T
|
||||
label: string
|
||||
}
|
||||
|
||||
function buildMentionKeyboard(currentValue: RoleMentionPermission): InlineKeyboard {
|
||||
interface PermissionConfig<T extends string> {
|
||||
key: PermissionType
|
||||
displayTitle: string
|
||||
selectPrompt: string
|
||||
options: PermissionOption<T>[]
|
||||
getField: (config: ChatConfig) => T
|
||||
setPermission: (chatId: number, value: T) => Promise<ChatConfig | null>
|
||||
describePermission: (value: T) => string
|
||||
}
|
||||
|
||||
const PERMISSION_CONFIGS: Record<PermissionType, PermissionConfig<any>> = {
|
||||
manage: {
|
||||
key: 'manage',
|
||||
displayTitle: 'Role Management Permission',
|
||||
selectPrompt: 'Select who can add/delete roles:',
|
||||
options: [
|
||||
{ value: 'everyone', label: 'Everyone' },
|
||||
{ value: 'all_admins', label: 'All Admins' },
|
||||
{ value: 'admin_can_promote_members', label: 'Admins: Promote Members' },
|
||||
{ value: 'admin_can_change_info', label: 'Admins: Change Info' },
|
||||
{ value: 'admin_can_manage_chat', label: 'Admins: Manage Chat' },
|
||||
{ value: 'only_owner', label: 'Only Owner' },
|
||||
] as PermissionOption<RoleManagePermission>[],
|
||||
getField: (config) => config.roleManagePermission,
|
||||
setPermission: ChatConfigService.setRoleManagePermission.bind(ChatConfigService),
|
||||
describePermission: PermissionService.describeRoleManagePermission.bind(PermissionService),
|
||||
},
|
||||
mention: {
|
||||
key: 'mention',
|
||||
displayTitle: 'Role Mention Permission',
|
||||
selectPrompt: 'Select who can mention roles:',
|
||||
options: [
|
||||
{ value: 'everyone', label: 'Everyone' },
|
||||
{ value: 'all_admins', label: 'All Admins' },
|
||||
{ value: 'only_owner', label: 'Only Owner' },
|
||||
] as PermissionOption<RoleMentionPermission>[],
|
||||
getField: (config) => config.roleMentionPermission,
|
||||
setPermission: ChatConfigService.setRoleMentionPermission.bind(ChatConfigService),
|
||||
describePermission: PermissionService.describeRoleMentionPermission.bind(PermissionService),
|
||||
},
|
||||
admin: {
|
||||
key: 'admin',
|
||||
displayTitle: 'Role Admin Permission',
|
||||
selectPrompt: 'Select who can use role admin commands (rolemembers, rolekick):',
|
||||
options: [
|
||||
{ value: 'everyone', label: 'Everyone' },
|
||||
{ value: 'all_admins', label: 'All Admins' },
|
||||
{ value: 'only_owner', label: 'Only Owner' },
|
||||
] as PermissionOption<RoleAdminPermission>[],
|
||||
getField: (config) => config.roleAdminPermission,
|
||||
setPermission: ChatConfigService.setRoleAdminPermission.bind(ChatConfigService),
|
||||
describePermission: PermissionService.describeRoleAdminPermission.bind(PermissionService),
|
||||
},
|
||||
}
|
||||
|
||||
function buildPermissionKeyboard<T extends string>(
|
||||
permConfig: PermissionConfig<T>,
|
||||
currentValue: T,
|
||||
): InlineKeyboard {
|
||||
const keyboard = new InlineKeyboard()
|
||||
for (const option of MENTION_PERMISSION_OPTIONS) {
|
||||
for (const option of permConfig.options) {
|
||||
const isSelected = option.value === currentValue
|
||||
const label = isSelected ? `✓ ${option.label}` : option.label
|
||||
keyboard.text(label, `config:mention:${option.value}`).row()
|
||||
keyboard.text(label, `config:${permConfig.key}:${option.value}`).row()
|
||||
}
|
||||
keyboard.text('« Back to Config', 'config:back')
|
||||
return keyboard
|
||||
|
|
@ -47,19 +85,18 @@ function buildMainConfigKeyboard(isOwner: boolean): InlineKeyboard {
|
|||
const keyboard = new InlineKeyboard()
|
||||
if (isOwner) {
|
||||
keyboard.text('⚙️ Role Management', 'config:show:manage').row()
|
||||
keyboard.text('📢 Role Mentions', 'config:show:mention')
|
||||
keyboard.text('📢 Role Mentions', 'config:show:mention').row()
|
||||
keyboard.text('👥 Role Admin', 'config:show:admin')
|
||||
}
|
||||
return keyboard
|
||||
}
|
||||
|
||||
export default function (bot: BotType) {
|
||||
// Command to show current configuration
|
||||
export default (bot: BotType) => {
|
||||
bot.command('config', async (ctx) => {
|
||||
if (!['group', 'supergroup'].includes(ctx.chat.type)) {
|
||||
return ctx.reply('This command can only be used in groups or supergroups')
|
||||
}
|
||||
|
||||
// Any admin can view config
|
||||
const isAdmin = await isChatAdmin(ctx.chat.id, ctx.from.id)
|
||||
if (!isAdmin) {
|
||||
return ctx.reply('This command can only be used by admins')
|
||||
|
|
@ -78,6 +115,9 @@ export default function (bot: BotType) {
|
|||
${bold('Role Mentions:')}
|
||||
${italic(PermissionService.describeRoleMentionPermission(config.roleMentionPermission))}
|
||||
|
||||
${bold('Role Admin:')}
|
||||
${italic(PermissionService.describeRoleAdminPermission(config.roleAdminPermission))}
|
||||
|
||||
${isOwner ? '' : italic('\nOnly the chat owner can change settings.')}
|
||||
`,
|
||||
{
|
||||
|
|
@ -86,190 +126,98 @@ export default function (bot: BotType) {
|
|||
)
|
||||
})
|
||||
|
||||
// Handle navigation to manage settings
|
||||
bot.callbackQuery('config:show:manage', async (ctx) => {
|
||||
const chatId = ctx.message?.chat.id
|
||||
const messageId = ctx.message?.id
|
||||
if (!chatId || !messageId) {
|
||||
return ctx.answerCallbackQuery({ text: 'Error: Could not determine chat', show_alert: true })
|
||||
}
|
||||
for (const permType of Object.keys(PERMISSION_CONFIGS) as PermissionType[]) {
|
||||
const permConfig = PERMISSION_CONFIGS[permType]
|
||||
|
||||
const isOwner = await isChatOwner(chatId, ctx.from.id)
|
||||
if (!isOwner) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Only the chat owner can change settings',
|
||||
show_alert: true,
|
||||
bot.callbackQuery(`config:show:${permType}`, async (ctx) => {
|
||||
const chatId = ctx.message?.chat.id
|
||||
const messageId = ctx.message?.id
|
||||
if (!chatId || !messageId) {
|
||||
return ctx.answerCallbackQuery({ text: 'Error: Could not determine chat', show_alert: true })
|
||||
}
|
||||
|
||||
const isOwner = await isChatOwner(chatId, ctx.from.id)
|
||||
if (!isOwner) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Only the chat owner can change settings',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
const config = await ChatConfigService.getOrCreate(chatId)
|
||||
const currentValue = permConfig.getField(config)
|
||||
|
||||
await bot.api.editMessageText({
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
text: format`
|
||||
${bold(permConfig.displayTitle)}
|
||||
|
||||
Current: ${italic(permConfig.describePermission(currentValue))}
|
||||
|
||||
${permConfig.selectPrompt}
|
||||
`,
|
||||
reply_markup: buildPermissionKeyboard(permConfig, currentValue),
|
||||
})
|
||||
}
|
||||
|
||||
const config = await ChatConfigService.getOrCreate(chatId)
|
||||
|
||||
await bot.api.editMessageText({
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
text: format`
|
||||
${bold('Role Management Permission')}
|
||||
|
||||
Current: ${italic(PermissionService.describeRoleManagePermission(config.roleManagePermission))}
|
||||
|
||||
Select who can add/delete roles:
|
||||
`,
|
||||
reply_markup: buildManageKeyboard(config.roleManagePermission),
|
||||
return ctx.answerCallbackQuery()
|
||||
})
|
||||
|
||||
return ctx.answerCallbackQuery()
|
||||
})
|
||||
bot.callbackQuery(new RegExp(`^config:${permType}:(.+)$`), async (ctx) => {
|
||||
const chatId = ctx.message?.chat.id
|
||||
const messageId = ctx.message?.id
|
||||
if (!chatId || !messageId) {
|
||||
return ctx.answerCallbackQuery({ text: 'Error: Could not determine chat', show_alert: true })
|
||||
}
|
||||
|
||||
// Handle navigation to mention settings
|
||||
bot.callbackQuery('config:show:mention', async (ctx) => {
|
||||
const chatId = ctx.message?.chat.id
|
||||
const messageId = ctx.message?.id
|
||||
if (!chatId || !messageId) {
|
||||
return ctx.answerCallbackQuery({ text: 'Error: Could not determine chat', show_alert: true })
|
||||
}
|
||||
const isOwner = await isChatOwner(chatId, ctx.from.id)
|
||||
if (!isOwner) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Only the chat owner can change this setting',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
const isOwner = await isChatOwner(chatId, ctx.from.id)
|
||||
if (!isOwner) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Only the chat owner can change settings',
|
||||
show_alert: true,
|
||||
const permission = ctx.queryPayload.split(':')[2]
|
||||
const validOptions = permConfig.options.map(opt => opt.value)
|
||||
|
||||
if (!validOptions.includes(permission)) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Invalid option',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
const updated = await permConfig.setPermission(chatId, permission)
|
||||
|
||||
if (!updated) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Failed to update configuration',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
const currentValue = permConfig.getField(updated)
|
||||
|
||||
await bot.api.editMessageText({
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
text: format`
|
||||
${bold(permConfig.displayTitle)}
|
||||
|
||||
Current: ${italic(permConfig.describePermission(currentValue))}
|
||||
|
||||
${permConfig.selectPrompt}
|
||||
`,
|
||||
reply_markup: buildPermissionKeyboard(permConfig, currentValue),
|
||||
})
|
||||
}
|
||||
|
||||
const config = await ChatConfigService.getOrCreate(chatId)
|
||||
|
||||
await bot.api.editMessageText({
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
text: format`
|
||||
${bold('Role Mention Permission')}
|
||||
|
||||
Current: ${italic(PermissionService.describeRoleMentionPermission(config.roleMentionPermission))}
|
||||
|
||||
Select who can mention roles:
|
||||
`,
|
||||
reply_markup: buildMentionKeyboard(config.roleMentionPermission),
|
||||
return ctx.answerCallbackQuery({
|
||||
text: `Updated: ${permConfig.describePermission(currentValue)}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return ctx.answerCallbackQuery()
|
||||
})
|
||||
|
||||
// Handle manage permission selection
|
||||
bot.callbackQuery(/^config:manage:(.+)$/, async (ctx) => {
|
||||
const chatId = ctx.message?.chat.id
|
||||
const messageId = ctx.message?.id
|
||||
if (!chatId || !messageId) {
|
||||
return ctx.answerCallbackQuery({ text: 'Error: Could not determine chat', show_alert: true })
|
||||
}
|
||||
|
||||
const isOwner = await isChatOwner(chatId, ctx.from.id)
|
||||
if (!isOwner) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Only the chat owner can change this setting',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
const permission = ctx.queryPayload.split(':')[2] as RoleManagePermission
|
||||
|
||||
const validOptions: RoleManagePermission[] = [
|
||||
'everyone',
|
||||
'all_admins',
|
||||
'admin_can_promote_members',
|
||||
'admin_can_change_info',
|
||||
'admin_can_manage_chat',
|
||||
'only_owner',
|
||||
]
|
||||
|
||||
if (!validOptions.includes(permission)) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Invalid option',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
const updated = await ChatConfigService.setRoleManagePermission(chatId, permission)
|
||||
|
||||
if (!updated) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Failed to update configuration',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
await bot.api.editMessageText({
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
text: format`
|
||||
${bold('Role Management Permission')}
|
||||
|
||||
Current: ${italic(PermissionService.describeRoleManagePermission(updated.roleManagePermission))}
|
||||
|
||||
Select who can add/delete roles:
|
||||
`,
|
||||
reply_markup: buildManageKeyboard(updated.roleManagePermission),
|
||||
})
|
||||
|
||||
return ctx.answerCallbackQuery({
|
||||
text: `Updated: ${PermissionService.describeRoleManagePermission(updated.roleManagePermission)}`,
|
||||
})
|
||||
})
|
||||
|
||||
// Handle mention permission selection
|
||||
bot.callbackQuery(/^config:mention:(.+)$/, async (ctx) => {
|
||||
const chatId = ctx.message?.chat.id
|
||||
const messageId = ctx.message?.id
|
||||
if (!chatId || !messageId) {
|
||||
return ctx.answerCallbackQuery({ text: 'Error: Could not determine chat', show_alert: true })
|
||||
}
|
||||
|
||||
const isOwner = await isChatOwner(chatId, ctx.from.id)
|
||||
if (!isOwner) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Only the chat owner can change this setting',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
const permission = ctx.queryPayload.split(':')[2] as RoleMentionPermission
|
||||
|
||||
const validOptions: RoleMentionPermission[] = ['everyone', 'all_admins', 'only_owner']
|
||||
|
||||
if (!validOptions.includes(permission)) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Invalid option',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
const updated = await ChatConfigService.setRoleMentionPermission(chatId, permission)
|
||||
|
||||
if (!updated) {
|
||||
return ctx.answerCallbackQuery({
|
||||
text: 'Failed to update configuration',
|
||||
show_alert: true,
|
||||
})
|
||||
}
|
||||
|
||||
await bot.api.editMessageText({
|
||||
chat_id: chatId,
|
||||
message_id: messageId,
|
||||
text: format`
|
||||
${bold('Role Mention Permission')}
|
||||
|
||||
Current: ${italic(PermissionService.describeRoleMentionPermission(updated.roleMentionPermission))}
|
||||
|
||||
Select who can mention roles:
|
||||
`,
|
||||
reply_markup: buildMentionKeyboard(updated.roleMentionPermission),
|
||||
})
|
||||
|
||||
return ctx.answerCallbackQuery({
|
||||
text: `Updated: ${PermissionService.describeRoleMentionPermission(updated.roleMentionPermission)}`,
|
||||
})
|
||||
})
|
||||
|
||||
// Handle back button to main config
|
||||
bot.callbackQuery('config:back', async (ctx) => {
|
||||
const chatId = ctx.message?.chat.id
|
||||
const messageId = ctx.message?.id
|
||||
|
|
@ -292,6 +240,9 @@ export default function (bot: BotType) {
|
|||
${bold('Role Mentions:')}
|
||||
${italic(PermissionService.describeRoleMentionPermission(config.roleMentionPermission))}
|
||||
|
||||
${bold('Role Admin:')}
|
||||
${italic(PermissionService.describeRoleAdminPermission(config.roleAdminPermission))}
|
||||
|
||||
${isOwner ? '' : italic('\nOnly the chat owner can change settings.')}
|
||||
`,
|
||||
reply_markup: buildMainConfigKeyboard(isOwner),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import type { BotType } from '@/bot/index.js'
|
||||
import { bold, code, format, italic } from 'gramio'
|
||||
import { RESERVED_NAMES, ROLE_NAME_REGEX } from '@/bot/utilities/constants.js'
|
||||
import { updateChatCommands } from '@/bot/utilities/commands.js'
|
||||
import { PermissionService } from '@/shared/services/permission.js'
|
||||
import { RoleService } from '@/shared/services/role.js'
|
||||
|
||||
export default function (bot: BotType) {
|
||||
export default (bot: BotType) => {
|
||||
bot.command('roleadd', async (ctx) => {
|
||||
if (!['group', 'supergroup'].includes(ctx.chat.type)) {
|
||||
return ctx.reply('This command can only be used in groups or supergroups')
|
||||
|
|
@ -40,19 +41,7 @@ export default function (bot: BotType) {
|
|||
return ctx.reply('failed to create role, skill issue')
|
||||
}
|
||||
|
||||
setImmediate(async () => {
|
||||
const roles = await RoleService.getByChatId(ctx.chatId)
|
||||
await bot.api.setMyCommands({
|
||||
scope: {
|
||||
chat_id: ctx.chatId,
|
||||
type: 'chat',
|
||||
},
|
||||
commands: roles.map(role => ({
|
||||
command: role.slug,
|
||||
description: `Mention all members of this role`,
|
||||
})),
|
||||
})
|
||||
})
|
||||
updateChatCommands(bot, ctx.chatId)
|
||||
|
||||
return ctx.reply(
|
||||
format`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import type { BotType } from '@/bot/index.js'
|
||||
import { bold, code, format } from 'gramio'
|
||||
import { updateChatCommands } from '@/bot/utilities/commands.js'
|
||||
import { PermissionService } from '@/shared/services/permission.js'
|
||||
import { RoleService } from '@/shared/services/role.js'
|
||||
|
||||
|
|
@ -34,19 +35,7 @@ export default (bot: BotType) => {
|
|||
return ctx.reply('failed to delete role, skill issue')
|
||||
}
|
||||
|
||||
setImmediate(async () => {
|
||||
const roles = await RoleService.getByChatId(ctx.chatId)
|
||||
await bot.api.setMyCommands({
|
||||
scope: {
|
||||
chat_id: ctx.chatId,
|
||||
type: 'chat',
|
||||
},
|
||||
commands: roles.map(role => ({
|
||||
command: role.slug,
|
||||
description: `Mention all members of this role`,
|
||||
})),
|
||||
})
|
||||
})
|
||||
updateChatCommands(bot, ctx.chatId)
|
||||
|
||||
return ctx.reply(format`role ${bold(role.slug)} deleted`)
|
||||
})
|
||||
|
|
|
|||
54
src/bot/commands/admin/role-kick.ts
Normal file
54
src/bot/commands/admin/role-kick.ts
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import type { BotType } from '@/bot/index.js'
|
||||
import { bold, code, format, mention } from 'gramio'
|
||||
import { PermissionService } from '@/shared/services/permission.js'
|
||||
import { RoleService } from '@/shared/services/role.js'
|
||||
|
||||
export default (bot: BotType) => {
|
||||
bot.command('rolekick', async (ctx) => {
|
||||
if (!['group', 'supergroup'].includes(ctx.chat.type)) {
|
||||
return ctx.reply('this command can only be used in groups or supergroups')
|
||||
}
|
||||
|
||||
const canAdmin = await PermissionService.canAdminRoles(ctx.chat.id, ctx.from.id)
|
||||
if (!canAdmin) {
|
||||
return ctx.reply('You don\'t have permission to use role admin commands')
|
||||
}
|
||||
|
||||
// Check if this is a reply to a message
|
||||
const replyMessage = ctx.replyMessage
|
||||
if (!replyMessage) {
|
||||
return ctx.reply(format`reply to a user's message to kick them from a role\nusage: ${code('/rolekick <rolename>')} (as reply)`)
|
||||
}
|
||||
|
||||
const targetUser = replyMessage.from
|
||||
if (!targetUser) {
|
||||
return ctx.reply('could not determine the user from the replied message')
|
||||
}
|
||||
|
||||
let [roleSlug] = (ctx.args ?? '').trim().split(' ')
|
||||
if (!roleSlug) {
|
||||
return ctx.reply(format`where is the role name bro?\nusage: ${code('/rolekick <rolename>')} (as reply)`)
|
||||
}
|
||||
|
||||
roleSlug = roleSlug.toLowerCase()
|
||||
|
||||
const role = await RoleService.getBySlugOrAlias(roleSlug, ctx.chatId)
|
||||
if (!role) {
|
||||
return ctx.reply('role not found')
|
||||
}
|
||||
|
||||
// Check if user is a member of the role
|
||||
const membership = await RoleService.getMemberById(role.id!, ctx.chatId, targetUser.id)
|
||||
if (!membership) {
|
||||
return ctx.reply(format`${mention(targetUser.firstName, { id: targetUser.id, is_bot: targetUser.isBot(), first_name: targetUser.firstName })} is not a member of ${bold(role.slug)}`)
|
||||
}
|
||||
|
||||
// Remove user from role
|
||||
const removed = await RoleService.removeMember(role.id!, targetUser.id)
|
||||
if (!removed) {
|
||||
return ctx.reply('failed to remove user from role, skill issue')
|
||||
}
|
||||
|
||||
return ctx.reply(format`${mention(targetUser.firstName, { id: targetUser.id, is_bot: targetUser.isBot(), first_name: targetUser.firstName })} has been kicked from ${bold(role.slug)}`)
|
||||
})
|
||||
}
|
||||
43
src/bot/commands/admin/role-members.ts
Normal file
43
src/bot/commands/admin/role-members.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import type { BotType } from '@/bot/index.js'
|
||||
import { bold, code, format, italic, join, mention } from 'gramio'
|
||||
import { PermissionService } from '@/shared/services/permission.js'
|
||||
import { RoleService } from '@/shared/services/role.js'
|
||||
|
||||
export default (bot: BotType) => {
|
||||
bot.command('rolemembers', async (ctx) => {
|
||||
if (!['group', 'supergroup'].includes(ctx.chat.type)) {
|
||||
return ctx.reply('this command can only be used in groups or supergroups')
|
||||
}
|
||||
|
||||
const canAdmin = await PermissionService.canAdminRoles(ctx.chat.id, ctx.from.id)
|
||||
if (!canAdmin) {
|
||||
return ctx.reply('You don\'t have permission to use role admin commands')
|
||||
}
|
||||
|
||||
let [roleSlug] = (ctx.args ?? '').trim().split(' ')
|
||||
if (!roleSlug) {
|
||||
return ctx.reply(format`where is the role name bro?\nusage: ${code('/rolemembers <name>')}`)
|
||||
}
|
||||
|
||||
roleSlug = roleSlug.toLowerCase()
|
||||
|
||||
const role = await RoleService.getBySlugOrAlias(roleSlug, ctx.chatId)
|
||||
if (!role) {
|
||||
return ctx.reply('role not found')
|
||||
}
|
||||
|
||||
const memberIds = await RoleService.getMemberIds(roleSlug, ctx.chatId)
|
||||
|
||||
if (memberIds.length === 0) {
|
||||
return ctx.reply(format`role ${bold(role.slug)} has no members`)
|
||||
}
|
||||
|
||||
const mentions = memberIds.map(id => mention('👤', { id, is_bot: false, first_name: '' }))
|
||||
|
||||
return ctx.reply(format`
|
||||
${bold(`Members of ${role.slug}`)} ${italic(`(${memberIds.length})`)}
|
||||
|
||||
${join(mentions, entity => entity, ' ')}
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { BotType } from "@/bot/index.js"
|
||||
import type { BotType } from "@/bot/index.js"
|
||||
|
||||
export default (bot: BotType) => {
|
||||
bot.command('resetautocomplete', async (ctx) => {
|
||||
|
|
|
|||
|
|
@ -22,13 +22,11 @@ export default (bot: BotType) => {
|
|||
}
|
||||
|
||||
const role = await RoleService.getBySlugOrAlias(slug, ctx.chatId)
|
||||
console.log(role)
|
||||
if (!role) {
|
||||
return ctx.reply('role not found')
|
||||
}
|
||||
|
||||
const isMember = await RoleService.getMemberById(role.id!, ctx.chatId, ctx.from.id)
|
||||
console.log(isMember)
|
||||
if (isMember !== null) {
|
||||
return ctx.reply('you are already in this role')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BotType } from "@/bot/index.js"
|
||||
import type { BotType } from "@/bot/index.js"
|
||||
import { RoleService } from "@/shared/services/role.js"
|
||||
import { format, join } from "gramio"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BotType } from "@/bot/index.js"
|
||||
import type { BotType } from "@/bot/index.js"
|
||||
import { RoleService } from "@/shared/services/role.js"
|
||||
import { bold, code, format } from "gramio"
|
||||
|
||||
|
|
@ -21,7 +21,6 @@ export default (bot: BotType) => {
|
|||
}
|
||||
|
||||
const isMember = await RoleService.getMemberById(role.id!, ctx.chatId, ctx.from.id)
|
||||
console.log(isMember)
|
||||
if (isMember === null) {
|
||||
return ctx.reply('you are not a member of this role')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BotType } from "@/bot/index.js"
|
||||
import type { BotType } from "@/bot/index.js"
|
||||
import { RoleService } from "@/shared/services/role.js"
|
||||
import { format, join } from "gramio"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue