bunch of stuff

administration.lua: everything's better; automatic migration.
database.usernames -> database.users. View with /me.
Nicks and lastfm usernames moved to database.users; auto migrate.
This commit is contained in:
topkecleon 2016-03-22 06:16:26 -04:00
parent aebb90f9b4
commit b5ea8f3bbe
14 changed files with 405 additions and 427 deletions

View File

@ -7,7 +7,7 @@ assert(JSON)
local BASE_URL = 'https://api.telegram.org/bot' .. config.bot_api_key local BASE_URL = 'https://api.telegram.org/bot' .. config.bot_api_key
if not config.bot_api_key then if config.bot_api_key == '' then
error('You did not set your bot token in config.lua!') error('You did not set your bot token in config.lua!')
end end
@ -88,6 +88,9 @@ end
sendLocation = function(chat_id, latitude, longitude, reply_to_message_id, disable_notification) sendLocation = function(chat_id, latitude, longitude, reply_to_message_id, disable_notification)
if latitude == 0 then latitude = 0.001 end
if longitude == 0 then longitude = 0.001 end
local url = BASE_URL .. '/sendLocation?chat_id=' .. chat_id .. '&latitude=' .. latitude .. '&longitude=' .. longitude local url = BASE_URL .. '/sendLocation?chat_id=' .. chat_id .. '&latitude=' .. latitude .. '&longitude=' .. longitude
if reply_to_message_id then if reply_to_message_id then

37
bot.lua
View File

@ -3,7 +3,7 @@ HTTPS = require('ssl.https')
URL = require('socket.url') URL = require('socket.url')
JSON = require('cjson') JSON = require('cjson')
version = '3.4' version = '3.5'
bot_init = function() -- The function run when the bot is started or reloaded. bot_init = function() -- The function run when the bot is started or reloaded.
@ -33,22 +33,39 @@ bot_init = function() -- The function run when the bot is started or reloaded.
math.random() math.random()
last_update = last_update or 0 -- Set loop variables: Update offset, last_update = last_update or 0 -- Set loop variables: Update offset,
last_cron = last_cron or os.date('%M', os.time()) -- the time of the last cron job, last_cron = last_cron or os.date('%M') -- the time of the last cron job,
is_started = true -- and whether or not the bot should be running. is_started = true -- and whether or not the bot should be running.
database.usernames = database.usernames or {} -- Table to cache usernames by user ID.
database.users = database.users or {} -- Table to cache userdata. database.users = database.users or {} -- Table to cache userdata.
database.users[tostring(bot.id)] = bot
-- Migration code. Remove in 3.6.
if database.lastfm then
for k,v in pairs(database.lastfm) do
if not database.users[k] then database.users[k] = {} end
database.users[k].lastfm = v
end
end
-- Migration code. Remove in 3.6.
if database.nicknames then
for k,v in pairs(database.nicknames) do
if not database.users[k] then database.users[k] = {} end
database.users[k].nickname = v
end
end
end end
on_msg_receive = function(msg) -- The fn run whenever a message is received. on_msg_receive = function(msg) -- The fn run whenever a message is received.
if msg.from.username then -- Create a user entry if it does not exist.
database.usernames[msg.from.username:lower()] = msg.from.id
end
if not database.users[tostring(msg.from.id)] then if not database.users[tostring(msg.from.id)] then
database.users[tostring(msg.from.id)] = {} database.users[tostring(msg.from.id)] = {}
end end
-- Clear things that no longer exist.
database.users[tostring(msg.from.id)].username = nil
database.users[tostring(msg.from.id)].last_name = nil
-- Wee.
for k,v in pairs(msg.from) do for k,v in pairs(msg.from) do
database.users[tostring(msg.from.id)][k] = v database.users[tostring(msg.from.id)][k] = v
end end
@ -77,7 +94,7 @@ on_msg_receive = function(msg) -- The fn run whenever a message is received.
end) end)
if not success then if not success then
sendReply(msg, 'Sorry, an unexpected error occurred.') sendReply(msg, 'Sorry, an unexpected error occurred.')
handle_exception(result, msg.text) handle_exception(result, msg.from.id .. ': ' .. msg.text)
return return
end end
-- If the action returns a table, make that table msg. -- If the action returns a table, make that table msg.
@ -107,8 +124,8 @@ while is_started do -- Start a loop while the bot should be running.
print(config.errors.connection) print(config.errors.connection)
end end
if last_cron ~= os.date('%M', os.time()) then -- Run cron jobs every minute. if last_cron ~= os.date('%M') then -- Run cron jobs every minute.
last_cron = os.date('%M', os.time()) last_cron = os.date('%M')
save_data(bot.username..'.db', database) -- Save the database. save_data(bot.username..'.db', database) -- Save the database.
for i,v in ipairs(plugins) do for i,v in ipairs(plugins) do
if v.cron then -- Call each plugin's cron function, if it has one. if v.cron then -- Call each plugin's cron function, if it has one.

View File

@ -15,7 +15,6 @@ return {
-- If you change this, make sure you also modify launch-tg.sh. -- If you change this, make sure you also modify launch-tg.sh.
cli_port = 4567, cli_port = 4567,
admin = 00000000, admin = 00000000,
admin_name = 'John Smith',
log_chat = nil, log_chat = nil,
about_text = [[ about_text = [[
I am otouto, the plugin-wielding, multi-purpose Telegram bot. I am otouto, the plugin-wielding, multi-purpose Telegram bot.

View File

@ -1,6 +1,6 @@
--[[ --[[
administration.lua administration.lua
Version 1.4 Version 1.5
Part of the otouto project. Part of the otouto project.
© 2016 topkecleon <drew@otou.to> © 2016 topkecleon <drew@otou.to>
GNU General Public License, version 2 GNU General Public License, version 2
@ -13,45 +13,42 @@
Important notices about updates will be here! Important notices about updates will be here!
The global banlist has been merged with the blacklist. This merge will occur Rules lists always exist, empty if there are no rules. Group arrays are now
automatically on versions 1.1 and 1.2. 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
Group rules will now be stored in tables rather than pre-numbered strings. will occur in versions 1.5 and 1.6.
Automatic migration will be in effect in versions 1.2 and 1.3.
]]-- ]]--
-- Build the administration db if nonexistent. -- Build the administration db if nonexistent.
if not database.administration then if not database.administration then
database.administration = { database.administration = {
global = { admins = {},
admins = {} groups = {}
}
} }
end end
-- Create the blacklist db if nonexistant. -- Migration code: Remove this in v1.7.
database.blacklist = database.blacklist or {} -- Group data is now stored in a "groups" array.
if not database.administration.groups then
-- Migration code: Remove this in v1.3. database.administration.groups = {}
-- Global ban list has been merged with blacklist. for k,v in pairs(database.administration) do
if database.administration.global.bans then if tonumber(k) then
for k in pairs(database.administration.global.bans) do database.administration.groups[k] = v
database.blacklist[k] = true database.administration[k] = nil
end
database.administration.global.bans = nil
end
-- Migration code: Remove this in v1.4.
-- Rule lists have been converted from strings to tables.
for k,v in pairs(database.administration) do
if type(v.rules) == 'string' then
local t = {}
for l in v.rules:gmatch('(.-)\n') do
table.insert(t, l:sub(6))
end end
v.rules = t
end end
end end
-- 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
end
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 {}
end
local sender = dofile('lua-tg/sender.lua') local sender = dofile('lua-tg/sender.lua')
tg = sender('localhost', config.cli_port) tg = sender('localhost', config.cli_port)
@ -82,7 +79,7 @@ local flags = {
}, },
[4] = { [4] = {
name = 'antibot', name = 'antibot',
desc = 'Prevents the addition of bots by non-moderators. Only useful in non-supergroups.', desc = 'Prevents the addition of bots by non-moderators.',
short = 'This group does not allow users to add bots.', short = 'This group does not allow users to add bots.',
enabled = 'Non-moderators will no longer be able to add bots.', enabled = 'Non-moderators will no longer be able to add bots.',
disabled = 'Non-moderators will now be able to add bots.' disabled = 'Non-moderators will now be able to add bots.'
@ -109,16 +106,16 @@ local get_rank = function(target, chat)
return 5 return 5
end end
if database.administration.global.admins[target] then if database.administration.admins[target] then
return 4 return 4
end end
if chat and database.administration[chat] then if chat and database.administration.groups[chat] then
if database.administration[chat].govs[target] then if database.administration.groups[chat].govs[target] then
return 3 return 3
elseif database.administration[chat].mods[target] then elseif database.administration.groups[chat].mods[target] then
return 2 return 2
elseif database.administration[chat].bans[target] then elseif database.administration.groups[chat].bans[target] then
return 0 return 0
end end
end end
@ -133,59 +130,40 @@ end
local get_target = function(msg) local get_target = function(msg)
local target = {} local target = user_from_message(msg)
if msg.reply_to_message then
local user = msg.reply_to_message.from
if msg.reply_to_message.new_chat_participant then
user = msg.reply_to_message.new_chat_participant
elseif msg.reply_to_message.left_chat_participant then
user = msg.reply_to_message.left_chat_participant
end
target.id = user.id
target.name = user.first_name
if user.last_name then
target.name = user.first_name .. ' ' .. user.last_name
end
else
target.name = 'User'
local input = get_word(msg.text, 2)
if not input then
target.err = 'Please provide a username or ID.'
else
target.id = resolve_username(input)
if target.id == nil then
target.err = 'Sorry, I do not recognize that username.'
elseif target.id == false then
target.err = 'Invalid ID or username.'
end
end
end
if target.id then if target.id then
target.id_str = tostring(target.id)
target.rank = get_rank(target.id, msg.chat.id) target.rank = get_rank(target.id, msg.chat.id)
end end
return target return target
end end
local kick_user = function(target, chat) local kick_user = function(chat, target)
target = tonumber(target) chat = math.abs(chat)
chat = tostring(chat)
if database.administration[chat].grouptype == 'group' then if chat > 1000000000000 then
tg:chat_del_user(tonumber(chat), target) chat = chat - 1000000000000
tg:_send('channel_kick channel#' .. chat .. ' user#' .. target .. '\n')
else else
tg:channel_kick(chat, target) tg:_send('chat_del_user chat#' .. chat .. ' user#' .. target .. '\n')
end end
end end
local get_photo = function(chat) local get_photo = function(chat)
local filename = tg:load_chat_photo(chat) chat = math.abs(chat)
local filename
if chat > 1000000000000 then
chat = chat - 1000000000000
filename = tg:_send('load_channel_photo channel#' .. chat .. '\n', true)
else
filename = tg:_send('load_chat_photo chat#' .. chat .. '\n', true)
end
if filename:find('FAIL') then if filename:find('FAIL') then
print('Error downloading photo for group ' .. chat .. '.') print('Error downloading photo for group ' .. chat .. '.')
return return
@ -195,9 +173,21 @@ local get_photo = function(chat)
end end
local get_link = function(chat)
chat = math.abs(chat)
if chat > 1000000000000 then
chat = chat - 1000000000000
return tg:_send('export_channel_link channel#' .. chat .. '\n', true)
else
return tg:_send('export_chat_link chat#' .. chat .. '\n', true)
end
end
local get_desc = function(chat_id) local get_desc = function(chat_id)
local group = database.administration[tostring(chat_id)] local group = database.administration.groups[tostring(chat_id)]
local output local output
if group.link then if group.link then
output = '*Welcome to* [' .. group.name .. '](' .. group.link .. ')*!*' output = '*Welcome to* [' .. group.name .. '](' .. group.link .. ')*!*'
@ -207,7 +197,7 @@ local get_desc = function(chat_id)
if group.motd then if group.motd then
output = output .. '\n\n*Message of the Day:*\n' .. group.motd output = output .. '\n\n*Message of the Day:*\n' .. group.motd
end end
if group.rules then if #group.rules > 0 then
output = output .. '\n\n*Rules:*' output = output .. '\n\n*Rules:*'
for i,v in ipairs(group.rules) do for i,v in ipairs(group.rules) do
output = output .. '\n*' .. i .. '.* ' .. v output = output .. '\n*' .. i .. '.* ' .. v
@ -237,15 +227,16 @@ local commands = {
privilege = 0, privilege = 0,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
if get_rank(msg.from.id, msg.chat.id) > 1 then if get_rank(msg.from.id, msg.chat.id) > 1 then
return true return true
end end
if not database.administration[msg.chat.id_str].flags[2] == true then if not group.flags[2] then
return true return true
end end
kick_user(msg.from.id, msg.chat.id) kick_user(msg.chat.id, msg.from.id)
sendMessage(msg.from.id, flags[2].kicked:gsub('GROUPNAME', msg.chat.title)) local output = flags[2].kicked:gsub('GROUPNAME', msg.chat.title)
sendMessage(msg.from.id, output)
end end
}, },
@ -257,14 +248,13 @@ local commands = {
privilege = 0, privilege = 0,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local rank = get_rank(msg.from.id, msg.chat.id) local rank = get_rank(msg.from.id, msg.chat.id)
local group = database.administration[msg.chat.id_str]
-- banned -- banned
if rank == 0 then if rank == 0 then
kick_user(msg.from.id, msg.chat.id) kick_user(msg.chat.id, msg.from.id)
sendMessage(msg.from.id, 'Sorry, you are banned from ' .. msg.chat.title .. '.') sendMessage(msg.from.id, 'Sorry, you are banned from ' .. msg.chat.title .. '.')
return return
end end
@ -274,8 +264,9 @@ local commands = {
-- antisquig Strict -- antisquig Strict
if group.flags[3] == true then if group.flags[3] == true then
if msg.from.name:match('[\216-\219][\128-\191]') or msg.from.name:match('') or msg.from.name:match('') then if msg.from.name:match('[\216-\219][\128-\191]') or msg.from.name:match('') or msg.from.name:match('') then
kick_user(msg.from.id, msg.chat.id) kick_user(msg.chat.id, msg.from.id)
sendMessage(msg.from.id, flags[3].kicked:gsub('GROUPNAME', msg.chat.title)) local output = flags[3].kicked:gsub('GROUPNAME', msg.chat.title)
sendMessage(msg.from.id, output)
return return
end end
end end
@ -291,7 +282,7 @@ local commands = {
-- banned -- banned
if get_rank(msg.new_chat_participant.id, msg.chat.id) == 0 then if get_rank(msg.new_chat_participant.id, msg.chat.id) == 0 then
kick_user(msg.new_chat_participant.id, msg.chat.id) kick_user(msg.chat.id, msg.new_chat_participant.id)
sendMessage(msg.new_chat_participant.id, 'Sorry, you are banned from ' .. msg.chat.title .. '.') sendMessage(msg.new_chat_participant.id, 'Sorry, you are banned from ' .. msg.chat.title .. '.')
return return
end end
@ -299,8 +290,9 @@ local commands = {
-- antisquig Strict -- antisquig Strict
if group.flags[3] == true then if group.flags[3] == true then
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 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
kick_user(msg.new_chat_participant.id, msg.chat.id) kick_user(msg.chat.id, msg.new_chat_participant.id)
sendMessage(msg.new_chat_participant.id, flags[3].kicked:gsub('GROUPNAME', msg.chat.title)) local output = flags[3].kicked:gsub('GROUPNAME', msg.chat.title)
sendMessage(msg.new_chat_participant.id, output)
return return
end end
end end
@ -308,7 +300,7 @@ local commands = {
-- antibot -- antibot
if msg.new_chat_participant.username and msg.new_chat_participant.username:match('bot$') then if msg.new_chat_participant.username and msg.new_chat_participant.username:match('bot$') then
if rank < 2 and group.flags[4] == true then if rank < 2 and group.flags[4] == true then
kick_user(msg.new_chat_participant.id, msg.chat.id) kick_user(msg.chat.id, msg.new_chat_participant.id)
return return
end end
else else
@ -334,6 +326,8 @@ local commands = {
else else
group.photo = get_photo(msg.chat.id) group.photo = get_photo(msg.chat.id)
end end
else
group.photo = get_photo(msg.chat.id)
end end
return return
@ -345,6 +339,8 @@ local commands = {
else else
group.photo = nil group.photo = nil
end end
else
group.photo = nil
end end
return return
@ -367,9 +363,9 @@ local commands = {
action = function(msg) action = function(msg)
local output = '' local output = ''
for k,v in pairs(database.administration) do for k,v in pairs(database.administration.groups) do
-- no "global" or unlisted groups -- no unlisted groups
if tonumber(k) and not v.flags[1] then if not v.flags[1] then
if v.link then if v.link then
output = output .. '• [' .. v.name .. '](' .. v.link .. ')\n' output = output .. '• [' .. v.name .. '](' .. v.link .. ')\n'
else else
@ -399,7 +395,7 @@ local commands = {
local rank = get_rank(msg.from.id, msg.chat.id) local rank = get_rank(msg.from.id, msg.chat.id)
local output = '*Commands for ' .. ranks[rank] .. ':*\n' local output = '*Commands for ' .. ranks[rank] .. ':*\n'
for i = 1, rank do for i = 1, rank do
for ind, val in ipairs(database.administration.global.help[i]) do for ind, val in ipairs(database.administration.help[i]) do
output = output .. '• /' .. val .. '\n' output = output .. '• /' .. val .. '\n'
end end
end end
@ -422,24 +418,33 @@ local commands = {
privilege = 1, privilege = 1,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
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
local modstring = '' local modstring = ''
for k,v in pairs(database.administration[msg.chat.id_str].mods) do for k,v in pairs(group.mods) do
modstring = modstring .. '' .. v .. ' (' .. k .. ')\n' modstring = modstring .. mod_format(k)
end end
if modstring ~= '' then if modstring ~= '' then
modstring = '*Moderators for* _' .. msg.chat.title .. '_ *:*\n' .. modstring modstring = '*Moderators for* _' .. msg.chat.title .. '_ *:*\n' .. modstring
end end
local govstring = '' local govstring = ''
for k,v in pairs(database.administration[msg.chat.id_str].govs) do for k,v in pairs(group.govs) do
govstring = govstring .. '' .. v .. ' (' .. k .. ')\n' govstring = govstring .. mod_format(k)
end end
if govstring ~= '' then if govstring ~= '' then
govstring = '*Governors for* _' .. msg.chat.title .. '_ *:*\n' .. govstring govstring = '*Governors for* _' .. msg.chat.title .. '_ *:*\n' .. govstring
end end
local adminstring = '*Administrators:*\n' .. config.admin_name .. ' (' .. config.admin .. ')\n' local adminstring = '*Administrators:*\n' .. mod_format(config.admin)
for k,v in pairs(database.administration.global.admins) do for k,v in pairs(database.administration.admins) do
adminstring = adminstring .. '' .. v .. ' (' .. k .. ')\n' adminstring = adminstring .. mod_format(k)
end end
local output = modstring .. govstring .. adminstring local output = modstring .. govstring .. adminstring
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
@ -476,11 +481,11 @@ local commands = {
privilege = 1, privilege = 1,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local output = 'No rules have been set for ' .. msg.chat.title .. '.' local output = 'No rules have been set for ' .. msg.chat.title .. '.'
if database.administration[msg.chat.id_str].rules then if #group.rules > 0 then
output = '*Rules for* _' .. msg.chat.title .. '_ *:*\n' output = '*Rules for* _' .. msg.chat.title .. '_ *:*\n'
for i,v in ipairs(database.administration[msg.chat.id_str].rules) do for i,v in ipairs(group.rules) do
output = output .. '*' .. i .. '.* ' .. v .. '\n' output = output .. '*' .. i .. '.* ' .. v .. '\n'
end end
end end
@ -498,10 +503,10 @@ local commands = {
privilege = 1, privilege = 1,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local output = 'No MOTD has been set for ' .. msg.chat.title .. '.' local output = 'No MOTD has been set for ' .. msg.chat.title .. '.'
if database.administration[msg.chat.id_str].motd then if group.motd then
output = '*MOTD for* _' .. msg.chat.title .. '_ *:*\n' .. database.administration[msg.chat.id_str].motd output = '*MOTD for* _' .. msg.chat.title .. '_ *:*\n' .. group.motd
end end
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
end end
@ -516,10 +521,10 @@ local commands = {
privilege = 1, privilege = 1,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local output = 'No link has been set for ' .. msg.chat.title .. '.' local output = 'No link has been set for ' .. msg.chat.title .. '.'
if database.administration[msg.chat.id_str].link then if group.link then
output = '[' .. msg.chat.title .. '](' .. database.administration[msg.chat.id_str].link .. ')' output = '[' .. msg.chat.title .. '](' .. group.link .. ')'
end end
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
end end
@ -543,7 +548,7 @@ local commands = {
local output = 'Leave this group manually or you will be unable to rejoin.' local output = 'Leave this group manually or you will be unable to rejoin.'
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
else else
kick_user(msg.from.id, msg.chat.id) kick_user(msg.chat.id, msg.from.id)
end end
end end
}, },
@ -566,21 +571,22 @@ local commands = {
sendReply(msg, target.name .. ' is too privileged to be kicked.') sendReply(msg, target.name .. ' is too privileged to be kicked.')
return return
end end
kick_user(target.id, msg.chat.id) kick_user(msg.chat.id, target.id)
sendMessage(msg.chat.id, target.name .. ' has been kicked.') sendMessage(msg.chat.id, target.name .. ' has been kicked.')
end end
}, },
{ -- ban { -- ban
triggers = { triggers = {
'^/ban[@'..bot.username..']*' '^/ban',
'^/unban'
}, },
command = 'ban <user>', command = 'ban <user>',
privilege = 2, privilege = 2,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local target = get_target(msg) local target = get_target(msg)
if target.err then if target.err then
sendReply(msg, target.err) sendReply(msg, target.err)
@ -590,41 +596,14 @@ local commands = {
sendReply(msg, target.name .. ' is too privileged to be banned.') sendReply(msg, target.name .. ' is too privileged to be banned.')
return return
end end
if database.administration[msg.chat.id_str].bans[target.id_str] then if group.bans[target.id_str] then
sendReply(msg, target.name .. ' is already banned.') group.bans[target.id_str] = nil
return sendReply(msg, target.name .. ' has been unbanned.')
else
group.bans[target.id_str] = true
kick_user(msg.chat.id, target.id)
sendReply(msg, target.name .. ' has been banned.')
end end
kick_user(target.id, msg.chat.id)
database.administration[msg.chat.id_str].bans[target.id_str] = true
sendMessage(msg.chat.id, target.name .. ' has been banned.')
end
},
{ -- unban
triggers = {
'^/unban[@'..bot.username..']*'
},
command = 'unban <user>',
privilege = 2,
interior = true,
action = function(msg)
local target = get_target(msg)
if target.err then
sendReply(msg, target.err)
return
end
if not database.administration[msg.chat.id_str].bans[target.id_str] then
if database.blacklist[target.id_str] then
sendReply(msg, target.name .. ' is globally banned.')
else
sendReply(msg, target.name .. ' is not banned.')
end
return
end
database.administration[msg.chat.id_str].bans[target.id_str] = nil
sendMessage(msg.chat.id, target.name .. ' has been unbanned.')
end end
}, },
@ -638,7 +617,7 @@ local commands = {
privilege = 3, privilege = 3,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local usage = 'usage: `/changerule <i> <newrule>`\n`/changerule <i> -- `deletes.' local usage = 'usage: `/changerule <i> <newrule>`\n`/changerule <i> -- `deletes.'
local input = msg.text:input() local input = msg.text:input()
if not input then if not input then
@ -658,24 +637,24 @@ local commands = {
sendMessage(msg.chat.id, output, true, msg.message_id, true) sendMessage(msg.chat.id, output, true, msg.message_id, true)
return return
end end
if not database.administration[msg.chat.id_str].rules then if not group.rules then
local output = 'Sorry, there are no rules to change. Please use /setrules.\n' .. usage local output = 'Sorry, there are no rules to change. Please use /setrules.\n' .. usage
sendMessage(msg.chat.id, output, true, msg.message_id, true) sendMessage(msg.chat.id, output, true, msg.message_id, true)
return return
end end
if not database.administration[msg.chat.id_str].rules[rule_num] then if not group.rules[rule_num] then
rule_num = #database.administration[msg.chat.id_str].rules + 1 rule_num = #group.rules + 1
end end
if rule_new == '--' or rule_new == '' then if rule_new == '--' or rule_new == '' then
if database.administration[msg.chat.id_str].rules[rule_num] then if group.rules[rule_num] then
table.remove(database.administration[msg.chat.id_str].rules, rule_num) table.remove(group.rules, rule_num)
sendReply(msg, 'That rule has been deleted.') sendReply(msg, 'That rule has been deleted.')
else else
sendReply(msg, 'There is no rule with that number.') sendReply(msg, 'There is no rule with that number.')
end end
return return
end end
database.administration[msg.chat.id_str].rules[rule_num] = rule_new group.rules[rule_num] = rule_new
local output = '*' .. rule_num .. '*. ' .. rule_new local output = '*' .. rule_num .. '*. ' .. rule_new
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
end end
@ -690,20 +669,24 @@ local commands = {
privilege = 3, privilege = 3,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local input = msg.text:match('^/setrules[@'..bot.username..']*(.+)') local input = msg.text:match('^/setrules[@'..bot.username..']* (.+)')
if not input then if not input then
sendReply(msg, '/setrules [rule]\n<rule>\n[rule]\n...') sendReply(msg, '/setrules [rule]\n<rule>\n[rule]\n...')
return return
elseif input == '--' or input == '' then
group.rules = {}
sendReply(msg, 'The rules have been cleared.')
return
end end
database.administration[msg.chat.id_str].rules = {} group.rules = {}
input = input:trim() .. '\n' input = input:trim() .. '\n'
local output = '*Rules for* _' .. msg.chat.title .. '_ *:*\n' local output = '*Rules for* _' .. msg.chat.title .. '_ *:*\n'
local i = 1 local i = 1
for l in input:gmatch('(.-)\n') do for l in input:gmatch('(.-)\n') do
output = output .. '*' .. i .. '.* ' .. l .. '\n' output = output .. '*' .. i .. '.* ' .. l .. '\n'
i = i + 1 i = i + 1
table.insert(database.administration[msg.chat.id_str].rules, l:trim()) table.insert(group.rules, l:trim())
end end
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
end end
@ -718,14 +701,18 @@ local commands = {
privilege = 3, privilege = 3,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local input = msg.text:input() local input = msg.text:input()
if not input then if not input then
sendReply(msg, '/' .. command) sendReply(msg, 'Please specify the new message of the day.')
return
elseif input == '--' or input == '' then
group.motd = nil
sendReply(msg, 'The MOTD has been cleared.')
return return
end end
input = input:trim() input = input:trim()
database.administration[msg.chat.id_str].motd = input group.motd = input
local output = '*MOTD for* _' .. msg.chat.title .. '_ *:*\n' .. input local output = '*MOTD for* _' .. msg.chat.title .. '_ *:*\n' .. input
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
end end
@ -740,13 +727,17 @@ local commands = {
privilege = 3, privilege = 3,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local input = msg.text:input() local input = msg.text:input()
if not input then if not input then
sendReply(msg, '/' .. command) sendReply(msg, 'Please specify the new link.')
return
elseif input == '--' or input == '' then
group.link = get_link(msg.chat.id)
sendReply(msg, 'The link has been regenerated.')
return return
end end
database.administration[msg.chat.id_str].link = input group.link = input
local output = '[' .. msg.chat.title .. '](' .. input .. ')' local output = '[' .. msg.chat.title .. '](' .. input .. ')'
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
end end
@ -761,7 +752,7 @@ local commands = {
privilege = 3, privilege = 3,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
local input = msg.text:input() local input = msg.text:input()
if input then if input then
input = get_word(input, 1) input = get_word(input, 1)
@ -771,18 +762,18 @@ local commands = {
if not input then if not input then
local output = '*Flags for* _' .. msg.chat.title .. '_ *:*\n' local output = '*Flags for* _' .. msg.chat.title .. '_ *:*\n'
for i,v in ipairs(flags) do for i,v in ipairs(flags) do
local status = database.administration[msg.chat.id_str].flags[i] or false local status = group.flags[i] or false
output = output .. '`[' .. i .. ']` *' .. v.name .. '*` = ' .. tostring(status) .. '`\n' .. v.desc .. '\n' output = output .. '`[' .. i .. ']` *' .. v.name .. '*` = ' .. tostring(status) .. '`\n' .. v.desc .. '\n'
end end
sendMessage(msg.chat.id, output, true, nil, true) sendMessage(msg.chat.id, output, true, nil, true)
return return
end end
local output local output
if database.administration[msg.chat.id_str].flags[input] == true then if group.flags[input] == true then
database.administration[msg.chat.id_str].flags[input] = false group.flags[input] = false
sendReply(msg, flags[input].disabled) sendReply(msg, flags[input].disabled)
else else
database.administration[msg.chat.id_str].flags[input] = true group.flags[input] = true
sendReply(msg, flags[input].enabled) sendReply(msg, flags[input].enabled)
end end
end end
@ -790,119 +781,83 @@ local commands = {
{ -- mod { -- mod
triggers = { triggers = {
'^/mod[@'..bot.username..']*$' '^/mod',
'^/demod'
}, },
command = 'mod <user>', command = 'mod <user>',
privilege = 3, privilege = 3,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
if not msg.reply_to_message then
sendReply(msg, 'This command must be run via reply.')
return
end
local target = get_target(msg)
if target.rank > 1 then
sendReply(msg, target.name .. ' is already a moderator or greater.')
return
end
if database.administration[msg.chat.id_str].grouptype == 'supergroup' then
tg:channel_set_admin(msg.chat.id, target, 1)
end
database.administration[msg.chat.id_str].mods[target.id_str] = target.name
sendReply(msg, target.name .. ' is now a moderator.')
end
},
{ -- demod
triggers = {
'^/demod[@'..bot.username..']*'
},
command = 'demod <user>',
privilege = 3,
interior = true,
action = function(msg)
local target = get_target(msg) local target = get_target(msg)
if target.err then if target.err then
sendReply(msg, target.err) sendReply(msg, target.err)
return return
end end
if target.rank ~= 2 then if group.mods[target.id_str] then
sendReply(msg, target.name .. ' is not a moderator.') if group.grouptype == 'supergroup' then
return tg:channel_set_admin(msg.chat.id, target, 0)
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
tg:channel_set_admin(msg.chat.id, target, 1)
end
group.mods[target.id_str] = true
sendReply(msg, target.name .. ' is now a moderator.')
end end
if database.administration[msg.chat.id_str].grouptype == 'supergroup' then
tg:channel_set_admin(msg.chat.id, target, 0)
end
database.administration[msg.chat.id_str].mods[target.id_str] = nil
sendReply(msg, target.name .. ' is no longer a moderator.')
end end
}, },
{ -- gov { -- gov
triggers = { triggers = {
'^/gov[@'..bot.username..']*$' '^/gov',
'^/degov'
}, },
command = 'gov <user>', command = 'gov <user>',
privilege = 4, privilege = 4,
interior = true, interior = true,
action = function(msg) action = function(msg, group)
if not msg.reply_to_message then
sendReply(msg, 'This command must be run via reply.')
return
end
local target = get_target(msg)
if target.rank > 2 then
sendReply(msg, target.name .. ' is already a governor or greater.')
return
elseif target.rank == 2 then
database.administration[msg.chat.id_str].mods[target.id_str] = nil
end
if database.administration[msg.chat.id_str].grouptype == 'supergroup' then
tg:channel_set_admin(msg.chat.id, target, 1)
end
database.administration[msg.chat.id_str].govs[target.id_str] = target.name
sendReply(msg, target.name .. ' is now a governor.')
end
},
{ -- degov
triggers = {
'^/degov[@'..bot.username..']*'
},
command = 'degov <user>',
privilege = 4,
interior = true,
action = function(msg)
local target = get_target(msg) local target = get_target(msg)
if target.err then if target.err then
sendReply(msg, target.err) sendReply(msg, target.err)
return return
end end
if target.rank ~= 3 then if group.govs[target.id_str] then
sendReply(msg, target.name .. ' is not a governor.') if group.grouptype == 'supergroup' then
return tg:channel_set_admin(msg.chat.id, target, 0)
end
group.govs[target.id_str] = nil
sendReply(msg, target.name .. ' is no longer a governor.')
else
if target.rank > 3 then
sendReply(msg, target.name .. ' is greater than a governor.')
return
end
if target.rank == 2 then
group.mods[target.id_str] = nil
end
if group.grouptype == 'supergroup' then
tg:channel_set_admin(msg.chat.id, target, 1)
end
group.govs[target.id_str] = true
sendReply(msg, target.name .. ' is now a governor.')
end end
if database.administration[msg.chat.id_str].grouptype == 'supergroup' then
tg:channel_set_admin(msg.chat.id, target, 0)
end
database.administration[msg.chat.id_str].govs[target.id_str] = nil
sendReply(msg, target.name .. ' is no longer a governor.')
end end
}, },
{ -- hammer { -- hammer
triggers = { triggers = {
'^/hammer[@'..bot.username..']*', '^/hammer',
'^/banall[@'..bot.username..']*' '^/unhammer'
}, },
command = 'hammer <user>', command = 'hammer <user>',
@ -920,27 +875,26 @@ local commands = {
return return
end end
if database.blacklist[target.id_str] then if database.blacklist[target.id_str] then
sendReply(msg, target.name .. ' is already globally banned.') database.blacklist[target.id_str] = nil
return sendReply(msg, target.name .. ' has been globally unbanned.')
end else
for k,v in pairs(database.administration) do database.blacklist[target.id_str] = true
if tonumber(k) then for k,v in pairs(database.administration.groups) do
kick_user(target.id, k) kick_user(k, target.id)
end end
sendReply(msg, target.name .. ' has been globally banned.')
end end
database.blacklist[target.id_str] = true
sendReply(msg, target.name .. ' has been globally banned.')
end end
}, },
{ -- unhammer { -- admin
triggers = { triggers = {
'^/unhammer[@'..bot.username..']*', '^/admin',
'^/unbanall[@'..bot.username..']*' '^/deadmin'
}, },
command = 'unhammer <user>', command = 'admin <user',
privilege = 4, privilege = 5,
interior = false, interior = false,
action = function(msg) action = function(msg)
@ -949,60 +903,21 @@ local commands = {
sendReply(msg, target.err) sendReply(msg, target.err)
return return
end end
if not database.blacklist[target.id_str] then if database.administration.admins[target.id_str] then
sendReply(msg, target.name .. ' is not globally banned.') database.administration.admins[target.id_str] = nil
return 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.')
end end
database.blacklist[target.id_str] = nil
sendReply(msg, target.name .. ' has been globally unbanned.')
end
},
{ -- admin
triggers = {
'^/admin[@'..bot.username..']*$'
},
command = 'admin <user>',
privilege = 5,
interior = false,
action = function(msg)
if not msg.reply_to_message then
sendReply(msg, 'This command must be run via reply.')
return
end
local target = get_target(msg)
if target.rank > 3 then
sendReply(msg, target.name .. ' is already an administrator or greater.')
return
elseif target.rank == 2 then
database.administration[msg.chat.id_str].mods[target.id_str] = nil
elseif target.rank == 3 then
database.administration[msg.chat.id_str].govs[target.id_str] = nil
end
database.administration.global.admins[target.id_str] = target.name
sendReply(msg, target.name .. ' is now an administrator.')
end
},
{ -- deadmin
triggers = {
'^/deadmin[@'..bot.username..']*'
},
command = 'deadmin <user>',
privilege = 5,
interior = false,
action = function(msg)
local target = get_target(msg)
if target.rank ~= 4 then
sendReply(msg, target.name .. ' is not an administrator.')
return
end
database.administration.global.admins[target.id_str] = nil
sendReply(msg, target.name .. ' is no longer an administrator.')
end end
}, },
@ -1016,23 +931,22 @@ local commands = {
interior = false, interior = false,
action = function(msg) action = function(msg)
if database.administration[msg.chat.id_str] then if database.administration.groups[msg.chat.id_str] then
sendReply(msg, 'I am already administrating this group.') sendReply(msg, 'I am already administrating this group.')
return return
end end
database.administration[msg.chat.id_str] = { database.administration.groups[msg.chat.id_str] = {
mods = {}, mods = {},
govs = {}, govs = {},
bans = {}, bans = {},
flags = {}, flags = {},
rules = {},
grouptype = msg.chat.type, grouptype = msg.chat.type,
name = msg.chat.title, name = msg.chat.title,
link = get_link(msg.chat.id),
photo = get_photo(msg.chat.id),
founded = os.time() founded = os.time()
} }
if msg.chat.type == 'group' then
database.administration[msg.chat.id_str].photo = get_photo(msg.chat.id)
database.administration[msg.chat.id_str].link = tg:export_chat_link(msg.chat.id)
end
sendReply(msg, 'I am now administrating this group.') sendReply(msg, 'I am now administrating this group.')
end end
}, },
@ -1050,15 +964,15 @@ local commands = {
action = function(msg) action = function(msg)
local input = msg.text:input() local input = msg.text:input()
if input then if input then
if database.administration[input] then if database.administration.groups[input] then
database.administration[input] = nil database.administration.groups[input] = nil
sendReply(msg, 'I am no longer administrating that group.') sendReply(msg, 'I am no longer administrating that group.')
else else
sendReply(msg, 'I do not administrate that group.') sendReply(msg, 'I do not administrate that group.')
end end
else else
if database.administration[msg.chat.id_str] then if database.administration.groups[msg.chat.id_str] then
database.administration[msg.chat.id_str] = nil database.administration.groups[msg.chat.id_str] = nil
sendReply(msg, 'I am no longer administrating this group.') sendReply(msg, 'I am no longer administrating this group.')
else else
sendReply(msg, 'I do not administrate this group.') sendReply(msg, 'I do not administrate this group.')
@ -1083,7 +997,7 @@ local commands = {
return return
end end
input = '*Admin Broadcast:*\n' .. input input = '*Admin Broadcast:*\n' .. input
for k,v in pairs(database.administration) do for k,v in pairs(database.administration.groups) do
if tonumber(k) then if tonumber(k) then
sendMessage(k, input, true, nil, true) sendMessage(k, input, true, nil, true)
end end
@ -1101,28 +1015,27 @@ for i,v in ipairs(commands) do
end end
end end
database.administration.global.help = {} database.administration.help = {}
for i,v in ipairs(ranks) do for i,v in ipairs(ranks) do
database.administration.global.help[i] = {} database.administration.help[i] = {}
end end
for i,v in ipairs(commands) do for i,v in ipairs(commands) do
if v.command then if v.command then
table.insert(database.administration.global.help[v.privilege], v.command) table.insert(database.administration.help[v.privilege], v.command)
end end
end end
local action = function(msg) local action = function(msg)
for i,v in ipairs(commands) do for i,v in ipairs(commands) do
for key,val in pairs(v.triggers) do for key,val in pairs(v.triggers) do
if msg.text_lower:match(val) then if msg.text_lower:match(val) then
if v.interior and not database.administration[msg.chat.id_str] then if v.interior and not database.administration.groups[msg.chat.id_str] then
break break
end end
if msg.chat.type ~= 'private' and get_rank(msg.from.id, msg.chat.id) < v.privilege then if msg.chat.type ~= 'private' and get_rank(msg.from.id, msg.chat.id) < v.privilege then
break break
end end
local res = v.action(msg) local res = v.action(msg, database.administration.groups[msg.chat.id_str])
if res ~= true then if res ~= true then
return res return res
end end

View File

@ -11,51 +11,22 @@ local triggers = {
local action = function(msg) local action = function(msg)
if database.blacklist[msg.from.id_str] then if database.blacklist[msg.from.id_str] then return end
return -- End if the sender is blacklisted. if not msg.text:match('^/blacklist') then return true end
if msg.from.id ~= config.admin then return end
local target = user_from_message(msg)
if target.err then
sendReply(msg, target.err)
return
end end
if not string.match(msg.text_lower, '^/blacklist') then if database.blacklist[tostring(target.id)] then
return true database.blacklist[tostring(target.id)] = nil
end sendReply(msg, target.name .. ' has been removed from the blacklist.')
if msg.from.id ~= config.admin then
return -- End if the user isn't admin.
end
local target, input
if msg.reply_to_message then
target = msg.reply_to_message.from.id
else else
input = msg.text:input() database.blacklist[tostring(target.id)] = true
if input then sendReply(msg, target.name .. ' has been added to the blacklist.')
input = get_word(input, 1)
if tonumber(input) then
target = input
else
target = resolve_username(input)
if target == nil then
sendReply(msg, 'Sorry, I do not recognize that username.')
return
elseif target == false then
sendReply(msg, 'Invalid ID or username.')
return
end
end
else
sendReply(msg, 'You must use this command via reply or by specifying an ID or username.')
return
end
end
target = tostring(target)
if database.blacklist[target] then
database.blacklist[target] = nil
sendReply(msg, input .. ' has been removed from the blacklist.')
else
database.blacklist[target] = true
sendReply(msg, input .. ' has been added to the blacklist.')
end end
end end

View File

@ -1,12 +1,12 @@
-- Put this on the bottom of your plugin list, after help.lua. -- Put this on the bottom of your plugin list, after help.lua.
local triggers = { local triggers = {
bot.first_name .. '%p?$' bot.first_name .. '%p*$'
} }
local action = function(msg) local action = function(msg)
local nick = database.nicknames[msg.from.id_str] or msg.from.first_name local nick = database.users[msg.from.id_str].nickname or msg.from.first_name
for k,v in pairs(config.greetings) do for k,v in pairs(config.greetings) do
for key,val in pairs(v) do for key,val in pairs(v) do

View File

@ -40,6 +40,10 @@ local action = function(msg)
title = title:sub(1, 45) .. '...' title = title:sub(1, 45) .. '...'
end end
local url = res_jdat.url local url = res_jdat.url
if not url then
sendReply(msg, config.errors.connection)
return
end
if url:find('%(') then if url:find('%(') then
output = output .. '' .. title .. '\n' .. url:gsub('_', '\\_') .. '\n' output = output .. '' .. title .. '\n' .. url:gsub('_', '\\_') .. '\n'
else else

View File

@ -4,10 +4,6 @@ if not config.lastfm_api_key then
return return
end end
if not database.lastfm then
database.lastfm = {}
end
local HTTP = require('socket.http') local HTTP = require('socket.http')
HTTP.TIMEOUT = 1 HTTP.TIMEOUT = 1
@ -17,7 +13,7 @@ local doc = [[```
Returns what you are or were last listening to. If you specify a username, info will be returned for that username. Returns what you are or were last listening to. If you specify a username, info will be returned for that username.
/fmset <username> /fmset <username>
Sets your last.fm username. Otherwise, /np will use your Telegram username. Use "/fmset -" to delete it. Sets your last.fm username. Otherwise, /np will use your Telegram username. Use "/fmset --" to delete it.
```]] ```]]
local triggers = { local triggers = {
@ -36,11 +32,11 @@ local action = function(msg)
elseif string.match(msg.text, '^/fmset') then elseif string.match(msg.text, '^/fmset') then
if not input then if not input then
sendMessage(msg.chat.id, doc, true, msg.message_id, true) sendMessage(msg.chat.id, doc, true, msg.message_id, true)
elseif input == '-' then elseif input == '--' or input == '' then
database.lastfm[msg.from.id_str] = nil database.users[msg.from.id_str].lastfm = nil
sendReply(msg, 'Your last.fm username has been forgotten.') sendReply(msg, 'Your last.fm username has been forgotten.')
else else
database.lastfm[msg.from.id_str] = input database.users[msg.from.id_str].lastfm = input
sendReply(msg, 'Your last.fm username has been set to "' .. input .. '".') sendReply(msg, 'Your last.fm username has been set to "' .. input .. '".')
end end
return return
@ -52,12 +48,12 @@ local action = function(msg)
local output = '' local output = ''
if input then if input then
username = input username = input
elseif database.lastfm[msg.from.id_str] then elseif database.users[msg.from.id_str].lastfm then
username = database.lastfm[msg.from.id_str] username = database.users[msg.from.id_str].lastfm
elseif msg.from.username then elseif msg.from.username then
username = msg.from.username username = msg.from.username
output = '\n\nYour username has been set to ' .. username .. '.\nTo change it, use /fmset <username>.' output = '\n\nYour username has been set to ' .. username .. '.\nTo change it, use /fmset <username>.'
database.lastfm[msg.from.id_str] = username database.users[msg.from.id_str].lastfm = username
else else
sendReply(msg, 'Please specify your last.fm username or set it with /fmset.') sendReply(msg, 'Please specify your last.fm username or set it with /fmset.')
return return

33
plugins/me.lua Normal file
View File

@ -0,0 +1,33 @@
local triggers = {
'^/me',
'^/me@'..bot.username
}
local action = function(msg)
local target = database.users[msg.from.id_str]
if msg.from.id == config.admin and (msg.reply_to_message or msg.text:input()) then
target = user_from_message(msg)
if target.err then
sendReply(msg, target.err)
return
end
end
local output = ''
for k,v in pairs(target) do
output = output .. '*' .. k .. ':* `' .. v .. '`\n'
end
output = output .. '\n'
for k,v in pairs(msg.chat) do
output = output .. '*' .. k .. ':* `' .. v .. '`\n'
end
sendMessage(msg.chat.id, output, true, nil, true)
end
return {
triggers = triggers,
action = action
}

View File

@ -1,7 +1,3 @@
if not database.nicknames then
database.nicknames = {}
end
local command = 'nick <nickname>' local command = 'nick <nickname>'
local doc = [[``` local doc = [[```
/nick <nickname> /nick <nickname>
@ -28,18 +24,18 @@ local action = function(msg)
local output local output
local input = msg.text:input() local input = msg.text:input()
if not input then if not input then
if database.nicknames[target.id_str] then if database.users[target.id_str].nickname then
output = target.name .. '\'s nickname is "' .. database.nicknames[target.id_str] .. '".' output = target.name .. '\'s nickname is "' .. database.users[target.id_str].nickname .. '".'
else else
output = target.name .. ' currently has no nickname.' output = target.name .. ' currently has no nickname.'
end end
elseif string.len(input) > 32 then elseif string.len(input) > 32 then
output = 'The character limit for nicknames is 32.' output = 'The character limit for nicknames is 32.'
elseif input == '--' or input == '' then elseif input == '--' or input == '' then
database.nicknames[target.id_str] = nil database.users[target.id_str].nickname = nil
output = target.name .. '\'s nickname has been deleted.' output = target.name .. '\'s nickname has been deleted.'
else else
database.nicknames[target.id_str] = input database.users[target.id_str].nickname = input
output = target.name .. '\'s nickname has been set to "' .. input .. '".' output = target.name .. '\'s nickname has been set to "' .. input .. '".'
end end

View File

@ -96,16 +96,16 @@ local action = function(msg)
local victim = msg.text:input() local victim = msg.text:input()
if msg.reply_to_message then if msg.reply_to_message then
if database.nicknames[tostring(msg.reply_to_message.from.id)] then if database.users[tostring(msg.reply_to_message.from.id)].nickname then
victim = database.nicknames[tostring(msg.reply_to_message.from.id)] victim = database.users[tostring(msg.reply_to_message.from.id)].nickname
else else
victim = msg.reply_to_message.from.first_name victim = msg.reply_to_message.from.first_name
end end
end end
local victor = msg.from.first_name local victor = msg.from.first_name
if database.nicknames[msg.from.id_str] then if database.users[msg.from.id_str].nickname then
victor = database.nicknames[msg.from.id_str] victor = database.users[msg.from.id_str].nickname
end end
if not victim then if not victim then
@ -117,6 +117,8 @@ local action = function(msg)
message = message:gsub('VICTIM', victim) message = message:gsub('VICTIM', victim)
message = message:gsub('VICTOR', victor) message = message:gsub('VICTOR', victor)
message = latcyr(message)
sendMessage(msg.chat.id, message) sendMessage(msg.chat.id, message)
end end

View File

@ -32,10 +32,6 @@ local action = function(msg)
local message = 'You are ' .. from_name .. ' and you are messaging ' .. to_name local message = 'You are ' .. from_name .. ' and you are messaging ' .. to_name
if database.nicknames[msg.from.id_str] then
message = message .. '\nYour nickname is ' .. database.nicknames[msg.from.id_str] .. '.'
end
sendReply(msg, message) sendReply(msg, message)
end end

View File

@ -45,9 +45,8 @@ local action = function(msg)
return return
end end
local i = math.random(jdat.pageInfo.resultsPerPage) local vid_url = 'https://www.youtube.com/watch?v=' .. jdat.items[1].id.videoId
local vid_url = 'https://www.youtube.com/watch?v=' .. jdat.items[i].id.videoId local vid_title = jdat.items[1].snippet.title
local vid_title = jdat.items[i].snippet.title
vid_title = vid_title:gsub('%(.+%)',''):gsub('%[.+%]','') vid_title = vid_title:gsub('%(.+%)',''):gsub('%[.+%]','')
local output = '[' .. vid_title .. '](' .. vid_url .. ')' local output = '[' .. vid_title .. '](' .. vid_url .. ')'

View File

@ -130,22 +130,61 @@ table_size = function(tab)
end end
resolve_username = function(target) resolve_username = function(input)
-- If $target is a known username, returns associated ID.
-- If $target is an unknown username, returns nil.
-- If $target is a number, returns that number.
-- Otherwise, returns false.
local input = tostring(target):lower() input = input:gsub('^@', '')
if input:match('^@') then for k,v in pairs(database.users) do
local uname = input:gsub('^@', '') if v.username and v.username:lower() == input:lower() then
return database.usernames[uname] return v
else end
return tonumber(target) or false
end end
end end
user_from_message = function(msg)
local input = msg.text_lower:input()
local target = {}
if msg.reply_to_message then
target = msg.reply_to_message.from
elseif input and tonumber(input) then
target.id = input
if database.users[input] then
for k,v in pairs(database.users[input]) do
target[k] = v
end
end
elseif input and input:match('^@') then
local uname = input:gsub('^@', '')
for k,v in pairs(database.users) do
if v.username and uname == v.username:lower() then
for key, val in pairs(v) do
target[key] = val
end
end
end
if not target.id then
target.err = 'Sorry, I don\'t recognize that username.'
end
else
target.err = 'Please specify a user via reply, ID, or username.'
end
if target.id then
target.id_str = tostring(target.id)
end
if not target.first_name then target.first_name = 'User' end
target.name = target.first_name
if target.last_name then
target.name = target.first_name .. ' ' .. target.last_name
end
return target
end
handle_exception = function(err, message) handle_exception = function(err, message)
if not err then err = '' end if not err then err = '' end
@ -196,3 +235,13 @@ download_file = function(url, filename)
return filename return filename
end end
markdown_escape = function(text)
text = text:gsub('_', '\\_')
text = text:gsub('%[', '\\[')
text = text:gsub('%*', '\\*')
text = text:gsub('`', '\\`')
return text
end