Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F117971
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
16 KB
Referenced Files
None
Subscribers
None
View Options
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 576c4ba..cf5afa3 100644
--- a/src/plugins/admin/init.lua
+++ b/src/plugins/admin/init.lua
@@ -1,68 +1,73 @@
--[[
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',
'slowmode',
'autodelete',
'topic',
'customcaptcha',
+ 'unpinall',
+ 'chatinfo',
+ 'customtitle',
+ 'joinrequest',
+ 'chatpermissions',
'bulkops',
-- 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..34d9c28
--- /dev/null
+++ b/src/plugins/admin/joinrequest.lua
@@ -0,0 +1,129 @@
+--[[
+ 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 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/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
Details
Attached
Mime Type
text/x-diff
Expires
Fri, May 15, 12:19 AM (1 d, 7 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
63781
Default Alt Text
(16 KB)
Attached To
Mode
R69 mattata
Attached
Detach File
Event Timeline