2016-02-23 12:15:48 +01:00
--[[
administration.lua
2016-03-28 08:15:46 +02:00
Version 1.6 .1
2016-02-23 12:15:48 +01:00
Part of the otouto project .
© 2016 topkecleon < drew @ otou.to >
GNU General Public License , version 2
This plugin provides self - hosted , single - realm group administration .
It requires tg ( http : // github.com / vysheng / tg ) with supergroup support .
For more documentation , view the readme or the manual ( otou.to / rtfm ) .
Remember to load this before blacklist.lua .
2016-02-25 10:42:13 +01:00
2016-03-04 23:08:21 +01:00
Important notices about updates will be here !
2016-03-22 11:16:26 +01:00
Rules lists always exist , empty if there are no rules . Group arrays are now
stored in a " groups " array rather than at the top level . Global data is now
stored at the top level rather than in a " global " array . Automatic migration
will occur in versions 1.5 and 1.6 .
2016-03-27 14:30:41 +02:00
/ groups will now list groups according to activity .
2016-02-23 12:15:48 +01:00
] ] --
-- Build the administration db if nonexistent.
2016-02-21 20:28:40 +01:00
if not database.administration then
database.administration = {
2016-03-22 11:16:26 +01:00
admins = { } ,
2016-03-27 14:30:41 +02:00
groups = { } ,
activity = { }
2016-02-20 11:07:20 +01:00
}
end
2016-03-31 13:53:12 +02:00
admin_temp = {
help = { } ,
flood = { }
}
2016-03-22 11:16:26 +01:00
-- Migration code: Remove this in v1.7.
-- Group data is now stored in a "groups" array.
if not database.administration . groups then
database.administration . groups = { }
for k , v in pairs ( database.administration ) do
if tonumber ( k ) then
database.administration . groups [ k ] = v
database.administration [ k ] = nil
end
2016-02-23 12:15:48 +01:00
end
end
2016-03-22 11:16:26 +01:00
-- Global data is stored at the top level.
if database.administration . global then
for k , v in pairs ( database.administration . global ) do
database.administration [ k ] = v
2016-02-25 10:42:13 +01:00
end
2016-03-22 11:16:26 +01:00
database.administration . global = nil
end
-- Rule lists remain empty, rather than nil, when there are no rules.
for k , v in pairs ( database.administration . groups ) do
v.rules = v.rules or { }
2016-02-25 10:42:13 +01:00
end
2016-03-27 14:30:41 +02:00
-- Migration code: Remove this in v1.8.
-- Most recent group activity is now cached for group listings.
if not database.administration . activity then
database.administration . activity = { }
for k , v in pairs ( database.administration . groups ) do
table.insert ( database.administration . activity , k )
end
end
drua = dofile ( ' drua-tg/drua-tg.lua ' )
drua.PORT = config.cli_port or 4567
2016-02-20 11:07:20 +01:00
local flags = {
[ 1 ] = {
name = ' unlisted ' ,
desc = ' Removes this group from the group listing. ' ,
2016-02-25 10:42:13 +01:00
short = ' This group is unlisted. ' ,
2016-02-20 11:07:20 +01:00
enabled = ' This group is no longer listed in /groups. ' ,
disabled = ' This group is now listed in /groups. '
} ,
[ 2 ] = {
name = ' antisquig ' ,
desc = ' Automatically removes users who post Arabic script or RTL characters. ' ,
2016-02-25 10:42:13 +01:00
short = ' This group does not allow Arabic script or RTL characters. ' ,
2016-02-20 11:07:20 +01:00
enabled = ' Users will now be removed automatically for posting Arabic script and/or RTL characters. ' ,
disabled = ' Users will no longer be removed automatically for posting Arabic script and/or RTL characters.. ' ,
2016-02-25 10:42:13 +01:00
kicked = ' You were automatically kicked from GROUPNAME for posting Arabic script and/or RTL characters. '
2016-02-20 11:07:20 +01:00
} ,
[ 3 ] = {
2016-03-31 13:53:12 +02:00
name = ' antisquig++ ' ,
2016-02-20 11:07:20 +01:00
desc = ' Automatically removes users whose names contain Arabic script or RTL characters. ' ,
2016-02-25 10:42:13 +01:00
short = ' This group does not allow users whose names contain Arabic script or RTL characters. ' ,
2016-02-20 11:07:20 +01:00
enabled = ' Users whose names contain Arabic script and/or RTL characters will now be removed automatically. ' ,
disabled = ' Users whose names contain Arabic script and/or RTL characters will no longer be removed automatically. ' ,
2016-02-25 10:42:13 +01:00
kicked = ' You were automatically kicked from GROUPNAME for having a name which contains Arabic script and/or RTL characters. '
2016-02-20 11:07:20 +01:00
} ,
[ 4 ] = {
name = ' antibot ' ,
2016-03-22 11:16:26 +01:00
desc = ' Prevents the addition of bots by non-moderators. ' ,
2016-02-25 10:42:13 +01:00
short = ' This group does not allow users to add bots. ' ,
2016-02-20 11:07:20 +01:00
enabled = ' Non-moderators will no longer be able to add bots. ' ,
disabled = ' Non-moderators will now be able to add bots. '
2016-03-31 13:53:12 +02:00
} ,
[ 5 ] = {
name = ' antiflood ' ,
desc = ' Prevents flooding by rate-limiting messages per user. ' ,
short = ' This group automatically removes users who flood. ' ,
enabled = ' Users will now be removed automatically for excessive messages. Use /antiflood to configure limits. ' ,
disabled = ' Users will no longer be removed automatically for excessive messages. ' ,
kicked = ' You were automatically kicked from GROUPNAME for flooding. '
2016-02-20 11:07:20 +01:00
}
}
2016-03-31 13:53:12 +02:00
local antiflood = {
text = 5 ,
voice = 5 ,
audio = 5 ,
contact = 5 ,
photo = 10 ,
video = 10 ,
location = 10 ,
document = 10 ,
sticker = 20
}
2016-02-20 11:07:20 +01:00
local ranks = {
[ 0 ] = ' Banned ' ,
[ 1 ] = ' Users ' ,
[ 2 ] = ' Moderators ' ,
[ 3 ] = ' Governors ' ,
[ 4 ] = ' Administrators ' ,
[ 5 ] = ' Owner '
}
local get_rank = function ( target , chat )
target = tostring ( target )
if chat then
chat = tostring ( chat )
end
if tonumber ( target ) == config.admin or tonumber ( target ) == bot.id then
return 5
end
2016-03-22 11:16:26 +01:00
if database.administration . admins [ target ] then
2016-02-20 11:07:20 +01:00
return 4
end
2016-03-22 11:16:26 +01:00
if chat and database.administration . groups [ chat ] then
if database.administration . groups [ chat ] . govs [ target ] then
2016-02-20 11:07:20 +01:00
return 3
2016-03-22 11:16:26 +01:00
elseif database.administration . groups [ chat ] . mods [ target ] then
2016-02-20 11:07:20 +01:00
return 2
2016-03-22 11:16:26 +01:00
elseif database.administration . groups [ chat ] . bans [ target ] then
2016-02-20 11:07:20 +01:00
return 0
end
end
2016-02-23 12:15:48 +01:00
if database.blacklist [ target ] then
2016-02-20 11:07:20 +01:00
return 0
end
return 1
end
local get_target = function ( msg )
2016-03-22 11:16:26 +01:00
local target = user_from_message ( msg )
2016-02-20 11:07:20 +01:00
if target.id then
target.rank = get_rank ( target.id , msg.chat . id )
end
return target
end
2016-03-28 08:15:46 +02:00
local mod_format = function ( id )
id = tostring ( id )
local user = database.users [ id ] or { first_name = ' Unknown ' }
local name = user.first_name
if user.last_name then name = user.first_name .. ' ' .. user.last_name end
name = markdown_escape ( name )
local output = ' • ' .. name .. ' `[ ' .. id .. ' ]` \n '
return output
end
2016-02-23 12:15:48 +01:00
local get_desc = function ( chat_id )
2016-03-22 11:16:26 +01:00
local group = database.administration . groups [ tostring ( chat_id ) ]
2016-03-28 08:15:46 +02:00
local t = { }
2016-02-23 12:15:48 +01:00
if group.link then
2016-03-28 08:15:46 +02:00
table.insert ( t , ' *Welcome to* [ ' .. group.name .. ' ]( ' .. group.link .. ' )*!* ' )
2016-02-23 12:15:48 +01:00
else
2016-03-28 08:15:46 +02:00
table.insert ( t , ' *Welcome to* _ ' .. group.name .. ' _*!* ' )
2016-02-23 12:15:48 +01:00
end
if group.motd then
2016-03-28 08:15:46 +02:00
table.insert ( t , ' *Message of the Day:* \n ' .. group.motd )
2016-02-23 12:15:48 +01:00
end
2016-03-22 11:16:26 +01:00
if # group.rules > 0 then
2016-03-28 08:15:46 +02:00
local rulelist = ' *Rules:* \n '
2016-02-25 10:42:13 +01:00
for i , v in ipairs ( group.rules ) do
2016-03-28 08:15:46 +02:00
rulelist = rulelist .. ' * ' .. i .. ' .* ' .. v .. ' \n '
2016-02-25 10:42:13 +01:00
end
2016-03-28 08:15:46 +02:00
table.insert ( t , rulelist : trim ( ) )
2016-02-25 10:42:13 +01:00
end
2016-03-28 08:15:46 +02:00
local flaglist = ' '
for i = 1 , # flags do
if group.flags [ i ] then
2016-03-31 13:53:12 +02:00
flaglist = flaglist .. ' • ' .. flags [ i ] . short .. ' \n '
2016-02-25 10:42:13 +01:00
end
2016-02-23 12:15:48 +01:00
end
2016-03-28 08:15:46 +02:00
if flaglist ~= ' ' then
table.insert ( t , ' *Flags:* \n ' .. flaglist : trim ( ) )
end
local modstring = ' '
for k , v in pairs ( group.mods ) do
modstring = modstring .. mod_format ( k )
end
if modstring ~= ' ' then
table.insert ( t , ' *Moderators:* \n ' .. modstring : trim ( ) )
end
local govstring = ' '
for k , v in pairs ( group.govs ) do
govstring = govstring .. mod_format ( k )
end
if govstring ~= ' ' then
table.insert ( t , ' *Governors:* \n ' .. govstring : trim ( ) )
end
return table.concat ( t , ' \n \n ' )
2016-02-23 12:15:48 +01:00
end
2016-02-20 11:07:20 +01:00
local commands = {
{ -- antisquig
triggers = {
' [ \216 - \219 ][ \128 - \191 ] ' , -- arabic
2016-02-25 10:42:13 +01:00
' ' , -- rtl
' ' , -- other rtl
2016-02-20 11:07:20 +01:00
} ,
privilege = 0 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
if get_rank ( msg.from . id , msg.chat . id ) > 1 then
return true
end
2016-03-22 11:16:26 +01:00
if not group.flags [ 2 ] then
2016-02-20 11:07:20 +01:00
return true
end
2016-03-27 14:30:41 +02:00
drua.kick_user ( msg.chat . id , msg.from . id )
2016-03-22 11:16:26 +01:00
local output = flags [ 2 ] . kicked : gsub ( ' GROUPNAME ' , msg.chat . title )
sendMessage ( msg.from . id , output )
2016-02-20 11:07:20 +01:00
end
} ,
{ -- generic
2016-03-27 14:30:41 +02:00
triggers = { ' ' } ,
2016-02-20 11:07:20 +01:00
privilege = 0 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local rank = get_rank ( msg.from . id , msg.chat . id )
-- banned
if rank == 0 then
2016-03-27 14:30:41 +02:00
drua.kick_user ( msg.chat . id , msg.from . id )
2016-02-20 11:07:20 +01:00
sendMessage ( msg.from . id , ' Sorry, you are banned from ' .. msg.chat . title .. ' . ' )
return
end
if rank < 2 then
-- antisquig Strict
if group.flags [ 3 ] == true then
2016-02-25 10:42:13 +01:00
if msg.from . name : match ( ' [ \216 - \219 ][ \128 - \191 ] ' ) or msg.from . name : match ( ' ' ) or msg.from . name : match ( ' ' ) then
2016-03-27 14:30:41 +02:00
drua.kick_user ( msg.chat . id , msg.from . id )
2016-03-22 11:16:26 +01:00
local output = flags [ 3 ] . kicked : gsub ( ' GROUPNAME ' , msg.chat . title )
sendMessage ( msg.from . id , output )
2016-02-20 11:07:20 +01:00
return
end
end
2016-03-31 13:53:12 +02:00
-- antiflood
if group.flags [ 5 ] == true then
if not group.antiflood then
group.antiflood = JSON.decode ( JSON.encode ( antiflood ) )
end
if not admin_temp.flood [ msg.chat . id_str ] then
admin_temp.flood [ msg.chat . id_str ] = { }
end
if not admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] then
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = 0
end
if msg.sticker then -- Thanks Brazil for discarding switches.
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] + group.antiflood . sticker
elseif msg.photo then
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] + group.antiflood . photo
elseif msg.document then
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] + group.antiflood . document
elseif msg.audio then
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] + group.antiflood . audio
elseif msg.contact then
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] + group.antiflood . contact
elseif msg.video then
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] + group.antiflood . video
elseif msg.location then
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] + group.antiflood . location
elseif msg.voice then
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] + group.antiflood . voice
else
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] + group.antiflood . text
end
if admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] > 99 then
drua.kick_user ( msg.chat . id , msg.from . id )
local output = flags [ 5 ] . kicked : gsub ( ' GROUPNAME ' , msg.chat . title )
sendMessage ( msg.from . id , output )
admin_temp.flood [ msg.chat . id_str ] [ msg.from . id_str ] = nil
return
end
end
2016-02-20 11:07:20 +01:00
end
if msg.new_chat_participant then
msg.new_chat_participant . name = msg.new_chat_participant . first_name
if msg.new_chat_participant . last_name then
msg.new_chat_participant . name = msg.new_chat_participant . first_name .. ' ' .. msg.new_chat_participant . last_name
end
-- banned
if get_rank ( msg.new_chat_participant . id , msg.chat . id ) == 0 then
2016-03-27 14:30:41 +02:00
drua.kick_user ( msg.chat . id , msg.new_chat_participant . id )
2016-02-20 11:07:20 +01:00
sendMessage ( msg.new_chat_participant . id , ' Sorry, you are banned from ' .. msg.chat . title .. ' . ' )
return
end
-- antisquig Strict
if group.flags [ 3 ] == true then
2016-02-25 10:42:13 +01:00
if msg.new_chat_participant . name : match ( ' [ \216 - \219 ][ \128 - \191 ] ' ) or msg.new_chat_participant . name : match ( ' ' ) or msg.new_chat_participant . name : match ( ' ' ) then
2016-03-27 14:30:41 +02:00
drua.kick_user ( msg.chat . id , msg.new_chat_participant . id )
2016-03-22 11:16:26 +01:00
local output = flags [ 3 ] . kicked : gsub ( ' GROUPNAME ' , msg.chat . title )
sendMessage ( msg.new_chat_participant . id , output )
2016-02-20 11:07:20 +01:00
return
end
end
-- antibot
2016-02-20 11:48:24 +01:00
if msg.new_chat_participant . username and msg.new_chat_participant . username : match ( ' bot$ ' ) then
2016-02-20 11:07:20 +01:00
if rank < 2 and group.flags [ 4 ] == true then
2016-03-27 14:30:41 +02:00
drua.kick_user ( msg.chat . id , msg.new_chat_participant . id )
2016-02-20 11:07:20 +01:00
return
end
else
2016-02-23 12:15:48 +01:00
local output = get_desc ( msg.chat . id )
2016-02-25 10:42:13 +01:00
sendMessage ( msg.new_chat_participant . id , output , true , nil , true )
2016-02-20 11:07:20 +01:00
return
end
elseif msg.new_chat_title then
if rank < 3 then
2016-03-27 14:30:41 +02:00
drua.rename_chat ( msg.chat . id , group.name )
2016-02-20 11:07:20 +01:00
else
group.name = msg.new_chat_title
end
return
elseif msg.new_chat_photo then
if group.grouptype == ' group ' then
if rank < 3 then
2016-03-27 14:30:41 +02:00
drua.set_photo ( msg.chat . id , group.photo )
2016-02-20 11:07:20 +01:00
else
2016-03-27 14:30:41 +02:00
group.photo = drua.get_photo ( msg.chat . id )
2016-02-20 11:07:20 +01:00
end
2016-03-22 11:16:26 +01:00
else
2016-03-27 14:30:41 +02:00
group.photo = drua.get_photo ( msg.chat . id )
2016-02-20 11:07:20 +01:00
end
return
elseif msg.delete_chat_photo then
if group.grouptype == ' group ' then
if rank < 3 then
2016-03-27 14:30:41 +02:00
drua.set_photo ( msg.chat . id , group.photo )
2016-02-20 11:07:20 +01:00
else
group.photo = nil
end
2016-03-22 11:16:26 +01:00
else
group.photo = nil
2016-02-20 11:07:20 +01:00
end
return
end
2016-03-27 14:30:41 +02:00
-- Last active time for group listing.
for i , v in pairs ( database.administration . activity ) do
if v == msg.chat . id_str then
table.remove ( database.administration . activity , i )
table.insert ( database.administration . activity , 1 , msg.chat . id_str )
end
end
2016-02-20 11:07:20 +01:00
return true
end
} ,
{ -- groups
triggers = {
2016-03-31 13:53:12 +02:00
' ^/groups$ ' ,
' ^/groups@ ' .. bot.username
2016-02-20 11:07:20 +01:00
} ,
command = ' groups ' ,
privilege = 1 ,
interior = false ,
action = function ( msg )
local output = ' '
2016-03-27 14:30:41 +02:00
for i , v in ipairs ( database.administration . activity ) do
local group = database.administration . groups [ v ]
if not group.flags [ 1 ] then -- no unlisted groups
if group.link then
output = output .. ' • [ ' .. group.name .. ' ]( ' .. group.link .. ' ) \n '
2016-02-20 11:07:20 +01:00
else
2016-03-27 14:30:41 +02:00
output = output .. ' • ' .. group.name .. ' \n '
2016-02-20 11:07:20 +01:00
end
end
end
if output == ' ' then
output = ' There are currently no listed groups. '
else
output = ' *Groups:* \n ' .. output
end
sendMessage ( msg.chat . id , output , true , nil , true )
end
} ,
{ -- ahelp
triggers = {
2016-03-31 13:53:12 +02:00
' ^/ahelp$ ' ,
' ^/ahelp@ ' .. bot.username
2016-02-20 11:07:20 +01:00
} ,
command = ' ahelp ' ,
privilege = 1 ,
interior = true ,
action = function ( msg )
2016-02-25 10:42:13 +01:00
local rank = get_rank ( msg.from . id , msg.chat . id )
local output = ' *Commands for ' .. ranks [ rank ] .. ' :* \n '
for i = 1 , rank do
2016-03-31 13:53:12 +02:00
for ind , val in ipairs ( admin_temp.help [ i ] ) do
2016-02-25 10:42:13 +01:00
output = output .. ' • / ' .. val .. ' \n '
end
end
if sendMessage ( msg.from . id , output , true , nil , true ) then
sendReply ( msg , ' I have sent you the requested information in a private message. ' )
else
sendMessage ( msg.chat . id , output , true , nil , true )
end
2016-02-20 11:07:20 +01:00
end
} ,
{ -- alist
triggers = {
2016-03-31 13:53:12 +02:00
' ^/ops$ ' ,
' ^/ops@ ' .. bot.username ,
' ^/oplist$ ' ,
' ^/oplist@ ' .. bot.username
2016-02-20 11:07:20 +01:00
} ,
command = ' ops ' ,
privilege = 1 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local modstring = ' '
2016-03-22 11:16:26 +01:00
for k , v in pairs ( group.mods ) do
modstring = modstring .. mod_format ( k )
2016-02-20 11:07:20 +01:00
end
if modstring ~= ' ' then
modstring = ' *Moderators for* _ ' .. msg.chat . title .. ' _ *:* \n ' .. modstring
end
local govstring = ' '
2016-03-22 11:16:26 +01:00
for k , v in pairs ( group.govs ) do
govstring = govstring .. mod_format ( k )
2016-02-20 11:07:20 +01:00
end
if govstring ~= ' ' then
govstring = ' *Governors for* _ ' .. msg.chat . title .. ' _ *:* \n ' .. govstring
end
2016-03-28 08:15:46 +02:00
local output = modstring .. govstring
if output == ' ' then
output = ' There are currently no moderators for this group. '
2016-02-20 11:07:20 +01:00
end
sendMessage ( msg.chat . id , output , true , nil , true )
end
} ,
2016-02-23 12:15:48 +01:00
{ -- desc
triggers = {
2016-03-31 13:53:12 +02:00
' ^/desc[ription]*$ ' ,
' ^/desc[ription]*@ ' .. bot.username
2016-02-23 12:15:48 +01:00
} ,
command = ' description ' ,
privilege = 1 ,
interior = true ,
action = function ( msg )
local output = get_desc ( msg.chat . id )
2016-02-25 10:42:13 +01:00
if sendMessage ( msg.from . id , output , true , nil , true ) then
sendReply ( msg , ' I have sent you the requested information in a private message. ' )
else
sendMessage ( msg.chat . id , output , true , nil , true )
end
2016-02-23 12:15:48 +01:00
end
} ,
2016-02-20 11:07:20 +01:00
{ -- rules
triggers = {
2016-03-31 13:53:12 +02:00
' ^/rules$ ' ,
' ^/rules@ ' .. bot.username
2016-02-20 11:07:20 +01:00
} ,
command = ' rules ' ,
privilege = 1 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local output = ' No rules have been set for ' .. msg.chat . title .. ' . '
2016-03-22 11:16:26 +01:00
if # group.rules > 0 then
2016-02-25 10:42:13 +01:00
output = ' *Rules for* _ ' .. msg.chat . title .. ' _ *:* \n '
2016-03-22 11:16:26 +01:00
for i , v in ipairs ( group.rules ) do
2016-02-25 10:42:13 +01:00
output = output .. ' * ' .. i .. ' .* ' .. v .. ' \n '
end
2016-02-20 11:07:20 +01:00
end
sendMessage ( msg.chat . id , output , true , nil , true )
end
} ,
{ -- motd
triggers = {
2016-03-31 13:53:12 +02:00
' ^/motd$ ' ,
' ^/motd@ ' .. bot.username
2016-02-20 11:07:20 +01:00
} ,
command = ' motd ' ,
privilege = 1 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local output = ' No MOTD has been set for ' .. msg.chat . title .. ' . '
2016-03-22 11:16:26 +01:00
if group.motd then
output = ' *MOTD for* _ ' .. msg.chat . title .. ' _ *:* \n ' .. group.motd
2016-02-20 11:07:20 +01:00
end
sendMessage ( msg.chat . id , output , true , nil , true )
end
} ,
{ -- link
triggers = {
2016-03-31 13:53:12 +02:00
' ^/link$ ' ,
' ^/link@ ' .. bot.username
2016-02-20 11:07:20 +01:00
} ,
command = ' link ' ,
privilege = 1 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local output = ' No link has been set for ' .. msg.chat . title .. ' . '
2016-03-22 11:16:26 +01:00
if group.link then
output = ' [ ' .. msg.chat . title .. ' ]( ' .. group.link .. ' ) '
2016-02-20 11:07:20 +01:00
end
sendMessage ( msg.chat . id , output , true , nil , true )
end
} ,
{ -- kickme
triggers = {
' ^/leave[@ ' .. bot.username .. ' ]* ' ,
' ^/kickme[@ ' .. bot.username .. ' ]* '
} ,
command = ' leave ' ,
privilege = 1 ,
interior = true ,
action = function ( msg )
if get_rank ( msg.from . id ) == 5 then
local output = ' I can \' t let you do that, ' .. msg.from . first_name .. ' . '
sendMessage ( msg.chat . id , output , true , nil , true )
elseif msg.chat . type == ' supergroup ' then
local output = ' Leave this group manually or you will be unable to rejoin. '
sendMessage ( msg.chat . id , output , true , nil , true )
else
2016-03-27 14:30:41 +02:00
drua.kick_user ( msg.chat . id , msg.from . id )
2016-02-20 11:07:20 +01:00
end
end
} ,
{ -- kick
triggers = {
' ^/kick[@ ' .. bot.username .. ' ]* '
} ,
command = ' kick <user> ' ,
privilege = 2 ,
interior = true ,
action = function ( msg )
local target = get_target ( msg )
if target.err then
sendReply ( msg , target.err )
return
elseif target.rank > 1 then
2016-02-27 04:06:38 +01:00
sendReply ( msg , target.name .. ' is too privileged to be kicked. ' )
2016-02-20 11:07:20 +01:00
return
end
2016-03-27 14:30:41 +02:00
drua.kick_user ( msg.chat . id , target.id )
2016-02-20 11:07:20 +01:00
sendMessage ( msg.chat . id , target.name .. ' has been kicked. ' )
end
} ,
{ -- ban
triggers = {
2016-03-22 11:16:26 +01:00
' ^/ban ' ,
' ^/unban '
2016-02-20 11:07:20 +01:00
} ,
command = ' ban <user> ' ,
privilege = 2 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local target = get_target ( msg )
if target.err then
sendReply ( msg , target.err )
return
end
if target.rank > 1 then
2016-02-27 04:06:38 +01:00
sendReply ( msg , target.name .. ' is too privileged to be banned. ' )
2016-02-20 11:07:20 +01:00
return
end
2016-03-22 11:16:26 +01:00
if group.bans [ target.id_str ] then
group.bans [ target.id_str ] = nil
sendReply ( msg , target.name .. ' has been unbanned. ' )
else
group.bans [ target.id_str ] = true
2016-03-27 14:30:41 +02:00
drua.kick_user ( msg.chat . id , target.id )
2016-03-22 11:16:26 +01:00
sendReply ( msg , target.name .. ' has been banned. ' )
2016-02-20 11:07:20 +01:00
end
end
} ,
2016-02-25 10:42:13 +01:00
{ -- changerule
triggers = {
' ^/changerule ' ,
' ^/changerule@ ' .. bot.username
} ,
2016-03-31 13:53:12 +02:00
command = ' changerule <i> <rule> ' ,
2016-02-25 10:42:13 +01:00
privilege = 3 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-25 10:42:13 +01:00
local usage = ' usage: `/changerule <i> <newrule>` \n `/changerule <i> -- `deletes. '
local input = msg.text : input ( )
if not input then
sendMessage ( msg.chat . id , usage , true , msg.message_id , true )
return
end
local rule_num = input : match ( ' ^%d+ ' )
if not rule_num then
local output = ' Please specify which rule you want to change. \n ' .. usage
sendMessage ( msg.chat . id , output , true , msg.message_id , true )
return
end
rule_num = tonumber ( rule_num )
local rule_new = input : input ( )
if not rule_new then
local output = ' Please specify the new rule. \n ' .. usage
sendMessage ( msg.chat . id , output , true , msg.message_id , true )
return
end
2016-03-22 11:16:26 +01:00
if not group.rules then
2016-02-25 10:42:13 +01:00
local output = ' Sorry, there are no rules to change. Please use /setrules. \n ' .. usage
sendMessage ( msg.chat . id , output , true , msg.message_id , true )
return
end
2016-03-22 11:16:26 +01:00
if not group.rules [ rule_num ] then
rule_num = # group.rules + 1
2016-02-25 10:42:13 +01:00
end
if rule_new == ' -- ' or rule_new == ' — ' then
2016-03-22 11:16:26 +01:00
if group.rules [ rule_num ] then
table.remove ( group.rules , rule_num )
2016-02-25 10:42:13 +01:00
sendReply ( msg , ' That rule has been deleted. ' )
else
sendReply ( msg , ' There is no rule with that number. ' )
end
return
end
2016-03-22 11:16:26 +01:00
group.rules [ rule_num ] = rule_new
2016-02-25 10:42:13 +01:00
local output = ' * ' .. rule_num .. ' *. ' .. rule_new
sendMessage ( msg.chat . id , output , true , nil , true )
end
} ,
2016-02-20 11:07:20 +01:00
{ -- setrules
triggers = {
' ^/setrules[@ ' .. bot.username .. ' ]* '
} ,
2016-03-31 13:53:12 +02:00
command = ' setrules <rules> ' ,
2016-02-20 11:07:20 +01:00
privilege = 3 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-03-31 13:53:12 +02:00
local input = msg.text : match ( ' ^/setrules[@ ' .. bot.username .. ' ]*(.+) ' )
2016-02-20 11:07:20 +01:00
if not input then
2016-03-31 13:53:12 +02:00
sendMessage ( msg.chat . id , ' ``` \n /setrules [rule] \n <rule> \n [rule] \n ... \n ``` ' , true , msg.message_id , true )
2016-02-20 11:07:20 +01:00
return
2016-03-31 13:53:12 +02:00
elseif input == ' -- ' or input == ' — ' then
2016-03-22 11:16:26 +01:00
group.rules = { }
sendReply ( msg , ' The rules have been cleared. ' )
return
2016-02-20 11:07:20 +01:00
end
2016-03-22 11:16:26 +01:00
group.rules = { }
2016-02-20 11:07:20 +01:00
input = input : trim ( ) .. ' \n '
2016-02-25 10:42:13 +01:00
local output = ' *Rules for* _ ' .. msg.chat . title .. ' _ *:* \n '
local i = 1
for l in input : gmatch ( ' (.-) \n ' ) do
output = output .. ' * ' .. i .. ' .* ' .. l .. ' \n '
2016-02-20 11:07:20 +01:00
i = i + 1
2016-03-22 11:16:26 +01:00
table.insert ( group.rules , l : trim ( ) )
2016-02-20 11:07:20 +01:00
end
sendMessage ( msg.chat . id , output , true , nil , true )
end
} ,
{ -- setmotd
triggers = {
' ^/setmotd[@ ' .. bot.username .. ' ]* '
} ,
command = ' setmotd <motd> ' ,
privilege = 3 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local input = msg.text : input ( )
if not input then
2016-03-31 13:53:12 +02:00
if msg.reply_to_message and msg.reply_to_message . text then
input = msg.reply_to_message . text
else
sendReply ( msg , ' Please specify the new message of the day. ' )
return
end
2016-03-22 11:16:26 +01:00
elseif input == ' -- ' or input == ' — ' then
group.motd = nil
sendReply ( msg , ' The MOTD has been cleared. ' )
2016-02-20 11:07:20 +01:00
return
end
input = input : trim ( )
2016-03-22 11:16:26 +01:00
group.motd = input
2016-02-20 11:07:20 +01:00
local output = ' *MOTD for* _ ' .. msg.chat . title .. ' _ *:* \n ' .. input
sendMessage ( msg.chat . id , output , true , nil , true )
end
} ,
{ -- setlink
triggers = {
' ^/setlink[@ ' .. bot.username .. ' ]* '
} ,
command = ' setlink <link> ' ,
privilege = 3 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local input = msg.text : input ( )
if not input then
2016-03-22 11:16:26 +01:00
sendReply ( msg , ' Please specify the new link. ' )
return
elseif input == ' -- ' or input == ' — ' then
2016-03-27 14:30:41 +02:00
group.link = drua.export_link ( msg.chat . id )
2016-03-22 11:16:26 +01:00
sendReply ( msg , ' The link has been regenerated. ' )
2016-02-20 11:07:20 +01:00
return
end
2016-03-22 11:16:26 +01:00
group.link = input
2016-02-20 11:07:20 +01:00
local output = ' [ ' .. msg.chat . title .. ' ]( ' .. input .. ' ) '
sendMessage ( msg.chat . id , output , true , nil , true )
end
} ,
{ -- flags
triggers = {
' ^/flags?[@ ' .. bot.username .. ' ]* '
} ,
command = ' flag <i> ' ,
privilege = 3 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local input = msg.text : input ( )
if input then
input = get_word ( input , 1 )
input = tonumber ( input )
if not input or not flags [ input ] then input = false end
end
if not input then
local output = ' *Flags for* _ ' .. msg.chat . title .. ' _ *:* \n '
for i , v in ipairs ( flags ) do
2016-03-22 11:16:26 +01:00
local status = group.flags [ i ] or false
2016-02-25 10:42:13 +01:00
output = output .. ' `[ ' .. i .. ' ]` * ' .. v.name .. ' *` = ' .. tostring ( status ) .. ' ` \n • ' .. v.desc .. ' \n '
2016-02-20 11:07:20 +01:00
end
sendMessage ( msg.chat . id , output , true , nil , true )
return
end
local output
2016-03-22 11:16:26 +01:00
if group.flags [ input ] == true then
group.flags [ input ] = false
2016-02-20 11:07:20 +01:00
sendReply ( msg , flags [ input ] . disabled )
else
2016-03-22 11:16:26 +01:00
group.flags [ input ] = true
2016-02-20 11:07:20 +01:00
sendReply ( msg , flags [ input ] . enabled )
end
end
} ,
2016-03-31 13:53:12 +02:00
{ -- antiflood
triggers = {
' ^/antiflood ' ,
' ^/antiflood@ ' .. bot.username
} ,
command = ' antiflood <type> <i> ' ,
privilege = 3 ,
interior = true ,
action = function ( msg , group )
if not group.flags [ 5 ] then
sendMessage ( msg.chat . id , ' antiflood is not enabled. Use `/flag 5` to enable it. ' , true , nil , true )
return
end
if not group.antiflood then
group.antiflood = JSON.decode ( JSON.encode ( antiflood ) )
end
local input = msg.text_lower : input ( )
local output
if input then
local key , val = input : match ( ' (%a+) (%d+) ' )
if not group.antiflood [ key ] or not tonumber ( val ) then
output = ' Not a valid message type or number. '
else
group.antiflood [ key ] = val
output = ' A * ' .. key .. ' * message is now worth * ' .. val .. ' * points. '
end
else
output = ' usage: `/antiflood <type> <i>` \n example: `/antiflood text 5` \n Use this command to configure the point values for each message type. When a user reaches 100 points, he is kicked. The points are reset each minute. The current values are: \n '
for k , v in pairs ( group.antiflood ) do
output = output .. ' * ' .. k .. ' :* ` ' .. v .. ' ` \n '
end
end
sendMessage ( msg.chat . id , output , true , msg.message_id , true )
end
} ,
2016-02-20 11:07:20 +01:00
{ -- mod
triggers = {
2016-03-22 11:16:26 +01:00
' ^/mod ' ,
' ^/demod '
2016-02-20 11:07:20 +01:00
} ,
command = ' mod <user> ' ,
privilege = 3 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local target = get_target ( msg )
if target.err then
sendReply ( msg , target.err )
return
end
2016-03-22 11:16:26 +01:00
if group.mods [ target.id_str ] then
if group.grouptype == ' supergroup ' then
2016-03-27 14:30:41 +02:00
drua.channel_set_admin ( msg.chat . id , target.id , 0 )
2016-03-22 11:16:26 +01:00
end
group.mods [ target.id_str ] = nil
sendReply ( msg , target.name .. ' is no longer a moderator. ' )
else
if target.rank > 2 then
sendReply ( msg , target.name .. ' is greater than a moderator. ' )
return
end
if group.grouptype == ' supergroup ' then
2016-03-31 13:53:12 +02:00
drua.channel_set_admin ( msg.chat . id , target.id , 2 )
2016-03-22 11:16:26 +01:00
end
group.mods [ target.id_str ] = true
sendReply ( msg , target.name .. ' is now a moderator. ' )
2016-02-20 11:07:20 +01:00
end
end
} ,
{ -- gov
triggers = {
2016-03-22 11:16:26 +01:00
' ^/gov ' ,
' ^/degov '
2016-02-20 11:07:20 +01:00
} ,
command = ' gov <user> ' ,
privilege = 4 ,
interior = true ,
2016-03-22 11:16:26 +01:00
action = function ( msg , group )
2016-02-20 11:07:20 +01:00
local target = get_target ( msg )
if target.err then
sendReply ( msg , target.err )
return
end
2016-03-22 11:16:26 +01:00
if group.govs [ target.id_str ] then
if group.grouptype == ' supergroup ' then
2016-03-27 14:30:41 +02:00
drua.channel_set_admin ( msg.chat . id , target.id , 0 )
2016-03-22 11:16:26 +01:00
end
group.govs [ target.id_str ] = nil
sendReply ( msg , target.name .. ' is no longer a governor. ' )
else
if target.rank == 2 then
group.mods [ target.id_str ] = nil
end
if group.grouptype == ' supergroup ' then
2016-03-31 13:53:12 +02:00
drua.channel_set_admin ( msg.chat . id , target.id , 2 )
2016-03-22 11:16:26 +01:00
end
group.govs [ target.id_str ] = true
sendReply ( msg , target.name .. ' is now a governor. ' )
2016-02-20 11:07:20 +01:00
end
end
} ,
{ -- hammer
triggers = {
2016-03-22 11:16:26 +01:00
' ^/hammer ' ,
' ^/unhammer '
2016-02-20 11:07:20 +01:00
} ,
command = ' hammer <user> ' ,
privilege = 4 ,
interior = false ,
action = function ( msg )
local target = get_target ( msg )
if target.err then
sendReply ( msg , target.err )
return
end
if target.rank > 3 then
2016-02-27 04:06:38 +01:00
sendReply ( msg , target.name .. ' is too privileged to be globally banned. ' )
2016-02-20 11:07:20 +01:00
return
end
2016-02-23 12:15:48 +01:00
if database.blacklist [ target.id_str ] then
2016-03-22 11:16:26 +01:00
database.blacklist [ target.id_str ] = nil
sendReply ( msg , target.name .. ' has been globally unbanned. ' )
else
database.blacklist [ target.id_str ] = true
for k , v in pairs ( database.administration . groups ) do
2016-03-27 14:30:41 +02:00
drua.kick_user ( k , target.id )
2016-02-20 11:07:20 +01:00
end
2016-03-22 11:16:26 +01:00
sendReply ( msg , target.name .. ' has been globally banned. ' )
2016-02-20 11:07:20 +01:00
end
end
} ,
{ -- admin
triggers = {
2016-03-22 11:16:26 +01:00
' ^/admin ' ,
' ^/deadmin '
2016-02-20 11:07:20 +01:00
} ,
2016-03-22 11:16:26 +01:00
command = ' admin <user ' ,
2016-02-20 11:07:20 +01:00
privilege = 5 ,
interior = false ,
action = function ( msg )
local target = get_target ( msg )
2016-03-22 11:16:26 +01:00
if target.err then
sendReply ( msg , target.err )
2016-02-20 11:07:20 +01:00
return
end
2016-03-22 11:16:26 +01:00
if database.administration . admins [ target.id_str ] then
database.administration . admins [ target.id_str ] = nil
sendReply ( msg , target.name .. ' is no longer an administrator. ' )
else
if target.rank == 5 then
sendReply ( msg , target.name .. ' is greater than an administrator. ' )
return
end
for k , v in pairs ( database.administration . groups ) do
v.mods [ target.id_str ] = nil
v.govs [ target.id_str ] = nil
end
database.administration . admins [ target.id_str ] = true
sendReply ( msg , target.name .. ' is now an administrator. ' )
2016-02-20 11:07:20 +01:00
end
end
} ,
{ -- gadd
triggers = {
' ^/gadd[@ ' .. bot.username .. ' ]*$ '
} ,
command = ' gadd ' ,
privilege = 5 ,
interior = false ,
action = function ( msg )
2016-03-22 11:16:26 +01:00
if database.administration . groups [ msg.chat . id_str ] then
2016-02-20 11:07:20 +01:00
sendReply ( msg , ' I am already administrating this group. ' )
return
end
2016-03-22 11:16:26 +01:00
database.administration . groups [ msg.chat . id_str ] = {
2016-02-20 11:07:20 +01:00
mods = { } ,
govs = { } ,
bans = { } ,
flags = { } ,
2016-03-22 11:16:26 +01:00
rules = { } ,
2016-02-20 11:07:20 +01:00
grouptype = msg.chat . type ,
name = msg.chat . title ,
2016-03-27 14:30:41 +02:00
link = drua.export_link ( msg.chat . id ) ,
photo = drua.get_photo ( msg.chat . id ) ,
2016-02-20 11:07:20 +01:00
founded = os.time ( )
}
2016-03-27 14:30:41 +02:00
table.insert ( database.administration . activity , msg.chat . id_str )
2016-02-20 11:07:20 +01:00
sendReply ( msg , ' I am now administrating this group. ' )
end
} ,
{ -- grem
triggers = {
' ^/grem[@ ' .. bot.username .. ' ]* ' ,
' ^/gremove[@ ' .. bot.username .. ' ]* '
} ,
command = ' gremove \\ [chat] ' ,
privilege = 5 ,
interior = true ,
action = function ( msg )
2016-03-28 08:15:46 +02:00
local input = msg.text : input ( ) or msg.chat . id_str
if database.administration . groups [ input ] then
database.administration . groups [ input ] = nil
for i , v in ipairs ( database.administration . activity ) do
if v == input then
table.remove ( database.administration . activity , i )
end
2016-02-27 04:06:38 +01:00
end
2016-03-28 08:15:46 +02:00
sendReply ( msg , ' I am no longer administrating that group. ' )
2016-02-27 04:06:38 +01:00
else
2016-03-28 08:15:46 +02:00
sendReply ( msg , ' I do not administrate that group. ' )
2016-02-20 11:07:20 +01:00
end
end
} ,
{ -- broadcast
triggers = {
' ^/broadcast[@ ' .. bot.username .. ' ]* '
} ,
command = ' broadcast <message> ' ,
privilege = 5 ,
interior = false ,
action = function ( msg )
local input = msg.text : input ( )
if not input then
sendReply ( msg , ' Give me something to broadcast. ' )
return
end
input = ' *Admin Broadcast:* \n ' .. input
2016-03-22 11:16:26 +01:00
for k , v in pairs ( database.administration . groups ) do
2016-03-26 11:12:01 +01:00
sendMessage ( k , input , true , nil , true )
2016-02-20 11:07:20 +01:00
end
end
}
}
2016-02-23 12:15:48 +01:00
-- Generate trigger table.
2016-02-20 11:07:20 +01:00
local triggers = { }
for i , v in ipairs ( commands ) do
2016-03-04 23:08:21 +01:00
for ind , val in ipairs ( v.triggers ) do
2016-02-20 11:07:20 +01:00
table.insert ( triggers , val )
end
end
2016-03-22 11:16:26 +01:00
database.administration . help = { }
2016-03-04 23:08:21 +01:00
for i , v in ipairs ( ranks ) do
2016-03-31 13:53:12 +02:00
admin_temp.help [ i ] = { }
2016-02-25 10:42:13 +01:00
end
for i , v in ipairs ( commands ) do
if v.command then
2016-03-31 13:53:12 +02:00
table.insert ( admin_temp.help [ v.privilege ] , v.command )
2016-02-20 11:07:20 +01:00
end
end
2016-02-25 10:42:13 +01:00
2016-02-27 04:06:38 +01:00
local action = function ( msg )
2016-02-20 11:07:20 +01:00
for i , v in ipairs ( commands ) do
for key , val in pairs ( v.triggers ) do
if msg.text_lower : match ( val ) then
2016-03-31 23:48:20 +02:00
if msg.chat . type == ' private ' then break end
2016-03-22 11:16:26 +01:00
if v.interior and not database.administration . groups [ msg.chat . id_str ] then
2016-02-20 11:07:20 +01:00
break
end
2016-03-31 23:48:20 +02:00
if get_rank ( msg.from . id , msg.chat . id ) < v.privilege then
2016-02-20 11:07:20 +01:00
break
end
2016-03-22 11:16:26 +01:00
local res = v.action ( msg , database.administration . groups [ msg.chat . id_str ] )
2016-02-20 11:07:20 +01:00
if res ~= true then
return res
end
end
end
end
return true
end
2016-03-31 13:53:12 +02:00
local cron = function ( )
admin_temp.flood = { }
end
2016-02-20 11:07:20 +01:00
local command = ' groups '
local doc = ' `Returns a list of administrated groups. \n Use /ahelp for more administrative commands.` '
return {
action = action ,
triggers = triggers ,
2016-03-31 13:53:12 +02:00
cron = cron ,
2016-02-20 11:07:20 +01:00
doc = doc ,
command = command
}