Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
22 KB
Referenced Files
None
Subscribers
None
diff --git a/src/plugins/admin/chatinfo.lua b/src/plugins/admin/chatinfo.lua
new file mode 100644
index 0000000..99efe3c
--- /dev/null
+++ b/src/plugins/admin/chatinfo.lua
@@ -0,0 +1,39 @@
+--[[
+ mattata v2.1 - Chat Info Plugin
+ Set chat title and description.
+]]
+
+local plugin = {}
+plugin.name = 'chatinfo'
+plugin.category = 'admin'
+plugin.description = 'Set chat title or description'
+plugin.commands = { 'settitle', 'setdescription' }
+plugin.help = '/settitle <title> - Set the chat title.\n/setdescription <text> - Set the chat description.'
+plugin.group_only = true
+plugin.admin_only = true
+
+function plugin.on_message(api, message, ctx)
+ if not message.args or message.args == '' then
+ if message.command == 'settitle' then
+ return api.send_message(message.chat.id, 'Usage: /settitle <new title>')
+ else
+ return api.send_message(message.chat.id, 'Usage: /setdescription <new description>')
+ end
+ end
+
+ if message.command == 'settitle' then
+ local result = api.set_chat_title(message.chat.id, message.args)
+ if result then
+ return api.send_message(message.chat.id, 'Chat title updated.')
+ end
+ return api.send_message(message.chat.id, 'Failed to update chat title. Make sure I have the correct permissions.')
+ else
+ local result = api.set_chat_description(message.chat.id, message.args)
+ if result then
+ return api.send_message(message.chat.id, 'Chat description updated.')
+ end
+ return api.send_message(message.chat.id, 'Failed to update chat description. Make sure I have the correct permissions.')
+ end
+end
+
+return plugin
diff --git a/src/plugins/admin/chatpermissions.lua b/src/plugins/admin/chatpermissions.lua
new file mode 100644
index 0000000..0e5f0c3
--- /dev/null
+++ b/src/plugins/admin/chatpermissions.lua
@@ -0,0 +1,101 @@
+--[[
+ mattata v2.1 - Chat Permissions Plugin
+ Manage default chat permissions with inline keyboard toggles.
+]]
+
+local plugin = {}
+plugin.name = 'chatpermissions'
+plugin.category = 'admin'
+plugin.description = 'Manage chat permissions'
+plugin.commands = { 'permissions', 'perms' }
+plugin.help = '/permissions - View and toggle default chat permissions.'
+plugin.group_only = true
+plugin.admin_only = true
+
+local json = require('dkjson')
+
+local PERMISSION_LABELS = {
+ { key = 'can_send_messages', label = 'Send Messages' },
+ { key = 'can_send_audios', label = 'Send Audios' },
+ { key = 'can_send_documents', label = 'Send Documents' },
+ { key = 'can_send_photos', label = 'Send Photos' },
+ { key = 'can_send_videos', label = 'Send Videos' },
+ { key = 'can_send_video_notes', label = 'Send Video Notes' },
+ { key = 'can_send_voice_notes', label = 'Send Voice Notes' },
+ { key = 'can_send_polls', label = 'Send Polls' },
+ { key = 'can_send_other_messages', label = 'Stickers/GIFs' },
+ { key = 'can_add_web_page_previews', label = 'Link Previews' },
+ { key = 'can_change_info', label = 'Change Info' },
+ { key = 'can_invite_users', label = 'Invite Users' },
+ { key = 'can_pin_messages', label = 'Pin Messages' },
+ { key = 'can_manage_topics', label = 'Manage Topics' },
+}
+
+local function build_keyboard(perms, chat_id)
+ local rows = {}
+ for _, perm in ipairs(PERMISSION_LABELS) do
+ local enabled = perms[perm.key]
+ local icon = enabled and '\xe2\x9c\x85' or '\xe2\x9b\x94'
+ table.insert(rows, { {
+ text = icon .. ' ' .. perm.label,
+ callback_data = 'chatpermissions:toggle:' .. chat_id .. ':' .. perm.key
+ } })
+ end
+ table.insert(rows, { { text = 'Done', callback_data = 'chatpermissions:done' } })
+ return json.encode({ inline_keyboard = rows })
+end
+
+local function get_current_permissions(api, chat_id)
+ local chat = api.get_chat(chat_id)
+ if chat and chat.result and chat.result.permissions then
+ return chat.result.permissions
+ end
+ -- Default to all enabled
+ local defaults = {}
+ for _, perm in ipairs(PERMISSION_LABELS) do
+ defaults[perm.key] = true
+ end
+ return defaults
+end
+
+function plugin.on_message(api, message, ctx)
+ local perms = get_current_permissions(api, message.chat.id)
+ local keyboard = build_keyboard(perms, message.chat.id)
+ return api.send_message(message.chat.id, '<b>Default Chat Permissions</b>\nTap a permission to toggle it.', 'html', false, false, nil, keyboard)
+end
+
+function plugin.on_callback_query(api, callback_query, message, ctx)
+ local data = callback_query.data
+ if not data then return end
+
+ if data == 'done' then
+ api.delete_message(message.chat.id, message.message_id)
+ return api.answer_callback_query(callback_query.id, 'Permissions saved.')
+ end
+
+ local chat_id, perm_key = data:match('^toggle:(%-?%d+):(.+)$')
+ if not chat_id or not perm_key then return end
+ chat_id = tonumber(chat_id)
+
+ -- Only admins can toggle
+ local permissions = require('src.core.permissions')
+ if not permissions.is_group_admin(api, chat_id, callback_query.from.id) then
+ return api.answer_callback_query(callback_query.id, 'Only admins can change permissions.')
+ end
+
+ local perms = get_current_permissions(api, chat_id)
+
+ -- Toggle
+ perms[perm_key] = not perms[perm_key]
+
+ local result = api.set_chat_permissions(chat_id, perms)
+ if not result then
+ return api.answer_callback_query(callback_query.id, 'Failed to update permissions.')
+ end
+
+ local keyboard = build_keyboard(perms, chat_id)
+ api.edit_message_reply_markup(message.chat.id, message.message_id, nil, keyboard)
+ return api.answer_callback_query(callback_query.id, 'Permission updated.')
+end
+
+return plugin
diff --git a/src/plugins/admin/customtitle.lua b/src/plugins/admin/customtitle.lua
new file mode 100644
index 0000000..298dcfc
--- /dev/null
+++ b/src/plugins/admin/customtitle.lua
@@ -0,0 +1,55 @@
+--[[
+ mattata v2.1 - Custom Title Plugin
+ Set custom admin titles.
+]]
+
+local plugin = {}
+plugin.name = 'customtitle'
+plugin.category = 'admin'
+plugin.description = 'Set admin custom title'
+plugin.commands = { 'customtitle', 'title' }
+plugin.help = '/customtitle <title> - Set a custom title for an admin. Reply to a user or pass their ID/username.'
+plugin.group_only = true
+plugin.admin_only = true
+
+function plugin.on_message(api, message, ctx)
+ local tools = require('telegram-bot-lua.tools')
+ local permissions = require('src.core.permissions')
+
+ if not permissions.can_promote(api, message.chat.id) then
+ return api.send_message(message.chat.id, 'I need the "Promote Members" admin permission to use this command.')
+ end
+
+ local target_id
+ local title
+
+ if message.reply and message.reply.from then
+ target_id = message.reply.from.id
+ title = message.args
+ elseif message.args then
+ local id_or_user, rest = message.args:match('^(%S+)%s+(.+)$')
+ if id_or_user then
+ target_id = tonumber(id_or_user) or ctx.redis.get('username:' .. id_or_user:lower():gsub('^@', ''))
+ title = rest
+ end
+ end
+
+ if not target_id or not title or title == '' then
+ return api.send_message(message.chat.id, 'Usage: Reply to an admin with /customtitle <title>, or use /customtitle <user> <title>')
+ end
+
+ if #title > 16 then
+ return api.send_message(message.chat.id, 'Custom title must be 16 characters or less.')
+ end
+
+ local result = api.set_chat_administrator_custom_title(message.chat.id, target_id, title)
+ if result then
+ return api.send_message(message.chat.id, string.format(
+ 'Custom title for <a href="tg://user?id=%s">this admin</a> set to: <b>%s</b>',
+ tostring(target_id), tools.escape_html(title)
+ ), 'html')
+ end
+ return api.send_message(message.chat.id, 'Failed to set custom title. The user must be an admin promoted by me.')
+end
+
+return plugin
diff --git a/src/plugins/admin/init.lua b/src/plugins/admin/init.lua
index 74c699e..0957f0c 100644
--- a/src/plugins/admin/init.lua
+++ b/src/plugins/admin/init.lua
@@ -1,63 +1,70 @@
--[[
mattata v2.0 - Admin Plugin Category
]]
return {
plugins = {
'administration',
'ban',
'unban',
'kick',
'mute',
'unmute',
'warn',
'tempban',
'tempmute',
'promote',
'demote',
'trust',
'untrust',
'report',
'staff',
'purge',
'rules',
'setwelcome',
'setcaptcha',
'antispam',
'filter',
'unfilter',
'wordfilter',
'antilink',
'logchat',
'setgrouplang',
'link',
'addalias',
'triggers',
'addtrigger',
'nodelete',
'channel',
'save',
'import',
'allowlist',
'blocklist',
'groups',
'join_captcha',
'pin',
'allowedlinks',
'allowlink',
+ 'unpinall',
+ 'chatinfo',
+ 'customtitle',
+ 'slowmode',
+ 'topic',
+ 'joinrequest',
+ 'chatpermissions',
-- Federation sub-package
'federation.newfed',
'federation.delfed',
'federation.joinfed',
'federation.leavefed',
'federation.fban',
'federation.unfban',
'federation.fbaninfo',
'federation.fpromote',
'federation.fdemote',
'federation.fadmins',
'federation.fallowlist',
'federation.myfeds',
'federation.feds'
}
}
diff --git a/src/plugins/admin/joinrequest.lua b/src/plugins/admin/joinrequest.lua
new file mode 100644
index 0000000..91e9b6b
--- /dev/null
+++ b/src/plugins/admin/joinrequest.lua
@@ -0,0 +1,135 @@
+--[[
+ mattata v2.1 - Join Request Plugin
+ Manage join request policies for groups with approval-required invites.
+ Depends on the on_chat_join_request router hook (Phase 3).
+]]
+
+local plugin = {}
+plugin.name = 'joinrequest'
+plugin.category = 'admin'
+plugin.description = 'Manage join request policy'
+plugin.commands = { 'joinrequest' }
+plugin.help = '/joinrequest <auto-approve|auto-reject|manual> - Set the join request policy for this chat.'
+plugin.group_only = true
+plugin.admin_only = true
+
+local json = require('dkjson')
+
+local POLICIES = {
+ ['auto-approve'] = true, ['approve'] = true, ['auto'] = true,
+ ['auto-reject'] = true, ['reject'] = true, ['deny'] = true,
+ ['manual'] = true, ['notify'] = true
+}
+
+local function normalize_policy(input)
+ input = input:lower()
+ if input == 'auto-approve' or input == 'approve' or input == 'auto' then
+ return 'auto-approve'
+ elseif input == 'auto-reject' or input == 'reject' or input == 'deny' then
+ return 'auto-reject'
+ elseif input == 'manual' or input == 'notify' then
+ return 'manual'
+ end
+ return nil
+end
+
+function plugin.on_message(api, message, ctx)
+ if not message.args or message.args == '' then
+ local current = ctx.db.call('sp_get_chat_setting', { message.chat.id, 'join_request_policy' })
+ local policy = (current and #current > 0) and current[1].value or 'manual'
+ return api.send_message(message.chat.id, string.format(
+ 'Current join request policy: <b>%s</b>\n\nUsage: /joinrequest <auto-approve|auto-reject|manual>',
+ policy
+ ), 'html')
+ end
+
+ local policy = normalize_policy(message.args)
+ if not policy then
+ return api.send_message(message.chat.id, 'Invalid policy. Use: auto-approve, auto-reject, or manual')
+ end
+
+ ctx.db.call('sp_upsert_chat_setting', { message.chat.id, 'join_request_policy', policy })
+ require('src.core.session').invalidate_setting(message.chat.id, 'join_request_policy')
+
+ return api.send_message(message.chat.id, string.format(
+ 'Join request policy set to <b>%s</b>.', policy
+ ), 'html')
+end
+
+-- Handle incoming join requests based on configured policy
+function plugin.on_chat_join_request(api, request, ctx)
+ local session = require('src.core.session')
+ local tools = require('telegram-bot-lua.tools')
+
+ local policy = session.get_cached_setting(request.chat.id, 'join_request_policy', function()
+ local result = ctx.db.call('sp_get_chat_setting', { request.chat.id, 'join_request_policy' })
+ if result and #result > 0 then return result[1].value end
+ return nil
+ end, 300)
+
+ if not policy or policy == 'manual' then
+ -- Post notification with approve/reject buttons
+ local keyboard = {
+ inline_keyboard = { {
+ { text = 'Approve', callback_data = 'joinrequest:approve:' .. request.from.id },
+ { text = 'Reject', callback_data = 'joinrequest:reject:' .. request.from.id }
+ } }
+ }
+ local text = string.format(
+ '<a href="tg://user?id=%d">%s</a> wants to join this chat.',
+ request.from.id,
+ tools.escape_html(request.from.first_name)
+ )
+ return api.send_message(request.chat.id, text, 'html', false, false, nil, json.encode(keyboard))
+
+ elseif policy == 'auto-approve' then
+ return api.approve_chat_join_request(request.chat.id, request.from.id)
+
+ elseif policy == 'auto-reject' then
+ return api.decline_chat_join_request(request.chat.id, request.from.id)
+ end
+end
+
+function plugin.on_callback_query(api, callback_query, message, ctx)
+ local data = callback_query.data
+ if not data then return end
+
+ local action, user_id = data:match('^(approve):(%d+)$')
+ if not action then
+ action, user_id = data:match('^(reject):(%d+)$')
+ end
+ if not action or not user_id then return end
+
+ user_id = tonumber(user_id)
+
+ -- Only admins can handle join requests
+ local permissions = require('src.core.permissions')
+ if not permissions.is_group_admin(api, message.chat.id, callback_query.from.id) then
+ return api.answer_callback_query(callback_query.id, 'Only admins can handle join requests.')
+ end
+
+ local tools = require('telegram-bot-lua.tools')
+ if action == 'approve' then
+ local result = api.approve_chat_join_request(message.chat.id, user_id)
+ if result then
+ api.edit_message_text(message.chat.id, message.message_id, string.format(
+ 'Join request from <a href="tg://user?id=%d">user</a> approved by %s.',
+ user_id, tools.escape_html(callback_query.from.first_name)
+ ), 'html')
+ return api.answer_callback_query(callback_query.id, 'Approved.')
+ end
+ return api.answer_callback_query(callback_query.id, 'Failed to approve. The request may have expired.')
+ else
+ local result = api.decline_chat_join_request(message.chat.id, user_id)
+ if result then
+ api.edit_message_text(message.chat.id, message.message_id, string.format(
+ 'Join request from <a href="tg://user?id=%d">user</a> rejected by %s.',
+ user_id, tools.escape_html(callback_query.from.first_name)
+ ), 'html')
+ return api.answer_callback_query(callback_query.id, 'Rejected.')
+ end
+ return api.answer_callback_query(callback_query.id, 'Failed to reject. The request may have expired.')
+ end
+end
+
+return plugin
diff --git a/src/plugins/admin/slowmode.lua b/src/plugins/admin/slowmode.lua
new file mode 100644
index 0000000..8575f6c
--- /dev/null
+++ b/src/plugins/admin/slowmode.lua
@@ -0,0 +1,50 @@
+--[[
+ mattata v2.1 - Slow Mode Plugin
+ Control slow mode delay in groups.
+]]
+
+local plugin = {}
+plugin.name = 'slowmode'
+plugin.category = 'admin'
+plugin.description = 'Set slow mode delay'
+plugin.commands = { 'slowmode', 'slow' }
+plugin.help = '/slowmode <off|10s|30s|1m|5m|15m|1h> - Set slow mode delay for the chat.'
+plugin.group_only = true
+plugin.admin_only = true
+
+local DELAYS = {
+ ['off'] = 0, ['0'] = 0, ['disable'] = 0,
+ ['10s'] = 10, ['10'] = 10,
+ ['30s'] = 30, ['30'] = 30,
+ ['1m'] = 60, ['60'] = 60, ['60s'] = 60,
+ ['5m'] = 300, ['300'] = 300, ['300s'] = 300,
+ ['15m'] = 900, ['900'] = 900, ['900s'] = 900,
+ ['1h'] = 3600, ['3600'] = 3600, ['3600s'] = 3600,
+}
+
+local function format_delay(seconds)
+ if seconds == 0 then return 'disabled' end
+ if seconds < 60 then return seconds .. ' seconds' end
+ if seconds < 3600 then return (seconds / 60) .. ' minutes' end
+ return (seconds / 3600) .. ' hour'
+end
+
+function plugin.on_message(api, message, ctx)
+ if not message.args or message.args == '' then
+ return api.send_message(message.chat.id, 'Usage: /slowmode <off|10s|30s|1m|5m|15m|1h>')
+ end
+
+ local delay = DELAYS[message.args:lower()]
+ if not delay then
+ return api.send_message(message.chat.id, 'Invalid delay. Options: off, 10s, 30s, 1m, 5m, 15m, 1h')
+ end
+
+ local result = api.set_chat_slow_mode_delay(message.chat.id, delay)
+ if result then
+ local label = format_delay(delay)
+ return api.send_message(message.chat.id, string.format('Slow mode set to <b>%s</b>.', label), 'html')
+ end
+ return api.send_message(message.chat.id, 'Failed to set slow mode. Make sure I have the correct permissions.')
+end
+
+return plugin
diff --git a/src/plugins/admin/topic.lua b/src/plugins/admin/topic.lua
new file mode 100644
index 0000000..39d0dea
--- /dev/null
+++ b/src/plugins/admin/topic.lua
@@ -0,0 +1,93 @@
+--[[
+ mattata v2.1 - Topic Plugin
+ Forum topic management for supergroups with topics enabled.
+]]
+
+local plugin = {}
+plugin.name = 'topic'
+plugin.category = 'admin'
+plugin.description = 'Manage forum topics'
+plugin.commands = { 'topic' }
+plugin.help = '/topic <create|close|reopen|delete|rename> [name] - Manage forum topics.'
+plugin.group_only = true
+plugin.admin_only = true
+
+function plugin.on_message(api, message, ctx)
+ if not message.chat.is_forum then
+ return api.send_message(message.chat.id, 'This command only works in forum-enabled groups.')
+ end
+
+ if not message.args or message.args == '' then
+ return api.send_message(message.chat.id, 'Usage:\n/topic create <name>\n/topic close\n/topic reopen\n/topic delete\n/topic rename <name>')
+ end
+
+ local subcommand, args = message.args:match('^(%S+)%s*(.*)')
+ subcommand = subcommand:lower()
+
+ local topic_id = message.message_thread_id
+
+ if subcommand == 'create' then
+ if not args or args == '' then
+ return api.send_message(message.chat.id, 'Usage: /topic create <name>')
+ end
+ local result = api.create_forum_topic(message.chat.id, args)
+ if result and result.result then
+ return api.send_message(message.chat.id, string.format(
+ 'Topic "<b>%s</b>" created.',
+ require('telegram-bot-lua.tools').escape_html(args)
+ ), 'html')
+ end
+ return api.send_message(message.chat.id, 'Failed to create topic.')
+
+ elseif subcommand == 'close' then
+ if not topic_id then
+ return api.send_message(message.chat.id, 'Send this command inside the topic you want to close.')
+ end
+ local result = api.close_forum_topic(message.chat.id, topic_id)
+ if result then
+ return api.send_message(message.chat.id, 'Topic closed.')
+ end
+ return api.send_message(message.chat.id, 'Failed to close topic.')
+
+ elseif subcommand == 'reopen' then
+ if not topic_id then
+ return api.send_message(message.chat.id, 'Send this command inside the topic you want to reopen.')
+ end
+ local result = api.reopen_forum_topic(message.chat.id, topic_id)
+ if result then
+ return api.send_message(message.chat.id, 'Topic reopened.')
+ end
+ return api.send_message(message.chat.id, 'Failed to reopen topic.')
+
+ elseif subcommand == 'delete' then
+ if not topic_id then
+ return api.send_message(message.chat.id, 'Send this command inside the topic you want to delete.')
+ end
+ local result = api.delete_forum_topic(message.chat.id, topic_id)
+ if result then
+ return -- topic deleted, can't send message to it
+ end
+ return api.send_message(message.chat.id, 'Failed to delete topic.')
+
+ elseif subcommand == 'rename' then
+ if not topic_id then
+ return api.send_message(message.chat.id, 'Send this command inside the topic you want to rename.')
+ end
+ if not args or args == '' then
+ return api.send_message(message.chat.id, 'Usage: /topic rename <new name>')
+ end
+ local result = api.edit_forum_topic(message.chat.id, topic_id, args)
+ if result then
+ return api.send_message(message.chat.id, string.format(
+ 'Topic renamed to "<b>%s</b>".',
+ require('telegram-bot-lua.tools').escape_html(args)
+ ), 'html')
+ end
+ return api.send_message(message.chat.id, 'Failed to rename topic.')
+
+ else
+ return api.send_message(message.chat.id, 'Unknown subcommand. Use: create, close, reopen, delete, rename')
+ end
+end
+
+return plugin
diff --git a/src/plugins/admin/unpinall.lua b/src/plugins/admin/unpinall.lua
new file mode 100644
index 0000000..1387efd
--- /dev/null
+++ b/src/plugins/admin/unpinall.lua
@@ -0,0 +1,28 @@
+--[[
+ mattata v2.1 - Unpin All Plugin
+ Unpins all messages in a chat.
+]]
+
+local plugin = {}
+plugin.name = 'unpinall'
+plugin.category = 'admin'
+plugin.description = 'Unpin all pinned messages'
+plugin.commands = { 'unpinall' }
+plugin.help = '/unpinall - Unpins all pinned messages in this chat.'
+plugin.group_only = true
+plugin.admin_only = true
+
+function plugin.on_message(api, message, ctx)
+ local permissions = require('src.core.permissions')
+ if not permissions.can_pin(api, message.chat.id) then
+ return api.send_message(message.chat.id, 'I need the "Pin Messages" admin permission to use this command.')
+ end
+
+ local result = api.unpin_all_chat_messages(message.chat.id)
+ if result then
+ return api.send_message(message.chat.id, 'All pinned messages have been unpinned.')
+ end
+ return api.send_message(message.chat.id, 'Failed to unpin messages. Make sure I have the correct permissions.')
+end
+
+return plugin

File Metadata

Mime Type
text/x-diff
Expires
Wed, Apr 1, 11:15 AM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
57029
Default Alt Text
(22 KB)

Event Timeline