Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
675 KB
Referenced Files
None
Subscribers
None
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/ai.sh b/ai.sh
new file mode 100644
index 0000000..d43f645
--- /dev/null
+++ b/ai.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+if [ ! -f ./configuration.lua ]
+then
+ echo "Please insert the required variables into configuration.example.lua. Then, you need to rename configuration.example.lua to configuration.lua!"
+else
+ cd helpers/
+ while true; do
+ lua ai.lua
+ echo "AI has stopped!"
+ sleep 3s
+ done
+fi
diff --git a/configuration.example.lua b/configuration.example.lua
index 0964f2e..c12ca4e 100644
--- a/configuration.example.lua
+++ b/configuration.example.lua
@@ -1,363 +1,387 @@
--[[
_ _ _
_ __ ___ __ _| |_| |_ __ _| |_ __ _
| '_ ` _ \ / _` | __| __/ _` | __/ _` |
| | | | | | (_| | |_| || (_| | || (_| |
|_| |_| |_|\__,_|\__|\__\__,_|\__\__,_|
- Configuration file for mattata v1.2
+ Configuration file for mattata v1.3
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
Each value in an array should be comma separated, with the exception of the last value!
Make sure you always update your configuration file after pulling changes from GitHub!
]]
local configuration = { -- Rename this file to configuration.lua for the bot to work!
['bot_token'] = '', -- In order for the bot to actually work, you MUST insert the Telegram
-- bot API token you received from @BotFather.
- ['connected_message'] = 'Connected to the Telegram bot API!', -- The message to print when the bot is connected to the Telegram bot API.
- ['version'] = '1.2', -- the version of mattata, don't change this!
+ ['connected_message'] = 'Connected to the Telegram bot API!', -- The message to print when the bot is connected to the Telegram bot API
+ ['version'] = '1.3', -- the version of mattata, don't change this!
-- The following two tokens will require you to have setup payments with @BotFather, and
-- a Stripe account with @stripe!
['stripe_live_token'] = '', -- Payment token you receive from @BotFather.
['stripe_test_token'] = '', -- Test payment token you receive from @BotFather.
['admins'] = { -- Here you need to specify the numerical ID of the users who shall have
-- FULL control over the bot, this includes access to server files via the lua and shell plugins.
221714512
},
- ['blacklist_plugin_exceptions'] = { -- An array of plugins that will still be used for blacklisted users.
+ ['allowlist_plugin_exceptions'] = { -- An array of plugins that will still be used for allowlisted users.
'antispam'
},
['beta_plugins'] = { -- An array of plugins that only the configured bot admins are able to use.
- 'array_of_beta_plugins_here'
+ 'array_of_beta_plugins'
},
['permanent_plugins'] = { -- An array of plugins that can't be disabled with /plugins.
'plugins',
'help',
'administration',
'about'
},
['updates'] = {
['timeout'] = 3, -- timeout in seconds for api.get_updates()
['limit'] = 100 -- message limit for api.get_updates() - must be between 1-100
},
['language'] = 'en', -- The two character locale to set your default language to.
['log_chat'] = nil, -- This needs to be the numerical identifier of the chat you wish to log
-- errors into. If it's not a private chat it should begin with a '-' symbol.
['log_admin_actions'] = true, -- Should administrative actions be logged? [true/false]
['log_channel'] = nil, -- This needs to be the numerical identifier of the channel you wish
-- to log administrative actions in by default. It should begin with a '-' symbol.
['bug_reports_chat'] = nil, -- This needs to be the numerical identifier of the chat you wish to send
-- bug reports into. If it's not a private chat it should begin with a '-' symbol.
['counter_channel'] = nil, -- This needs to be the numerical identifier of the channel you wish
-- to forward messages into, for use with the /counter command. It should begin with a '-' symbol.
- ['download_location'] = '/your/downloads/directory', -- The location to save all downloaded media to.
- ['fonts_directory'] = '/your/fonts/directory', -- The location where fonts are stored for CAPTCHAs
- ['respond_to_misc'] = true, -- Respond to shitpostings/memes in mattata.lua? [true/false]
- ['max_copypasta_length'] = 300, -- The maximum number of characters a message can have to be
- -- able to have /copypasta used on it.
+ ['download_location'] = '/path/to/downloads', -- The location to save all downloaded media to.
+ ['fonts_directory'] = '/path/to/fonts', -- The location where fonts are stored for CAPTCHAs
['debug'] = true, -- Turn this on to print EVEN MORE information to the terminal.
['redis'] = { -- Configurable options for connecting the bot to redis. Do NOT modify
-- these settings if you don't know what you're doing!
['host'] = '127.0.0.1',
['port'] = 6379,
['password'] = nil,
['db'] = 2
},
['keys'] = { -- API keys needed for the full functionality of several plugins.
['cats'] = '', -- http://thecatapi.com/api-key-registration.html
['translate'] = '', -- https://tech.yandex.com/keys/get/?service=trnsl
['lyrics'] = '', -- https://developer.musixmatch.com/admin/applications
['lastfm'] = '', -- http://www.last.fm/api/account/create
['weather'] = '', -- https://darksky.net/dev/register
['youtube'] = '', -- https://console.developers.google.com/apis
['maps'] = '', -- https://console.cloud.google.com/google/maps-apis
['location'] = '', -- https://opencagedata.com/api
['bing'] = '', -- https://datamarket.azure.com/account/keys
['flickr'] = '', -- https://www.flickr.com/services/apps/create/noncommercial/
['news'] = '', -- https://newsapi.org/
['twitch'] = '', -- https://twitchapps.com/tmi/
['pastebin'] = '', -- https://pastebin.com/api
['dictionary'] = { -- https://developer.oxforddictionaries.com/
['id'] = '',
['key'] = ''
},
['adfly'] = { -- https://ay.gy/publisher/tools#tools-api
['api_key'] = '',
['user_id'] = '',
['secret_key'] = ''
},
['pasteee'] = '', -- https://paste.ee/
['google'] = { -- https://console.developers.google.com/apis
['api_key'] = '',
['cse_key'] = ''
},
['steam'] = '', -- https://steamcommunity.com/dev/apikey
['spotify'] = { -- https://developer.spotify.com/my-applications/#!/applications/create
['client_id'] = '',
['client_secret'] = '',
- ['redirect_uri'] = ''
+ ['redirect_uri'] = 'https://t.me/mattatabot?start='
},
['twitter'] = { -- https://apps.twitter.com/app/new
['consumer_key'] = '',
['consumer_secret'] = ''
},
['imgur'] = { -- https://api.imgur.com/oauth2/addclient
['client_id'] = '',
['client_secret'] = ''
},
- ['spamwatch'] = '' -- https://t.me/SpamWatchSupport
+ ['spamwatch'] = '', -- https://t.me/SpamWatchSupport
+ ['wolframalpha'] = '' -- https://developer.wolframalpha.com/portal/myapps/
},
['errors'] = { -- Messages to provide a more user-friendly approach to errors.
['connection'] = 'Connection error.',
['results'] = 'I couldn\'t find any results for that.',
['supergroup'] = 'This command can only be used in supergroups.',
['admin'] = 'You need to be a moderator or an administrator in this chat in order to use this command.',
['unknown'] = 'I don\'t recognise that user. If you would like to teach me who they are, forward a message from them to any chat that I\'m in.',
['generic'] = 'An unexpected error occured. Please report this error using /bugreport.'
},
['limits'] = {
['bing'] = {
['private'] = 15,
['public'] = 7
},
['stackoverflow'] = {
['private'] = 12,
['public'] = 8
},
['reddit'] = {
['private'] = 8,
['public'] = 4
},
['chatroulette'] = 512,
['copypasta'] = 300,
['drawtext'] = 1000,
['help'] = {
['per_page'] = 4
}
},
['administration'] = { -- Values used in administrative plugins
['warnings'] = {
['maximum'] = 10,
['minimum'] = 2,
['default'] = 3
},
+ ['captcha'] = {
+ ['length'] = {
+ ['min'] = 4,
+ ['max'] = 10,
+ ['default'] = 7
+ },
+ ['size'] = {
+ ['min'] = 20,
+ ['max'] = 50,
+ ['default'] = 40
+ }
+ },
['allowed_links'] = {
'username',
'telegram',
'mattata',
'admin',
'admins'
},
['store_chat_members'] = true,
['global_antispam'] = { -- normal antispam is processed in plugins/antispam.mattata
['ttl'] = 5, -- amount of seconds to process the messages in
['message_warning_amount'] = 10, -- amount of messages a user can send in the TTL until they're warned
- ['message_blacklist_amount'] = 25, -- amount of messages a user can send in the TTL until they're blacklisted
- ['blacklist_length'] = 86400, -- amount (in seconds) to blacklist the user for (set it to -1 if you want it forever)
+ ['message_allowlist_amount'] = 25, -- amount of messages a user can send in the TTL until they're allowlisted
+ ['allowlist_length'] = 86400, -- amount (in seconds) to allowlist the user for (set it to -1 if you want it forever)
['max_code_length'] = 64 -- maximum length of code or pre entities that are allowed with "remove pasted code" setting on
},
['default'] = {
['antispam'] = {
['text'] = 8,
['forwarded'] = 16,
['sticker'] = 4,
['photo'] = 4,
['video'] = 4,
['location'] = 4,
['voice'] = 4,
['game'] = 2,
['venue'] = 4,
['video_note'] = 4,
['invoice'] = 2,
['contact'] = 2,
['dice'] = 1,
['poll'] = 1
}
},
['feds'] = {
['group_limit'] = 3,
['shortened_feds'] = {
['name'] = 'uuid'
}
},
['voteban'] = {
['upvotes'] = {
['maximum'] = 50,
['minimum'] = 2,
['default'] = 5
},
['downvotes'] = {
['maximum'] = 50,
['minimum'] = 2,
['default'] = 5
}
}
},
['join_messages'] = { -- Values used in plugins/administration.lua.
'Welcome, NAME!',
'Hello, NAME!',
'Enjoy your stay, NAME!',
'I\'m glad you joined, NAME!',
'Howdy, NAME!',
'Hi, NAME!'
},
['groups'] = {
- ['name'] = 'https://t.me/link'
+ ['name'] = 't.me/username'
},
['sort_groups'] = true, -- Decides whether groups will be sorted by name in /groups.
['stickers'] = { -- Values used in mattata.lua, for administrative plugin functionality.
-- These are the file_id values for stickers which are binded to the relevant command.
['ban'] = {
'AgAD0AIAAlAYNw0',
'AgADzwIAAlAYNw0'
},
['warn'] = {
'AgAD0QIAAlAYNw0',
'AgAD0gIAAlAYNw0'
},
['kick'] = {
'AgAD0wIAAlAYNw0'
}
},
['slaps'] = {
'{THEM} was shot by {ME}.',
'{THEM} was pricked to death.',
'{THEM} walked into a cactus while trying to escape {ME}.',
'{THEM} drowned.',
'{THEM} drowned whilst trying to escape {ME}.',
'{THEM} blew up.',
'{THEM} was blown up by {ME}.',
'{THEM} hit the ground too hard.',
'{THEM} fell from a high place.',
'{THEM} fell off a ladder.',
'{THEM} fell into a patch of cacti.',
'{THEM} was doomed to fall by {ME}.',
'{THEM} was blown from a high place by {ME}.',
'{THEM} was squashed by a falling anvil.',
'{THEM} went up in flames.',
'{THEM} burned to death.',
'{THEM} was burnt to a crisp whilst fighting {ME}.',
'{THEM} walked into a fire whilst fighting {ME}.',
'{THEM} tried to swim in lava.',
'{THEM} tried to swim in lava whilst trying to escape {ME}.',
'{THEM} was struck by lightning.',
'{THEM} was slain by {ME}.',
'{THEM} got finished off by {ME}.',
'{THEM} was killed by magic.',
'{THEM} was killed by {ME} using magic.',
'{THEM} starved to death.',
'{THEM} suffocated in a wall.',
'{THEM} fell out of the world.',
'{THEM} was knocked into the void by {ME}.',
'{THEM} withered away.',
'{THEM} was pummeled by {ME}.',
'{THEM} was fragged by {ME}.',
'{THEM} was desynchronized.',
'{THEM} was wasted.',
'{THEM} was busted.',
'{THEM}\'s bones are scraped clean by the desolate wind.',
'{THEM} has died of dysentery.',
'{THEM} fainted.',
'{THEM} is out of usable Pokemon! {THEM} whited out!',
'{THEM} is out of usable Pokemon! {THEM} blacked out!',
'{THEM} whited out!',
'{THEM} blacked out!',
'{THEM} says goodbye to this cruel world.',
'{THEM} got rekt.',
'{THEM} was sawn in half by {ME}.',
'{THEM} died. I blame {ME}.',
'{THEM} was axe-murdered by {ME}.',
'{THEM}\'s melon was split by {ME}.',
'{THEM} was sliced and diced by {ME}.',
'{THEM} was split from crotch to sternum by {ME}.',
'{THEM}\'s death put another notch in {ME}\'s axe.',
'{THEM} died impossibly!',
'{THEM} died from {ME}\'s mysterious tropical disease.',
'{THEM} escaped infection by dying.',
'{THEM} played hot-potato with a grenade.',
'{THEM} was knifed by {ME}.',
'{THEM} fell on his sword.',
'{THEM} ate a grenade.',
'{THEM}\'s parents got shot by {ME}.',
'{THEM} practiced being {ME}\'s clay pigeon.',
'{THEM} is what\'s for dinner!',
'{THEM} was terminated by {ME}.',
'{THEM} was shot before being thrown out of a plane.',
'{THEM} was not invincible.',
'{THEM} has encountered an error.',
'{THEM} died and reincarnated as a goat.',
'{ME} threw {THEM} off a building.',
'{THEM} is sleeping with the fishes.',
'{THEM} got a premature burial.',
'{ME} replaced all of {THEM}\'s music with Nickelback.',
'{ME} spammed {THEM}\'s email.',
'{ME} cut {THEM}\'s genitals off with a rusty pair of scissors!',
'{ME} made {THEM} a knuckle sandwich.',
'{ME} slapped {THEM} with pure nothing.',
'{ME} hit {THEM} with a small, interstellar spaceship.',
'{THEM} was quickscoped by {ME}.',
'{ME} put {THEM} in check-mate.',
'{ME} RSA-encrypted {THEM} and deleted the private key.',
'{ME} put {THEM} in the friendzone.',
'{ME} molested {THEM} in a shed.',
'{ME} slaps {THEM} with a DMCA takedown request!',
'{THEM} became a corpse blanket for {ME}.',
'Death is when the monsters get you. Death comes for {THEM}.',
'Cowards die many times before their death. {THEM} never tasted death but once.',
'{THEM} died of hospital gangrene.',
'{THEM} got a house call from Doctor {ME}.',
'{ME} beheaded {THEM}.',
'{THEM} got stoned...by an angry mob.',
'{ME} sued the pants off {THEM}.',
'{THEM} was impeached.',
'{THEM} was beaten to a pulp by {ME}.',
'{THEM} was forced to have cheeky bum sex with {ME}!',
'{THEM} was one-hit KO\'d by {ME}.',
'{ME} sent {THEM} to /dev/null.',
'{ME} sent {THEM} down the memory hole.',
'{THEM} was a mistake.',
'{THEM} is a failed abortion.',
'{THEM}\'s birth certificate is just an apology letter from their local condom dispensary.',
'\'{THEM} was a mistake.\' - {ME}',
'{ME} checkmated {THEM} in two moves.',
'{THEM} was brutally raped by {ME}.'
}
}
local get_plugins = function(extension, directory)
- extension = extension and tostring(extension) or 'mattata'
+ extension = extension and tostring(extension) or 'lua'
if extension:match('^%.') then
extension = extension:match('^%.(.-)$')
end
directory = directory and tostring(directory) or 'plugins'
if directory:match('/$') then
directory = directory:match('^(.-)/$')
end
local plugins = {}
- local all = io.popen('ls ' .. directory .. '/'):read('*all')
+ local list = io.popen('ls ' .. directory .. '/')
+ local all = list:read('*all')
+ list:close()
for plugin in all:gmatch('[%w_-]+%.' .. extension .. ' ?') do
plugin = plugin:match('^([%w_-]+)%.' .. extension .. ' ?$')
table.insert(plugins, plugin)
end
return plugins
end
+local get_fonts = function()
+ local fonts = {}
+ local list = io.popen('ls fonts/')
+ local all = list:read('*all')
+ list:close()
+ for font in all:gmatch('%a+') do
+ table.insert(fonts, font)
+ end
+ return fonts
+end
+
configuration.plugins = get_plugins()
configuration.administrative_plugins = get_plugins(nil, 'plugins/administration')
+configuration.administration.captcha.files = get_fonts()
for _, v in pairs(configuration.administrative_plugins) do
table.insert(configuration.plugins, v)
end
return configuration
--[[
End of configuration, you're good to go.
Use `./launch.sh` to start the bot.
If you can't execute the script, try running `chmod +x launch.sh`
-]]
+]]
\ No newline at end of file
diff --git a/fonts/alef/alef.ttf b/fonts/alef/alef.ttf
new file mode 100644
index 0000000..3390fb9
Binary files /dev/null and b/fonts/alef/alef.ttf differ
diff --git a/fonts/algerian/algerian.ttf b/fonts/algerian/algerian.ttf
new file mode 100644
index 0000000..dcc72ae
Binary files /dev/null and b/fonts/algerian/algerian.ttf differ
diff --git a/fonts/antiqua/antiqua.ttf b/fonts/antiqua/antiqua.ttf
new file mode 100644
index 0000000..d52046c
Binary files /dev/null and b/fonts/antiqua/antiqua.ttf differ
diff --git a/fonts/arial/arial.ttf b/fonts/arial/arial.ttf
new file mode 100644
index 0000000..886789b
Binary files /dev/null and b/fonts/arial/arial.ttf differ
diff --git a/fonts/bauhaus/bauhaus.ttf b/fonts/bauhaus/bauhaus.ttf
new file mode 100644
index 0000000..42c3238
Binary files /dev/null and b/fonts/bauhaus/bauhaus.ttf differ
diff --git a/fonts/britanic/britanic.ttf b/fonts/britanic/britanic.ttf
new file mode 100644
index 0000000..e98502b
Binary files /dev/null and b/fonts/britanic/britanic.ttf differ
diff --git a/fonts/calibri/calibri.ttf b/fonts/calibri/calibri.ttf
new file mode 100644
index 0000000..aac4726
Binary files /dev/null and b/fonts/calibri/calibri.ttf differ
diff --git a/fonts/cambria/cambria.ttf b/fonts/cambria/cambria.ttf
new file mode 100644
index 0000000..c70283c
Binary files /dev/null and b/fonts/cambria/cambria.ttf differ
diff --git a/fonts/cantarell/cantarell.ttf b/fonts/cantarell/cantarell.ttf
new file mode 100644
index 0000000..ff7a11d
Binary files /dev/null and b/fonts/cantarell/cantarell.ttf differ
diff --git a/fonts/centaur/centaur.ttf b/fonts/centaur/centaur.ttf
new file mode 100644
index 0000000..1c2abac
Binary files /dev/null and b/fonts/centaur/centaur.ttf differ
diff --git a/fonts/century/century.ttf b/fonts/century/century.ttf
new file mode 100644
index 0000000..cb46e46
Binary files /dev/null and b/fonts/century/century.ttf differ
diff --git a/fonts/chiller/chiller.ttf b/fonts/chiller/chiller.ttf
new file mode 100644
index 0000000..3ebfa84
Binary files /dev/null and b/fonts/chiller/chiller.ttf differ
diff --git a/fonts/comic.ttf b/fonts/comic/comic.ttf
similarity index 100%
rename from fonts/comic.ttf
rename to fonts/comic/comic.ttf
diff --git a/fonts/consolas/consolas.ttf b/fonts/consolas/consolas.ttf
new file mode 100644
index 0000000..e881ca4
Binary files /dev/null and b/fonts/consolas/consolas.ttf differ
diff --git a/fonts/corbel/corbel.ttf b/fonts/corbel/corbel.ttf
new file mode 100644
index 0000000..34fd5aa
Binary files /dev/null and b/fonts/corbel/corbel.ttf differ
diff --git a/fonts/courier/courier.ttf b/fonts/courier/courier.ttf
new file mode 100644
index 0000000..46a0712
Binary files /dev/null and b/fonts/courier/courier.ttf differ
diff --git a/fonts/curlz/curlz.ttf b/fonts/curlz/curlz.ttf
new file mode 100644
index 0000000..fbcd460
Binary files /dev/null and b/fonts/curlz/curlz.ttf differ
diff --git a/fonts/dosis/dosis.ttf b/fonts/dosis/dosis.ttf
new file mode 100644
index 0000000..2f28866
Binary files /dev/null and b/fonts/dosis/dosis.ttf differ
diff --git a/fonts/ebrima/ebrima.ttf b/fonts/ebrima/ebrima.ttf
new file mode 100644
index 0000000..50b4894
Binary files /dev/null and b/fonts/ebrima/ebrima.ttf differ
diff --git a/fonts/forte/forte.ttf b/fonts/forte/forte.ttf
new file mode 100644
index 0000000..f4dfaa7
Binary files /dev/null and b/fonts/forte/forte.ttf differ
diff --git a/fonts/garamond/garamond.ttf b/fonts/garamond/garamond.ttf
new file mode 100644
index 0000000..0606e80
Binary files /dev/null and b/fonts/garamond/garamond.ttf differ
diff --git a/fonts/georgia/georgia.ttf b/fonts/georgia/georgia.ttf
new file mode 100644
index 0000000..43672d8
Binary files /dev/null and b/fonts/georgia/georgia.ttf differ
diff --git a/fonts/hack/hack.ttf b/fonts/hack/hack.ttf
new file mode 100644
index 0000000..92a90cb
Binary files /dev/null and b/fonts/hack/hack.ttf differ
diff --git a/fonts/lucida/lucida.ttf b/fonts/lucida/lucida.ttf
new file mode 100644
index 0000000..607f839
Binary files /dev/null and b/fonts/lucida/lucida.ttf differ
diff --git a/fonts/papyrus/papyrus.ttf b/fonts/papyrus/papyrus.ttf
new file mode 100644
index 0000000..b530afb
Binary files /dev/null and b/fonts/papyrus/papyrus.ttf differ
diff --git a/fonts/perpetua/perpetua.ttf b/fonts/perpetua/perpetua.ttf
new file mode 100644
index 0000000..846b3dc
Binary files /dev/null and b/fonts/perpetua/perpetua.ttf differ
diff --git a/fonts/roboto/roboto.ttf b/fonts/roboto/roboto.ttf
new file mode 100644
index 0000000..0e58508
Binary files /dev/null and b/fonts/roboto/roboto.ttf differ
diff --git a/fonts/script/script.ttf b/fonts/script/script.ttf
new file mode 100644
index 0000000..776f51c
Binary files /dev/null and b/fonts/script/script.ttf differ
diff --git a/fonts/segoe/segoe.ttf b/fonts/segoe/segoe.ttf
new file mode 100644
index 0000000..0f52cbd
Binary files /dev/null and b/fonts/segoe/segoe.ttf differ
diff --git a/fonts/source/source.ttf b/fonts/source/source.ttf
new file mode 100644
index 0000000..6cbdd36
Binary files /dev/null and b/fonts/source/source.ttf differ
diff --git a/fonts/stencil/stencil.ttf b/fonts/stencil/stencil.ttf
new file mode 100644
index 0000000..3cc031b
Binary files /dev/null and b/fonts/stencil/stencil.ttf differ
diff --git a/fonts/tahoma/tahoma.ttf b/fonts/tahoma/tahoma.ttf
new file mode 100644
index 0000000..b7b7086
Binary files /dev/null and b/fonts/tahoma/tahoma.ttf differ
diff --git a/fonts/tequila/tequila.ttf b/fonts/tequila/tequila.ttf
new file mode 100644
index 0000000..fb89baf
Binary files /dev/null and b/fonts/tequila/tequila.ttf differ
diff --git a/fonts/times/times.ttf b/fonts/times/times.ttf
new file mode 100644
index 0000000..a998fee
Binary files /dev/null and b/fonts/times/times.ttf differ
diff --git a/fonts/vera/vera.ttf b/fonts/vera/vera.ttf
new file mode 100644
index 0000000..58cd6b5
Binary files /dev/null and b/fonts/vera/vera.ttf differ
diff --git a/fonts/verdana/verdana.ttf b/fonts/verdana/verdana.ttf
new file mode 100644
index 0000000..9a34997
Binary files /dev/null and b/fonts/verdana/verdana.ttf differ
diff --git a/plugins/ai.lua b/helpers/ai.lua
similarity index 71%
copy from plugins/ai.lua
copy to helpers/ai.lua
index 1522099..c50d505 100644
--- a/plugins/ai.lua
+++ b/helpers/ai.lua
@@ -1,259 +1,239 @@
---[[
- Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
- This code is licensed under the MIT. See LICENSE for details.
-]]
-
local ai = {}
-local mattata = require('mattata')
+package.path = '/usr/local/share/lua/5.3/?.lua;/usr/local/share/lua/5.3/?/init.lua;/usr/local/lib/lua/5.3/?.lua;/usr/local/lib/lua/5.3/?/init.lua;../?.lua;./?/init.lua'
+local redis = require('libs.redis')
+local configuration = require('configuration')
+local api = require('telegram-bot-lua.core').configure(configuration.bot_token)
local https = require('ssl.https')
local url = require('socket.url')
local ltn12 = require('ltn12')
local md5 = require('md5')
-
-function ai:on_new_message(message)
- if not message.text or message.is_command then
- return false
- elseif message.text and message.reply and message.reply.text and message.reply.from.id == self.info.id and not message.reply.entities then
- return ai.on_message(self, message)
- end
- local triggers = {
- '^' .. self.info.first_name:lower() .. ',? ',
- '^@?' .. self.info.username:lower() .. ',? '
- }
- for _, trigger in pairs(triggers) do
- if message.text:lower():match(trigger) then
- return ai.on_message(self, message)
- end
- end
- if message.chat.type == 'private' and not message.is_command and not message.text:match('^[/!#]') and message.text then
- return ai.on_message(self, message)
- end
- return
-end
-
function ai.unescape(str)
if not str then
return false
end
str = str:gsub('%%(%x%x)', function(x)
return tostring(tonumber(x, 16)):char()
end)
return str
end
function ai.cookie()
local cookie = {}
local _, res, headers = https.request({
['url'] = 'http://www.cleverbot.com/',
['method'] = 'GET'
})
if res ~= 200 then
return false
end
local set = headers['set-cookie']
local k, v = set:match('([^%s;=]+)=?([^%s;]*)')
cookie[k] = v
return cookie
end
-function ai.talk(message, reply)
+function ai.talk(message, reply, language)
if not message then
return false
end
- return ai.cleverbot(message, reply)
+ return ai.cleverbot(message, reply, language)
end
-function ai.cleverbot(message, reply)
+function ai.cleverbot(message, reply, language)
local cookie = ai.cookie()
if not cookie then
return false
end
for k, v in pairs(cookie) do
cookie[#cookie + 1] = k .. '=' .. v
end
local query = 'stimulus=' .. url.escape(message)
if reply then
query = query .. '&vText2=' .. url.escape(reply)
end
- query = query .. '&cb_settings_scripting=no&islearning=1&icognoid=wsf&icognocheck='
+ query = query .. '&cb_settings_language=' .. language .. '&cb_settings_scripting=no&islearning=1&icognoid=wsf&icognocheck='
local icognocheck = md5.sumhexa(query:sub(8, 33))
query = query .. icognocheck
local agents = {
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
'Mozilla/5.0 CK={} (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763'
}
local agent = agents[math.random(#agents)]
- local old = https.TIMEOUT
- https.TIMEOUT = 2
+ local old_timeout = https.TIMEOUT
+ https.TIMEOUT = 5
local _, res, headers = https.request({
['url'] = 'https://www.cleverbot.com/webservicemin?uc=UseOfficialCleverbotAPI&dl=en&flag=&user=&mode=1&alt=0&reac=&emo=&sou=website&xed=&',
['method'] = 'POST',
['headers'] = {
['Host'] = 'www.cleverbot.com',
['User-Agent'] = agent,
['Accept'] = '*/*',
['Accept-Language'] = 'en-US,en;q=0.5',
['Accept-Encoding'] = 'gzip, deflate',
['Referrer'] = 'https://www.cleverbot.com/',
['Content-Length'] = query:len(),
['Content-Type'] = 'text/plain;charset=UTF-8',
['Cookie'] = table.concat(cookie, ';'),
['DNT'] = '1'
},
['source'] = ltn12.source.string(query)
})
- https.TIMEOUT = old
+ https.TIMEOUT = old_timeout
if res ~= 200 or not headers.cboutput then
return false
end
local output = ai.unescape(headers.cboutput)
if not output then
return false
end
return output
end
-function ai:process(message, reply)
+function ai.process(message, reply, language)
if not message then
return ai.unsure()
end
local original_message = message
message = message:lower()
+ local success = api.get_me()
if message:match('^hi%s*') or message:match('^hello%s*') or message:match('^howdy%s*') or message:match('^hi.?$') or message:match('^hello.?$') or message:match('^howdy.?$') then
return ai.greeting()
elseif message:match('^bye%s*') or message:match('^good[%-%s]?bye%s*') or message:match('^bye$') or message:match('^good[%-%s]?bye$') then
return ai.farewell()
elseif message:match('%s*y?o?ur%s*name%s*') or message:match('^what%s*is%s*y?o?ur%s*name') then
- return string.format('My name is %s, what\'s yours?', self.info.first_name)
+ return string.format('My name is %s, what\'s yours?', success.result.first_name)
elseif message:match('^do y?o?u[%s.]*') then
return ai.choice(message)
elseif message:match('^how%s*a?re?%s*y?o?u.?') or message:match('.?how%s*a?re?%s*y?o?u%s*') or message:match('.?how%s*a?re?%s*y?o?u.?$') or message:match('^a?re?%s*y?o?u%s*oka?y?.?$') or message:match('%s*a?re?%s*y?o?u%s*oka?y?.?$') then
return ai.feeling()
else
- return ai.talk(original_message, reply or false)
+ return ai.talk(original_message, reply or false, language)
end
end
function ai.greeting()
local greetings = {
'Hello!',
'Hi.',
'How are you?',
'What\'s up?',
'Are you okay?',
'How\'s it going?',
'What\'s your name?',
'What are you up to?',
'Hello.',
'Hey!',
'Hey.',
'Howdy!',
'Howdy.',
'Hello there!',
'Hello there.'
}
return greetings[math.random(#greetings)]
end
function ai.farewell()
local farewells = {
'Goodbye!',
'Bye.',
'I\'ll speak to you later, yeah?',
'See ya!',
'Oh, bye then.',
'Bye bye.',
'BUH-BYE!',
'Aw. See ya.'
}
return farewells[math.random(#farewells)]
end
function ai.unsure()
local unsure = {
'What?',
'I really don\'t understand.',
'What are you trying to say?',
'Huh?',
'Um..?',
'Excuse me?',
'What does that mean?'
}
return unsure[math.random(#unsure)]
end
function ai.feeling()
local feelings = {
'I am good thank you!',
'I am well.',
'Good, how about you?',
'Very well thank you; you?',
'Never better!',
'I feel great!'
}
return feelings[math.random(#feelings)]
end
function ai.choice(message)
local generic_choices = {
'I do!',
'I do not.',
'Nah, of course not!',
'Why would I?',
'Um...',
'I sure do!',
'Yes, do you?',
'Nope!',
'Yeah!'
}
local personal_choices = {
'I love you!',
'I\'m sorry, but I don\'t really like you!',
'I really like you.',
'I\'m crazy about you!'
}
if message:match('%s*me.?$') then
return personal_choices[math.random(#personal_choices)]
end
return generic_choices[math.random(#generic_choices)]
end
function ai.offline()
local responses = {
'I don\'t feel like talking right now!',
'I don\'t want to talk at the moment.',
'Can we talk later?',
'I\'m not in the mood right now...',
'Leave me alone!',
'Please can I have some time to myself?',
'I really don\'t want to talk to anyone right now!',
'Please leave me in peace.',
'I don\'t wanna talk right now, I hope you understand.'
}
return responses[math.random(#responses)]
end
-function ai:on_message(message)
- self.is_ai = true
- mattata.send_chat_action(message.chat.id, 'typing')
- local text = message.text:gsub('^' .. self.info.first_name:lower() .. ',? ', ''):gsub('^@?' .. self.info.username:lower() .. ',? ', '')
- text = text:gsub(self.info.first_name:lower(), 'you'):gsub('@?' .. self.info.username:lower(), 'you')
- local reply = false
- if message.reply and message.reply.text and message.reply.from.id == self.info.id and not message.reply.entities then
- reply = message.reply.text
- end
- local output = ai.process(self, text, reply)
- if not output then
- return false
- end
- local success = mattata.send_reply(message, output)
- if output:lower():match('g?o?o?d?bye') or output:lower():match('see ya') and not mattata.is_group_admin(message.chat.id, self.info.id) and mattata.is_group_admin(message.chat.id, message.from.id) then
- return mattata.leave_chat(message.chat.id)
+while true do
+ local messages = redis:keys('ai:*:*')
+ if next(messages) then
+ for _, message in pairs(messages) do
+ local chat_id, message_id = message:match('^ai:(.-):(.-)$')
+ local text = redis:hget(message, 'text')
+ local reply = redis:hget(message, 'reply') or false
+ local language = redis:hget(message, 'language') or 'en'
+ api.send_chat_action(chat_id, 'typing')
+ local output = ai.process(text, reply, language)
+ if output then
+ local msg = {
+ ['chat'] = {
+ ['id'] = chat_id
+ },
+ ['message_id'] = message_id
+ }
+ redis:del(message)
+ api.send_reply(msg, output)
+ end
+ end
end
- return success
-end
-
-return ai
\ No newline at end of file
+ os.execute('sleep 0.1s')
+end
\ No newline at end of file
diff --git a/install.sh b/install.sh
index bbae8b2..a385777 100644
--- a/install.sh
+++ b/install.sh
@@ -1,61 +1,61 @@
printf "This script is intended to work with Ubuntu 16.04 - 18.04, other versions may also\n"
printf "work. Root access is required to complete the installation. Press enter to continue,\n"
printf "or press CTRL + C to abort.\n"
read
set -e
sudo apt-get update
-aptlist="git wget openssl coreutils make gcc libreadline-dev redis-server unzip libexpat1-dev libcurl3 libcurl3-gnutls ruby ruby-dev libgd-dev imagemagick tesseract-ocr"
+aptlist="git wget openssl coreutils make gcc libreadline-dev redis-server unzip libexpat1-dev libcurl3 libcurl3-gnutls ruby ruby-dev libgd-dev imagemagick tesseract-ocr libpcre3-dev"
for package in $aptlist; do
printf "[Info] Installing $package...\n"
sudo apt-get --yes --force-yes install $package
done
if [ ! -f "`which lua`" ]; then
printf "[Info] Downloading Lua 5.3.5...\n"
wget -N http://www.lua.org/ftp/lua-5.3.5.tar.gz
printf "[Info] Extracting Lua 5.3.5...\n"
tar zxf lua-5.3.5.tar.gz
cd lua-5.3.5/
printf "[Info] Installing Lua 5.3.5...\n"
sudo make linux test
sudo make install
sudo cp /usr/local/bin/lua /usr/bin/lua
sudo cp /usr/local/bin/luac /usr/bin/luac
cd ../
fi
if [ ! -f "`which luarocks`" ]; then
printf "[Info] Downloading LuaRocks...\n"
git clone --recursive https://github.com/keplerproject/luarocks
cd luarocks/
printf "[Info] Building LuaRocks...\n"
sudo ./configure --lua-version=5.3 --versioned-rocks-dir
sudo make build
printf "[Info] Installing LuaRocks...\n"
sudo make install
cd ../
fi
printf "[Info] Installing openssl...\n"
sudo luarocks install --server=http://luarocks.org/dev openssl
-rocklist="luasocket luasec multipart-post lpeg dkjson serpent redis-lua luafilesystem uuid html-entities feedparser telegram-bot-lua lzlib"
+rocklist="luasocket luasec multipart-post lpeg dkjson serpent redis-lua luafilesystem uuid html-entities feedparser telegram-bot-lua lzlib lrexlib-pcre"
for rock in $rocklist; do
printf "[Info] Installing $rock...\n"
sudo luarocks install $rock
done
printf "[Info] Installing lua-captcha...\n"
git clone git://github.com/lua-programming/lua-captcha.git
cp patch/malloc.patch lua-captcha/
cd lua-captcha/
git apply malloc.patch
sudo luarocks make rockspec/lua-captcha-1.0-0.rockspec
cd ../
printf "[Info] Installing redis-dump...\n"
sudo gem install redis-dump
printf "[Info] Installing ImageMagick...\n"
wget https://imagemagick.org/download/binaries/magick
printf "[Info] Cleaning up installation files...\n"
sudo rm -rf lua-5.3.5/
sudo rm lua-5.3.5.tar.gz
sudo rm -rf luarocks/
sudo rm -rf patch/
sudo rm -rf lua-captcha/
sudo -k
printf "[Info] Installation complete.\n"
diff --git a/languages/de_de.lua b/languages/de_de.lua
index 9cde412..921963d 100644
--- a/languages/de_de.lua
+++ b/languages/de_de.lua
@@ -1,778 +1,778 @@
-- This is a language file for mattata
-- Language: de-de
-- Author: LKD70, CodeNameT1M
-- DO NOT CHANGE ANYTHING THAT BEGINS OR ENDS WITH A %
-- THESE ARE PLACEHOLDERS!
-- DO NOT CHANGE ANY MARKDOWN/HTML FORMATTING!
-- IF YOU ARE UNSURE, ASK ON TELEGRAM (t.me/mattataDev)
return {
['errors'] = {
['connection'] = 'Verbindungs Fehler.',
['results'] = 'Kein Ergebnis gefunden.',
['supergroup'] = 'Dieser Befehl kann nur in Supergruppen benutzt werden.',
['admin'] = 'Für diesen Befehl musst du ein Moderator oder Administrator in dieser Gruppe sein.',
['unknown'] = 'Ich kann den Benutzer nicht erkennen. Wenn du mich lehren möchtest wer dieser Benutzer ist, dann leite einfach eine Nachricht von diesem Benutzer in eine Gruppe in der ich auch bin .',
['generic'] = 'Ein Fehler ist passiert!',
['use'] = 'Du hast keine Benutzungserlaubnis!',
['private'] = 'You can only use this command in private chat!'
},
['addcommand'] = {
['1'] = 'Please specify the command in the format <code>/command - description</code>',
['2'] = 'I couldn\'t retrieve my commands!',
['3'] = 'The command description can\'t be longer than 256 characters!',
['4'] = 'An unknown error occurred! I couldn\'t add your command!',
['5'] = 'Success! Command added.'
},
['addrule'] = {
['1'] = 'Please specify the rule you would like to add!',
['2'] = 'You don\'t have any rules to add to! Please set group rules using /setrules!',
['3'] = 'I couldn\'t add that rule, as it would make the length of the rules longer than Telegram\'s 4096 character limit!',
['4'] = 'I couldn\'t add that rule, it appears it contains invalid Markdown formatting!',
['5'] = 'Successfully updated the rules!'
},
['addslap'] = {
['1'] = 'You can only use this command in groups!',
['2'] = 'The slap cannot contain curly braces apart from placeholders!',
['3'] = 'The slap cannot be any longer than 256 characters in length!',
['4'] = 'I\'ve successfully added that slap as a possibility for /slap in this group!',
['5'] = 'You must include placeholders in your slap. Use {ME} for the person executing and {THEM} for the victim.'
},
['administration'] = {
['1'] = 'Enable Administration',
['2'] = 'Disable Administration',
['3'] = 'Anti-Spam Settings',
['4'] = 'Warning Settings',
['5'] = 'Vote-Ban Settings',
['6'] = 'Welcome New Users?',
['7'] = 'Send Rules On Join?',
['8'] = 'Send Rules In Group?',
['9'] = 'Back',
['10'] = 'Next',
['11'] = 'Word Filter',
['12'] = 'Anti-Bot',
['13'] = 'Anti-Link',
['14'] = 'Log Actions?',
['15'] = 'Anti-RTL',
['16'] = 'Anti-Spam Action',
['17'] = 'Ban',
['18'] = 'Kick',
['19'] = 'Delete Commands?',
['20'] = 'Force Group Language?',
['21'] = 'Send Settings In Group?',
['22'] = 'Delete Reply On Action?',
['23'] = 'Require Captcha?',
['24'] = 'Use Inline Captcha?',
['25'] = 'Ban SpamWatch-flagged users?',
['26'] = 'Number of warnings until %s:',
['27'] = 'Upvotes needed to ban:',
['28'] = 'Downvotes needed to dismiss:',
['29'] = 'Deleted %s, and its matching link from the database!',
['30'] = 'There were no entries found in the database matching "%s"!',
['31'] = 'You\'re not an administrator in that chat!',
['32'] = 'The minimum number of upvotes required for a vote-ban is %s.',
['33'] = 'The maximum number of upvotes required for a vote-ban is %s.',
['34'] = 'The minimum number of downvotes required for a vote-ban is %s.',
['35'] = 'The maximum number of downvotes required for a vote-ban is %s.',
['36'] = 'The maximum number of warnings is %s.',
['37'] = 'The minimum number of warnings is %s.',
['38'] = 'You can add one or more words to the word filter by using /filter <word(s)>',
['39'] = 'You will no longer be reminded that the administration plugin is disabled. To enable it, use /administration.',
['40'] = 'That\'s not a valid chat!',
['41'] = 'You don\'t appear to be an administrator in that chat!',
['42'] = 'My administrative functionality can only be used in groups/channels! If you\'re looking for help with using my administrative functionality, check out the "Administration" section of /help! Alternatively, if you wish to manage the settings for a group you administrate, you can do so here by using the syntax /administration <chat>.',
['43'] = 'Use the keyboard below to adjust the administration settings for <b>%s</b>:',
['44'] = 'Please send me a [private message](https://t.me/%s), so that I can send you this information.',
['45'] = 'I have sent you the information you requested via private chat.',
['46'] = 'Remove Channel Pins?',
['47'] = 'Remove Other Pins?',
['48'] = 'Remove Pasted Code?',
['49'] = 'Prevent Inline Bots?',
['50'] = 'Kick Media On Join?',
['51'] = 'Enable Plugins For Admins?',
['52'] = 'Kick URLs On Join?'
},
['afk'] = {
['1'] = 'Tut mir leid. Dieses Feature ist nur dann verfügbar, wenn der Benutzer einen öffentlichen @Benutzername hat!',
['2'] = '%s ist wieder zurück nachdem er/sie nicht anwesend war für %s!',
['3'] = 'Notiz',
['4'] = '%s ist nicht anwesend.%s'
},
['antispam'] = {
['1'] = 'Disable',
['2'] = 'Enable',
['3'] = 'Disable limit',
['4'] = 'Enable limits on %s',
['5'] = 'All Administration Settings',
['6'] = '%s [%s] has kicked %s [%s] from %s [%s] for hitting the configured anti-spam limit for [%s] media.',
['7'] = 'Kicked %s for hitting the configured antispam limit for [%s] media.',
['8'] = 'The maximum limit is 100.',
['9'] = 'The minimum limit is 1.',
['10'] = 'Modify the anti-spam settings for %s below:',
['11'] = 'Hey %s, if you\'re going to send code that is longer than %s characters in length, please do so using /paste in <a href="https://t.me/%s">private chat with me</a>!',
['12'] = '%s <code>[%s]</code> has %s %s <code>[%s]</code> from %s <code>[%s]</code> for sending Telegram invite link(s).\n#chat%s #user%s',
['13'] = '%s %s for sending Telegram invite link(s).',
- ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to whitelist it, use /whitelistlink <links>.',
+ ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to allowlist it, use /allowlink <links>.',
['15'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending media within their first few messages.\n#chat%s #user%s',
['16'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending a URL within their first few messages.\n#chat%s #user%s'
},
['appstore'] = {
['1'] = 'Ansehen in iTunes',
['2'] = 'rating',
['3'] = 'ratings'
},
['authspotify'] = {
['1'] = 'You are already authorised using that account.',
['2'] = 'Authorising, please wait...',
['3'] = 'A connection error occured. Are you sure you replied with the correct link? It should look like',
['4'] = 'Successfully authorised your Spotify account!'
},
['avatar'] = {
['1'] = 'Ich konnte kein Profilbild für den Benutzer abrufen. Bitte sorge dafür, dass du einen gültigen Benutzername oder eine gültige Identifikationsnummer angegeben hast.',
['2'] = 'Dieser Benutzer hat keine Profilbilder.',
['3'] = 'Dieser Benutzer hat nicht viele Profilbilder!',
['4'] = 'Dieser Benutzer ist opted out(ausgetreten) von der Datensammlung funktionalität, deswegen ist es mir nicht möglich die Profil Bilder anzuzeigen.',
['5'] = 'User: %s\nPhoto: %s/%s\nSend /avatar %s [offset] to @%s to view a specific photo of this user',
['6'] = 'User: %s\nPhoto: %s/%s\nUse /avatar %s [offset] to view a specific photo of this user'
},
['ban'] = {
['1'] = 'Welchen Benutzer soll ich sperren? Du kannst den Benutzer mit dem Benutzernamen oder mit der Identifikationsnummer angeben.',
['2'] = 'Ich kann diesen Benutzer nicht sperren, weil er/sie ein Moderator oder Administrator in dieser Gruppe ist.',
['3'] = 'Ich kann diesen Benutzer nicht sperren, weil er/sie die Gruppe schon verlassen hat.',
['4'] = 'Ich kann diesen Benutzer nicht sperren, weil er/sie für die Gruppe schon gesperrt ist.',
['5'] = 'Ich muss Administrationsberechtigung haben damit ich den Benutzer sperren kann. Bitte kümmer dich um das Problem und versuche es noch einmal.',
['6'] = '%s <code>[%s]</code> has banned %s <code>[%s]</code> from %s <code>[%s]</code>%s.\n%s %s',
['7'] = '%s has banned %s%s.'
},
['bash'] = {
['1'] = 'Zum durchführen gebe ein Befehl an bitte!',
['2'] = 'Erfolg!'
},
- ['blacklist'] = {
+ ['blocklist'] = {
['1'] = 'Welchen Benutzer soll ich auf die schwarze Liste setzen? Du kannst den Benutzer mit dem Benutzernamen oder mit der Identifikationsnummer angeben.',
['2'] = 'Ich kann diesen Benutzer nicht auf die schwarze Liste setzen, weil er/sie ein Moderator oder Administrator in dieser Gruppe ist.',
['3'] = 'Ich kann diesen Benutzer nicht auf die schwarze Liste setzen, weil er/sie die Gruppe schon verlassen hat.',
['4'] = 'Ich kann diesen Benutzer nicht auf die schwarze Liste setzen, weil er/sie für die gruppe schon gesperrt ist.',
- ['5'] = '%s <code>[%s]</code> has blacklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
- ['6'] = '%s has blacklisted %s from using %s%s.'
+ ['5'] = '%s <code>[%s]</code> has blocklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
+ ['6'] = '%s has blocklisted %s from using %s%s.'
},
- ['blacklistchat'] = {
+ ['blocklistchat'] = {
['1'] = '%s ist nun auf der schwarzen Liste. Ich will euch auch verlassen wenn ich hinzugefügt werde!',
['2'] = '%s ist ein Benutzer. Dieser Befehl ist für die schwarze Liste von Unterhaltungen wie Gruppen und Kanäle!',
['3'] = '%s ist keine gültige Unterhaltung!'
},
['bugreport'] = {
['1'] = 'Erfolg! Dein Fehlerbericht wurde gesendet. Die Identifikationsnummer für diesen Bericht ist #%s.',
['2'] = 'Es ist ein Fehler aufgetreten mit dem Fehlerbericht!'
},
['calc'] = {
['1'] = 'Zum senden des Ergebnis klicken.',
['2'] = '"%s" was an unexpected word!',
['3'] = 'You cannot have a unit before a number!'
},
['captionbotai'] = {
['1'] = 'Ich kann das Bild wirklich nicht beschreiben!'
},
['cats'] = {
['1'] = 'Miau!'
},
['channel'] = {
['1'] = 'Du bist nicht berechtigt zum benutzen!',
['2'] = 'Es sieht so aus als wärst du nicht mehr ein Administrator dieser Gruppe!',
['3'] = 'Ich konnte deine Nachricht nicht senden. Bist du sicher, dass ich immer noch befugt bin zum senden von Nachrichten in dieser Gruppe?',
['4'] = 'Deine Nachricht ist gesendet!',
['5'] = 'Es war mir nicht möglich eine List mit Administratoren von dieser Gruppe zu bekommen!',
['6'] = 'Es sieht so aus als wärst kein Administrator dieser Gruppe!',
['7'] = 'Bitte spezifiere die Nachricht und benutze den Syntax /channel <Kanal> <Nachricht>.',
['8'] = 'Bist du dir sicher, dass du die nachricht senden möchtest? Das ist wie es ausehen wird:',
['9'] = 'Ja, ich bin sicher!',
['10'] = 'Diese Nachricht hat ein falsches Format! Bitte korigiere den Syntax und versuche es noch einmal.'
},
['chatroulette'] = {
['1'] = 'Hey! Please don\'t send messages longer than %s characters. We don\'t want to annoy the other user!',
['2'] = '*Anonymous said:*\n```\n%s\n```\nTo end your session, send /endchat.',
['3'] = 'I\'m afraid I lost connection from the other user! To begin a new chat, please send /chatroulette!',
['4'] = 'The other person you were chatting with has ended the session. To start a new one, send /chatroulette.',
['5'] = 'Successfully ended your session. To start a new one, send /chatroulette.',
['6'] = 'I have successfully removed you from the list of available users.',
['7'] = 'You don\'t have a session set up at the moment. To start one, send /chatroulette.',
['8'] = 'Finding you a session, please wait...',
['9'] = 'I\'m afraid there aren\'t any available users right now, but I have added you to the list of available users! To stop this completely, please send /endchat.',
['10'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.',
['11'] = 'I\'m afraid the user who I tried to pair you with has since blocked me. Please try and send /chatroulette again to try and connect to me!',
['12'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.'
},
['commandstats'] = {
['1'] = 'Es wurden keine Befehle in dieser Unterhaltung gesendet!',
['2'] = '<b>Befehl Statistiken für:</b> %s\n\n%s\n<b>Summe der gesendeten Befehle:</b> %s',
['3'] = 'Die Befehl Statistiken für diese Unterhaltung wurden gelöscht!',
['4'] = 'Ich konnte die Befehl Statistiken für diese Unterhaltung nicht löschen. Wurden sie vielleicht schon gelöscht?'
},
['control'] = {
['1'] = 'Pfft, wie du willst!',
['2'] = '%s ist am Neuladen...'
},
['copypasta'] = {
['1'] = 'Der Antowrten-zu text kann nicht länger sein als %s Zeichen!'
},
['coronavirus'] = {
['1'] = [[*COVID-19 Statistics for:* %s
*New confirmed cases:* %s
*Total confirmed cases:* %s
*New deaths:* %s
*Total deaths:* %s
*New recovered cases:* %s
*Total recovered cases:* %s]]
},
['custom'] = {
['1'] = 'Erfolg! Die Nachricht wird nun jedesmal gesendet wen jemand %s benutzt!',
['2'] = 'Der Auslöser "%s" existiert nicht!',
['3'] = 'Der Auslöser "%s" ist gelöscht!',
['4'] = 'Du hast keine eigene Auslöser angegeben!',
['5'] = 'Eigene Befehle für %s:\n',
['6'] = 'Zum machen von eigenen Befehlen, benutze diesen Syntax:\n/custom new #Auslöser <Wert>. Zum listen aller bestehenden Auslöser, benutze /custom list. Zum löschen eines Auslösers, benutze /custom del #Auslöser.'
},
['delete'] = {
['1'] = 'Ich konnte die Nachricht nicht löschen. Ist die Nachricht vielleicht zu alt oder existiert nicht?'
},
['demote'] = {
['1'] = 'Welchen Benutzer soll ich degradieren? Du kannst den Benutzer mit dem Benutzernamen oder mit der Identifikationsnummer angeben.',
['2'] = 'Ich kann den Benutzer nicht degradieren, weil er/sie ein Moderator oder Administrator in dieser Gruppe ist.',
['3'] = 'Ich kann den Benutzer nicht degradieren, weil er/sie die Gruppe schon verlassen hat.',
['4'] = 'Ich kann den Benutzer nicht degradieren, weil er/sie von der Gruppe entfernt wurde.'
},
['dice'] = {
['1'] = 'Die mindest Spannweite ist %s.',
['2'] = 'Die maximal Spannweite und Zählung ist beides %s.',
['3'] = 'Die maximal Spannweite ist %s, die maximal Zählung ist %s.',
['4'] = '%s rollt mit einer Spannweite von %s:\n'
},
['doge'] = {
['1'] = 'Bitte gebe den text ein welchen du in Doge-ify sehen willst. Jeder Satz sollte getrennt sein mit Schrägstrich oder neue Zeile..'
},
['donate'] = {
['1'] = '<b>Hello, %s!</b>\n\nIf you\'re feeling generous, you can contribute to the mattata project by making a monetary donation of any amount. This will go towards server costs and any time and resources used to develop mattata. This is an optional act, however it is greatly appreciated and your name will also be listed publically on mattata\'s GitHub page.\n\nIf you\'re still interested, you can donate <a href="https://paypal.me/wrxck">here</a>. Thank you for your continued support!'
},
['duckduckgo'] = {
['1'] = 'Ich bin nicht sicher was das ist!'
},
['eightball'] = {
['1'] = 'Ja.',
['2'] = 'Nein.',
['3'] = 'Es ist warscheinlich so.',
['4'] = 'Also... Wenn ich du wäre würde ich später noch mal fragen.'
},
['exec'] = {
['1'] = 'Bitte wähle die Sprache in der dein Code ausgeführt werden soll:',
['2'] = 'Ein Fehler ist aufgetreten! Die Verbindung ist unterbrochen. Hast du versucht mich langsamer zu machen?',
['3'] = 'Du hast ausgewählt: "%s" – bist du sicher?',
['4'] = 'Zurück',
['5'] = 'Ich bin sicher',
['6'] = 'Bitte gebe den Schnipsel Code ein, welchen du durchführen willst. Du must keine Sprache wählen, wir machen das später!',
['7'] = 'Bitte wähle die Sprache in der dein Code ausgeführt werden soll:'
},
['facebook'] = {
['1'] = 'Ein Fehler ist aufgetreten!',
['2'] = 'Bitte gebe den Namen von dem Facebook Benutzer ein, von welchem du ein Profilbild bekommen willst.',
['3'] = 'Schaue @%s in Facebook an'
},
['fact'] = {
['1'] = 'Generiere nochmal'
},
['fban'] = {
['1'] = 'Which user would you like me to Fed-ban? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot Fed-ban this user because they are a moderator or an administrator in this chat.'
},
['flickr'] = {
['1'] = 'Du hast gesucht für:',
['2'] = 'Bitte gebe einen Suchbegriff ein (das ist, was ich in flickr für dich suchen soll, d.h. "Big Ben" will ein Bild vom Big Ben in London senden).',
['3'] = 'Mehr Ergebnisse.'
},
['game'] = {
['1'] = 'Total gewonnen: %s\nTotal verloren: %s\nGuthaben: %s mattacoins',
['2'] = 'Dem Spiel beitreten',
['3'] = 'Dieses Spiel hat schon geendet!',
['4'] = 'Du bist nicht an der reihe!',
['5'] = 'Du bist kein Mitspieler von diesem Spiel!',
['6'] = 'Du kannst da nicht hingehen!',
['7'] = 'Du bist schon ein Mitspieler von diesem Spiel!',
['8'] = 'Dieses Spiel hat schon angefangen!',
['9'] = '%s [%s] spielt gegen %s [%s]\nEs ist %s an der reihe!',
['10'] = '%s hat das Spiel gewonnen gegen %s!',
['11'] = '%s hat das spiel gezogen gegen %s!',
['12'] = 'Warte für einen Gegenspieler...',
['13'] = 'Tic-Tac-Toe',
['14'] = 'Klick zum senden des Spiels in die Unterhaltung!',
['15'] = 'Statistik für %s:\n',
['16'] = 'Spiel Tic-Tac-Toe!'
},
- ['gblacklist'] = {
+ ['gblocklist'] = {
['1'] = 'Bitte Antworte-zu dem Benutzer, welchen du global auf der schwarzen Liste haben möchtest, oder gebe ihn/sie mit Benutzername/Identifikationsnummer an.',
['2'] = 'Ich kann keine Information über "%s" finden, bitte prüfe nach ob der Benutzername/Identifikationsnummer gültig ist und versuche es noch einmal.',
['3'] = 'Das ist ein/e %s, aber kein Benutzer!'
},
['gif'] = {
['1'] = 'Bitte gebe einen Suchbegriff ein (das ist, was ich in GIPHY für dich suchen soll, d.h. "Katze" will ein GIF von einer Katze senden).'
},
- ['gwhitelist'] = {
+ ['gallowlist'] = {
['1'] = 'Bitte Antworte-zu dem Benutzer, welchen du global auf der weißen Liste haben möchtest, oder gebe ihn/sie mit Benutzername/Identifikationsnummer an.',
['2'] = 'Ich kann keine Information über "%s" finden, bitte prüfe nach ob der Benutzername/Identifikationsnummer gültig ist und versuche es noch einmal.',
['3'] = 'Das ist ein/e %s, aber kein Benutzer!'
},
['hackernews'] = {
['1'] = 'Top Stories von Hacker News:'
},
['help'] = {
['1'] = 'Kein Ergebnis gefunden!',
['2'] = 'Keine Eigenschaften gefunden, welche übereinstimmen mit "%s". Bitte versuche ein bischen spezifischer zu sein!',
['3'] = '\n\nArguments: <erforderlich> [optional]\n\nSuche für Eigenschaften oder bekomme Hilfe mit der Benutzung von einem Befehl meiner inline Search Funktionalität - erwähne mich in irgendeiner Unterhaltung mit dem Syntax @%s <Suchbegriff>.',
['4'] = 'Vorherige',
['5'] = 'Nächste',
['6'] = 'Zurück',
['7'] = 'Suche',
['8'] = 'Du bist auf Seite %s von %s!',
['9'] = [[
Ich kann viele administrative Handlungen in deinen Gruppen machen. Du brauchst mich nur als Administrator hinzufügen und sende /administration zum anpassen der Einstellungen für deine Gruppe.
Hier sind einige administrative Befehle und ein kurzer Kommentar bezüglich was sie tun:
• /pin <text> - Sende einen formatierten Text, welcher auch bearbeitet werden kann mit dem selben Befehl und anderem Text, zum ersparen vom anheften eines textes den du nicht bearbeiten kannst to save you from having to re-pin a message if you can't edit it (was passieren kann, wenn der Text älter als 48 Stunden ist).
• /ban - Sperre einen Benutzer mit einer Antwort zu deren Text, oder mit spezifizieren mit deren Benutzername/Identifikationsnummer.
• /kick - Kick (sperren und dann sperre aufheben) einen Benutzer mit einer Antwort zu deren Text, oder mit spezifizieren mit deren Benutzername/Identifikationsnummer.
• /unban - Die Sperre eines Benutzer aufheben mit einer Antwort zu deren Text, oder mit spezifizieren mit deren Benutzername/Identifikationsnummer.
• /setrules <text> - Mache einen formatierten Text als Gruppenregel, welcher gesendet wird, wenn jemand /rules benutzt.
]],
['10'] = [[
• /setwelcome - Mache einen formatierten Text als Wilkommens Text, welcher jedesmal gesendet wird, wenn ein neuer Benutzer der Gruppe beitritt (der Willkommens Text kann ausgeschalted werden im Administration Menü, erreichbar durch /administration). Du kannst Platzhalter benutzen für einen individuellen Willkommens Text für jeden Benutzer. Benutze $user_id zum einfügen des Benutzers Identifikationsnummer, $chat_id zum einfügen der Gruppen Identifikationsnummer, $name zum einfügen des Benutzers name, $title zum einfügen des Gruppennamen und $username zum einfügen des Benutzers Benutzername (wenn der Benutzer keinen @Benutzernamen hat, wird deren Name benutzt, also ist es das beste, dieses zu vermeiden mit der Benutzung von $name).
• /warn - Warne einen Benutzer und sperre ihn/sie, wenn mehr als das Maximum der Warnungen ausgesprochen wurden.
• /mod - Befördere den Antworten-zu Benutzer. Gib im zugriff zu administrative Befehle wie /ban, /kick, /warn usw. (das ist sinnvoll wenn du nicht möchtest, dass jemand Nachrichten löschen kann)
• /demod - Degradiere den Antworten-zu Benutzer. Nehme deren Moderationstatus weg und die Möglichkeit zum benutzen administrativen Befehlen.
• /staff - Sehe den Gruppenerschaffer, Administratoren und Moderatoren in einer schön formatierten Liste.
]],
['11'] = [[
• /report - Sendet den Antworten-zu Text zu allen Administratoren und warnt sie vor der aktuellen Situation.
• /setlink <URL> - Ändert den Gruppen Link zu der gegebenen URL, welcher gesendet wird wenn jemand /link benutzt.
• /links <text> - Weiße Liste von allen gefundenen Telegram Links im angegebenen Text (einschließlich @Benutzername links)
]],
['12'] = 'Nachfolgend sind einige Links die du vielleicht nützlich findest:',
['13'] = 'Development',
['14'] = 'Channel',
['15'] = 'Support',
['16'] = 'FAQ',
['17'] = 'Source',
['18'] = 'Donate',
['19'] = 'Rate',
['20'] = 'Administration Log',
['21'] = 'Admin Settings',
['22'] = 'Plugins',
['23'] = [[
<b>Hallo %s! Mein Name ist %s, schön dich zu treffen.</b> %s
Ich verstehe viele Befehle, welche du lernen kannst wenn du den "Commands" Knopf drückst in der angehängten Tastatur.
%s <b>Tip:</b> Benutze den "Settings" Knopf zum verändern wie ich arbeite%s!
%s <b>Wenn du mich für sinnvoll hälst, oder vielleicht nur helfen willst?</b> Spenden sind willkommen, benutze /donate für mehr Information!
]],
['24'] = 'in'
},
['id'] = {
['1'] = 'Ich kann den Benutzer nicht erkennen. Wenn du mich lehren möchtest wer dieser Benutzer ist, dann leite einfach eine Nachricht von diesem Benutzer in eine Gruppe in der ich auch bin .',
['2'] = 'Abgefragte Unterhaltung:',
['3'] = 'Diese Unterhaltung:',
['4'] = 'Klick zum senden des Ergebnis!'
},
['imdb'] = {
['1'] = 'Vorherige',
['2'] = 'Nächste',
['3'] = 'Du bist auf Seite %s von %s!'
},
['import'] = {
['1'] = 'Ich kann die Unterhaltung nicht erkennen!',
['2'] = 'Dies ist keine Supergruppe, des wegen kann ich keine Einstellungen von da importieren!',
['3'] = 'Administrative Einstellungen erfolgreich importiert und ich habe die Plugins umgeschaltet von %s zu %s!'
},
['info'] = {
['1'] = [[
```
Redis:
%s Konfigurationsdatei: %s
%s Modus: %s
%s TCP Port: %s
%s Version: %s
%s Betriebszeit: %s Tage
%s Verarbeitete Identifikationsnummern: %s
%s Abgelaufene Schlüssel: %s
%s Benutzeranzahl: %s
%s Gruppenanzahl: %s
System:
%s OS: %s
```
]]
},
['instagram'] = {
['1'] = '@%s in Instagram'
},
['ipsw'] = {
['1'] = '<b>%s</b> iOS %s\n\n<code>MD5 sum: %s\nSHA1 sum: %s\nFile size: %s GB</code>\n\n<i>%s %s</i>',
['2'] = 'Diese Firmware ist nicht mehr signiert!',
['3'] = 'Diese Firmware ist noch signiert!',
['4'] = 'Bitte wähle dein Model:',
['5'] = 'Bitte wähle deine Firmware Version:',
['6'] = 'Bitte wähle deinen Geräte Typ:',
['7'] = 'iPod Touch',
['8'] = 'iPhone',
['9'] = 'iPad',
['10'] = 'Apple TV'
},
['ispwned'] = {
['1'] = 'Dieses Konto wurde in folgenden undichten Stellen gefunden:'
},
['itunes'] = {
['1'] = 'Name:',
['2'] = 'Artist:',
['3'] = 'Album:',
['4'] = 'Track:',
['5'] = 'Disc:',
['6'] = 'Die orginale Frage kann nicht gefunden werden. Du hast wahrscheinlich den orginalen Text gelöscht.',
['7'] = 'Das Kunstwerk kann weiter unten gefunden werden:',
['8'] = 'Bitte gebe einen Suchbegriff ein (das ist, was ich in iTunes für dich suchen soll, d.h. "Green Day American Idiot" gibt dir das erste Ergebnis von American Idiot von Green Day).',
['9'] = 'Bekomme Album Kunstwerke'
},
['kick'] = {
['1'] = 'Welchen Benutzer soll ich raus werfen? Du kannst ihn/sie mit dem @Benutzernamen oder mit der Identifikationsnummer angeben.',
['2'] = 'Ich kann den Benutzer nicht raus werfen, weil er/sie Moderator oder Administrator in dieser Gruppe ist.',
['3'] = 'Ich kann den Benutzer nicht raus werfen, weil er/sie hat die Gruppe schon verlassen hat.',
['4'] = 'Ich kann den Benutzer nicht raus werfen, weil er/sie schon von der Gruppe entfernt wurde.',
['5'] = 'Ich brauche administrative Berechtigung zum raus werfen des Benutzers. Bitte behebe das Problem und versuche es noch einmal.'
},
['lastfm'] = {
['1'] = '%s\'s last.fm Benutzername wurde zu "%s" gesendet.',
['2'] = 'Dein last.fm Benutzername wurde vergessen!',
['3'] = 'Im Moment hast du keinen last.fm Benutzernamen!',
['4'] = 'Bitte gebe deinen letzten last.fm Benutzernamen an oder richte ihn mit /fmset ein.',
['5'] = 'Keine Vergangenheit für diesen Benutzer gefunden.',
['6'] = '%s hört im Moment:\n',
['7'] = '%s hörte zuletzt:\n',
['8'] = 'Unbekannt',
['9'] = 'Klick zum senden des Ergebnis.'
},
['location'] = {
['1'] = 'Du hast keinen Standort angegeben. Welchen Standort möchtest du haben?'
},
['logchat'] = {
['1'] = 'Bitte gebe den Benutzernamen oder die Identifikationsnummer der Unterhaltung an, in welche du alle administrativen Handlungen senden möchtest.',
['2'] = 'Überprüfe ob die Unterhaltungen gültig ist...',
['3'] = 'Tut mir leid aber es sieht so aus, also ob du eine ungültige Unterhaltung, oder eine Unterhaltung in der ich nicht drin bin, angegeben hast. Bitte behebe das Problem und versuche es noch einmal.',
['4'] = 'Du kannst keinen Benutzer als logchat angeben!',
['5'] = 'Es sieht so aus, also ob du kein Administrator der Unterhaltung bistt!',
['6'] = 'Es sieht so aus, als ob ich schon administrative Handlungsrechte in dieser Gruppe besitze. Wenn du mir administrative Handlungsrechte in einer anderen Gruppe geben willst benutze /logchat.',
['7'] = 'Diese Unterhaltung ist gültig. Ich werde nun einen Testtext zu der Unterhaltung schicken, um zu sehen ob ich die Genehmigung zum schreiben habe!',
['8'] = 'Hallo, Welt - dies ist ein Testext zum herausfinden ob ich die Gehnemigung zum schreiben habe - wenn du das liest, dann ist alles OK!',
['9'] = 'Alles fertig! Von nun an alle administrativen Handlungen werden auch zu %s gesendet - zum ändern der Unterhaltung, in die du administrative Handlungen senden möchtest, sende /logchat.'
},
['lua'] = {
['1'] = 'bitte gebe eine Reihe von Lua ein zum ausführen!'
},
['lyrics'] = {
['1'] = 'Spotify',
['2'] = 'Zeige Liedtext',
['3'] = 'Bitte gebe einen Suchbegriff ein (das ist, zu welchem Lied/Sänger/Gruppe ich den Liedtext suchen soll, d.h. "Green Day Basket Case" gibt dir den Liedtext zu dem Lied song Basket Case von Green Day).'
},
['minecraft'] = {
['1'] = '<b>%s hat den Benutzernamen %s mal gewechselt</b>',
['2'] = '<b>%s hat den Benutzernamen %s mal gewechselt</b>',
['3'] = 'Vorherige',
['4'] = 'Nächste',
['5'] = 'Zurück',
['6'] = 'UUID',
['7'] = 'BenutzerBild',
['8'] = 'Benutzername Vergangenheit',
['9'] = 'Bitte wähle eine Option:',
['10'] = 'Bitte gebe den Benutzernamen des Minecraft Spielers an, für welchen du Informationen sehen möchtest (d.h. wen du "Notch" sendest kannst du die Informationen von dem Spieler Notch einsehen).',
['11'] = 'Minecraft Benutzernamen sind zwischen 3 und 16 Zeichen lang.'
},
['mute'] = {
['1'] = 'Welchen Benutzer soll ich stumm schalten? Du kannst den Benutzer mit dem @Benutzername oder mit der Indetifikationsnummer angeben.',
['2'] = 'Ich kann den Benutzer nich stumm schalten, weil der Benutzer in dieser Unterhaltung schon stumm geschaltet ist.',
['3'] = 'Ich kann den Benutzer nich stumm schalten, weil der Benutzer in dieser Unterhaltung Moderator oder Administrator ist.',
['4'] = 'Ich kann den Benutzer nich stumm schalten, weil der Benutzer diese Unterhaltung schon verlassen hat oder rausgeworfen wurde.',
['5'] = 'Zum stumm schalten des Benutzers muss ich Administrationsrechte haben. Bitte ändere meine Rechte und versuche es noch einmal.'
},
['myspotify'] = {
['1'] = 'Profil',
['2'] = 'Folgende',
['3'] = 'Vor kurzem gespielt',
['4'] = 'Derzeit spielen',
['5'] = 'Top Lieder',
['6'] = 'Top Künstler',
['7'] = 'Es sieht nicht so aus, als würdest du einem Künstler folgen!',
['8'] = 'Dein Top Künstler',
['9'] = 'Es sieht so aus, als würdest du keine Lieder in deiner Sammlung haben!',
['10'] = 'Deine Top Lieder',
['11'] = 'Es sieht nicht so aus, als würdest du einem Künstler folgen!',
['12'] = 'Künstler denen du folgst',
['13'] = 'Es sieht nicht so aus als hättest du vor kurzem irgendwelche lieder gespielt!',
['14'] = '<b>Vor kurzem gespielt</b>\n%s %s\n%s %s\n%s Gehört um %s:%s am %s/%s/%s.',
['15'] = 'Deine Anfrage wurde akzeptiert aber die Bearbeitung wurde noch nicht beendet.',
['16'] = 'Es sieht nicht so aus als würdest du dir im moment etwas anhören!',
['17'] = 'Derzeit spielen',
['18'] = 'Beim erneuten Autorisieren deines Spotify Accounts ist ein Fehler aufgetreten!',
['19'] = 'Dein Spotify Account wurde erneut erfolgreich Autorisiert! Deine orginal Anfrage wird bearbeitet...',
['20'] = 'Erneutes Autorisieren deines Spotify Accounts, bitte warten...',
['21'] = 'Zum verbinden deines Spotify Accounts musst du mattata autorisieren. Klick [hier](https://accounts.spotify.com/en/authorize?client_id=%s&response_type=code&redirect_uri=%s&scope=user-library-read,playlist-read-private,playlist-read-collaborative,user-read-private,user-read-email,user-follow-read,user-top-read,user-read-playback-state,user-read-recently-played,user-read-currently-playing,user-modify-playback-state) and press the green "OKAY" button to link mattata to your Spotify account. After you\'ve done that, send the link you were redirected to (it should begin with "%s", followed by a unique code) in reply to this message.',
['22'] = 'Wiedergabeliste',
['23'] = 'Benutze Inline Mode',
['24'] = 'Lyrics',
['25'] = 'Keine Geräte gefunden.',
['26'] = 'Es sieht so aus, als wenn du keine Wiedergabeliste hast.',
['27'] = 'Deine Wiedergabeliste',
['28'] = '%s %s [%s Lieder]',
['29'] = '%s %s [%s]\nSpotify %s Benutzer\n\n<b>Gerät:</b>\n%s',
['30'] = 'Spiele vorheriges Lied...',
['31'] = 'Du bist kein Premium Benutzer!',
['32'] = 'Ich kann keine Geräte finden.',
['33'] = 'Spiele nächstes Lied...',
['34'] = 'Lied wird fortgesetzt...',
['35'] = 'Dein Gerät ist im moment nicht erreichbar...',
['36'] = 'Keine Geräte gefunden!',
['37'] = 'Pause Lied...',
['38'] = 'Jetzt spielen',
['39'] = 'Mixe deine Musik...',
['40'] = 'Das ist keine gültig Lautstärke. Gebe bitte eine Nummer zwischen 0 und 100 an.',
['41'] = 'Die Lautstärke wurde auf %s%% eingestellt!',
['42'] = 'Dies Nachricht benutzt ein altes Plugin, zum anfragen eines neues bitte sende /myspotify!'
},
['name'] = {
['1'] = 'Der Name auf den ich im moment antworte ist "%s" - zum ändern, benutze /name <text> ( <text> ist der Name auf den du willst, dass ich andworte).',
['2'] = 'Mein neuer Name muss zwischen 2 und 32 Buchstaben lang sein!',
['3'] = 'Mein Name kann nur aus Buchstaben bestehen!',
['4'] = 'Ich antworten nun auf "%s", und nicht mehr auf "%s" - zum ändern, benutze /name <text> ( <text> ist der Name auf den du willst, dass ich andworte).'
},
['netflix'] = {
['1'] = 'Mehr lesen.'
},
['news'] = {
['1'] = '"<code>%s</code>" ist kein gültiges Lua Muster.',
['2'] = 'Ich konnte keine Quellenliste bekommen.',
['3'] = '<b>Nachrichtenquelle gefunden zu</b> "<code>%s</code>":\n\n%s',
['4'] = '<b>Hier sind die aktuellen verfügbaren Nachrichtenquellen, welche du mit</b> /news<b> benutzen kannst. Benutze</b> /nsources &lt;query&gt; <b>zum durchsuchen der Liste von Nachrichtenquellen für ein besseres Ergebnis. Die suche wird abgestimmt mit den Lua Mustern</b>\n\n%s',
['5'] = 'Du hast keine bevorzugte Nachrichtenquelle. Benutze /setnews <Quelle>. Zum ansehen einer Quellenliste benutze /nsources, oder beschränke das Ergebnis mit /nsources <Abfrage>.',
['6'] = 'Deine derzeit bevorzugte Nachrichtenquelle ist %s. Zum ändern benutze /setnews <Quelle>.Zum ansehen einer Quellenliste benutze /nsources, oder beschränke das Ergebnis mit /nsources <Abfrage>.',
['7'] = 'Deine derzeit bevorzugte Nachrichtenquelle ist %s! Zum ansehen der derzeiting Top Story benutze /news.',
['8'] = 'Dies ist keine gültige Nachrichtenquelle. Zum ansehen einer Quellenliste benutze /nsources, oder beschränke das Ergebnis mit /nsources <Abfrage>.',
['9'] = 'Deine bevorzugte Nachrichtenquelle wurde zu %s aktualisiert! Zum ansehen der derzeiting Top Story benutze /news.',
['10'] = 'Dies ist keine gültige Nachrichtenquelle. Zum ansehen einer Quellenliste benutze /nsources. Wenn du eine bevorzugte Nachrichtenquelle hast benutze /setnews <Quelle> und do bekommst automatisch von dieser Quelle Nachrichten geschickt wenn du /news sendest.',
['11'] = 'Mehr lesen.'
},
['nick'] = {
['1'] = 'Dein Spitzname is vergessen!',
['2'] = 'Dein Spitzname wurde geändert zu "%s"!'
},
['optout'] = {
['1'] = 'Du bist opted-in(beigetreten), dass die Daten, welche du sendest, gesammelt werden! Benutze /optout zum opt-out(austreten).',
['2'] = 'Du bist opted-out(ausgetreten), dass die Daten, welche du sendest, gesammelt werden! Benutze /optin zum opt-in(beitreten).'
},
['paste'] = {
['1'] = 'Bitte suche einen Service aus zum hochladen und einfügen deines Textes:'
},
['pay'] = {
['1'] = 'Du hast im Moment %s mattacoins. Verdiene mehr wenn du das Spiel Tic-Tac-Toe gewinnst. Benutze /game - Du gewinnst 100 mattacoins für jedes gewonnene Spiel und du verlierst 50 für jedes verlorene Spiel.',
['2'] = 'Du musst diesen Befehl benutzen als Antwort zu dem Benutzer dem du mattacoins senden willst.',
['3'] = 'Bitte gebe die Menge der mattacoins an, welche du zu %s senden möchtest.',
['4'] = 'Die Menge sollte in einer Zahl angegeben sein, welche nicht kleiner als 0 sein kann.',
['5'] = 'Du kannst kein Geld zu dir selbst schicken!',
['6'] = 'Du hast nicht genug Guthaben zum durchführen der Transaktion!',
['7'] = '%s mattacoins wurden gesendet zu %s. Dein neues Guthaben ist %s mattacoins.'
},
['pin'] = {
['1'] = 'Du hast noch keinen pin gesetzt. Benutze /pin <dein Text> um deinen Text zu pinnen. Markdown formatierung ist verfügbar.',
['2'] = 'Hier ist die letzte nachricht die mit /pin generiert wurde',
['3'] = 'Ich habe einen bereits existierenden pin in meiner Datenbank gefunden, aber die nachricht, die ich bereits gesendet habe, aber sie wurde gelöscht, und ich finde sie nicht mehr. Benutze /pin <dein Text> um deinen Text zu pinnen. Markdown formatierung ist verfügbar.',
['4'] = 'Es ist ein fehler bei der aktualisierung deines pins aufgetreten. Vielleicht hat dein Text eine ungültige Markdown formatierung, oder sie wurde gelöscht. Ich versuche dir einen neuen pin zu senden, welchen du unten findest - falls du es ändern möchtest, wenn die nachricht noch existiert, benutze /pin <dein text>.',
['5'] = 'Ich kann den text nicht senden weil er eine ungültige Markdown formatierung hat.',
['6'] = 'Klick hier um den pin zu sehen, aktualisiert mit dem Text den du mir gegeben hast.'
},
['pokedex'] = {
['1'] = 'Name: %s\nID: %s\nArt: %s\nBeschreibung: %s'
},
['prime'] = {
['1'] = 'Bitte gebe eine Zahl zwischen 1 und 99999 ein.',
['2'] = '%s ist eine Primzahl!',
['3'] = '%s ist KEINE Primzahl...'
},
['promote'] = {
['1'] = 'Ich kann diesen Benutzer nicht beförderen, weil er/sie Moderator oder Administrator in dieser Gruppe ist.',
['2'] = 'Ich kann diesen Benutzer nicht beförderen, weil er/sie hat die Gruppe schon verlassen hat.',
['3'] = 'Ich kann diesen Benutzer nicht beförderen, weil er/sie schon von der Gruppe entfernt wurde.'
},
['quote'] = {
['1'] = 'Dieser Benutzer ist opted out(ausgetreten) von der Datensammlung funktionalität.',
['2'] = 'Da sind keine Zitate von %s%s! Du kannst Zitate speichern wenn du /save als Antwort zu dem gesendeten text(welchen du als Zitat speichern willst).'
},
['randomsite'] = {
['1'] = 'Generiere nochmal'
},
['randomword'] = {
['1'] = 'Generiere nochmal',
['2'] = 'Dein zufälliges Wort ist <b>%s</b>!'
},
['report'] = {
['1'] = 'Bitte Antworte zu der Nachricht die du einem GruppenAdminsitrator melden möchtest.',
['2'] = 'Du kannst deine eigenen Nachrichten nicht melden, machst du vielleicht Witze?',
['3'] = '<b>%s braucht Hilfe in %s!</b>',
['4'] = 'Klicke hier zum ansehen der gemeldeten Nachricht.',
['5'] = 'Ich habe die Nachricht erfolgreich gemeldet zu %s admin(s)!'
},
['rms'] = {
['1'] = 'Heiliges GNU!'
},
['save'] = {
['1'] = 'Dieser Benutzer ist opted out(ausgetreten) von der Datensammlung funktionalität.',
['2'] = 'Dieser Text ist gespeichert in meiner Datei und wird zu der List möglicher Antworten hinzugefügt, wenn /quote benutzt wird als Antwort zu %s%s!'
},
['sed'] = {
['1'] = '%s\n\n<i>%s wollte das nicht sagen!</i>',
['2'] = '%s\n\n<i>%s hat zugegeben verloren zu haben.</i>',
['3'] = '%s\n\n<i>%s ist sich nicht sicher obe er/sie missverstanden ist...</i>',
['4'] = 'Ach halt die Klappe, <i>wann habe ich jemals nicht recht?</i>',
['5'] = '"<code>%s</code>" ist kein gültiges Lua Muster.',
['6'] = '<b>Hallo, %s, meintest du:</b>\n<i>%s</i>',
['7'] = 'Ja',
['8'] = 'Nein',
['9'] = 'Bin nicht sicher'
},
['setgrouplang'] = {
['1'] = 'Die Sprache in dieser Gruppe wurde eingstellet zu %s!',
['2'] = 'Die Sprache in dieser Gruppe ist im moment %s.\nBitte nehme zur Kenntnis, dass vielleicht noch nicht alles vollständig Übersetzt ist. Wenn du die Sprache ändern möchtest, wähle unten auf der Tastatur eine aus:',
['3'] = 'Die Möglichkeit, dass alle Benutzer in dieser Gruppe die selbe Sprache benutzent müssen, ist im moment ausgeschaltet. Diese Einstellung sollte von /administration eingestellet werden, damit es einfacher ist für dich, habe ich unten Knöpfe zum einstellen hinzugefügt.',
['4'] = 'Einschalten',
['5'] = 'Ausschalten'
},
['setlang'] = {
['1'] = 'Deine Sprache wurde eingestellt zu %s!',
['2'] = 'Deine Sprache ist im Moment eingestellt zu %s.\nBitte beachte, dass manche Wörter oder Sätze noch nicht übersetzet sind. Wenn du deine Sprache ändern möchtest, suche dir eine aus in der Tastatur unten:'
},
['setlink'] = {
['1'] = 'Das ist keine gültige URL.',
['2'] = 'Link erfolgreich gesetzt!'
},
['setrules'] = {
['1'] = 'Ungültige Markdown-Formatierung.',
['2'] = 'Neue Regeln erfolgreich eingestellt!'
},
['setwelcome'] = {
['1'] = 'Was möchtest als Willkommens Text haben? Den angegebenen Text wird formatiert und jedesmal gesendet, wenn ein Benutzer der Gruppe beitritt (Der Willkommens Text kann ausgeschaltet werden im Administrations Menue, erreichbar mit /administration). Du kannst Platzhalter benutzen für einen individuellen Willkommens Text für jeden Benutzer. Benutze $user_id zum einfügen des Benutzers Identifikationsnummer, $chat_id zum einfügen der Gruppen Identifikationsnummer, $name zum einfügen des Benutzers name, $title zum einfügen des Gruppennamen und $username zum einfügen des Benutzers Benutzername (wenn der Benutzer keinen @Benutzernamen hat, wird deren Name benutzt, also ist es das beste, dieses zu vermeiden mit der Benutzung von $name).',
['2'] = 'Da ist ein Fehler mit dem Format deines Textes aufgetreten. Bitte Überprüfe die Syntax und versuche es noch einmal.',
['3'] = 'Der Willkommens Text für %s wurde erfolgreich aktualisiert!'
},
['share'] = {
['1'] = 'Teilen'
},
['shorten'] = {
['1'] = 'Bitte wähle einen URL Verkürzer aus mit den Buttons unten:'
},
['shsh'] = {
['1'] = 'Für den ECID konnte ich keine SHSH blobs holen. Bitte mache sicher, dass sie gültig sind und das to sie gespeichert hast auf https://tsssaver.1conan.com.',
['2'] = 'SHSH blobs sind verfügbar für das Gerät mit der folgenden Version von iOS:\n',
['3'] = 'Download .zip'
},
['statistics'] = {
['1'] = 'Es wurden keine Nachrichten in dieser Unterhaltung gesendet!',
['2'] = '<b>Statistiken für:</b> %s\n\n%s\n<b>Summe der gesendeten Nachrichten:</b> %s',
['3'] = 'Die Statistiken für diese Unterhaltung wurde gelöscht!',
['4'] = 'Ich konnte die Statistiken für dies Unterhaltung nicht löschen. Vielleicht wurde sie schon gelöscht?'
},
['steam'] = {
['1'] = 'Dein Steam Benutzername wurde gespeichert mit "%s".',
['2'] = '"%s" ist kein gültiger Steam Benutzername.',
['3'] = '%s ist ein Steam Benutzer seit %s, in %s. Er/Sie hat sich das letzte mal ausgelogt am %s, in %s. Klick <a href="%s">here</a> zum ansehen von deren Steam Profil.',
['4'] = '%s, alias "%s",'
},
['synonym'] = {
['1'] = 'Du könntest das Wort <b>%s</b> benutzen, wäre besser als %s.'
},
['thoughts'] = {
['1'] = '%s\n\nPositive: <code>%s%% [%s]</code>\nNegative: <code>%s%% [%s]</code>\nGleichgültige: <code>%s%% [%s]</code>\nSumme Gedanken: <code>%s</code>'
},
['tobinary'] = {
['1'] = 'Bitte gebe ein Wort oder Satz ein, welchen du umwandeln willst zu Binary.'
},
['trust'] = {
['1'] = 'Ich kann den Benutzer nicht zu trust(vertrauen) einstellen, weil er Moderator oder Administrator in dieser Gruppe ist.',
['2'] = 'Ich kann den Benutzer nicht zu trust(vertrauen) einstellen, weil er die Gruppe schon verlassen hat.',
['3'] = 'Ich kann den Benutzer nicht zu trust(vertrauen) einstellen, weil er von dieser Gruppe entfernt wurde.'
},
['unmute'] = {
['1'] = 'Welchen Benutzer soll ich zu Stören einstellen? Gebe den Benutzer mit dem @Benutzername oder der Identifikationsnummer an.',
['2'] = 'Ich kann den Benutzer nicht zu Stören einstellen, weil er im moment nicht stumm geschalted ist..',
['3'] = 'Ich kann den Benutzer nicht zu Stören einstellen, weil er Moderator oder Administrator dieser Gruppe ist.',
['4'] = 'Ich kann den Benutzer nicht zu Stören einstellen, weil er die Gruppe schon verlassen hat oder von der Gruppe entfernt wurde.'
},
['untrust'] = {
['1'] = 'Welchen Benutzer soll ich zu untrust(nicht vertrauen) einstellen? Gebe den Benutzer mit dem @Benutzername oder der Identifikationsnummer an.',
['2'] = 'Ich kann den Benutzer nicht zu untrust(nicht vertrauen) einstellen, weil er Moderator oder Administrator in dieser Gruppe ist.',
['3'] = 'Ich kann den Benutzer nicht zu untrust(nicht vertrauen) einstellen, weil er die Gruppe schon verlassen hat.',
['4'] = 'Ich kann den Benutzer nicht zu untrust(nicht vertrauen) einstellen, weil er von dieser Gruppe entfernt wurde.'
},
['upload'] = {
['1'] = 'Bitte antworte zu der Datei, welche du hochlanden willst zum Server. Sie muss <= 20 MB sein.',
['2'] = 'Die Datei ist zu groß. Sie muss <= 20 MB sein.',
['3'] = 'Ich konnte die Datei nicht bekommen, wahrscheinlich ist sie zu alt.',
['4'] = 'Es ist ein Fehler aufgetreten beim abrufen der Datei.',
['5'] = 'Die Datei wurde erfolgreich hochgelanden zum Server - sie kan gefunden werden mit <code>%s</code>!'
},
['version'] = {
['1'] = '@%s alias %s `[%s]` läuft mit mattata %s, kreiert von [Matthew Hesketh](https://t.me/wrxck). Der Quellcode ist auf [GitHub](https://github.com/wrxck/mattata) zu bekommen.'
},
['voteban'] = {
['1'] = 'Für welchen Benutzer möchtest einen vote-ban(Wahl zur Sperre) eröffnen? Gebe den Benutzer mit dem @Benutzername oder der Identifikationsnummer an.',
['2'] = 'Ich kann keinen vote-ban(Wahl zur Sperre) für diesen Benutzer aufsetzen, weil er Moderator oder Administrator in dieser Gruppe ist.',
['3'] = 'Ich kann keinen vote-ban(Wahl zur Sperre) für diesen Benutzer aufsetzen, weil er die Gruppe schon verlassen hat oder von der Gruppe entfernt wurde.',
['4'] = 'Soll %s [%s] gesperrt werden von %s? %s dafür(Yes) werden gebraucht für eine sofortige Sperre und %s dagegen(No) werden gebraucht zum sofortigen schliessen der Wahl.',
['5'] = 'Ja [%s]',
['6'] = 'Nein [%s]',
['7'] = 'Die Leute haben gesprochen. Ich have %s [%s] von %s gesperrt, weil %s Leute dafür gewählt haben.',
['8'] = 'Der erfordliche Anzahl dafür wurde erreicht, aber es war mir nicht möglich %s zu sperren - vielleicht hat er/sie die Gruppe schon verlassen oder wurde befördert seit die Wahl eröffnet wurde? Es ist entweder das, oder ich habe keine Administrationsrechte mehr.',
['9'] = 'Die Leute haben gesprochen. Ich habe %s [%s] nicht von %s gesperrt, weil %s Leute dagegen gewählt haben.',
['10'] = 'Du hast dafür gewählt %s [%s] zu sperren!',
['11'] = 'Deine Wahl wurde zurückgezogen,zum eingeben einer neuen Wahl benutze die Knöpfe nocheinmal.',
['12'] = 'Du hast dagegen gewählt %s [%s] zu sperren!',
['13'] = 'Eine Wahl zum bannen des Benutzers wurde schon eröffnet!'
},
['weather'] = {
['1'] = 'Du hast keinen Standort ausgewählt. Zum auswählen benutze /setloc <Standort>.',
['2'] = 'Im Moment ist es %s (fühlt sich an wie %s) in %s. %s'
},
['welcome'] = {
['1'] = 'Group Rules'
},
- ['whitelist'] = {
+ ['allowlist'] = {
['1'] = 'Welchen Benutzer soll ich auf die Weiße Liste setzen? Gebe den Benutzer mit dem @Benutzername oder der Identifikationsnummer an.',
['2'] = 'Ich kann den Benutzer nicht auf die Weiße Liste setzen, weil er Moderator oder Administrator in dieser Gruppe ist.',
['3'] = 'Ich kann den Benutzer nicht auf die Weiße Liste setzen, weil er die Gruppe schon verlassen hat.',
['4'] = 'Ich kann den Benutzer nicht auf die Weiße Liste setzen, weil er von der Gruppe entfernt wurde.'
},
['wikipedia'] = {
['1'] = 'Mehr lesen.'
},
['youtube'] = {
['1'] = 'Vorherige',
['2'] = 'Nächste',
['3'] = 'Du bist auf Seite %s von %s!'
}
}
diff --git a/languages/en_us.lua b/languages/en_us.lua
index b08e826..7767aec 100644
--- a/languages/en_us.lua
+++ b/languages/en_us.lua
@@ -1,809 +1,809 @@
-- This is a language file for mattata
-- Language: en-us
-- Author: wrxck
-- DO NOT CHANGE ANYTHING THAT BEGINS OR ENDS WITH A %
-- THESE ARE PLACEHOLDERS!
-- DO NOT CHANGE ANY MARKDOWN/HTML FORMATTING!
-- IF YOU ARE UNSURE, ASK ON TELEGRAM (t.me/mattataDev)
return {
['errors'] = {
['connection'] = 'Connection error.',
['results'] = 'I couldn\'t find any results for that.',
['supergroup'] = 'This command can only be used in supergroups.',
['admin'] = 'You need to be a moderator or an administrator in this chat in order to use this command.',
['unknown'] = 'I don\'t recognize that user. If you would like to teach me who they are, forward a message from them to any chat that I\'m in.',
['generic'] = 'An error occured!',
['use'] = 'You are not allowed to use this!',
['private'] = 'You can only use this command in private chat!'
},
['addcommand'] = {
['1'] = 'Please specify the command in the format <code>/command - description</code>',
['2'] = 'I couldn\'t retrieve my commands!',
['3'] = 'The command description can\'t be longer than 256 characters!',
['4'] = 'An unknown error occurred! I couldn\'t add your command!',
['5'] = 'Success! Command added.'
},
['addrule'] = {
['1'] = 'Please specify the rule you would like to add!',
['2'] = 'You don\'t have any rules to add to! Please set group rules using /setrules!',
['3'] = 'I couldn\'t add that rule, as it would make the length of the rules longer than Telegram\'s 4096 character limit!',
['4'] = 'I couldn\'t add that rule, it appears it contains invalid Markdown formatting!',
['5'] = 'Successfully updated the rules!'
},
['addslap'] = {
['1'] = 'You can only use this command in groups!',
['2'] = 'The slap cannot contain curly braces apart from placeholders!',
['3'] = 'The slap cannot be any longer than 256 characters in length!',
['4'] = 'I\'ve successfully added that slap as a possibility for /slap in this group!',
['5'] = 'You must include placeholders in your slap. Use {ME} for the person executing and {THEM} for the victim.'
},
['administration'] = {
['1'] = 'Enable Administration',
['2'] = 'Disable Administration',
['3'] = 'Anti-Spam Settings',
['4'] = 'Warning Settings',
['5'] = 'Vote-Ban Settings',
['6'] = 'Welcome New Users?',
['7'] = 'Send Rules On Join?',
['8'] = 'Send Rules In Group?',
['9'] = 'Back',
['10'] = 'Next',
['11'] = 'Word Filter',
['12'] = 'Anti-Bot',
['13'] = 'Anti-Link',
['14'] = 'Log Actions?',
['15'] = 'Anti-RTL',
['16'] = 'Anti-Spam Action',
['17'] = 'Ban',
['18'] = 'Kick',
['19'] = 'Delete Commands?',
['20'] = 'Force Group Language?',
['21'] = 'Send Settings In Group?',
['22'] = 'Delete Reply On Action?',
['23'] = 'Require Captcha?',
['24'] = 'Use Inline Captcha?',
['25'] = 'Ban SpamWatch-flagged users?',
['26'] = 'Number of warnings until %s:',
['27'] = 'Upvotes needed to ban:',
['28'] = 'Downvotes needed to dismiss:',
['29'] = 'Deleted %s, and its matching link from the database!',
['30'] = 'There were no entries found in the database matching "%s"!',
['31'] = 'You\'re not an administrator in that chat!',
['32'] = 'The minimum number of upvotes required for a vote-ban is %s.',
['33'] = 'The maximum number of upvotes required for a vote-ban is %s.',
['34'] = 'The minimum number of downvotes required for a vote-ban is %s.',
['35'] = 'The maximum number of downvotes required for a vote-ban is %s.',
['36'] = 'The maximum number of warnings is %s.',
['37'] = 'The minimum number of warnings is %s.',
['38'] = 'You can add one or more words to the word filter by using /filter <word(s)>',
['39'] = 'You will no longer be reminded that the administration plugin is disabled. To enable it, use /administration.',
['40'] = 'That\'s not a valid chat!',
['41'] = 'You don\'t appear to be an administrator in that chat!',
['42'] = 'My administrative functionality can only be used in groups/channels! If you\'re looking for help with using my administrative functionality, check out the "Administration" section of /help! Alternatively, if you wish to manage the settings for a group you administrate, you can do so here by using the syntax /administration <chat>.',
['43'] = 'Use the keyboard below to adjust the administration settings for <b>%s</b>:',
['44'] = 'Please send me a [private message](https://t.me/%s), so that I can send you this information.',
['45'] = 'I have sent you the information you requested via private chat.',
['46'] = 'Remove Channel Pins?',
['47'] = 'Remove Other Pins?',
['48'] = 'Remove Pasted Code?',
['49'] = 'Prevent Inline Bots?',
['50'] = 'Kick Media On Join?',
['51'] = 'Enable Plugins For Admins?',
['52'] = 'Kick URLs On Join?'
},
['afk'] = {
['1'] = 'Sorry, I\'m afraid this feature is only available to users with a public @username!',
['2'] = '%s has returned after being AFK for %s!',
['3'] = 'Note',
['4'] = '%s is now AFK.%s'
},
['antispam'] = {
['1'] = 'Disable',
['2'] = 'Enable',
['3'] = 'Disable limit',
['4'] = 'Enable limits on %s',
['5'] = 'All Administration Settings',
['6'] = '%s [%s] has kicked %s [%s] from %s [%s] for hitting the configured anti-spam limit for [%s] media.',
['7'] = 'Kicked %s for hitting the configured antispam limit for [%s] media.',
['8'] = 'The maximum limit is 100.',
['9'] = 'The minimum limit is 1.',
['10'] = 'Modify the anti-spam settings for %s below:',
['11'] = 'Hey %s, if you\'re going to send code that is longer than %s characters in length, please do so using /paste in <a href="https://t.me/%s">private chat with me</a>!',
['12'] = '%s <code>[%s]</code> has %s %s <code>[%s]</code> from %s <code>[%s]</code> for sending Telegram invite link(s).\n#chat%s #user%s',
['13'] = '%s %s for sending Telegram invite link(s).',
- ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to whitelist it, use /whitelistlink <links>.',
+ ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to allowlist it, use /allowlink <links>.',
['15'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending media within their first few messages.\n#chat%s #user%s',
['16'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending a URL within their first few messages.\n#chat%s #user%s'
},
['appstore'] = {
['1'] = 'View on iTunes',
['2'] = 'rating',
['3'] = 'ratings'
},
['authspotify'] = {
['1'] = 'You are already authorised using that account.',
['2'] = 'Authorising, please wait...',
['3'] = 'A connection error occured. Are you sure you replied with the correct link? It should look like',
['4'] = 'Successfully authorised your Spotify account!'
},
['avatar'] = {
['1'] = 'I couldn\'t retrieve the profile photos for that user, please ensure you specified a valid username or numerical ID.',
['2'] = 'That user doesn\'t have any profile photos.',
['3'] = 'That user doesn\'t have that many profile photos!',
['4'] = 'That user has opted-out of data-collecting functionality, therefore I am not able to show you any of their profile photos.',
['5'] = 'User: %s\nPhoto: %s/%s\nSend /avatar %s [offset] to @%s to view a specific photo of this user',
['6'] = 'User: %s\nPhoto: %s/%s\nUse /avatar %s [offset] to view a specific photo of this user'
},
['ban'] = {
['1'] = 'Which user would you like me to ban? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot ban this user because they are a moderator or an administrator in this chat.',
['3'] = 'I cannot ban this user because they have already left this chat.',
['4'] = 'I cannot ban this user because they have already been banned from this chat.',
['5'] = 'I need to have administrative permissions in order to ban this user. Please amend this issue, and try again.',
['6'] = '%s <code>[%s]</code> has banned %s <code>[%s]</code> from %s <code>[%s]</code>%s.\n%s %s',
['7'] = '%s has banned %s%s.'
},
['bash'] = {
['1'] = 'Please specify a command to run!',
['2'] = 'Success!'
},
- ['blacklist'] = {
- ['1'] = 'Which user would you like me to blacklist? You can specify this user by their @username or numerical ID.',
- ['2'] = 'I cannot blacklist this user because they are a moderator or an administrator in this chat.',
- ['3'] = 'I cannot blacklist this user because they have already left this chat.',
- ['4'] = 'I cannot blacklist this user because they have already been banned from this chat.',
- ['5'] = '%s <code>[%s]</code> has blacklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
- ['6'] = '%s has blacklisted %s from using %s%s.'
- },
- ['blacklistchat'] = {
- ['1'] = '%s has now been blacklisted, and I will leave whenever I am added there!',
- ['2'] = '%s is a user, this command is only for blacklisting chats such as groups and channels!',
+ ['blocklist'] = {
+ ['1'] = 'Which user would you like me to blocklist? You can specify this user by their @username or numerical ID.',
+ ['2'] = 'I cannot blocklist this user because they are a moderator or an administrator in this chat.',
+ ['3'] = 'I cannot blocklist this user because they have already left this chat.',
+ ['4'] = 'I cannot blocklist this user because they have already been banned from this chat.',
+ ['5'] = '%s <code>[%s]</code> has blocklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
+ ['6'] = '%s has blocklisted %s from using %s%s.'
+ },
+ ['blocklistchat'] = {
+ ['1'] = '%s has now been blocklisted, and I will leave whenever I am added there!',
+ ['2'] = '%s is a user, this command is only for blocklisting chats such as groups and channels!',
['3'] = '%s doesn\'t appear to be a valid chat!'
},
['bugreport'] = {
['1'] = 'Success! Your bug report has been sent. The ID of this report is #%s.',
['2'] = 'There was a problem whilst reporting that bug! Ha, the irony!'
},
['calc'] = {
['1'] = 'Click to send the result.',
['2'] = '"%s" was an unexpected word!',
['3'] = 'You cannot have a unit before a number!'
},
['captionbotai'] = {
['1'] = 'I really cannot describe that picture!'
},
['cats'] = {
['1'] = 'Meow!'
},
['channel'] = {
['1'] = 'You are not allowed to use this!',
['2'] = 'You don\'t appear to be an administrator in that chat anymore!',
['3'] = 'I couldn\'t send your message, are you sure I still have permission to send messages in that chat?',
['4'] = 'Your message has been sent!',
['5'] = 'I was unable to retrieve a list of administrators for that chat!',
['6'] = 'You don\'t appear to be an administrator in that chat!',
['7'] = 'Please specify the message to send, using the syntax /channel <channel> <message>.',
['8'] = 'Are you sure you want to send this message? This is how it will look:',
['9'] = 'Yes, I\'m sure!',
['10'] = 'That message contains invalid Markdown formatting! Please correct your syntax and try again.'
},
['chatroulette'] = {
['1'] = 'Hey! Please don\'t send messages longer than %s characters. We don\'t want to annoy the other user!',
['2'] = '*Anonymous said:*\n```\n%s\n```\nTo end your session, send /endchat.',
['3'] = 'I\'m afraid I lost connection from the other user! To begin a new chat, please send /chatroulette!',
['4'] = 'The other person you were chatting with has ended the session. To start a new one, send /chatroulette.',
['5'] = 'Successfully ended your session. To start a new one, send /chatroulette.',
['6'] = 'I have successfully removed you from the list of available users.',
['7'] = 'You don\'t have a session set up at the moment. To start one, send /chatroulette.',
['8'] = 'Finding you a session, please wait...',
['9'] = 'I\'m afraid there aren\'t any available users right now, but I have added you to the list of available users! To stop this completely, please send /endchat.',
['10'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.',
['11'] = 'I\'m afraid the user who I tried to pair you with has since blocked me. Please try and send /chatroulette again to try and connect to me!',
['12'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.'
},
['commandstats'] = {
['1'] = 'No commands have been sent in this chat!',
['2'] = '<b>Command statistics for:</b> %s\n\n%s\n<b>Total commands sent:</b> %s',
['3'] = 'The command statistics for this chat have been reset!',
['4'] = 'I could not reset the command statistics for this chat. Perhaps they have already been reset?'
},
['control'] = {
['1'] = 'Pfft, you wish!',
['2'] = '%s is reloading...'
},
['copypasta'] = {
['1'] = 'The replied-to text musn\'t be any longer than %s characters!'
},
['coronavirus'] = {
['1'] = [[*COVID-19 Statistics for:* %s
*New confirmed cases:* %s
*Total confirmed cases:* %s
*New deaths:* %s
*Total deaths:* %s
*New recovered cases:* %s
*Total recovered cases:* %s]]
},
['counter'] = {
['1'] = 'I couldn\'t add a counter to that message!'
},
['custom'] = {
['1'] = 'Success! That message will now be sent every time somebody uses %s!',
['2'] = 'The trigger "%s" does not exist!',
['3'] = 'The trigger "%s" has been deleted!',
['4'] = 'You don\'t have any custom triggers set!',
['5'] = 'Custom commands for %s:\n',
['6'] = 'To create a new, custom command, use the following syntax:\n/custom new #trigger <value>. To list all current triggers, use /custom list. To delete a trigger, use /custom del #trigger.'
},
['delete'] = {
['1'] = 'I could not delete that message. Perhaps the message is too old or non-existent?'
},
['demote'] = {
['1'] = 'Which user would you like me to demote? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot demote this user because they are not a moderator or an administrator in this chat.',
['3'] = 'I cannot demote this user because they have already left this chat.',
['4'] = 'I cannot demote this user because they have already been kicked from this chat.'
},
['dice'] = {
['1'] = 'The minimum range is %s.',
['2'] = 'The maximum range and count are both %s.',
['3'] = 'The maximum range is %s, and the maximum count is %s.',
['4'] = '%s rolls with a range of %s:\n'
},
['doge'] = {
['1'] = 'Please enter the text you want to Doge-ify. Each sentence should be separated using slashes or new lines.'
},
['donate'] = {
['1'] = '<b>Hello, %s!</b>\n\nIf you\'re feeling generous, you can contribute to the mattata project by making a monetary donation of any amount. This will go towards server costs and any time and resources used to develop mattata. This is an optional act, however it is greatly appreciated and your name will also be listed publically on mattata\'s GitHub page.\n\nIf you\'re still interested, you can donate <a href="https://paypal.me/wrxck">here</a>. Thank you for your continued support!'
},
['duckduckgo'] = {
['1'] = 'I\'m not sure what that is!'
},
['eightball'] = {
['1'] = 'Yes.',
['2'] = 'No.',
['3'] = 'It is likely so.',
['4'] = 'Well, uh... I\'d ask again later, if I were you.'
},
['exec'] = {
['1'] = 'Please select the language you would like to execute your code in:',
['2'] = 'An error occured! The connection timed-out. Were you trying to make me lag?',
['3'] = 'You have selected "%s" – are you sure?',
['4'] = 'Back',
['5'] = 'I\'m sure',
['6'] = 'Please enter a snippet of code that you would like to run. You don\'t need to specify the language, we will do that afterwards!',
['7'] = 'Please select the language you would like to execute your code in:'
},
['facebook'] = {
['1'] = 'An error occured!',
['2'] = 'Please enter the name of the Facebook user you would like to get the profile picture of.',
['3'] = 'View @%s on Facebook'
},
['fact'] = {
['1'] = 'Generate Another'
},
['fban'] = {
['1'] = 'Which user would you like me to Fed-ban? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot Fed-ban this user because they are a moderator or an administrator in this chat.'
},
['flickr'] = {
['1'] = 'You searched for:',
['2'] = 'Please enter a search query (that is, what you want me to search Flickr for, i.e. "Big Ben" will return a photograph of Big Ben in London).',
['3'] = 'More Results'
},
['fortune'] = {
['1'] = 'Click to send your fortune!'
},
['frombinary'] = {
['1'] = 'Please enter the binary value you would like to convert to a string.',
['2'] = 'Malformed binary!'
},
['game'] = {
['1'] = 'Total wins: %s\nTotal losses: %s\nBalance: %s mattacoins',
['2'] = 'Join Game',
['3'] = 'This game has already ended!',
['4'] = 'It\'s not your turn!',
['5'] = 'You are not part of this game!',
['6'] = 'You cannot go here!',
['7'] = 'You are already part of this game!',
['8'] = 'This game has already started!',
['9'] = '%s [%s] is playing against %s [%s]\nIt is currently %s\'s turn!',
['10'] = '%s won the game against %s!',
['11'] = '%s drew the game against %s!',
['12'] = 'Waiting for opponent...',
['13'] = 'Tic-Tac-Toe',
['14'] = 'Click to send the game to your chat!',
['15'] = 'Statistics for %s:\n',
['16'] = 'Play Tic-Tac-Toe!'
},
- ['gblacklist'] = {
- ['1'] = 'Please reply-to the user you\'d like to globally blacklist, or specify them by username/ID.',
+ ['gblocklist'] = {
+ ['1'] = 'Please reply-to the user you\'d like to globally blocklist, or specify them by username/ID.',
['2'] = 'I couldn\'t get information about "%s", please check it\'s a valid username/ID and try again.',
['3'] = 'That\'s a %s, not a user!'
},
['gif'] = {
['1'] = 'Please enter a search query (that is, what you want me to search GIPHY for, i.e. "cat" will return a GIF of a cat).'
},
['godwords'] = {
['1'] = 'Please enter a numerical value, between 1 and 64!',
['2'] = 'That number is too small, please specify one between 1 and 64!',
['3'] = 'That number is too large, please specify one between 1 and 64!'
},
- ['gwhitelist'] = {
- ['1'] = 'Please reply-to the user you\'d like to globally whitelist, or specify them by username/ID.',
+ ['gallowlist'] = {
+ ['1'] = 'Please reply-to the user you\'d like to globally allowlist, or specify them by username/ID.',
['2'] = 'I couldn\'t get information about "%s", please check it\'s a valid username/ID and try again.',
['3'] = 'That\'s a %s, not a user!'
},
['hackernews'] = {
['1'] = 'Top Stories from Hacker News:'
},
['help'] = {
['1'] = 'No results found!',
['2'] = 'There were no features found matching "%s", please try and be more specific!',
['3'] = '\n\nArguments: <required> [optional]\n\nSearch for a feature or get help with a command by using my inline search functionality - just mention me in any chat using the syntax @%s <search query>.',
['4'] = 'Previous',
['5'] = 'Next',
['6'] = 'Back',
['7'] = 'Search',
['8'] = 'You are on page %s of %s!',
['9'] = [[
I can perform many administrative actions in your groups, just add me as an administrator and send /administration to adjust the settings for your group.
Here are some administrative commands and a brief comment regarding what they do:
• /pin <text> - Send a Markdown-formatted message which can be edited by using the same command with different text, to save you from having to re-pin a message if you can't edit it (which happens if the message is older than 48 hours)
• /ban - Ban a user by replying to one of their messages, or by specifying them by username/ID
• /kick - Kick (ban and then unban) a user by replying to one of their messages, or by specifying them by username/ID
• /unban - Unban a user by replying to one of their messages, or by specifying them by username/ID
• /setrules <text> - Set the given Markdown-formatted text as the group rules, which will be sent whenever somebody uses /rules
]],
['10'] = [[
• /setwelcome - Set the given Markdown-formatted text as a welcome message that will be sent every time a user joins your group (the welcome message can be disabled in the administration menu, accessible via /administration). You can use placeholders to automatically customise the welcome message for each user. Use $user\_id to insert the user's numerical ID, $chat\_id to insert the chat's numerical ID, $name to insert the user's name, $title to insert the chat title and $username to insert the user's username (if the user doesn't have an @username, their name will be used instead, so it is best to avoid using this with $name)
• /warn - Warn a user, and ban them when they hit the maximum number of warnings
• /mod - Promote the replied-to user, giving them access to administrative commands such as /ban, /kick, /warn etc. (this is useful when you don't want somebody to have the ability to delete messages!)
• /demod - Demote the replied-to user, stripping them from their moderation status and revoking their ability to use administrative commands
• /staff - View the group's creator, administrators, and moderators in a neatly-formatted list
]],
['11'] = [[
• /report - Forwards the replied-to message to all administrators and alerts them of the current situation
• /setlink <URL> - Set the group's link to the given URL, which will be sent whenever somebody uses /link
-• /links <text> - Whitelists all of the Telegram links found in the given text (includes @username links)
+• /links <text> - Allowlists all of the Telegram links found in the given text (includes @username links)
]],
['12'] = 'Below are some links you might find useful:',
['13'] = 'Development',
['14'] = 'Channel',
['15'] = 'Support',
['16'] = 'FAQ',
['17'] = 'Source',
['18'] = 'Donate',
['19'] = 'Rate',
['20'] = 'Administration Log',
['21'] = 'Admin Settings',
['22'] = 'Plugins',
['23'] = [[
<b>Hi %s! My name's %s, it's a pleasure to meet you</b> %s
I understand many commands, which you can learn more about by pressing the "Commands" button using the attached keyboard.
%s <b>Tip:</b> Use the "Settings" button to change how I work%s!
%s <b>Find me useful, or just want to help?</b> Donations are very much appreciated, use /donate for more information!
]],
['24'] = 'in'
},
['id'] = {
['1'] = 'I\'m sorry, but I don\'t recognize that user. To teach me who they are, forward a message from them to me or get them to send me a message.',
['2'] = 'Queried Chat:',
['3'] = 'This Chat:',
['4'] = 'Click to send the result!'
},
['imdb'] = {
['1'] = 'Previous',
['2'] = 'Next',
['3'] = 'You are on page %s of %s!'
},
['import'] = {
['1'] = 'I don\'t recognize that chat!',
['2'] = 'That\'s not a supergroup, therefore I cannot import any settings from it!',
['3'] = 'Successfully imported administrative settings & toggled plugins from %s to %s!'
},
['info'] = {
['1'] = [[
```
Redis:
%s Config File: %s
%s Mode: %s
%s TCP Port: %s
%s Version: %s
%s Uptime: %s days
%s Process ID: %s
%s Expired Keys: %s
%s User Count: %s
%s Group Count: %s
System:
%s OS: %s
```
]]
},
['instagram'] = {
['1'] = '@%s on Instagram'
},
['ipsw'] = {
['1'] = '<b>%s</b> iOS %s\n\n<code>MD5 sum: %s\nSHA1 sum: %s\nFile size: %s GB</code>\n\n<i>%s %s</i>',
['2'] = 'This firmware is no longer being signed!',
['3'] = 'This firmware is still being signed!',
['4'] = 'Please select your model:',
['5'] = 'Please select your firmware version:',
['6'] = 'Please select your device type:',
['7'] = 'iPod Touch',
['8'] = 'iPhone',
['9'] = 'iPad',
['10'] = 'Apple TV'
},
['ispwned'] = {
['1'] = 'That account was found in the following leaks:'
},
['isup'] = {
['1'] = 'This website appears to be up, maybe it\'s just you?',
['2'] = 'That doesn\'t appear to be a valid site!',
['3'] = 'It\'s not just you, this website looks down from here.'
},
['itunes'] = {
['1'] = 'Name:',
['2'] = 'Artist:',
['3'] = 'Album:',
['4'] = 'Track:',
['5'] = 'Disc:',
['6'] = 'The original query could not be found, you\'ve probably deleted the original message.',
['7'] = 'The artwork can be found below:',
['8'] = 'Please enter a search query (that is, what you want me to search iTunes for, i.e. "Green Day American Idiot" will return information about the first result for American Idiot by Green Day).',
['9'] = 'Get Album Artwork'
},
['kick'] = {
['1'] = 'Which user would you like me to kick? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot kick this user because they are a moderator or an administrator in this chat.',
['3'] = 'I cannot kick this user because they have already left this chat.',
['4'] = 'I cannot kick this user because they have already been kicked from this chat.',
['5'] = 'I need to have administrative permissions in order to kick this user. Please amend this issue, and try again.'
},
['lastfm'] = {
['1'] = '%s\'s last.fm username has been set to "%s".',
['2'] = 'Your last.fm username has been forgotten!',
['3'] = 'You don\'t currently have a last.fm username set!',
['4'] = 'Please specify your last.fm username or set it with /fmset.',
['5'] = 'No history was found for this user.',
['6'] = '%s is currently listening to:\n',
['7'] = '%s last listened to:\n',
['8'] = 'Unknown',
['9'] = 'Click to send the result.'
},
['lmgtfy'] = {
['1'] = 'Let me Google that for you!'
},
['location'] = {
['1'] = 'You don\'t have a location set. What would you like your new location to be?'
},
['logchat'] = {
['1'] = 'Please enter the username or numerical ID of the chat you wish to log all administrative actions into.',
['2'] = 'Checking to see whether that chat is valid...',
['3'] = 'I\'m sorry, it appears you\'ve either specified an invalid chat, or you\'ve specified a chat I haven\'t been added to yet. Please rectify this and try again.',
['4'] = 'You can\'t set a user as your log chat!',
['5'] = 'You don\'t appear to be an administrator in that chat!',
['6'] = 'It seems I\'m already logging administrative actions into that chat! Use /logchat to specify a new one.',
['7'] = 'That chat is valid, I\'m now going to try and send a test message to it, just to ensure I have permission to post!',
['8'] = 'Hello, World - this is a test message to check my posting permissions - if you\'re reading this, then everything went OK!',
['9'] = 'All done! From now on, any administrative actions in this chat will be logged into %s - to change the chat you want me to log administrative actions into, just send /logchat.'
},
['lua'] = {
['1'] = 'Please enter a string of Lua to execute!'
},
['lyrics'] = {
['1'] = 'Spotify',
['2'] = 'Show Lyrics',
['3'] = 'Please enter a search query (that is, what song/artist/lyrics you want me to get lyrics for, i.e. "Green Day Basket Case" will return the lyrics for the song Basket Case by Green Day).'
},
['minecraft'] = {
['1'] = '<b>%s has changed his/her username %s time</b>',
['2'] = '<b>%s has changed his/her username %s times</b>',
['3'] = 'Previous',
['4'] = 'Next',
['5'] = 'Back',
['6'] = 'UUID',
['7'] = 'Avatar',
['8'] = 'Username History',
['9'] = 'Please select an option:',
['10'] = 'Please enter the username of the Minecraft player you would like to view information about (i.e. sending "Notch" will view information about the player Notch).',
['11'] = 'Minecraft usernames are between 3 and 16 characters long.'
},
['msglink'] = {
['1'] = 'You can only use this command in supergroups and channels.',
['2'] = 'This %s must be public, with a @username.',
['3'] = 'Please reply to the message you\'d like to get a link for.'
},
['mute'] = {
['1'] = 'Which user would you like me to mute? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot mute this user because they are already muted in this chat.',
['3'] = 'I cannot mute this user because they are a moderator or an administrator in this chat.',
['4'] = 'I cannot mute this user because they have already left (or been kicked from) this chat.',
['5'] = 'I need to have administrative permissions in order to mute this user. Please amend this issue, and try again.'
},
['myspotify'] = {
['1'] = 'Profile',
['2'] = 'Following',
['3'] = 'Recently Played',
['4'] = 'Currently Playing',
['5'] = 'Top Tracks',
['6'] = 'Top Artists',
['7'] = 'You don\'t appear to be following any artists!',
['8'] = 'Your Top Artists',
['9'] = 'You don\'t appear to have any tracks in your library!',
['10'] = 'Your Top Tracks',
['11'] = 'You don\'t appear to be following any artists!',
['12'] = 'Artists You Follow',
['13'] = 'You don\'t appear to have recently played any tracks!',
['14'] = '<b>Recently Played</b>\n%s %s\n%s %s\n%s Listened to at %s:%s on %s/%s/%s.',
['15'] = 'The request has been accepted for processing, but the processing has not been completed.',
['16'] = 'You don\'t appear to be listening to anything right now!',
['17'] = 'Currently Playing',
['18'] = 'An error occured whilst re-authorising your Spotify account!',
['19'] = 'Successfully re-authorised your Spotify account! Processing your original request...',
['20'] = 'Re-authorising your Spotify account, please wait...',
['21'] = 'You need to authorise mattata in order to connect your Spotify account. Click [here](https://accounts.spotify.com/en/authorize?client_id=%s&response_type=code&redirect_uri=%s&scope=user-library-read,playlist-read-private,playlist-read-collaborative,user-read-private,user-read-email,user-follow-read,user-top-read,user-read-playback-state,user-read-recently-played,user-read-currently-playing,user-modify-playback-state) and press the green "OKAY" button to link mattata to your Spotify account. After you\'ve done that, send the link you were redirected to (it should begin with "%s", followed by a unique code) in reply to this message.',
['22'] = 'Playlists',
['23'] = 'Use Inline Mode',
['24'] = 'Lyrics',
['25'] = 'No devices were found.',
['26'] = 'You don\'t appear to have any playlists.',
['27'] = 'Your Playlists',
['28'] = '%s %s [%s tracks]',
['29'] = '%s %s [%s]\nSpotify %s user\n\n<b>Devices:</b>\n%s',
['30'] = 'Playing previous track...',
['31'] = 'You are not a premium user!',
['32'] = 'I could not find any devices.',
['33'] = 'Playing next track...',
['34'] = 'Resuming track...',
['35'] = 'Your device is temporarily unavailable...',
['36'] = 'No devices were found!',
['37'] = 'Pausing track...',
['38'] = 'Now playing',
['39'] = 'Shuffling your music...',
['40'] = 'That\'s not a valid volume. Please specify a number between 0 and 100.',
['41'] = 'The volume has been set to %s%%!',
['42'] = 'This message is using an old version of this plugin, please request a new one by sending /myspotify!'
},
['name'] = {
['1'] = 'The name I currently respond to is "%s" - to change this, use /name <text> (where <text> is what you want me to respond to).',
['2'] = 'My new name needs to be between 2 and 32 characters long!',
['3'] = 'My name may only contain alphanumeric characters!',
['4'] = 'I will now respond to "%s", instead of "%s" - to change this, use /name <text> (where <text> is what you want me to respond to).'
},
['netflix'] = {
['1'] = 'Read more.'
},
['news'] = {
['1'] = '"<code>%s</code>" isn\'t a valid Lua pattern.',
['2'] = 'I couldn\'t retrieve a list of sources.',
['3'] = '<b>News sources found matching</b> "<code>%s</code>":\n\n%s',
['4'] = '<b>Here are the current available news sources you can use with</b> /news<b>. Use</b> /nsources &lt;query&gt; <b>to search the list of news sources for a more specific set of results. Searches are matched using Lua patterns</b>\n\n%s',
['5'] = 'You don\'t have a preferred news source. Use /setnews <source> to set one. View a list of sources using /nsources, or narrow down the results by using /nsources <query>.',
['6'] = 'Your current preferred news source is %s. Use /setnews <source> to change it. View a list of sources using /nsources, or narrow down the results by using /nsources <query>.',
['7'] = 'Your preferred source is already set to %s! Use /news to view the current top story.',
['8'] = 'That\'s not a valid news source. View a list of sources using /nsources, or narrow down the results by using /nsources <query>.',
['9'] = 'Your preferred news source has been updated to %s! Use /news to view the current top story.',
['10'] = 'That\'s not a valid source, use /nsources to view a list of available sources. If you have a preferred source, use /setnews <source> to automatically have news from that source sent when you send /news, without any arguments needed.',
['11'] = 'Read more.'
},
['nick'] = {
['1'] = 'Your nickname has now been forgotten!',
['2'] = 'Your nickname has been set to "%s"!'
},
['ninegag'] = {
['1'] = 'Read More'
},
['optout'] = {
['1'] = 'You have opted-in to having data you send collected! Use /optout to opt-out.',
['2'] = 'You have opted-out of having data you send collected! Use /optin to opt-in.'
},
['paste'] = {
['1'] = 'Please select a service to upload your paste to:'
},
['pay'] = {
['1'] = 'You currently have %s mattacoins. Earn more by winning games of Tic-Tac-Toe, using /game - You will win 100 mattacoins for every game you win, and you will lose 50 for every game you lose.',
['2'] = 'You must use this command in reply to the user you\'d like to send mattacoins to.',
['3'] = 'Please specify the amount of mattacoins you\'d like to give %s.',
['4'] = 'The amount specified should be a numerical value, of which can be no less than 0.',
['5'] = 'You can\'t send money to yourself!',
['6'] = 'You don\'t have enough funds to complete that transaction!',
['7'] = '%s mattacoins have been sent to %s. Your new balance is %s mattacoins.'
},
['pin'] = {
['1'] = 'You haven\'t set a pin before. Use /pin <text> to set one. Markdown formatting is supported.',
['2'] = 'Here is the last message generated using /pin.',
['3'] = 'I found an existing pin in the database, but the message I sent it in seems to have been deleted, and I can\'t find it anymore. You can set a new one with /pin <text>. Markdown formatting is supported.',
['4'] = 'There was an error whilst updating your pin. Either the text you entered contained invalid Markdown syntax, or the pin has been deleted. I\'m now going to try and send you a new pin, which you\'ll be able to find below - if you need to modify it then, after ensuring the message still exists, use /pin <text>.',
['5'] = 'I couldn\'t send that text because it contains invalid Markdown syntax.',
['6'] = 'Click here to see the pin, updated to contain the text you gave me.'
},
['pokedex'] = {
['1'] = 'Name: %s\nID: %s\nType: %s\nDescription: %s'
},
['prime'] = {
['1'] = 'Please enter a number between 1 and 99999.',
['2'] = '%s is a prime number!',
['3'] = '%s is NOT a prime number...'
},
['promote'] = {
['1'] = 'I cannot promote this user because they are a moderator or an administrator of this chat.',
['2'] = 'I cannot promote this user because they have already left this chat.',
['3'] = 'I cannot promote this user because they have already been kicked from this chat.'
},
['quote'] = {
['1'] = 'This user has opted out of data-storing functionality.',
['2'] = 'There are no saved quotes for %s%s! You can save one by using /save in reply to a message they send.'
},
['randomsite'] = {
['1'] = 'Generate Another'
},
['randomword'] = {
['1'] = 'Generate Another',
['2'] = 'Your random word is <b>%s</b>!'
},
['report'] = {
['1'] = 'Please reply to the message you would like to report to the group\'s administrators.',
['2'] = 'You can\'t report your own messages, are you just trying to be funny?',
['3'] = '<b>%s needs help in %s!</b>',
['4'] = 'Click here to view the reported message.',
['5'] = 'I\'ve successfully reported that message to %s admin(s)!'
},
['rms'] = {
['1'] = 'Holy GNU!'
},
['save'] = {
['1'] = 'This user has opted out of data-storing functionality.',
['2'] = 'That message has been saved in my database, and added to the list of possible responses for when /quote is used in reply to %s%s!'
},
['sed'] = {
['1'] = '%s\n\n<i>%s didn\'t mean to say this!</i>',
['2'] = '%s\n\n<i>%s has admitted defeat.</i>',
['3'] = '%s\n\n<i>%s isn\'t sure if they were mistaken...</i>',
['4'] = 'Screw you, <i>when am I ever wrong?</i>',
['5'] = '"<code>%s</code>" isn\'t a valid Lua pattern.',
['6'] = '<b>Hi, %s, did you mean:</b>\n<i>%s</i>',
['7'] = 'Yes',
['8'] = 'No',
['9'] = 'Not sure'
},
['setgrouplang'] = {
['1'] = 'This group\'s language has been set to %s!',
['2'] = 'This group\'s language is currently %s.\nPlease note that some strings may not be translated as of yet. If you\'d like to change your language, select one using the keyboard below:',
['3'] = 'The option to force users to use the same language in this group is currently disabled. This setting should be toggled from /administration but, to make things easier for you, I\'ve included a button below.',
['4'] = 'Enable',
['5'] = 'Disable'
},
['setlang'] = {
['1'] = 'Your language has been set to %s!',
['2'] = 'Your language is currently %s.\nPlease note that some strings may not be translated as of yet. If you\'d like to change your language, select one using the keyboard below:'
},
['setlink'] = {
['1'] = 'That\'s not a valid URL.',
['2'] = 'Link set successfully!'
},
['setrules'] = {
['1'] = 'Invalid Markdown formatting.',
['2'] = 'Successfully set the new rules!'
},
['setwelcome'] = {
['1'] = 'What would you like the welcome message to be? The text you specify will be Markdown-formatted and sent every time a user joins the chat (the welcome message can be disabled in the administration menu, accessible via /administration). You can use placeholders to automatically customise the welcome message for each user. Use $user_id to insert the user\'s numerical ID, $chat_id to insert the chat\'s numerical ID, $name to insert the user\'s name, $title to insert the chat\'s title and $username to insert the user\'s username (if the user doesn\'t have an @username, their name will be used instead, so it is best to avoid using this in conjunction with $name).',
['2'] = 'There was an error formatting your message, please check your Markdown syntax and try again.',
['3'] = 'The welcome message for %s has successfully been updated!'
},
['share'] = {
['1'] = 'Share'
},
['shorten'] = {
['1'] = 'Please select a URL shortener using the buttons below:'
},
['shsh'] = {
['1'] = 'I couldn\'t fetch any SHSH blobs for that ECID, please ensure it\'s valid and you have saved them using https://tsssaver.1conan.com.',
['2'] = 'SHSH blobs for that device are available for the following versions of iOS:\n',
['3'] = 'Download .zip'
},
['statistics'] = {
['1'] = 'No messages have been sent in this chat!',
['2'] = '<b>Statistics for:</b> %s\n\n%s\n<b>Total messages sent:</b> %s',
['3'] = 'The statistics for this chat have been reset!',
['4'] = 'I could not reset the statistics for this chat. Perhaps they have already been reset?'
},
['steam'] = {
['1'] = 'Your Steam username has been set to "%s".',
['2'] = '"%s" isn\'t a valid Steam username.',
['3'] = '%s has been a user on Steam since %s, on %s. They last logged off at %s, on %s. Click <a href="%s">here</a> to view their Steam profile.',
['4'] = '%s, AKA "%s",'
},
['synonym'] = {
['1'] = 'You could use the word <b>%s</b>, instead of %s.'
},
['thoughts'] = {
['1'] = '%s\n\nPositive: <code>%s%% [%s]</code>\nNegative: <code>%s%% [%s]</code>\nIndifferent: <code>%s%% [%s]</code>\nTotal thoughts: <code>%s</code>'
},
['tobinary'] = {
['1'] = 'Please enter the string you would like to convert to binary.'
},
['trust'] = {
['1'] = 'I cannot trust this user because they are a moderator or an administrator of this chat.',
['2'] = 'I cannot trust this user because they have already left this chat.',
['3'] = 'I cannot trust this user because they have already been kicked from this chat.'
},
['unmute'] = {
['1'] = 'Which user would you like me to unmute? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot unmute this user because they are not currently muted in this chat.',
['3'] = 'I cannot unmute this user because they are a moderator or an administrator in this chat.',
['4'] = 'I cannot unmute this user because they have already left (or been kicked from) this chat.'
},
['untrust'] = {
['1'] = 'Which user would you like me to untrust? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot untrust this user because they are a moderator or an administrator in this chat.',
['3'] = 'I cannot untrust this user because they have already left this chat.',
['4'] = 'I cannot untrust this user because they have already been kicked from this chat.'
},
['upload'] = {
['1'] = 'Please reply to the file you\'d like to download to the server. It must be <= 20 MB.',
['2'] = 'That file is too large. It must be <= 20 MB.',
['3'] = 'I couldn\'t get this file, it\'s probably too old.',
['4'] = 'There was an error whilst retrieving this file.',
['5'] = 'Successfully downloaded the file to the server - it can be found at <code>%s</code>!'
},
['version'] = {
['1'] = '@%s AKA %s `[%s]` is running mattata %s, created by [Matthew Hesketh](https://t.me/wrxck). The source code is available on [GitHub](https://github.com/wrxck/mattata).'
},
['voteban'] = {
['1'] = 'Which user would you like to open up a vote-ban for? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot setup a vote-ban for this user because they are a moderator or an administrator in this chat.',
['3'] = 'I cannot setup a vote-ban for this user because they have already left (or been kicked from) this chat.',
['4'] = 'Should %s [%s] be banned from %s? %s upvotes are required for an immediate ban, and %s downvotes are required for this vote to be closed.',
['5'] = 'Yes [%s]',
['6'] = 'No [%s]',
['7'] = 'The people have spoken. I have banned %s [%s] from %s because %s people voted for me to do so.',
['8'] = 'The required upvote amount was reached, however, I was unable to ban %s - perhaps they\'ve left the group or been promoted since we opened the vote to ban them? It\'s either that, or I no longer have the administrative privileges required in order to perform this action!',
['9'] = 'The people have spoken. I haven\'t banned %s [%s] from %s because the required %s people downvoted the decision to ban them.',
['10'] = 'You upvoted the decision to ban %s [%s]!',
['11'] = 'Your current vote has been retracted, use the buttons again to re-submit your vote.',
['12'] = 'You downvoted the decision to ban %s [%s]!',
['13'] = 'A vote-ban has already been opened for this user!'
},
['weather'] = {
['1'] = 'You don\'t have a location set. Use /setloc <location> to set one.',
['2'] = 'It\'s currently %s (feels like %s) in %s. %s'
},
['welcome'] = {
['1'] = 'Group Rules'
},
- ['whitelist'] = {
- ['1'] = 'Which user would you like me to whitelist? You can specify this user by their @username or numerical ID.',
- ['2'] = 'I cannot whitelist this user because they are a moderator or an administrator in this chat.',
- ['3'] = 'I cannot whitelist this user because they have already left this chat.',
- ['4'] = 'I cannot whitelist this user because they have already been banned from this chat.'
+ ['allowlist'] = {
+ ['1'] = 'Which user would you like me to allowlist? You can specify this user by their @username or numerical ID.',
+ ['2'] = 'I cannot allowlist this user because they are a moderator or an administrator in this chat.',
+ ['3'] = 'I cannot allowlist this user because they have already left this chat.',
+ ['4'] = 'I cannot allowlist this user because they have already been banned from this chat.'
},
['wikipedia'] = {
['1'] = 'Read more.'
},
['youtube'] = {
['1'] = 'Previous',
['2'] = 'Next',
['3'] = 'You are on page %s of %s!'
}
}
\ No newline at end of file
diff --git a/languages/pl_pl.lua b/languages/pl_pl.lua
index 7bfc719..6109935 100644
--- a/languages/pl_pl.lua
+++ b/languages/pl_pl.lua
@@ -1,809 +1,809 @@
-- This is a language file for mattata
-- Language: pl-pl
-- Author: GingerPlusPlus
-- DO NOT CHANGE ANYTHING THAT BEGINS OR ENDS WITH A %
-- THESE ARE PLACEHOLDERS!
-- DO NOT CHANGE ANY MARKDOWN/HTML FORMATTING!
-- IF YOU ARE UNSURE, ASK ON TELEGRAM (t.me/mattataDev)
return {
['errors'] = {
['connection'] = 'Błąd połączenia.',
['results'] = 'Brak pasujących wyników.',
['supergroup'] = 'Ta komenda może być używana tylko w supergrupach.',
['admin'] = 'Aby użyć tej komendy, musisz być moderatorem lub administratorem w tej grupie.',
['unknown'] = 'Nieznany użytkownik. Aby pokazać mi kto to, przekaż wiadomość od niego do dowolnego czatu w którym jestem.',
['generic'] = 'Wystąpił błąd!',
['use'] = 'You are not allowed to use this!',
['private'] = 'You can only use this command in private chat!'
},
['addcommand'] = {
['1'] = 'Please specify the command in the format <code>/command - description</code>',
['2'] = 'I couldn\'t retrieve my commands!',
['3'] = 'The command description can\'t be longer than 256 characters!',
['4'] = 'An unknown error occurred! I couldn\'t add your command!',
['5'] = 'Success! Command added.'
},
['addrule'] = {
['1'] = 'Please specify the rule you would like to add!',
['2'] = 'You don\'t have any rules to add to! Please set group rules using /setrules!',
['3'] = 'I couldn\'t add that rule, as it would make the length of the rules longer than Telegram\'s 4096 character limit!',
['4'] = 'I couldn\'t add that rule, it appears it contains invalid Markdown formatting!',
['5'] = 'Successfully updated the rules!'
},
['addslap'] = {
['1'] = 'You can only use this command in groups!',
['2'] = 'The slap cannot contain curly braces apart from placeholders!',
['3'] = 'The slap cannot be any longer than 256 characters in length!',
['4'] = 'I\'ve successfully added that slap as a possibility for /slap in this group!',
['5'] = 'You must include placeholders in your slap. Use {ME} for the person executing and {THEM} for the victim.'
},
['administration'] = {
['1'] = 'Enable Administration',
['2'] = 'Disable Administration',
['3'] = 'Anti-Spam Settings',
['4'] = 'Warning Settings',
['5'] = 'Vote-Ban Settings',
['6'] = 'Welcome New Users?',
['7'] = 'Send Rules On Join?',
['8'] = 'Send Rules In Group?',
['9'] = 'Back',
['10'] = 'Next',
['11'] = 'Word Filter',
['12'] = 'Anti-Bot',
['13'] = 'Anti-Link',
['14'] = 'Log Actions?',
['15'] = 'Anti-RTL',
['16'] = 'Anti-Spam Action',
['17'] = 'Ban',
['18'] = 'Kick',
['19'] = 'Delete Commands?',
['20'] = 'Force Group Language?',
['21'] = 'Send Settings In Group?',
['22'] = 'Delete Reply On Action?',
['23'] = 'Require Captcha?',
['24'] = 'Use Inline Captcha?',
['25'] = 'Ban SpamWatch-flagged users?',
['26'] = 'Number of warnings until %s:',
['27'] = 'Upvotes needed to ban:',
['28'] = 'Downvotes needed to dismiss:',
['29'] = 'Deleted %s, and its matching link from the database!',
['30'] = 'There were no entries found in the database matching "%s"!',
['31'] = 'You\'re not an administrator in that chat!',
['32'] = 'The minimum number of upvotes required for a vote-ban is %s.',
['33'] = 'The maximum number of upvotes required for a vote-ban is %s.',
['34'] = 'The minimum number of downvotes required for a vote-ban is %s.',
['35'] = 'The maximum number of downvotes required for a vote-ban is %s.',
['36'] = 'The maximum number of warnings is %s.',
['37'] = 'The minimum number of warnings is %s.',
['38'] = 'You can add one or more words to the word filter by using /filter <word(s)>',
['39'] = 'You will no longer be reminded that the administration plugin is disabled. To enable it, use /administration.',
['40'] = 'That\'s not a valid chat!',
['41'] = 'You don\'t appear to be an administrator in that chat!',
['42'] = 'My administrative functionality can only be used in groups/channels! If you\'re looking for help with using my administrative functionality, check out the "Administration" section of /help! Alternatively, if you wish to manage the settings for a group you administrate, you can do so here by using the syntax /administration <chat>.',
['43'] = 'Use the keyboard below to adjust the administration settings for <b>%s</b>:',
['44'] = 'Please send me a [private message](https://t.me/%s), so that I can send you this information.',
['45'] = 'I have sent you the information you requested via private chat.',
['46'] = 'Remove Channel Pins?',
['47'] = 'Remove Other Pins?',
['48'] = 'Remove Pasted Code?',
['49'] = 'Prevent Inline Bots?',
['50'] = 'Kick Media On Join?',
['51'] = 'Enable Plugins For Admins?',
['52'] = 'Kick URLs On Join?'
},
['afk'] = {
['1'] = 'Ta funkcja jest dostępna tylko dla użytkowników posiadających @username.',
['2'] = '%s powrócił(a) po nieobecności trwającej %s!',
['3'] = 'Komentarz',
['4'] = '%s jest teraz AFK.%s'
},
['antispam'] = {
['1'] = 'Disable',
['2'] = 'Enable',
['3'] = 'Disable limit',
['4'] = 'Enable limits on %s',
['5'] = 'All Administration Settings',
['6'] = '%s [%s] has kicked %s [%s] from %s [%s] for hitting the configured anti-spam limit for [%s] media.',
['7'] = 'Kicked %s for hitting the configured antispam limit for [%s] media.',
['8'] = 'The maximum limit is 100.',
['9'] = 'The minimum limit is 1.',
['10'] = 'Modify the anti-spam settings for %s below:',
['11'] = 'Hey %s, if you\'re going to send code that is longer than %s characters in length, please do so using /paste in <a href="https://t.me/%s">private chat with me</a>!',
['12'] = '%s <code>[%s]</code> has %s %s <code>[%s]</code> from %s <code>[%s]</code> for sending Telegram invite link(s).\n#chat%s #user%s',
['13'] = '%s %s for sending Telegram invite link(s).',
- ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to whitelist it, use /whitelistlink <links>.',
+ ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to allowlist it, use /allowlink <links>.',
['15'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending media within their first few messages.\n#chat%s #user%s',
['16'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending a URL within their first few messages.\n#chat%s #user%s'
},
['appstore'] = {
['1'] = 'Zobacz na iTunes',
['2'] = 'rating',
['3'] = 'ratings'
},
['authspotify'] = {
['1'] = 'You are already authorised using that account.',
['2'] = 'Authorising, please wait...',
['3'] = 'A connection error occured. Are you sure you replied with the correct link? It should look like',
['4'] = 'Successfully authorised your Spotify account!'
},
['avatar'] = {
['1'] = 'Nie mogę dostać zdjęć profilowych tego użytkownika, upewnij się że podano poprawne @username lub ID.',
['2'] = 'Ten użytkownik nie ma żadnych zdjęć profilowych.',
['3'] = 'Ten użytkownik nie ma aż tylu zdjęć profilowych!',
['4'] = 'Ten użytkownik zrezygnował ze zbierania danych na jego temat, toteż nie mogę pokazać Ci jego zdjęć profilowych.',
['5'] = 'User: %s\nPhoto: %s/%s\nSend /avatar %s [offset] to @%s to view a specific photo of this user',
['6'] = 'User: %s\nPhoto: %s/%s\nUse /avatar %s [offset] to view a specific photo of this user'
},
['ban'] = {
['1'] = 'Kogo mam zbanować? Podaj @username lub ID.',
['2'] = 'Nie mogę zbanować tego użytkownika, ponieważ jest to moderator lub administrator tej grupy.',
['3'] = 'Nie mogę zbanować tego użytkownika, ponieważ opuścił on tę grupę.',
['4'] = 'Nie mogę zbanować tego użytkownika, ponieważ został on zbanowany już wcześniej.',
['5'] = 'Potrzebuję uprawnień administratora aby móc banować.',
['6'] = '%s <code>[%s]</code> has banned %s <code>[%s]</code> from %s <code>[%s]</code>%s.\n%s %s',
['7'] = '%s has banned %s%s.'
},
['bash'] = {
['1'] = 'Podaj komendę to uruchomienia.',
['2'] = 'Sukces!'
},
- ['blacklist'] = {
+ ['blocklist'] = {
['1'] = 'Kogo mam ignorować? Podaj @username lub ID.',
['2'] = 'Nie mogę ignorować tego użytkownika, ponieważ jest to moderator lub administrator tej grupy.',
['3'] = 'Nie mogę ignorować tego użytkownika, ponieważ opuścił on tę grupę.',
['4'] = 'Nie mogę ignorować tego użytkownika, ponieważ został on zbanowany.',
- ['5'] = '%s <code>[%s]</code> has blacklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
- ['6'] = '%s has blacklisted %s from using %s%s.'
+ ['5'] = '%s <code>[%s]</code> has blocklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
+ ['6'] = '%s has blocklisted %s from using %s%s.'
},
- ['blacklistchat'] = {
+ ['blocklistchat'] = {
['1'] = '%s został dodany do czarnej listy, nie pozwolę się tam dodać!',
['2'] = '%s jest użytkownikiem, ta komenda służy do blokowanie grup i kanałów!',
['3'] = '%s wydaje się nie istnieć!'
},
['bugreport'] = {
['1'] = 'Twój raport o błędzie został wysłany; ID Twojego raportu to #%s.',
['2'] = 'Wystąpił problem podczas raportowania błędu...'
},
['calc'] = {
['1'] = 'Klinknij aby wysłać.',
['2'] = '"%s" was an unexpected word!',
['3'] = 'You cannot have a unit before a number!'
},
['captionbotai'] = {
['1'] = 'Nie potrafię opisać tego obrazka.'
},
['cats'] = {
['1'] = 'Miau!'
},
['channel'] = {
['1'] = 'Nie masz wymaganych uprawnień.',
['2'] = 'Wygląda na to że już nie administrujesz tamtą grupą.',
['3'] = 'Twoja wiadomość nie mogła zostać wysłana, upewnij się że mam uprawnienia administratora w tamtym kanale.',
['4'] = 'Twoja wiadomość została wysłana.',
['5'] = 'Nie mogę pobrać listy admistratorów tamtej grupy.',
['6'] = 'Wygląda na to że nie jesteś administratorem w tamtej grupie.',
['7'] = 'Podaj wiadomość do wysłania, używając /channel <kanał> <wiadomość>.',
['8'] = 'Czy jesteś pewien że chcesz wysłać tą wiadomość? Będzie ona wyglądać tak:',
['9'] = 'Potwierdź',
['10'] = 'Wiadmość zawiera niepoprawny Markdown! Popraw składnię i spróbuj ponownie.'
},
['chatroulette'] = {
['1'] = 'Hey! Please don\'t send messages longer than %s characters. We don\'t want to annoy the other user!',
['2'] = '*Anonymous said:*\n```\n%s\n```\nTo end your session, send /endchat.',
['3'] = 'I\'m afraid I lost connection from the other user! To begin a new chat, please send /chatroulette!',
['4'] = 'The other person you were chatting with has ended the session. To start a new one, send /chatroulette.',
['5'] = 'Successfully ended your session. To start a new one, send /chatroulette.',
['6'] = 'I have successfully removed you from the list of available users.',
['7'] = 'You don\'t have a session set up at the moment. To start one, send /chatroulette.',
['8'] = 'Finding you a session, please wait...',
['9'] = 'I\'m afraid there aren\'t any available users right now, but I have added you to the list of available users! To stop this completely, please send /endchat.',
['10'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.',
['11'] = 'I\'m afraid the user who I tried to pair you with has since blocked me. Please try and send /chatroulette again to try and connect to me!',
['12'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.'
},
['commandstats'] = {
['1'] = 'Nie wysłano jeszcze żadnych komend w tej grupie!',
['2'] = '<b>Statystyki komend w:</b> %s\n\n%s\n<b>Liczba wszystkich komend:</b> %s',
['3'] = 'Zresetowano statystyki komend w tej grupie!',
['4'] = 'Błąd podczas resetowania statystyk, może zostały one zresetowane już wcześniej?'
},
['control'] = {
['1'] = 'Heh, chciałbyś!',
['2'] = '%s restartuje się...'
},
['copypasta'] = {
['1'] = 'Wiadomość na którą odpowiadasz tą komendą nie może być dłuższa niż %s znaków!'
},
['coronavirus'] = {
['1'] = [[*COVID-19 Statistics for:* %s
*New confirmed cases:* %s
*Total confirmed cases:* %s
*New deaths:* %s
*Total deaths:* %s
*New recovered cases:* %s
*Total recovered cases:* %s]]
},
['counter'] = {
['1'] = 'Dodawanie licznika do wiadomości nie powiodło się!'
},
['custom'] = {
['1'] = 'Sukces! Ta wiadomość zostanie wysłana za każdym razem gdy ktoś napisze %s!',
['2'] = 'Wyzwalacz "%s" nie istnieje!',
['3'] = 'Wyzwalacz "%s" został usunięty!',
['4'] = 'Nie utworzono żadnych wyzwalaczy',
['5'] = 'Wyzwalacze w %s:\n',
['6'] = 'Aby utworzyć nowy wyzwalacz, napisz:\n/custom new #wyzwalacz <wartość>.\nAby zobaczyć listę wyzwalaczy, napisz /custom list. Aby usunąć wyzwalacz, napisz, use /custom del #wyzwalacz.'
},
['delete'] = {
['1'] = 'Nie mogę usunąć tej wiadomości. Może jest za stara, albo nie istnieje?'
},
['demote'] = {
['1'] = 'Kogo mam zdegradować? Podaj @username lub ID.',
['2'] = 'Nie mogę zdegradować tego użytkownika, ponieważ nie jest to moderator tej grupy.',
['3'] = 'Nie mogę zdegradować tego użytkownika, ponieważ opuścił on tę grupę.',
['4'] = 'Nie mogę zdegradować tego użytkownika, ponieważ został on wyrzucony z tej grupy.',
},
['dice'] = {
['1'] = 'Najmniejsza dopuszczalna liczba ścian to %s.',
['2'] = '%s to limit liczby ścian, i liczby rzutów.',
['3'] = 'Limit liczby ścian to %s, a limit liczby rzutów to %s.',
['4'] = '%s rzutów %s-ścienną kostką:\n'
},
['doge'] = {
['1'] = 'Podaj tekst do umieszczenia na obrazku z Piesełem. Rozdziel wypowiedzi ukośnikiem lub nową linią.'
},
['duckduckgo'] = {
['1'] = 'Nie wiem co to jest!'
},
['donate'] = {
['1'] = '<b>Hello, %s!</b>\n\nIf you\'re feeling generous, you can contribute to the mattata project by making a monetary donation of any amount. This will go towards server costs and any time and resources used to develop mattata. This is an optional act, however it is greatly appreciated and your name will also be listed publically on mattata\'s GitHub page.\n\nIf you\'re still interested, you can donate <a href="https://paypal.me/wrxck">here</a>. Thank you for your continued support!'
},
['eightball'] = {
['1'] = 'Tak.',
['2'] = 'Nie.',
['3'] = 'Prawdopodobnie.',
['4'] = 'Uh... spytaj ponownie później.'
},
['exec'] = {
['1'] = 'Wybierz język:',
['2'] = 'To trwało zbyt długo... Czy próbowałeś mnie zawiesić?',
['3'] = 'Wybrano %s – jesteś pewien?',
['4'] = 'Powrót',
['5'] = 'Potwierdź',
['6'] = 'Podaj fragment kodu który chcesz uruchomić, o język zapytam za chwilę.',
['7'] = 'Wybierz język:'
},
['facebook'] = {
['1'] = 'Wystąpił błąd!',
['2'] = 'Podaj Facebookową nazwę użytkownika.',
['3'] = 'Zobacz %s na Facebooku'
},
['fact'] = {
['1'] = 'Wygeneruj inny'
},
['fban'] = {
['1'] = 'Which user would you like me to Fed-ban? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot Fed-ban this user because they are a moderator or an administrator in this chat.'
},
['flickr'] = {
['1'] = 'Szukano:',
['2'] = 'Czego chcesz szukać na Flickr?',
['3'] = 'Więcej wyników'
},
['fortune'] = {
['1'] = 'Kliknij aby wysłać.'
},
['frombinary'] = {
['1'] = 'Wprowadź liczbę binarną którą chcesz przeliczyć na tekst.',
['2'] = 'Nie jest to poprawna liczba binarna!'
},
['game'] = {
['1'] = 'Zwycięstwa: %s\nPorażki: %s\nSaldo: %s mattamonet',
['2'] = 'Dołącz',
['3'] = 'Gra się już skończyła!',
['4'] = 'Nie Twój ruch!',
['5'] = 'Nie jesteś w tej grze!',
['6'] = 'To pole jest już zajęte, wybierz inne!',
['7'] = 'Już jesteś w grze!',
['8'] = 'Gra została rozpoczęta już wcześniej!',
['9'] = '%s [%s] gra przeciwko %s [%s]\nKolej na ruch gracza %s!',
['10'] = '%s wygrał(a) z %s!',
['11'] = '%s zremisował(a) z %s!',
['12'] = 'Czekanie na przeciwnika...',
['13'] = 'Kółko i krzyżyk',
['14'] = 'Klinkij aby rozpocząć grę w tej grupie!',
['15'] = 'Statystyki dla %s:\n',
['16'] = 'Zagraj w kółko i krzyżyk!'
},
- ['gblacklist'] = {
+ ['gblocklist'] = {
['1'] = 'Odpowiedz do użytkownika którego mam wszędzie ignorować, bądź podaj jego @username lub ID.',
['2'] = 'Nie mogę dostać informacji o "%s", upewnij się że jest to poprawny @username lub ID.',
['3'] = 'To %s, a nie użytkownik!'
},
['gif'] = {
['1'] = 'Co mam wyszukać na Giphy?'
},
['godwords'] = {
['1'] = 'Podaj liczbę naturalną pomiędzy 1 a 64!',
['2'] = 'Liczba zbyt mała, musi należeć do przedziału od 1 do 64!',
['3'] = 'Liczba zbyt duża, musi należeć do przedziału od 1 do 64!'
},
- ['gwhitelist'] = {
+ ['gallowlist'] = {
['1'] = 'Odpowiedz do użytkownika któremu mam znowu odpowiedać, bądź podaj jego @username lub ID.',
['2'] = 'Nie mogę dostać informacji o "%s", upewnij się że jest to poprawny @username lub ID.',
['3'] = 'To %s, a nie użytkownik!'
},
['hackernews'] = {
['1'] = 'Najlepsze historie z Hacker News:'
},
['help'] = {
['1'] = 'Brak pasujących wyników!',
['2'] = 'Brak funkcji których nazwa pasuje do "%s"!',
['3'] = '\n\nArgumenty: <wymagane> [opcjonalne]\n\nSzukaj funkcji lub przeczytaj pomoc do komendy używając wyszukiwania inline - w dowolnym czacie, napisz @%s <czego szukasz>.',
['4'] = 'Poprzednia',
['5'] = 'Następna',
['6'] = 'Powrót',
['7'] = 'Szukaj',
['8'] = 'Strona %s z %s',
['9'] = [[
Mogę wykonywać wiele akcji administracyjnych w Twoich grupach, dodaj mnie do grupy jako administrator i wyślij /administration żeby dostosować ustawienia dla swojej grupy.
Niektóre polecenia administracyjne i ich krótki opis:
• /pin <tekst> - Tworzy wiadomość do przypięcia (używane jest formatowanie Markdown). Użyj ponownie aby zedytować przypiętą wiadomość bez konieczności przypinania nowej wiadomości.
• /ban - Zbanuj użytkownika, odpowiadając tą komendą na jego wiadomość, bądź podając jego ID lub @username jako argument
• /kick - Wyrzuć (ban, następnie unban) użytkownika, odpowiadając tą komendą na jego wiadomość, bądź podając jego ID lub @username jako argument
• /unban - Anuluj bana użytkownika, odpowiadając tą komendą na jego wiadomość, bądź podając jego ID lub @username jako argument
• /setrules <tekst> - Ustaw tekst (sformatowany Markdownem) jako zasady grupy, które można przeczytać pisząc /rules
]],
['10'] = [[
• /setwelcome <tekst> - Co chcesz powiedzieć każdemu nowemu członkowi? Możesz używać Markdown do formatowania. (Wiadomość powitalną można wyłączyć w menu administracyjnym, pisząc /administration). Użyj $user\_id aby wstawić ID dołączającego użytkownika, $chat\_id aby wstawić ID grupy, $name aby wstawić the imię użytkownika, $title aby wstawić nazwę grupy i $username aby wstawić @username użytkownika (jeśli użytkownik nie ma @username, zostanie wstawione jego imię, więc najlepiej nie używać $name i $username koło siebie)
• /warn - Ostrzeż użytkownika. Użytkownik zostanie zbanowany jeśli osiągnie limit ostrzeżeń
• /mod - Awansuj użytkownika na moderatora, pozwalając im używać poleceń administracyjnych, takich jak /ban, /kick, /warn itp.
• /demod - Zdegraduj moderatora do zwykłego użytkownika, odbierając im możliwość używania poleceń administracyjnych
• /staff - Wyświetl twórcę grupy, administratorów i moderatorów
]],
['11'] = [[
• /report - Przekazuje wiadomość na którą odpowiadasz administratorom, ostrzegając ich o zaistniałej sytuacji
• /setlink <URL> - Ustaw link do grupy, który można zobaczyć poleceniem /link
• /links <tekst> - Pozwól na wysyłanie linków znalezionych w tekście (także linki zapisane jako @username)
]],
['12'] = 'Poniżej jest parę linków które mogą Ci się przydać:',
['13'] = 'Development',
['14'] = 'Kanał',
['15'] = 'Wsparcie',
['16'] = 'Częste pytania',
['17'] = 'Kod źródłowy',
['18'] = 'Wspomóż finansowo',
['19'] = 'Oceń',
['20'] = 'Log administracyjny',
['21'] = 'Ustawienia administracyjne',
['22'] = 'Plugins', --!
['23'] = [[
<b>Cześć %s! Mam na imię %s, miło Cię poznać</b> %s
Rozumiem wiele poleceń, które możesz poznać klikając przycisk "Commands".
%s <b>Wskazówka:</b> Użyj przycisku "Settings" poniżej aby dostosować moje zachowanie%s!
%s <b>Find me useful, or just want to help?</b> Donations are very much appreciated, use /donate for more information!
]],
['24'] = 'w'
},
['id'] = {
['1'] = 'Nieznany użytkownik. Aby pokazać mi kto to, przekaż wiadomość od niego do dowolnego czatu w którym jestem.',
['2'] = 'Czat o który pytano:',
['3'] = 'Ten czat:',
['4'] = 'Kliknij aby wysłać.'
},
['imdb'] = {
['1'] = 'Poprzednia',
['2'] = 'Następna',
['3'] = 'Strona %s z %s'
},
['import'] = {
['1'] = 'Nie rozpoznaję tamtego czatu!',
['2'] = 'To nie jest supergrupa, więc nie mogę zaimportować z niej żadnych ustawień!',
['3'] = 'Pomyślnie zaimportowano ustawienia administracyjne i stan pluginów z %s do %s!'
},
['info'] = {
['1'] = [[
```
Redis:
%s plik konfiguracyjny: %s
%s tryb: %s
%s port TCP: %s
%s wersja: %s
%s czas pracy: %s days
%s ID procesu: %s
%s Przeterminowane wpisy: %s
%s liczba użytkowników: %s
%s liczba grup: %s
System:
%s OS: %s
```
]]
},
['instagram'] = {
['1'] = '@%s na Instagramie'
},
['ipsw'] = {
['1'] = '<b>%s</b> iOS %s\n\n<code>Suma kontrolna MD5: %s\nSuma kontrolna SHA1: %s\nRozmiar pliku: %s GB</code>\n\n<i>%s %s</i>',
['2'] = 'To firmware nie jest już podpisywane!',
['3'] = 'To firmware jest wciąż podpisywane!',
['4'] = 'Wybierz swój model:',
['5'] = 'Wybierz swoją wersję firmware:',
['6'] = 'Wybierz swój typ urządzenia:',
['7'] = 'iPod Touch',
['8'] = 'iPhone',
['9'] = 'iPad',
['10'] = 'Apple TV'
},
['ispwned'] = {
['1'] = 'To konto zostało znalezione w następujących wyciekach:'
},
['isup'] = {
['1'] = 'Ta strona internetowa wydaje się działać, może tylko u Ciebie nie działa?',
['2'] = 'Nie wygląda mi to na poprawny adres strony internetowej...',
['3'] = 'Nie tylko u Ciebie, tutaj też ta strona internetowa wydaje się nie działać.'
},
['itunes'] = {
['1'] = 'Nazwa:',
['2'] = 'Artysta:',
['3'] = 'Album:',
['4'] = 'Utwór:',
['5'] = 'Płyta:',
['6'] = 'Wiadomość zawierająca polecenie została usunięta.',
['7'] = 'Okładka poniżej:',
['8'] = 'Co mam wyszukać na iTunes?',
['9'] = 'Okładka albumu'
},
['kick'] = {
['1'] = 'Kogo mam wyrzucić? Podaj @username lub ID.',
['2'] = 'Nie mogę wyrzucić tego użytkownika, ponieważ jest to moderator lub administrator tej grupy.',
['3'] = 'Nie mogę wyrzucić tego użytkownika, ponieważ opuścił on tę grupę.',
['4'] = 'Nie mogę wyrzucić tego użytkownika, ponieważ został on wyrzucony już wcześniej.',
['5'] = 'Potrzebuję uprawnień administratora aby móc wyrzucać.'
},
['lastfm'] = {
['1'] = 'Nazwa użytkownika last.fm użytkownika %s została ustawiona na "%s".',
['2'] = 'Twoja nazwa użytkownika last.fm została zapomniana!',
['3'] = 'Nie masz ustawionej nazwy użytkownika last.fm!',
['4'] = 'Proszę podaj swoją nazwę użytkownika last.fm bądź ustaw ją używając /fmset.',
['5'] = 'Nie znaleziono historii tego użytkownika.',
['6'] = '%s słucha w tej chwili:\n',
['7'] = '%s ostatnio słuchał(a):\n',
['8'] = 'Nieznany',
['9'] = 'Kliknij aby wysłać.'
},
['lmgtfy'] = {
['1'] = 'Wygoogluję to za Ciebie!'
},
['location'] = {
['1'] = 'Nie masz ustawionej lokalizacji. Co mam ustawić jako Twoją nową lokalizację?'
},
['logchat'] = {
['1'] = 'Podaj @username bądź ID grupy w której mam rejestrować akcje administracyjnych.',
['2'] = 'Sprawdzam czy tamta grupa jest ok...',
['3'] = 'Przepraszam, wygląda na to, że grupa nie istnieje, bądź nie jestem jej członkiem. Napraw to i spróbuj ponownie.',
['4'] = 'Nie możesz ustawić użytkownika jako dziennik akcji administracyjnych!',
['5'] = 'Nie jesteś administratorem w tamtej grupie!',
['6'] = 'Wygląda na to że już rejestruję akcje administracyjne w tamtej grupie! Użyj /logchat by wybrać inną.',
['7'] = 'Jak na razie wszystko w porządku, spróbuję wysłać tam testową wiadomość żeby upawnić się że mogę wywyłać tam wiadomości...',
['8'] = 'Witaj świecie - to wiadomość testowa, żeby sprawdzić czy mogę tu pisać - jeśli to czytasz, wszystko poszło zgodnie z planem!',
['9'] = 'Wszystko ok! Od teraz, każda akcja administracyjna w tej grupie będzie rejestrowana w %s - aby wybrać inne miejsce, napisz /logchat.'
},
['lua'] = {
['1'] = 'Podaj proszę fragment kodu Lua do uruchomienia:'
},
['lyrics'] = {
['1'] = 'Spotify',
['2'] = 'Pokaż tekst',
['3'] = 'Podaj tytuł piosenki/artystę/fragment tekstu.'
},
['minecraft'] = {
['1'] = '<b>%s zmienił(a) nazwę użytkownika %s raz</b>',
['2'] = '<b>%s zmienił(a) nazwę użytkownika %s razy</b>',
['3'] = 'Poprzednia',
['4'] = 'Następna',
['5'] = 'Powrót',
['6'] = 'UUID',
['7'] = 'Avatar',
['8'] = 'Historia nazwy użytkownika',
['9'] = 'Wybierz:',
['10'] = 'Podaj nazwę użytkownika gracza Minecraft.',
['11'] = 'Nazwy użytkownika w Minecraft mają długość od 3 do 16 znaków.'
},
['msglink'] = {
['1'] = 'Ta komenda może być używana tylko w supergrupach i kanałach.',
['2'] = 'Ta %s musi być publiczna, musi mieć @username.',
['3'] = 'Odpisz tą komendą na wiadomość aby otrzymać linka do wiadomości.'
},
['mute'] = {
['1'] = 'Kogo mam wyciszyć? Podaj @username lub ID.',
['2'] = 'Nie mogę wyciszyć tego użytkownika, ponieważ został on wyciszony już wcześniej.',
['3'] = 'Nie mogę wyciszyć tego użytkownika, ponieważ jest to moderator lub administrator tej grupy.',
['4'] = 'Nie mogę wyciszyć tego użytkownika, ponieważ opuścił on tę grupę lub został z niej wyrzucony.',
['5'] = 'Potrzebuję uprawnień administratora aby móc wyciszać.'
},
['myspotify'] = {
['1'] = 'Profil',
['2'] = 'Śledzący',
['3'] = 'Niedawno odtwarzane',
['4'] = 'Aktualnie odtwarzane',
['5'] = 'Najczęściej odtwarzane utwory',
['6'] = 'Top Artists', --!
['7'] = 'Wygląda na to, że nie śledzisz żadnych artystów!',
['8'] = 'Your Top Artists',
['9'] = 'Wygląda na to, że nie masz żadnych utworów w bibliotece!',
['10'] = 'Utwory najczęściej odtwarzane przez Ciebie',
['11'] = 'Wygląda na to, że nie śledzisz żadnych artystów!',
['12'] = 'Artyści których śledzisz',
['13'] = 'Nie odtwarzano ostatnie żadnych utworów!',
['14'] = '<b>Niedawno odtwarzane</b>\n%s %s\n%s %s\n%s Słuchano o %d:%d dnia %d/%d/%d.',
['15'] = 'Zaakceptowano żądanie, trwa przetwarzanie.',
['16'] = 'Wygląda na to, że niczego teraz nie słuchasz!',
['17'] = 'Aktualnie odtwarzane',
['18'] = 'Wystąpił błąd podczas ponownej autoryzacji Twojego konta Spotify!',
['19'] = 'Ponowna autoryzacja Twojego konta Spotify powiodła się! Przetwarzanie Twojego oryginalnego żądania...',
['20'] = 'Trwa ponowna autoryzacja Twojego konta Spotify, proszę czekać...',
['21'] = 'Potrzebujesz autoryzować Mattatę aby połączyć się ze swoim kontem Spotify. Kliknij [tutaj](https://accounts.spotify.com/en/authorize?client_id=%s&response_type=code&redirect_uri=%s&scope=user-library-read%%20playlist-read-private%%20playlist-read-collaborative%%20user-read-private%%20user-read-birthdate%%20user-read-email%%20user-follow-read%%20user-top-read%%20user-read-playback-state%%20user-read-recently-played%%20user-read-currently-playing) i kliknij zielony przycisk "OKAY" aby połączyć Mattatę do Twojego konta Spotify. Następnie wyślij link do którego Cię przekierowano (powinien się zaczynać od "%s", a następnie zawierać unikatowy kod) w odpowiedzi na tę wiadomość.',
['22'] = 'Listy odtwarzania',
['23'] = 'Użyj trybu inline',
['24'] = 'Tekst piosenki',
['25'] = 'Nie znaleziono żadnych urządzeń.',
['26'] = 'Wygląda na to, że nie masz żadnych list odtwarzania.',
['27'] = 'Twoje listy odtwarzania',
['28'] = '%s %s [%s utworów]',
['29'] = '%s %s [%s]\nSpotify %s user\n\n<b>Urządzenia:</b>\n%s', --!
['30'] = 'Włączam poprzedni utwor...',
['31'] = 'Nie masz konta premium!',
['32'] = 'Nie znaleziono żadnych urządzeń.',
['33'] = 'Włączam następny utwór...',
['34'] = 'Wznawiam odtwarzanie...',
['35'] = 'Twoje urządzenie jest tymczasowo niedostępne...',
['36'] = 'Nie znaleziono żadnych urządzeń!',
['37'] = 'Wstrzymuję odtwarzanie...',
['38'] = 'Trwa odtwarzanie',
['39'] = 'Losuję kolejność odtwarzania...',
['40'] = 'To nie jest poprawny poziom głośności. Podaj liczbę między 0 a 100.',
['41'] = 'Głośność została ustawiona na %s%%!',
['42'] = 'Ta wiadomość została wysłana przez wcześniejszą wersję pluginu, poproś o nową wysyłając /myspotify!'
},
['name'] = {
['1'] = 'Aktualnie reaguję na imię "%s" - aby to zmienić, użyj /name <imię>.',
['2'] = 'Moje nowe imię musi mieć długość od 2 do 32 znaków!',
['3'] = 'Moje nowe imię musi się składać tylko z liter i cyfr!',
['4'] = 'Będę od teraz reagować na "%s", zamiast "%s" - aby to zmienić, użyj /name <imię>.'
},
['netflix'] = {
['1'] = 'Czytaj więcej'
},
['news'] = {
['1'] = '"<code>%s</code>" isn\'t a valid Lua pattern.', --!
['2'] = 'Nie mogę pobrać listy źródeł.',
['3'] = '<b>Źródła newsów pasujących do wzorca</b> "<code>%s</code>":\n\n%s',
['4'] = '<b>Aktualnie dostępne źródła newsów których możesz używać w </b> /news<b>. Użyj</b> /nsources &lt;Lua_pattern&gt; <b>aby przeszukać tę listę pod kątem bardziej specyficznych rezultatów.</b>\n\n%s',
['5'] = 'Nie masz preferowanego źródła newsów. Użyj /setnews <źródło> aby ustawić. Przejrzyj listę źródeł używając /nsources, lub zawęź wyniki używając /nsources <Lua_pattern>.',
['6'] = 'Twoje aktualne preferowane źródło newsów to %s. Użyj /setnews <źródło> aby to zmienić. Przejrzyj listę źródeł używając /nsources, lub zawęź wyniki używając /nsources <Lua_pattern>.',
['7'] = 'Twoje preferowane źródło informacji jest już ustawione na %s! Użyj /news aby zobaczyć aktualną najlepszą historię.',
['8'] = 'Nieznane źródło newsów. Przejrzyj listę źródeł używając /nsources, lub zawęź wyniki używając /nsources <Lua_pattern>.',
['9'] = 'Twoje preferowane źródło newsów zostało zmienione na %s! Użyj /news aby zobaczyć aktualną najlepszą historię.',
['10'] = 'Nieznane źródło newsów. Przejrzyj listę źródeł używając /nsources. Jeśli masz ulubione źródło, użyj /setnews <źródło> żeby pobierać zeń newsy kiedy użyjesz /news bez argumentów.',
['11'] = 'Czytaj więcej'
},
['nick'] = {
['1'] = 'Twoja ksywka została zapomniana!',
['2'] = 'Twoja ksywka została ustawiona na "%s"!'
},
['ninegag'] = {
['1'] = 'Czytaj więcej'
},
['optout'] = {
['1'] = 'Pozwoliłeś na zbieranie danych które wysyłasz! Użyj /optout aby zrezygnować.',
['2'] = 'Zrezygnowałeś ze zbieranie danych które wysyłasz! Użyj /optin aby pozwolić na zbieranie danych.'
},
['paste'] = {
['1'] = 'Wybierz serwis do którego mam wysłać Twój tekst:'
},
['pay'] = {
['1'] = 'Masz aktualnie %s mattamonet. Zdobądź więcej wygrywając w kółko i krzyżyk, używając /game - wygrasz 100 mattamonet za każdą wygraną, i stracisz 50 za każdą przegraną.',
['2'] = 'Musisz użyć tej komendy w odpowiedzi do użytkownika któremu chcesz przelać mattamonety',
['3'] = 'Ile mettamonet chcesz przelać do %s?',
['4'] = 'Podana ilość musi być liczbą nieujemną.',
['5'] = 'Nie możesz przelać mattamonet do siebie!',
['6'] = 'Nie masz tylu mattamonet!',
['7'] = '%s mattamonet zostało przelanych do to %s. Masz teraz %s mattamonet.'
},
['pokedex'] = {
['1'] = 'Nazwa: %s\nID: %s\nTyp: %s\nOpis: %s'
},
['pin'] = {
['1'] = 'Nie utworzono wcześniej żadnej wiadomości do przypięcia. Użyj /pin <tekst> aby utworzyć. Użyj Markdown do formatowania.',
['2'] = 'Oto ostatnia wiadomość utworzona przez /pin.',
['3'] = 'Znaleziono wiadomość do przypięcia w bazie danych, ale wygląda na to że została ona usunięta z grupy. Utwórz nową używając /pin <tekst>. Użyj Markdown do formatowania.',
['4'] = 'Wystąpił błąd podczas aktualizowania wiadomości do przypięcia. Wprowadzony tekst mógł zawierać nieprawidłowy Markdown, bądź wiadomość do przypięcia została usunięta. Spróbuję wysłać nową wiadomość do przypięcia, znajdziesz ją poniżej - jeśli potrzebujesz ją zmodyfikować, po upewnieniu się że istnieje, użyj /pin <tekst>.',
['5'] = 'Tekst zawiera nieprawidłowy Markdown.',
['6'] = 'Kliknij tutaj aby zobaczyć zaktualizowaną przypiętą wiadomość.'
},
['prime'] = {
['1'] = 'Podaj liczbę między 1 a 99999.',
['2'] = '%s jest liczbą piewszą!',
['3'] = '%s NIE jest liczbą pierwszą...'
},
['promote'] = {
['1'] = 'Nie mogę awansować tego użytkownika na moderatora, ponieważ jest to moderator lub administrator tej grupy.',
['2'] = 'Nie mogę awansować tego użytkownika na moderatora, ponieważ opuścił on tę grupę.',
['3'] = 'Nie mogę awansować tego użytkownika na moderatora, ponieważ został on wyrzucony z tej grupy.'
},
['quote'] = {
['1'] = 'Ten użytkownik zrezygnował ze zbierania danych na jego temat',
['2'] = 'Brak zapisanych cytatów użytkownika %s%s! Odpisz na wiadomość poleceniem /save aby zapisać.'
},
['randomsite'] = {
['1'] = 'Wygeneruj inną'
},
['randomword'] = {
['1'] = 'Wygeneruj inne',
['2'] = 'Twoje losowe słowo to <b>%s</b>!'
},
['report'] = {
['1'] = 'Please reply to the message you would like to report to the group\'s administrators.',
['2'] = 'You can\'t report your own messages, are you just trying to be funny?',
['3'] = '<b>%s needs help in %s!</b>',
['4'] = 'Click here to view the reported message.',
['5'] = 'I\'ve successfully reported that message to %s admin(s)!'
},
['rms'] = {
['1'] = 'Holy GNU!' --!
},
['save'] = {
['1'] = 'Ten użytkownik zrezygnował ze zbierania danych na jego temat',
['2'] = 'Wiadomość zapisana w bazie danych i dodana do listy możliwych odpowiedzi gdy /quote jest użyte w odpowiedzi do %s%s!'
},
['sed'] = {
['1'] = '%s\n\n<i>%s nie miał(a) tego na myśli!</i>',
['2'] = '%s\n\n<i>%s przyznał(a) się do porażki.</i>',
['3'] = '%s\n\n<i>%s nie ma pewności czy się nie pomylił(a)...</i>',
['4'] = 'Odczep się, ja <i>nigdy</i> się nie mylę!',
['5'] = '"<code>%s</code>" isn\'t a valid Lua pattern.', --!
['6'] = '<b>Hej, %s, miałeś na myśli:</b>\n<i>%s</i>',
['7'] = 'Tak',
['8'] = 'Nie',
['9'] = 'Nie wiem'
},
['setgrouplang'] = {
['1'] = 'Język tej grupy został ustawiony na %s!',
['2'] = 'Aktualnu język tej grupy to %s.\nPamiętaj że tłumaczenie może nie być kompletne. Aby zmienić język, użyj klawiatury poniżej:',
['3'] = 'Wspólny język dla tej grupy jest wyłączony. Aby to zmienić, użyj przycisku poniżej lub menu /administration.',
['4'] = 'Włącz',
['5'] = 'Wyłącz'
},
['setlang'] = {
['1'] = 'Twój język został ustawiony na %s!',
['2'] = 'Aktualnie wybrany język %s.\nPamiętaj że tłumaczenie może nie być kompletne. Jeśli chcesz zmienić język, użyj klawiatury poniżej:'
},
['setlink'] = {
['1'] = 'To nie jest poprawny URL.',
['2'] = 'Link został ustawiony!'
},
['setrules'] = {
['1'] = 'Niepoprawny Markdown.',
['2'] = 'Ustawienie zasad powiodło się!'
},
['setwelcome'] = {
['1'] = 'Co chcesz powiedzieć każdemu nowemu członkowi? Możesz używać Markdown do formatowania. (Wiadomość powitalną można wyłączyć w menu administracyjnym, pisząc /administration). Użyj $user_id aby wstawić ID dołączającego użytkownika, $chat_id aby wstawić ID grupy, $name aby wstawić the imię użytkownika, $title aby wstawić nazwę grupy i $username aby wstawić @username użytkownika (jeśli użytkownik nie ma @username, zostanie wstawione jego imię, więc najlepiej nie używać $name i $username koło siebie).',
['2'] = 'Twoja wiadomość jest niepoprawnie sformatowana, sprawdź swój Markdown i spróbuj ponownie.',
['3'] = 'Zapisano wiadomość powitalną dla %s!'
},
['share'] = {
['1'] = 'Udostępnij'
},
['shorten'] = {
['1'] = 'Wybierz skracacz linków używając przycisków poniżej:'
},
['shsh'] = {
['1'] = 'Nie mogę pobrać żadnych SHSH blobs dla tego ECID, upewnij się że jest poprawny i zapisałeś go używając https://tsssaver.1conan.com.',
['2'] = 'SHSH blobs dla tego urządzenia są dostępne dla następujących wersji iOS:\n',
['3'] = 'Pobierz .zip'
},
['statistics'] = {
['1'] = 'W tej grupie nie wysłano jeszcze żadnej wiadomości!',
['2'] = '<b>Statystyki w:</b> %s\n\n%s\n<b>Liczba wszystkich wiadomości:</b> %s',
['3'] = 'Zresetowano statystyki w tej grupie!',
['4'] = 'Błąd podczas resetowania statystyk, może zostały one zresetowane już wcześniej?'
},
['steam'] = {
['1'] = 'Twoja nazwa użytkownika na Steamie została ustawiona na "%s".',
['2'] = '"%s" nie jest poprawną nazwą użytkownika na Steamie.',
['3'] = '%s jest użytkownikiem Steama od %s, %s.\nData ostatniego wylogowania: %s, %s.\n<a href="%s">Profil na Steamie</a>',
['4'] = '%s, AKA "%s",'
},
['synonym'] = {
['1'] = 'Możesz użyć słowa <b>%s</b> zamiast %s.'
},
['thoughts'] = {
['1'] = '%s\n\nPozytywnie: <code>%s%% [%s]</code>\nNegatywnie: <code>%s%% [%s]</code>\nObojętnie: <code>%s%% [%s]</code>\nWszystkich przemyśleń: <code>%s</code>'
},
['tobinary'] = {
['1'] = 'Podaj ciąg znaków który chcesz skonwertować do liczby binarnej.'
},
['trust'] = {
['1'] = 'Nie mogę zaufać temu użytkownikowi, ponieważ jest to moderator lub administrator tej grupy.',
['2'] = 'Nie mogę zaufać temu użytkownikowi, ponieważ opuścił on tę grupę.',
['3'] = 'Nie mogę zaufać temu użytkownikowi, ponieważ został on wyrzucony już wcześniej.',
},
['unmute'] = {
['1'] = 'Komu mam pozwolić mówić? Podaj @username lub ID.',
['2'] = 'Nie mogę pozwolić mówić temu użytkownikowi, ponieważ nie został on wyciszony.',
['3'] = 'Nie mogę pozwolić mówić temu użytkownikowi, ponieważ jest to moderator lub administrator tej grupy.',
['4'] = 'Nie mogę pozwolić mówić temu użytkownikowi, ponieważ opuścił on tę grupę lub został z niej wyrzucony.',
},
['untrust'] = {
['1'] = 'Komu mam przestać ufać? Podaj @username lub ID.',
['2'] = 'Nie mogę przestać ufać temu użytkownikowi, ponieważ jest to moderator lub administrator tej grupy.',
['3'] = 'Nie mogę przestać ufać temu użytkownikowi, ponieważ opuścił on tę grupę.',
['4'] = 'Nie mogę przestać ufać temu użytkownikowi, ponieważ został on wyrzucony z tej grupy.',
},
['upload'] = {
['1'] = 'Odpowiedz na plik który chcesz ściągnąć na serwer. Plik musi ważyć <= 20 MB.',
['2'] = 'Plik zbyt duży, limit to 20 MB.',
['3'] = 'Nie można pobrać pliku, prawdopodobnie jest zbyt stary.',
['4'] = 'Wystąpił błąd podczas pobierania pliku.',
['5'] = 'Pobrano plik na serwer, ścieżka: <code>%s</code>.'
},
['version'] = {
['1'] = '@%s AKA %s `[%s]` działa pod kontrolą mattata %s, stworzona przez [Matthew Hesketh](https://t.me/wrxck). Kod źródłowy jest dostępny na [GitHubie](https://github.com/wrxck/mattata).'
},
['voteban'] = {
['1'] = 'Dla kogo mam otworzyć głosowanie nad banem? Podaj @username lub ID.',
['2'] = 'Nie mogę otworzyć głosowania nad banem tego użytkownika, ponieważ jest to moderator lub administrator tej grupy.',
['3'] = 'Nie mogę otworzyć głosowania nad banem tego użytkownika, ponieważ opuścił on tę grupę lub został z niej wyrzucony.',
['4'] = 'Czy %s [%s] powinien zostać zbanowany z %s? %s głosów za jest wymaganych aby zbanować, a %s głosów przeciw jest wymaganych aby zamknąć to głosowanie bez banowania.',
['5'] = 'Tak [%s]',
['6'] = 'Nie [%s]',
['7'] = 'Grupa zdecydowała. %s [%s] został zbanowany z %s ponieważ %s ludzi tak zagłosowało.',
['8'] = 'Osiągnięto wymaganą liczba głosów za banem, jednakże nie mogę zbanować %s - może opuścił(a) on(a) groupę, lub otrzymał(a) nominację na moderatora w międzyczasie, albo ja nie mam już uprawnień administratora.',
['9'] = 'Grupa zdecydowała. Nie banuję %s [%s] z %s ponieważ wymaganych %s ludzi zagłosowało przeciwko banowi.',
['10'] = 'Głosowałeś za banem dla %s [%s]!',
['11'] = 'Głos został cofnięty, możesz zagłosować ponownie.',
['12'] = 'Zagłosowałeś przeciwko banowi dla %s [%s]!',
['13'] = 'A vote-ban has already been opened for this user!'
},
['weather'] = {
['1'] = 'Nie masz ustawionej lokalizacji. Użyj /setloc <lokalizacja> aby ustawić.',
['2'] = 'Aktualna temperatura: %s (odczuwalna: %s) w %s. %s'
},
['welcome'] = {
['1'] = 'Przeczytaj zasady'
},
- ['whitelist'] = {
+ ['allowlist'] = {
['1'] = 'Kogo mam przestać ignorować? Podaj @username lub ID.',
['2'] = 'Nie mogę przestać ignorować tego użytkownika, ponieważ jest to moderator lub administrator tej grupy.',
['3'] = 'Nie mogę przestać ignorować tego użytkownika, ponieważ opuścił on tę grupę.',
['4'] = 'Nie mogę przestać ignorować tego użytkownika, ponieważ został on zbanowany.',
},
['wikipedia'] = {
['1'] = 'Czytaj więcej'
},
['youtube'] = {
['1'] = 'Poprzedni',
['2'] = 'Następny',
['3'] = 'Strona %s z %s'
}
}
\ No newline at end of file
diff --git a/languages/pt_br.lua b/languages/pt_br.lua
index cbb4b6a..aa45a3a 100644
--- a/languages/pt_br.lua
+++ b/languages/pt_br.lua
@@ -1,730 +1,730 @@
-- This is a language file for mattata
-- Language: pt-br
-- Author: American_Jesus
-- DO NOT CHANGE ANYTHING THAT BEGINS OR ENDS WITH A %
-- THESE ARE PLACEHOLDERS!
-- DO NOT CHANGE ANY MARKDOWN/HTML FORMATTING!
-- IF YOU ARE UNSURE, ASK ON TELEGRAM (t.me/mattataDev)
return {
['errors'] = {
['connection'] = 'Erro de conexão.',
['results'] = 'Eu não consegui encontrar nenhum resultado para isso.',
['supergroup'] = 'Este comando só pode ser usado em super grupos.',
['admin'] = 'Precisa ser moderador ou administrador neste grupo para usar este comando.',
['unknown'] = 'Eu não reconheço esse(s) utilizador(es). Se gostaria de me ensinar quem ele(s) são, encaminhe-me uma mensagem dele(s) para qualquer conversa que eu estou.',
['generic'] = 'Ocorreu um erro!',
['use'] = 'Você não tem permissão para usar isso!',
['private'] = 'You can only use this command in private chat!'
},
['addcommand'] = {
['1'] = 'Please specify the command in the format <code>/command - description</code>',
['2'] = 'I couldn\'t retrieve my commands!',
['3'] = 'The command description can\'t be longer than 256 characters!',
['4'] = 'An unknown error occurred! I couldn\'t add your command!',
['5'] = 'Success! Command added.'
},
['addrule'] = {
['1'] = 'Please specify the rule you would like to add!',
['2'] = 'You don\'t have any rules to add to! Please set group rules using /setrules!',
['3'] = 'I couldn\'t add that rule, as it would make the length of the rules longer than Telegram\'s 4096 character limit!',
['4'] = 'I couldn\'t add that rule, it appears it contains invalid Markdown formatting!',
['5'] = 'Successfully updated the rules!'
},
['addslap'] = {
['1'] = 'You can only use this command in groups!',
['2'] = 'The slap cannot contain curly braces apart from placeholders!',
['3'] = 'The slap cannot be any longer than 256 characters in length!',
['4'] = 'I\'ve successfully added that slap as a possibility for /slap in this group!',
['5'] = 'You must include placeholders in your slap. Use {ME} for the person executing and {THEM} for the victim.'
},
['administration'] = {
['1'] = 'Enable Administration',
['2'] = 'Disable Administration',
['3'] = 'Anti-Spam Settings',
['4'] = 'Warning Settings',
['5'] = 'Vote-Ban Settings',
['6'] = 'Welcome New Users?',
['7'] = 'Send Rules On Join?',
['8'] = 'Send Rules In Group?',
['9'] = 'Back',
['10'] = 'Next',
['11'] = 'Word Filter',
['12'] = 'Anti-Bot',
['13'] = 'Anti-Link',
['14'] = 'Log Actions?',
['15'] = 'Anti-RTL',
['16'] = 'Anti-Spam Action',
['17'] = 'Ban',
['18'] = 'Kick',
['19'] = 'Delete Commands?',
['20'] = 'Force Group Language?',
['21'] = 'Send Settings In Group?',
['22'] = 'Delete Reply On Action?',
['23'] = 'Require Captcha?',
['24'] = 'Use Inline Captcha?',
['25'] = 'Ban SpamWatch-flagged users?',
['26'] = 'Number of warnings until %s:',
['27'] = 'Upvotes needed to ban:',
['28'] = 'Downvotes needed to dismiss:',
['29'] = 'Deleted %s, and its matching link from the database!',
['30'] = 'There were no entries found in the database matching "%s"!',
['31'] = 'You\'re not an administrator in that chat!',
['32'] = 'The minimum number of upvotes required for a vote-ban is %s.',
['33'] = 'The maximum number of upvotes required for a vote-ban is %s.',
['34'] = 'The minimum number of downvotes required for a vote-ban is %s.',
['35'] = 'The maximum number of downvotes required for a vote-ban is %s.',
['36'] = 'The maximum number of warnings is %s.',
['37'] = 'The minimum number of warnings is %s.',
['38'] = 'You can add one or more words to the word filter by using /filter <word(s)>',
['39'] = 'You will no longer be reminded that the administration plugin is disabled. To enable it, use /administration.',
['40'] = 'That\'s not a valid chat!',
['41'] = 'You don\'t appear to be an administrator in that chat!',
['42'] = 'My administrative functionality can only be used in groups/channels! If you\'re looking for help with using my administrative functionality, check out the "Administration" section of /help! Alternatively, if you wish to manage the settings for a group you administrate, you can do so here by using the syntax /administration <chat>.',
['43'] = 'Use the keyboard below to adjust the administration settings for <b>%s</b>:',
['44'] = 'Please send me a [private message](https://t.me/%s), so that I can send you this information.',
['45'] = 'I have sent you the information you requested via private chat.',
['46'] = 'Remove Channel Pins?',
['47'] = 'Remove Other Pins?',
['48'] = 'Remove Pasted Code?',
['49'] = 'Prevent Inline Bots?',
['50'] = 'Kick Media On Join?',
['51'] = 'Enable Plugins For Admins?',
['52'] = 'Kick URLs On Join?'
},
['afk'] = {
['1'] = 'Desculpe, receio que este elemento esteja disponível somente para utilizadores com um @utilizador público!',
['2'] = '%s voltou depois de estar AFK por %s!',
['3'] = 'Nota',
['4'] = '%s está agora AFK.%s'
},
['antispam'] = {
['1'] = 'Desabilitar',
['2'] = 'Habilitar',
['3'] = 'Desabilitar limite',
['4'] = 'Habilitar limite para %s',
['5'] = 'Todas as Configurações de Administração',
['6'] = '%s [%s] has kicked %s [%s] from %s [%s] for hitting the configured anti-spam limit for [%s] media.',
['7'] = 'Kicked %s for hitting the configured antispam limit for [%s] media.',
['8'] = 'The maximum limit is 100.',
['9'] = 'The minimum limit is 1.',
['10'] = 'Modificar as configurações de anti-spam para %s abaixo:',
['11'] = 'Hey %s, if you\'re going to send code that is longer than %s characters in length, please do so using /paste in <a href="https://t.me/%s">private chat with me</a>!',
['12'] = '%s <code>[%s]</code> has %s %s <code>[%s]</code> from %s <code>[%s]</code> for sending Telegram invite link(s).\n#chat%s #user%s',
['13'] = '%s %s for sending Telegram invite link(s).',
- ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to whitelist it, use /whitelistlink <links>.',
+ ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to allowlist it, use /allowlink <links>.',
['15'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending media within their first few messages.\n#chat%s #user%s',
['16'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending a URL within their first few messages.\n#chat%s #user%s'
},
['appstore'] = {
['1'] = 'Ver no iTunes',
['2'] = 'rating',
['3'] = 'ratings'
},
['authspotify'] = {
['1'] = 'You are already authorised using that account.',
['2'] = 'Authorising, please wait...',
['3'] = 'A connection error occured. Are you sure you replied with the correct link? It should look like',
['4'] = 'Successfully authorised your Spotify account!'
},
['avatar'] = {
['1'] = 'Não consegui obter fotos de perfil para esse utilizador, verifique se especificou um nome de utilizador ou ID numérico válido.',
['2'] = 'Esse utilizador não tem fotos de perfil.',
['3'] = 'Esse utilizador não tem assim tantas de perfil!',
['4'] = 'That user has opted-out of data-collecting functionality, therefore I am not able to show you any of their profile photos.',
['5'] = 'User: %s\nPhoto: %s/%s\nSend /avatar %s [offset] to @%s to view a specific photo of this user',
['6'] = 'User: %s\nPhoto: %s/%s\nUse /avatar %s [offset] to view a specific photo of this user'
},
['ban'] = {
['1'] = 'Qual utilizador gostaria que eu bane? Pode especificar esse utilizador pelo seu @username ou ID numérico.',
['2'] = 'Não consigo banir esse utilizador porque ele é um moderador ou um administrador neste grupo.',
['3'] = 'Não consigo banir este utilizador porque ele saiu deste grupo.',
['4'] = 'Não consigo banir este utilizador porque ele já foi banido deste grupo.',
['5'] = 'Eu preciso ter permissões administrativas para banir esse utilizador. Corrija este problema e tente novamente.',
['6'] = '%s <code>[%s]</code> has banned %s <code>[%s]</code> from %s <code>[%s]</code>%s.\n%s %s',
['7'] = '%s has banned %s%s.'
},
['bash'] = {
['1'] = 'Especifique um comando para executar!',
['2'] = 'Sucesso!'
},
- ['blacklist'] = {
+ ['blocklist'] = {
['1'] = 'Qual utilizador gostaria de adicionar a lista negra? Pode especificar este utilizador pelo seu @username ou ID numérico.',
['2'] = 'Não consigo adicionar a lista negra esse utilizador porque ele é um moderador ou um administrador neste grupo.',
['3'] = 'Não consigo adicionar a lista negra esse utilizador porque ele já deixou este grupo.',
['4'] = 'Não consigo adicionar a lista negra esse utilizador porque ele já foi banido neste grupo.',
- ['5'] = '%s <code>[%s]</code> has blacklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
- ['6'] = '%s has blacklisted %s from using %s%s.'
+ ['5'] = '%s <code>[%s]</code> has blocklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
+ ['6'] = '%s has blocklisted %s from using %s%s.'
},
- ['blacklistchat'] = {
+ ['blocklistchat'] = {
['1'] = '%s foi adicionado a lista negra, e vou deixar lá quem eu adicionar!',
['2'] = '%s é um utilizador, este comando é apenas para lista negras em conversas como grupos e canais!',
['3'] = '%s não parece ser uma conversa valida!'
},
['bugreport'] = {
['1'] = 'Sucesso! Seu relatório de bug foi enviado. O ID deste relatório é #%s.',
['2'] = 'Ocorreu um problema enquanto relatava esse bug! Ah, a ironia!'
},
['calc'] = {
['1'] = 'Clique para enviar o resultado.',
['2'] = '"%s" was an unexpected word!',
['3'] = 'You cannot have a unit before a number!'
},
['captionbotai'] = {
['1'] = 'Eu realmente não posso descrever essa imagem!'
},
['cats'] = {
['1'] = 'Meow!'
},
['channel'] = {
['1'] = 'Não tem permissão para usar isso!',
['2'] = 'Parece já não ser um administrador nesse grupo!',
['3'] = 'Não consegui enviar a sua mensagem, tem certeza de que ainda tenho permissão para enviar mensagens nesse grupo?',
['4'] = 'A sua mensagem foi enviada!',
['5'] = 'Não consegui recuperar uma lista de administradores para desse grupo!',
['6'] = 'Não parece ser um administrador desse grupo!',
['7'] = 'Especifique a mensagem a enviar, utilizando a sintaxe /channel <canal> <mensagem>.',
['8'] = 'Tem certeza de que deseja enviar esta mensagem? É assim que vai aparecer:',
['9'] = 'Sim, tenho a certeza!',
['10'] = 'Essa mensagem contém formatação Markdown inválida! Corrija a sintaxe e tente novamente.'
},
['chatroulette'] = {
['1'] = 'Hey! Please don\'t send messages longer than %s characters. We don\'t want to annoy the other user!',
['2'] = '*Anonymous said:*\n```\n%s\n```\nTo end your session, send /endchat.',
['3'] = 'I\'m afraid I lost connection from the other user! To begin a new chat, please send /chatroulette!',
['4'] = 'The other person you were chatting with has ended the session. To start a new one, send /chatroulette.',
['5'] = 'Successfully ended your session. To start a new one, send /chatroulette.',
['6'] = 'I have successfully removed you from the list of available users.',
['7'] = 'You don\'t have a session set up at the moment. To start one, send /chatroulette.',
['8'] = 'Finding you a session, please wait...',
['9'] = 'I\'m afraid there aren\'t any available users right now, but I have added you to the list of available users! To stop this completely, please send /endchat.',
['10'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.',
['11'] = 'I\'m afraid the user who I tried to pair you with has since blocked me. Please try and send /chatroulette again to try and connect to me!',
['12'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.'
},
['commandstats'] = {
['1'] = 'Nenhum comando foi enviado neste chat!',
['2'] = '<b>Estatísticas de comandos para:</b> %s\n\n%s\n<b>Total de comandos enviados:</b> %s',
['3'] = 'As estatísticas de comandos para este chat foram resetadas!',
['4'] = 'Não consegui resetar as estatísticas de comandos para este chat. Talvez eu já as tenha resetado?'
},
['control'] = {
['1'] = 'Pfft, querias!',
['2'] = '%s está recarregando...'
},
['copypasta'] = {
['1'] = 'O texto respondido não deverá exceder %s caracteres!'
},
['coronavirus'] = {
['1'] = [[*COVID-19 Statistics for:* %s
*New confirmed cases:* %s
*Total confirmed cases:* %s
*New deaths:* %s
*Total deaths:* %s
*New recovered cases:* %s
*Total recovered cases:* %s]]
},
['counter'] = {
['1'] = 'Eu não pude adicionar um contador a essa mensagem!'
},
['custom'] = {
['1'] = 'Sucesso! Essa mensagem será enviada toda vez que alguém usar %s!',
['2'] = 'O trigger "%s" não existe!',
['3'] = 'O trigger "%s" foi apagado!',
['4'] = 'Ainda não tem triggers personalizado definidos!',
['5'] = 'Comandos personalizados para %s:\n',
['6'] = 'Para criar um novo comando personalizado, use a seguinte sintaxe:\n/custom new #trigger <valor>. Para listar todos os triggers atuais, use /custom list. Para apagar um trigger, use /custom del #trigger.'
},
['delete'] = {
['1'] = 'Não consegui apagar essa mensagem. Talvez a mensagem seja muito antiga ou inexistente?'
},
['demote'] = {
['1'] = 'Qual utilizador gostaria que eu despromovesse? Pode especificar este utilizador pelo seu @username ou ID numérico.',
['2'] = 'Eu não posso despromover esse utilizador porque ele não é um moderador ou um administrador neste grupo.',
['3'] = 'Eu não posso despromover esse utilizador porque ele já deixou este grupo.',
['4'] = 'Não consigo despromover esse utilizador porque ele já foi expulso deste grupo.'
},
['doge'] = {
['1'] = 'Por favor, escreva o texto que deseja para Doge-ify. Cada sentença deve ser separada usando barras (/) ou novas linhas.'
},
['donate'] = {
['1'] = '<b>Hello, %s!</b>\n\nIf you\'re feeling generous, you can contribute to the mattata project by making a monetary donation of any amount. This will go towards server costs and any time and resources used to develop mattata. This is an optional act, however it is greatly appreciated and your name will also be listed publically on mattata\'s GitHub page.\n\nIf you\'re still interested, you can donate <a href="https://paypal.me/wrxck">here</a>. Thank you for your continued support!'
},
['exec'] = {
['1'] = 'Selecione a linguagem em que gostaria de executar o seu código:',
['2'] = 'Ocorreu um erro! Tempo de ligação expirou. Está tentando me engasgar?',
['3'] = 'Selecionou "%s" – tem a certeza?',
['4'] = 'Voltar',
['5'] = 'Tenho certeza',
['6'] = 'Introduza um fragmento de código que pretende executar. Não precisa especificar a linguagem, faremos isso depois!',
['7'] = 'Selecione a linguagem em que gostaria de executar o seu código:'
},
['facebook'] = {
['1'] = 'Ocorreu um erro!',
['2'] = 'Escreva o nome de utilizador do Facebook do qual gostaria de obter a foto do perfil.',
['3'] = 'Visitas @%s no Facebook'
},
['fact'] = {
['1'] = 'Gerar Outro'
},
['fban'] = {
['1'] = 'Which user would you like me to Fed-ban? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot Fed-ban this user because they are a moderator or an administrator in this chat.'
},
['flickr'] = {
['1'] = 'Pesquisou por:',
['2'] = 'Introduza uma consulta de pesquisa (Ou seja, o que quer que eu procure no Flickr, i.e. "Big Ben" mostrara uma fotografia do Big Ben em Londres).',
['3'] = 'Mais Resultados'
},
['game'] = {
['1'] = 'Total de vitórias: %s\nTotal de derrotas: %s\nBalanço: %s mattacoins',
['2'] = 'Entrar no Jogo',
['3'] = 'Este jogo já acabou!',
['4'] = 'Não é a sua vez!',
['5'] = 'Não faz parte deste jogo!',
['6'] = 'Não pode ser ai!',
['7'] = 'Já faz parte deste jogo!',
['8'] = 'Este jogo já começou!',
['9'] = '%s [%s] está a jogar contra %s [%s]\nE é a vez de %s\'s a jogar!',
['10'] = '%s ganhou o jogo contra %s!',
['11'] = '%s criou um jogo contra %s!',
['12'] = 'A espera pelo oponente...',
['13'] = 'Jogo do Galo',
['14'] = 'Clique para enviar o jogo para o seu grupo!',
['15'] = 'Estatísticas %s:\n',
['16'] = 'Jogar ao Jogo do Galo!'
},
- ['gblacklist'] = {
+ ['gblocklist'] = {
['1'] = 'Responda ao utilizador que deseja incluir na lista negra global ou especifique-o por nome de utilizador/ID.',
['2'] = 'Não conseguir obter informações sobre "%s", verifique se é um nome de utilizador/ID válido e tente novamente.',
['3'] = 'Isso é um %s, não um utilizador!'
},
['gif'] = {
['1'] = 'Introduza uma consulta de pesquisa (Que é, o que quer que eu procure no GIPHY, ex: "cat" irá mostrar um GIF de um gato).'
},
- ['gwhitelist'] = {
+ ['gallowlist'] = {
['1'] = 'Responda ao utilizador que deseja incluir na lista branca global ou especifique-o por nome de utilizador/ID.',
['2'] = 'Não conseguir obter informações sobre "%s", verifique se é um nome de utilizador/ID válido e tente novamente.',
['3'] = 'Isso é um %s, não um utilizador!'
},
['hackernews'] = {
['1'] = 'Histórias principais de Hacker News:'
},
['help'] = {
['1'] = 'Nenhum resultado encontrado!',
['2'] = 'Não foram encontrados elementos que correspondam a "%s", Por favor, tente ser mais específico!',
['3'] = '\n\nArgumentos: <requer> [opcional]\n\nProcurar um elemento ou obter ajuda com um comando usando minha funcionalidade de pesquisa inline - apenas me mencione em qualquer grupo usando a sintaxe @%s <texto de procura>.',
['4'] = 'Anterior',
['5'] = 'Seguinte',
['6'] = 'Voltar',
['7'] = 'Procurar',
['8'] = 'Está na pagina %s de %s!',
['9'] = [[
Posso executar muitas ações administrativas nos seus grupos, basta adicionar-me como administrador e envie /administration para ajustar as configurações do seu grupo.
Aqui estão alguns comandos administrativos e um breve comentário sobre o que eles fazem:
• /pin <texto> - Envie uma mensagem formatada em Markdown que pode ser editada usando o mesmo comando com texto diferente, para evitar de ter que afixar novamente uma mensagem se não poder edita-la (o que acontece se a mensagem tiver mais de 48 horas)
• /ban - Banir um utilizador respondendo a uma de suas mensagens ou especificando com o nome de utilizador/ID
• /kick - Expulsar (banir e depois remover ban) um utilizador respondendo a uma de suas mensagens ou especificando com o nome de utilizador/ID
• /unban - Remover ban a um utilizador respondendo a uma de suas mensagens ou especificando com o nome de utilizador/ID
• /setrules <texto> - Defina o texto formatado como Markdown como as regras de grupo, que serão enviadas sempre que alguém usar /rules
]],
['10'] = [[
• /setwelcome - Defina o texto formatado como Markdown como uma mensagem de boas-vindas que será enviada sempre que um utilizador se juntar ao seu grupo (A mensagem de boas-vindas pode ser desativada no menu de administração, acessível via /administration). Pode usar espaços reservados para personalizar automaticamente a mensagem de boas-vindas para cada utilizador. Use $user_id para inserir o ID numérico do utilizador, $chat_id para inserir o ID numérico do grupo, $name para inserir o nome do utilizador, $title para inserir o título do grupo e $username para inserir o nome de utilizador do utilizador (Se o utilizador não tiver um @utilizador, o seu nome será usado em vez disso, para evitar é melhor usar isso com $name)
• /warn - Avisa um utilizador, e bane-o quando atingirem o número máximo de avisos
• /mod - Promove um utilizador respondendo a, dando acesso a comandos administrativos como /ban, /kick, /warn etc. (isto é útil quando não quer que alguém tenha a capacidade de apagar mensagens!)
• /demod - Despromove um utilizador respondendo a, removendo do seu estatuto de moderação e revogando sua capacidade de usar comandos administrativos
• /staff - Mostrar o criador, administradores e moderadores do grupo numa lista bem formatada
]],
['11'] = [[
• /report - Encaminha a mensagem de resposta para todos os administradores e os alerta da situação atual
• /setlink <URL> - Define o endereço do grupo para o URL fornecido, que será enviado sempre que alguém usar /link
• /links <texto> - Listas brancas todos os endereços Telegram encontrados no texto fornecido (inclui endereços de @utilizador)
]],
['12'] = 'Abaixo estão alguns links que pode achar úteis:',
['13'] = 'Desenvolvimento',
['14'] = 'Canal',
['15'] = 'Suporte',
['16'] = 'FAQ',
['17'] = 'Código Fonte',
['18'] = 'Doar',
['19'] = 'Rate',
['20'] = 'Registo de Administração',
['21'] = 'Definições de administrador',
['22'] = 'Plugins',
['23'] = [[
<b>Olá %s! O meu nome é %s, é um prazer conhece-lo</b> %s
Eu entendo muitos comandos, que você pode aprender mais sobre pressionando o botão "Comandos" usando o teclado acoplado.
%s <b>Dica:</b> Use o botão "Definições" para alterar o modo como eu trabalho%s!
%s <b>Find me useful, or just want to help?</b> Donations are very much appreciated, use /donate for more information!
]],
['24'] = 'em'
},
['id'] = {
['1'] = 'Desculpe, mas eu não reconheço esse utilizador. Ensine-me quem ele é, encaminhando uma mensagem dele a mim ou faça com que ele me enviem uma mensagem.',
['2'] = 'Grupo consultado:',
['3'] = 'Este grupo:',
['4'] = 'Clique para enviar o resultado!'
},
['imdb'] = {
['1'] = 'Anterior',
['2'] = 'Seguinte',
['3'] = 'Está na pagina %s de %s!'
},
['import'] = {
['1'] = 'Eu não reconheço esse grupo!',
['2'] = 'Isso não é um super grupo, portanto não consigo importar nenhuma configuração dele!',
['3'] = 'Configurações administrativas importadas e plugins alternados com sucesso de %s para %s!'
},
['info'] = {
['1'] = [[
```
Redis:
%s Ficheiro de Configuração: %s
%s Modo: %s
%s Porta TCP: %s
%s Versão: %s
%s Tempo de atividade: %s days
%s ID do Processo: %s
%s Keys Expiradas: %s
%s Contagem de Utilizadores: %s
%s Contagem de Grupos: %s
Sistema:
%s OS: %s
```
]]
},
['instagram'] = {
['1'] = '@%s no Instagram'
},
['ipsw'] = {
['1'] = '<b>%s</b> iOS %s\n\n<code>MD5 sum: %s\nSHA1 sum: %s\nTamanho do ficheiro: %s GB</code>\n\n<i>%s %s</i>',
['2'] = 'Este firmware não está mais sendo assinado!',
['3'] = 'Este firmware ainda está sendo assinado!',
['4'] = 'Selecione o seu modelo:',
['5'] = 'Selecione a versão do firmware:',
['6'] = 'Selecione seu tipo de dispositivo:',
['7'] = 'iPod Touch',
['8'] = 'iPhone',
['9'] = 'iPad',
['10'] = 'Apple TV'
},
['ispwned'] = {
['1'] = 'Essa conta foi encontrada nos seguintes fugas de informação:'
},
['itunes'] = {
['1'] = 'Nome:',
['2'] = 'Artista:',
['3'] = 'Álbum:',
['4'] = 'Faixa:',
['5'] = 'Disco:',
['6'] = 'A consulta original não pôde ser encontrada, provavelmente apagou a mensagem original.',
['7'] = 'A capa pode ser encontrada abaixo:',
['8'] = 'Introduza uma consulta de pesquisa (Ou seja, o que quer que eu procure no iTunes, Ex: "Green Day American Idiot" ira mostrar informações sobre o primeiro resultado para American Idiot dos Green Day).',
['9'] = 'Obter Capa do Álbum'
},
['kick'] = {
['1'] = 'Qual utilizador gostaria que eu expulsasse? Pode especificar este utilizador por seu @utilizador ou ID numérico.',
['2'] = 'Eu não consigo expulsar esse utilizador porque ele é um moderador ou administrador neste grupo.',
['3'] = 'Eu não consigo expulsar esse utilizador porque ele já deixou este grupo.',
['4'] = 'Não consigo expulsar esse utilizador porque ele já foi expulso deste grupo.',
['5'] = 'Eu preciso ter permissões administrativas para expulsar esse utilizador. Corrija este problema e tente novamente.'
},
['lastfm'] = {
['1'] = '%s\'s utilizador de last.fm foi definido para "%s".',
['2'] = 'O seu utilizador last.fm foi esquecido!',
['3'] = 'Não tem atualmente um utilizado do last.fm definido!',
['4'] = 'Especifique o utilizador do last.fm ou defina com /fmset.',
['5'] = 'Nenhum histórico foi encontrado para este utilizador.',
['6'] = '%s está atualmente a ouvir:\n',
['7'] = '%s ouviu ultimamente:\n',
['8'] = 'Desconhecido',
['9'] = 'Clique para enviar o resultado.'
},
['location'] = {
['1'] = 'Não tem uma localização definida. O que nova localização gostaria que fosse?'
},
['logchat'] = {
['1'] = 'Escreva o nome de utilizador ou ID numérico do grupo no qual deseja registar todas as ações administrativas.',
['2'] = 'A verificar se o grupo é válido...',
['3'] = 'Desculpe, parece que especificou um grupo inválido, ou especificou um grupo que eu ainda não adicionado. Corrija e tente novamente.',
['4'] = 'Não pode definir um utilizador como o seu grupo de registo!',
['5'] = 'Não parece ser administrador nesse grupo!',
['6'] = 'Parece que eu já estou registar ações administrativas nesse grupo! Use /logchat para especificar um novo.',
['7'] = 'Esse grupo é válido, vou tentar e enviar uma mensagem de teste para ele, apenas para garantir que tenho permissão para falar!',
['8'] = 'Olá mundo - esta é uma mensagem de teste para verificar minhas permissões de escrita - se estiver a ler isto, então tudo correu bem!',
['9'] = 'Tudo feito! De agora em diante, Quaisquer ações administrativas neste grupo serão registadas em %s - para mudar o grupo que quer que eu registe ações administrativas, basta enviar /logchat.'
},
['lua'] = {
['1'] = 'Digite uma string de Lua para executar!'
},
['lyrics'] = {
['1'] = 'Spotify',
['2'] = 'Mostrar letra',
['3'] = 'Introduza uma consulta de pesquisa (isto é, que musica/artista/letra quer que eu obtenha letras, Ex: "Green Day Basket Case" irá mostrar a letra para Basket Case dos Green Day).'
},
['minecraft'] = {
['1'] = '<b>%s mudou o seu utilizador %s vez</b>',
['2'] = '<b>%s mudou o seu utilizador %s vezes</b>',
['3'] = 'Anterior',
['4'] = 'Seguinte',
['5'] = 'Voltar',
['6'] = 'UUID',
['7'] = 'Avatar',
['8'] = 'Histórico de Utilizador',
['9'] = 'Selecione uma opção:',
['10'] = 'Escreva o nome de utilizador do jogador do Minecraft que gostaria de ver informações (Ex: enviando "Notch" irá ver as informações sobre o jogador Notch).',
['11'] = 'Os nomes de utilizadores do Minecraft têm entre 3 e 16 caracteres.'
},
['mute'] = {
['1'] = 'Que utilizador gostaria que ficasse silenciar? Pode especificar este utilizador pelo seu @utilizador ou ID numérico.',
['2'] = 'Não consigo silenciar este utilizador porque já estão silenciados neste grupo.',
['3'] = 'Não consigo silenciar este utilizador porque ele é um moderador ou administrador neste grupo.',
['4'] = 'Não consigo silenciar este utilizador porque ele já deixou (ou foi expulso) deste grupo.',
['5'] = 'Eu preciso ter permissões administrativas para silenciar este utilizador. Corrija este problema e tente novamente.'
},
['myspotify'] = {
['1'] = 'Perfil',
['2'] = 'Seguindo',
['3'] = 'Recently Played',
['4'] = 'Currently Playing',
['5'] = 'Top Tracks',
['6'] = 'Top Artistas',
['7'] = 'You don\'t appear to be following any artists!',
['8'] = 'Seus Top Artistas',
['9'] = 'You don\'t appear to have any tracks in your library!',
['10'] = 'Your Top Tracks',
['11'] = 'You don\'t appear to be following any artists!',
['12'] = 'Artists You Follow',
['13'] = 'You don\'t appear to have recently played any tracks!',
['14'] = '<b>Recently Played</b>\n%s %s\n%s %s\n%s Listened to at %s:%s on %s/%s/%s.',
['15'] = 'The request has been accepted for processing, but the processing has not been completed.',
['16'] = 'You don\'t appear to be listening to anything right now!',
['17'] = 'Currently Playing',
['18'] = 'An error occured whilst re-authorising your Spotify account!',
['19'] = 'Successfully re-authorised your Spotify account! Processing your original request...',
['20'] = 'Re-authorising your Spotify account, please wait...',
['21'] = 'You need to authorise mattata in order to connect your Spotify account. Click [here](https://accounts.spotify.com/en/authorize?client_id=%s&response_type=code&redirect_uri=%s&scope=user-library-read,playlist-read-private,playlist-read-collaborative,user-read-private,user-read-email,user-follow-read,user-top-read,user-read-playback-state,user-read-recently-played,user-read-currently-playing,user-modify-playback-state) and press the green "OKAY" button to link mattata to your Spotify account. After you\'ve done that, send the link you were redirected to (it should begin with "%s", followed by a unique code) in reply to this message.',
['22'] = 'Playlists',
['23'] = 'Use Inline Mode',
['24'] = 'Lyrics',
['25'] = 'No devices were found.',
['26'] = 'You don\'t appear to have any playlists.',
['27'] = 'Your Playlists',
['28'] = '%s %s [%s tracks]',
['29'] = '%s %s [%s]\nSpotify %s user\n\n<b>Devices:</b>\n%s',
['30'] = 'Playing previous track...',
['31'] = 'You are not a premium user!',
['32'] = 'I could not find any devices.',
['33'] = 'Playing next track...',
['34'] = 'Resuming track...',
['35'] = 'Your device is temporarily unavailable...',
['36'] = 'No devices were found!',
['37'] = 'Pausing track...',
['38'] = 'Now playing',
['39'] = 'Shuffling your music...',
['40'] = 'That\'s not a valid volume. Please specify a number between 0 and 100.',
['41'] = 'The volume has been set to %s%%!',
['42'] = 'This message is using an old version of this plugin, please request a new one by sending /myspotify!'
},
['name'] = {
['1'] = 'O nome pelo qual respondo atualmente é "%s" - para alterar isso, use /name <texto> (onde <texto> é o nome pelo qual quer que eu responda).',
['2'] = 'Meu novo nome precisa ter entre 2 e 32 caracteres!',
['3'] = 'Meu nome só pode conter caracteres alfanuméricos!',
['4'] = 'Vou agora responder a "%s", em vez de "%s" - para alterar isso, use /name <texto> (onde <text> o nome a qual quer que eu responda).'
},
['netflix'] = {
['1'] = 'Ver mais.'
},
['news'] = {
['1'] = '"<code>%s</code>" não é um padrão Lua válido.',
['2'] = 'Eu não consegui obter uma lista de fontes.',
['3'] = '<b>Fontes de notícias encontradas correspondentes</b> "<code>%s</code>":\n\n%s',
['4'] = '<b>Aqui estão as fontes de notícias disponíveis que pode usar com</b> /news<b>. Use</b> /nsources &lt;pesquisa&gt; <b>para pesquisar a lista de fontes de notícias para um conjunto mais específico de resultados. As pesquisas são combinadas usando padrões Lua</b>\n\n%s',
['5'] = 'Não tem uma fonte de notícias preferida. Use /setnews <source> para definir uma. Veja a lista de fontes usando /nsources, ou restringir os resultados usando /nsources <pesquisa>.',
['6'] = 'A sua fonte de notícias preferida atual é %s. Use /setnews <source> para alterar isso. Veja a lista de fontes usando /nsources, ou restringir os resultados usando /nsources <pesquisa>.',
['7'] = 'A sua fonte preferida já está definida para %s! Use /news para ver a história principal atual.',
['8'] = 'Isso não é uma fonte de notícias válida. Exibir uma lista de fontes usando /nsources, ou restringir os resultados usando /nsources <pesquisa>.',
['9'] = 'A sua fonte de notícias preferida foi atualizada para %s! Use /news para ver a história principal atual.',
['10'] = 'Isso não é uma fonte válida, use /nsources para ver uma lista de fontes disponíveis. Se tem uma fonte preferida, use /setnews <fonte> Para receber automaticamente notícias daquela fonte enviada quando envie /news, sem quaisquer argumentos necessários.',
['11'] = 'Ver mais.'
},
['nick'] = {
['1'] = 'O seu nick foi esquecido!',
['2'] = 'O seu nick foi definido como "%s"!'
},
['optout'] = {
['1'] = 'Optou por enviar os seus dados! Use /optout para excluir.',
['2'] = 'Optou por não enviar os seus dados! Use /optin para enviar.'
},
['paste'] = {
['1'] = 'Selecione um serviço para enviar copia:'
},
['pin'] = {
['1'] = 'Não definiu ainda uma mensagem afixada. Use /pin <texto> para definir uma. A formatação Markdown é suportada.',
['2'] = 'Aqui está a última mensagem gerada usando /pin.',
['3'] = 'Eu encontrei uma mensagem afixada existente na base de dados, mas a mensagem que enviei parece ter sido apagada, e não consigo mais encontra-la. Pode definir uma nova usando /pin <texto>. A formatação Markdown é suportada.',
['4'] = 'Ocorreu um erro ao atualizar a mensagem afixada. Ou o texto inserido continha um sintaxe Markdown inválido, ou a mensagem afixada foi apagada. Eu estou agora tentar e enviar-lhe uma mensagem afixada nova, que será capaz de encontrar abaixo - se precisar modifica-lo, depois de garantir que a mensagem ainda existe, use /pin <texto>.',
['5'] = 'Eu não consegui enviar esse texto porque ele contém um sintaxe Markdown inválido.',
['6'] = 'Clique aqui para ver a mensagem afixada, atualizado para contendo o texto que me enviou.'
},
['pokedex'] = {
['1'] = 'Nome: %s\nID: %s\nTipo: %s\nDescrição: %s'
},
['promote'] = {
['1'] = 'Não consigo promover este utilizador porque é moderador ou administrador deste grupo.',
['2'] = 'Não consigo promover este utilizador porque já saiu deste grupo.',
['3'] = 'Não consigo promover esse utilizador porque ele já foi expulso deste grupo.'
},
['quote'] = {
['1'] = 'Este utilizador desativou a funcionalidade de armazenamento de dados.',
['2'] = 'Não há citações guardadas para %s%s! Pode guardar um usando /save em resposta a uma mensagem que enviam.'
},
['report'] = {
['1'] = 'Please reply to the message you would like to report to the group\'s administrators.',
['2'] = 'You can\'t report your own messages, are you just trying to be funny?',
['3'] = '<b>%s precisa de ajuda em %s!</b>',
['4'] = 'Click here to view the reported message.',
['5'] = 'I\'ve successfully reported that message to %s admin(s)!'
},
['save'] = {
['1'] = 'Este utilizador desativou a funcionalidade de armazenamento de dados.',
['2'] = 'Esta mensagem foi gravada na minha base de dados, e adicionado à lista de possíveis respostas para quando /quote è usado em resposta a %s%s!'
},
['sed'] = {
['1'] = '%s\n\n<i>%s não quis dizer isso!</i>',
['2'] = '%s\n\n<i>%s admitiu a sua derrota.</i>',
['3'] = '%s\n\n<i>%s não tem certeza se eles estavam errados...</i>',
['4'] = 'Vai-te lixar, <i>quando é que eu estou errado?</i>',
['5'] = '"<code>%s</code>" não é um modelo Lua válido.',
['6'] = '<b>%s quis dizer:</b>\n<i>%s</i>',
['7'] = 'Sim',
['8'] = 'Não',
['9'] = 'Não tenho certeza'
},
['setgrouplang'] = {
['1'] = 'O idioma deste grupo foi alterado para %s!',
['2'] = 'This group\'s language is currently %s.\nPlease note that some strings may not be translated as of yet. If you\'d like to change your language, select one using the keyboard below:',
['3'] = 'The option to force users to use the same language in this group is currently disabled. This setting should be toggled from /administration but, to make things easier for you, I\'ve included a button below.',
['4'] = 'Habilitar',
['5'] = 'Desabilitar'
},
['setlang'] = {
['1'] = 'O seu idioma foi definido para %s!',
['2'] = 'O seu idioma é atualmente %s.\nTome nota que algumas sequencias de caracteres podem não estar traduzidas. Se quiser alterar seu idioma, selecione um usando o teclado abaixo:'
},
['setlink'] = {
['1'] = 'Não é um URL valido.',
['2'] = 'Endereço definido com sucesso!'
},
['setrules'] = {
['1'] = 'Formato Markdown invalido.',
['2'] = 'Regras definidas com sucesso!'
},
['setwelcome'] = {
['1'] = 'O que mensagem gostaria de boas-vindas que fosse? O texto que especificar será formato em Markdown e enviado toda vez que um utilizador se juntar ao grupo (A mensagem de boas-vindas pode ser desativada no menu de administração, acessível via /administration). Pode usar espaços reservados para personalizar automaticamente a mensagem de boas-vindas para cada utilizador. Use $user_id para inserir o ID numérico do utilizador, $chat_id para inserir o ID numérico do grupo, $name para inserir o nome do utilizador, $title para inserir o título do grupo e $username para inserir o nome de utilizador do utilizador (Se o utilizador não tiver um @utilizador, o seu nome será usado em vez disso, para evitar é melhor usar isso com $name).',
['2'] = 'Ocorreu um erro ao formatar a mensagem, verifique a sintaxe de Markdown e tente novamente.',
['3'] = 'A mensagem de boas-vindas para %s foi atualizada com sucesso!'
},
['share'] = {
['1'] = 'Partilhar'
},
['shorten'] = {
['1'] = 'Selecione um URL shortener usando os botões abaixo:'
},
['shsh'] = {
['1'] = 'Eu não consegui obter qualquer blobs SHSH para esse ECID, assegure-se de que é válido e os guardou usando https://tsssaver.1conan.com.',
['2'] = 'Os blobs SHSH para esse dispositivo estão disponíveis para as seguintes versões do iOS:\n',
['3'] = 'Transferir .zip'
},
['statistics'] = {
['1'] = 'No messages have been sent in this chat!',
['2'] = '<b>Statistics for:</b> %s\n\n%s\n<b>Total messages sent:</b> %s',
['3'] = 'The statistics for this chat have been reset!',
['4'] = 'I could not reset the statistics for this chat. Perhaps they have already been reset?'
},
['steam'] = {
['1'] = 'O seu nome de utilizador do Steam foi definido para "%s".',
['2'] = '"%s" não é um nome de utilizador Steam valido.',
['3'] = '%s é utilizador do Steam desde %s, em %s. Desligou a ultima vez %s, em %s. Clique <a href="%s">aqui</a> para ver o perfil no Steam.',
['4'] = '%s, AKA "%s",'
},
['trust'] = {
['1'] = 'I cannot trust this user because they are a moderator or an administrator of this chat.',
['2'] = 'I cannot trust this user because they have already left this chat.',
['3'] = 'I cannot trust this user because they have already been kicked from this chat.'
},
['unmute'] = {
['1'] = 'Que utilizador gostaria que removesse silenciar? Pode especificar este utilizador pelo seu @utilizador ou ID numérico.',
['2'] = 'Não consigo remover silenciar a este utilizador porque não está atualmente silenciado neste grupo.',
['3'] = 'Não consigo remover silenciar a este utilizador porque ele é um moderador ou administrador neste grupo.',
['4'] = 'Não consigo remover silenciar a este utilizador porque ele já deixou (ou foi expulso) deste grupo.',
},
['untrust'] = {
['1'] = 'Which user would you like me to untrust? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot untrust this user because they are a moderator or an administrator in this chat.',
['3'] = 'I cannot untrust this user because they have already left this chat.',
['4'] = 'I cannot untrust this user because they have already been kicked from this chat.'
},
['upload'] = {
['1'] = 'Responda a mensagem do ficheiro que pretende transferir para o servidor. Deve ser <= 20 MB.',
['2'] = 'Ficheiro é demasiado grande. Deve ser <= 20 MB.',
['3'] = 'Não consegui obter esse ficheiro, é provavelmente muito antigo.',
['4'] = 'Ocorreu um erro ao recuperar esse ficheiro.',
['5'] = 'Ficheiro transferido para o servidor com sucesso - pode ser encontrado em <code>%s</code>!'
},
['voteban'] = {
['1'] = 'Qual utilizador gostaria de abrir uma votação para banir? Pode especificar este utilizador pelo seu @utilizador ou ID numérico.',
['2'] = 'Não consigo criar uma votação para este utilizador porque ele é um moderador ou administrador neste grupo.',
['3'] = 'Não consigo criar uma votação para este utilizador porque ele já deixaram (ou foi expulso) deste grupo.',
['4'] = '%s [%s] deve ser banido por %s? %s voto a favor para banir imediatamente, e %s votos contra para fechar esta votação.',
['5'] = 'Sim [%s]',
['6'] = 'Não [%s]',
['7'] = 'O povo falou. E baniu %s [%s] por %s porque %s pessoas votaram a favor.',
['8'] = 'O montante de votos a favor necessários foi atingido, no entanto, não foi pode banir %s - talvez deixou o grupo ou foi promovido desde que abrimos a votação para banir? É isso ou não tenho mais os privilégios administrativos necessários para executar esta ação!',
['9'] = 'O povo falou. E não foi banido %s [%s] por %s porque %s pessoa decidiram votar contra.',
['10'] = 'Votou a favor na decisão de banir %s [%s]!',
['11'] = 'O seu voto atual foi retirado, use os botões novamente para reenviar o seu voto.',
['12'] = 'Votou contra na decisão de banir %s [%s]!',
['13'] = 'A vote-ban has already been opened for this user!'
},
['weather'] = {
['1'] = 'Ainda não tem uma localização definida. Use /setloc <localização> para definir uma.',
['2'] = 'Está atualmente %s (parece %s) em %s. %s'
},
['welcome'] = {
['1'] = 'Regras do Grupo'
},
- ['whitelist'] = {
+ ['allowlist'] = {
['1'] = 'Qual utilizador gostaria de adicionar à white-list? Pode especificar este utilizador pelo seu @utilizador ou ID numérico.',
['2'] = 'Não consigo adicionar à white-list esse utilizador porque ele é um moderador ou administrador neste grupo.',
['3'] = 'Não consigo adicionar à white-list esse utilizador porque ele já deixou este grupo.',
['4'] = 'Não consigo adicionar à white-list esse utilizador porque ele já foi banido neste grupo.'
},
['wikipedia'] = {
['1'] = 'Ver mais.'
},
['youtube'] = {
['1'] = 'Anterior',
['2'] = 'Seguinte',
['3'] = 'Está na pagina %s de %s!'
}
}
\ No newline at end of file
diff --git a/languages/pt_pt.lua b/languages/pt_pt.lua
index b592198..867154a 100644
--- a/languages/pt_pt.lua
+++ b/languages/pt_pt.lua
@@ -1,730 +1,730 @@
-- This is a language file for mattata
-- Language: pt-pt
-- Author: American_Jesus
-- DO NOT CHANGE ANYTHING THAT BEGINS OR ENDS WITH A %
-- THESE ARE PLACEHOLDERS!
-- DO NOT CHANGE ANY MARKDOWN/HTML FORMATTING!
-- IF YOU ARE UNSURE, ASK ON TELEGRAM (t.me/mattataDev)
return {
['errors'] = {
['connection'] = 'Erro de ligação.',
['results'] = 'Eu não consegui encontrar nenhum resultado para isso.',
['supergroup'] = 'Este comando só pode ser usado em super grupos.',
['admin'] = 'Precisa ser moderador ou administrador neste grupo para usar este comando.',
['unknown'] = 'Eu não reconheço esse(s) utilizador(es). Se gostaria de me ensinar quem ele(s) são, encaminhe-me uma mensagem dele(s) para qualquer conversa que eu estou.',
['generic'] = 'Ocorreu um erro!',
['use'] = 'You are not allowed to use this!',
['private'] = 'You can only use this command in private chat!'
},
['addcommand'] = {
['1'] = 'Please specify the command in the format <code>/command - description</code>',
['2'] = 'I couldn\'t retrieve my commands!',
['3'] = 'The command description can\'t be longer than 256 characters!',
['4'] = 'An unknown error occurred! I couldn\'t add your command!',
['5'] = 'Success! Command added.'
},
['addrule'] = {
['1'] = 'Please specify the rule you would like to add!',
['2'] = 'You don\'t have any rules to add to! Please set group rules using /setrules!',
['3'] = 'I couldn\'t add that rule, as it would make the length of the rules longer than Telegram\'s 4096 character limit!',
['4'] = 'I couldn\'t add that rule, it appears it contains invalid Markdown formatting!',
['5'] = 'Successfully updated the rules!'
},
['addslap'] = {
['1'] = 'You can only use this command in groups!',
['2'] = 'The slap cannot contain curly braces apart from placeholders!',
['3'] = 'The slap cannot be any longer than 256 characters in length!',
['4'] = 'I\'ve successfully added that slap as a possibility for /slap in this group!',
['5'] = 'You must include placeholders in your slap. Use {ME} for the person executing and {THEM} for the victim.'
},
['administration'] = {
['1'] = 'Enable Administration',
['2'] = 'Disable Administration',
['3'] = 'Anti-Spam Settings',
['4'] = 'Warning Settings',
['5'] = 'Vote-Ban Settings',
['6'] = 'Welcome New Users?',
['7'] = 'Send Rules On Join?',
['8'] = 'Send Rules In Group?',
['9'] = 'Back',
['10'] = 'Next',
['11'] = 'Word Filter',
['12'] = 'Anti-Bot',
['13'] = 'Anti-Link',
['14'] = 'Log Actions?',
['15'] = 'Anti-RTL',
['16'] = 'Anti-Spam Action',
['17'] = 'Ban',
['18'] = 'Kick',
['19'] = 'Delete Commands?',
['20'] = 'Force Group Language?',
['21'] = 'Send Settings In Group?',
['22'] = 'Delete Reply On Action?',
['23'] = 'Require Captcha?',
['24'] = 'Use Inline Captcha?',
['25'] = 'Ban SpamWatch-flagged users?',
['26'] = 'Number of warnings until %s:',
['27'] = 'Upvotes needed to ban:',
['28'] = 'Downvotes needed to dismiss:',
['29'] = 'Deleted %s, and its matching link from the database!',
['30'] = 'There were no entries found in the database matching "%s"!',
['31'] = 'You\'re not an administrator in that chat!',
['32'] = 'The minimum number of upvotes required for a vote-ban is %s.',
['33'] = 'The maximum number of upvotes required for a vote-ban is %s.',
['34'] = 'The minimum number of downvotes required for a vote-ban is %s.',
['35'] = 'The maximum number of downvotes required for a vote-ban is %s.',
['36'] = 'The maximum number of warnings is %s.',
['37'] = 'The minimum number of warnings is %s.',
['38'] = 'You can add one or more words to the word filter by using /filter <word(s)>',
['39'] = 'You will no longer be reminded that the administration plugin is disabled. To enable it, use /administration.',
['40'] = 'That\'s not a valid chat!',
['41'] = 'You don\'t appear to be an administrator in that chat!',
['42'] = 'My administrative functionality can only be used in groups/channels! If you\'re looking for help with using my administrative functionality, check out the "Administration" section of /help! Alternatively, if you wish to manage the settings for a group you administrate, you can do so here by using the syntax /administration <chat>.',
['43'] = 'Use the keyboard below to adjust the administration settings for <b>%s</b>:',
['44'] = 'Please send me a [private message](https://t.me/%s), so that I can send you this information.',
['45'] = 'I have sent you the information you requested via private chat.',
['46'] = 'Remove Channel Pins?',
['47'] = 'Remove Other Pins?',
['48'] = 'Remove Pasted Code?',
['49'] = 'Prevent Inline Bots?',
['50'] = 'Kick Media On Join?',
['51'] = 'Enable Plugins For Admins?',
['52'] = 'Kick URLs On Join?'
},
['afk'] = {
['1'] = 'Desculpe, receio que este elemento esteja disponível somente para utilizadores com um @utilizador público!',
['2'] = '%s voltou depois de estar AFK por %s!',
['3'] = 'Nota',
['4'] = '%s está agora AFK.%s'
},
['antispam'] = {
['1'] = 'Disable',
['2'] = 'Enable',
['3'] = 'Disable limit',
['4'] = 'Enable limits on %s',
['5'] = 'All Administration Settings',
['6'] = '%s [%s] has kicked %s [%s] from %s [%s] for hitting the configured anti-spam limit for [%s] media.',
['7'] = 'Kicked %s for hitting the configured antispam limit for [%s] media.',
['8'] = 'The maximum limit is 100.',
['9'] = 'The minimum limit is 1.',
['10'] = 'Modify the anti-spam settings for %s below:',
['11'] = 'Hey %s, if you\'re going to send code that is longer than %s characters in length, please do so using /paste in <a href="https://t.me/%s">private chat with me</a>!',
['12'] = '%s <code>[%s]</code> has %s %s <code>[%s]</code> from %s <code>[%s]</code> for sending Telegram invite link(s).\n#chat%s #user%s',
['13'] = '%s %s for sending Telegram invite link(s).',
- ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to whitelist it, use /whitelistlink <links>.',
+ ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to allowlist it, use /allowlink <links>.',
['15'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending media within their first few messages.\n#chat%s #user%s',
['16'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending a URL within their first few messages.\n#chat%s #user%s'
},
['appstore'] = {
['1'] = 'Ver no iTunes',
['2'] = 'rating',
['3'] = 'ratings'
},
['authspotify'] = {
['1'] = 'You are already authorised using that account.',
['2'] = 'Authorising, please wait...',
['3'] = 'A connection error occured. Are you sure you replied with the correct link? It should look like',
['4'] = 'Successfully authorised your Spotify account!'
},
['avatar'] = {
['1'] = 'Não consegui obter fotos de perfil para esse utilizador, verifique se especificou um nome de utilizador ou ID numérico válido.',
['2'] = 'Esse utilizador não tem fotos de perfil.',
['3'] = 'Esse utilizador não tem assim tantas de perfil!',
['4'] = 'That user has opted-out of data-collecting functionality, therefore I am not able to show you any of their profile photos.',
['5'] = 'User: %s\nPhoto: %s/%s\nSend /avatar %s [offset] to @%s to view a specific photo of this user',
['6'] = 'User: %s\nPhoto: %s/%s\nUse /avatar %s [offset] to view a specific photo of this user'
},
['ban'] = {
['1'] = 'Qual utilizador gostaria que eu bane? Pode especificar esse utilizador pelo seu @username ou ID numérico.',
['2'] = 'Não consigo banir esse utilizador porque ele é um moderador ou um administrador neste grupo.',
['3'] = 'Não consigo banir este utilizador porque ele saiu deste grupo.',
['4'] = 'Não consigo banir este utilizador porque ele já foi banido deste grupo.',
['5'] = 'Eu preciso ter permissões administrativas para banir esse utilizador. Corrija este problema e tente novamente.',
['6'] = '%s <code>[%s]</code> has banned %s <code>[%s]</code> from %s <code>[%s]</code>%s.\n%s %s',
['7'] = '%s has banned %s%s.'
},
['bash'] = {
['1'] = 'Especifique um comando para executar!',
['2'] = 'Sucesso!'
},
- ['blacklist'] = {
+ ['blocklist'] = {
['1'] = 'Qual utilizador gostaria de adicionar a lista negra? Pode especificar este utilizador pelo seu @username ou ID numérico.',
['2'] = 'Não consigo adicionar a lista negra esse utilizador porque ele é um moderador ou um administrador neste grupo.',
['3'] = 'Não consigo adicionar a lista negra esse utilizador porque ele já deixou este grupo.',
['4'] = 'Não consigo adicionar a lista negra esse utilizador porque ele já foi banido neste grupo.',
- ['5'] = '%s <code>[%s]</code> has blacklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
- ['6'] = '%s has blacklisted %s from using %s%s.'
+ ['5'] = '%s <code>[%s]</code> has blocklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
+ ['6'] = '%s has blocklisted %s from using %s%s.'
},
- ['blacklistchat'] = {
+ ['blocklistchat'] = {
['1'] = '%s foi adicionado a lista negra, e vou deixar lá quem eu adicionar!',
['2'] = '%s é um utilizador, este comando é apenas para lista negras em conversas como grupos e canais!',
['3'] = '%s não parece ser uma conversa valida!'
},
['bugreport'] = {
['1'] = 'Sucesso! Seu relatório de bug foi enviado. O ID deste relatório é #%s.',
['2'] = 'Ocorreu um problema enquanto relatava esse bug! Ah, a ironia!'
},
['calc'] = {
['1'] = 'Clique para enviar o resultado.',
['2'] = '"%s" was an unexpected word!',
['3'] = 'You cannot have a unit before a number!'
},
['captionbotai'] = {
['1'] = 'Eu realmente não posso descrever essa imagem!'
},
['cats'] = {
['1'] = 'Meow!'
},
['channel'] = {
['1'] = 'Não tem permissão para usar isso!',
['2'] = 'Parece já não ser um administrador nesse grupo!',
['3'] = 'Não consegui enviar a sua mensagem, tem certeza de que ainda tenho permissão para enviar mensagens nesse grupo?',
['4'] = 'A sua mensagem foi enviada!',
['5'] = 'Não consegui recuperar uma lista de administradores para desse grupo!',
['6'] = 'Não parece ser um administrador desse grupo!',
['7'] = 'Especifique a mensagem a enviar, utilizando a sintaxe /channel <canal> <mensagem>.',
['8'] = 'Tem certeza de que deseja enviar esta mensagem? É assim que vai aparecer:',
['9'] = 'Sim, Tenho a certeza!',
['10'] = 'Essa mensagem contém formatação Markdown inválido! Corrija a sintaxe e tente novamente.'
},
['chatroulette'] = {
['1'] = 'Hey! Please don\'t send messages longer than %s characters. We don\'t want to annoy the other user!',
['2'] = '*Anonymous said:*\n```\n%s\n```\nTo end your session, send /endchat.',
['3'] = 'I\'m afraid I lost connection from the other user! To begin a new chat, please send /chatroulette!',
['4'] = 'The other person you were chatting with has ended the session. To start a new one, send /chatroulette.',
['5'] = 'Successfully ended your session. To start a new one, send /chatroulette.',
['6'] = 'I have successfully removed you from the list of available users.',
['7'] = 'You don\'t have a session set up at the moment. To start one, send /chatroulette.',
['8'] = 'Finding you a session, please wait...',
['9'] = 'I\'m afraid there aren\'t any available users right now, but I have added you to the list of available users! To stop this completely, please send /endchat.',
['10'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.',
['11'] = 'I\'m afraid the user who I tried to pair you with has since blocked me. Please try and send /chatroulette again to try and connect to me!',
['12'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.'
},
['commandstats'] = {
['1'] = 'No commands have been sent in this chat!',
['2'] = '<b>Command statistics for:</b> %s\n\n%s\n<b>Total commands sent:</b> %s',
['3'] = 'The command statistics for this chat have been reset!',
['4'] = 'I could not reset the command statistics for this chat. Perhaps they have already been reset?'
},
['control'] = {
['1'] = 'Pfft, querias!',
['2'] = '%s está a recarregar...'
},
['copypasta'] = {
['1'] = 'O texto respondido não deverá exceder %s caracteres!'
},
['coronavirus'] = {
['1'] = [[*COVID-19 Statistics for:* %s
*New confirmed cases:* %s
*Total confirmed cases:* %s
*New deaths:* %s
*Total deaths:* %s
*New recovered cases:* %s
*Total recovered cases:* %s]]
},
['counter'] = {
['1'] = 'Eu não pude adicionar um contador a essa mensagem!'
},
['custom'] = {
['1'] = 'Sucesso! Essa mensagem será enviada toda vez que alguém usar %s!',
['2'] = 'O trigger "%s" não existe!',
['3'] = 'O trigger "%s" foi apagado!',
['4'] = 'Ainda não tem triggers personalizado definidos!',
['5'] = 'Comandos personalizados para %s:\n',
['6'] = 'Para criar um novo comando personalizado, use a seguinte sintaxe:\n/custom new #trigger <valor>. Para listar todos os triggers atuais, use /custom list. Para apagar um trigger, use /custom del #trigger.'
},
['delete'] = {
['1'] = 'Não consegui apagar essa mensagem. Talvez a mensagem seja muito antiga ou inexistente?'
},
['demote'] = {
['1'] = 'Qual utilizador gostaria que eu despromovesse? Pode especificar este utilizador pelo seu @username ou ID numérico.',
['2'] = 'Eu não posso despromover esse utilizador porque ele não é um moderador ou um administrador neste grupo.',
['3'] = 'Eu não posso despromover esse utilizador porque ele já deixou este grupo.',
['4'] = 'Não consigo despromover esse utilizador porque ele já foi expulso deste grupo.'
},
['doge'] = {
['1'] = 'Por favor, escreva o texto que deseja para Doge-ify. Cada sentença deve ser separada usando barras (/) ou novas linhas.'
},
['donate'] = {
['1'] = '<b>Hello, %s!</b>\n\nIf you\'re feeling generous, you can contribute to the mattata project by making a monetary donation of any amount. This will go towards server costs and any time and resources used to develop mattata. This is an optional act, however it is greatly appreciated and your name will also be listed publically on mattata\'s GitHub page.\n\nIf you\'re still interested, you can donate <a href="https://paypal.me/wrxck">here</a>. Thank you for your continued support!'
},
['exec'] = {
['1'] = 'Selecione a linguagem em que gostaria de executar o seu código:',
['2'] = 'Ocurreu um erro! Tempo de ligação expirou. Está a tentar fazer-me lag?',
['3'] = 'Selecionou "%s" – tem a certeza?',
['4'] = 'Voltar',
['5'] = 'Tenho a certeza',
['6'] = 'Introduza um fragmento de código que pretende executar. Não precisa especificar a linguagem, faremos isso depois!',
['7'] = 'Selecione a linguagem em que gostaria de executar o seu código:'
},
['facebook'] = {
['1'] = 'Ocorreu um erro!',
['2'] = 'Escreva o nome de utilizador do Facebook do qual gostaria de obter a foto do perfil.',
['3'] = 'Visitas @%s no Facebook'
},
['fact'] = {
['1'] = 'Gerar Outro'
},
['fban'] = {
['1'] = 'Which user would you like me to Fed-ban? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot Fed-ban this user because they are a moderator or an administrator in this chat.'
},
['flickr'] = {
['1'] = 'Pesquisou por:',
['2'] = 'Introduza uma consulta de pesquisa (Ou seja, o que quer que eu procure no Flickr, i.e. "Big Ben" mostrara uma fotografia do Big Ben em Londres).',
['3'] = 'Mais Resultados'
},
['game'] = {
['1'] = 'Total de vitórias: %s\nTotal de derrotas: %s\nBalanço: %s mattacoins',
['2'] = 'Entrar no Jogo',
['3'] = 'Este jogo já acabou!',
['4'] = 'Não é a sua vez!',
['5'] = 'Não faz parte deste jogo!',
['6'] = 'Não pode ser ai!',
['7'] = 'Já faz parte deste jogo!',
['8'] = 'Este jogo já começou!',
['9'] = '%s [%s] está a jogar contra %s [%s]\nE é a vez de %s\'s a jogar!',
['10'] = '%s ganhou o jogo contra %s!',
['11'] = '%s criou um jogo contra %s!',
['12'] = 'A espera pelo oponente...',
['13'] = 'Jogo do Galo',
['14'] = 'Clique para enviar o jogo para o seu grupo!',
['15'] = 'Estatísticas %s:\n',
['16'] = 'Jogar ao Jogo do Galo!'
},
- ['gblacklist'] = {
+ ['gblocklist'] = {
['1'] = 'Responda ao utilizador que deseja incluir na lista negra global ou especifique-o por nome de utilizador/ID.',
['2'] = 'Não conseguir obter informações sobre "%s", verifique se é um nome de utilizador/ID válido e tente novamente.',
['3'] = 'Isso é um %s, não um utilizador!'
},
['gif'] = {
['1'] = 'Introduza uma consulta de pesquisa (Que é, o que quer que eu procure no GIPHY, ex: "cat" irá mostrar um GIF de um gato).'
},
- ['gwhitelist'] = {
+ ['gallowlist'] = {
['1'] = 'Responda ao utilizador que deseja incluir na lista branca global ou especifique-o por nome de utilizador/ID.',
['2'] = 'Não conseguir obter informações sobre "%s", verifique se é um nome de utilizador/ID válido e tente novamente.',
['3'] = 'Isso é um %s, não um utilizador!'
},
['hackernews'] = {
['1'] = 'Histórias principais de Hacker News:'
},
['help'] = {
['1'] = 'Nenhum resultado encontrado!',
['2'] = 'Não foram encontrados elementos que correspondam a "%s", Por favor, tente ser mais específico!',
['3'] = '\n\nArgumentos: <requer> [opcional]\n\nProcurar um elemento ou obter ajuda com um comando usando minha funcionalidade de pesquisa inline - apenas me mencione em qualquer grupo usando a sintaxe @%s <texto de procura>.',
['4'] = 'Anterior',
['5'] = 'Seguinte',
['6'] = 'Voltar',
['7'] = 'Procurar',
['8'] = 'Está na pagina %s de %s!',
['9'] = [[
Posso executar muitas ações administrativas nos seus grupos, basta adicionar-me como administrador e envie /administration para ajustar as configurações do seu grupo.
Aqui estão alguns comandos administrativos e um breve comentário sobre o que eles fazem:
• /pin <texto> - Envie uma mensagem formatada em Markdown que pode ser editada usando o mesmo comando com texto diferente, para evitar de ter que afixar novamente uma mensagem se não poder edita-la (o que acontece se a mensagem tiver mais de 48 horas)
• /ban - Banir um utilizador respondendo a uma de suas mensagens ou especificando com o nome de utilizador/ID
• /kick - Expulsar (banir e depois remover ban) um utilizador respondendo a uma de suas mensagens ou especificando com o nome de utilizador/ID
• /unban - Remover ban a um utilizador respondendo a uma de suas mensagens ou especificando com o nome de utilizador/ID
• /setrules <texto> - Defina o texto formatado como Markdown como as regras de grupo, que serão enviadas sempre que alguém usar /rules
]],
['10'] = [[
• /setwelcome - Defina o texto formatado como Markdown como uma mensagem de boas-vindas que será enviada sempre que um utilizador se juntar ao seu grupo (A mensagem de boas-vindas pode ser desativada no menu de administração, acessível via /administration). Pode usar espaços reservados para personalizar automaticamente a mensagem de boas-vindas para cada utilizador. Use $user_id para inserir o ID numérico do utilizador, $chat_id para inserir o ID numérico do grupo, $name para inserir o nome do utilizador, $title para inserir o título do grupo e $username para inserir o nome de utilizador do utilizador (Se o utilizador não tiver um @utilizador, o seu nome será usado em vez disso, para evitar é melhor usar isso com $name)
• /warn - Avisa um utilizador, e bane-o quando atingirem o número máximo de avisos
• /mod - Promove um utilizador respondendo a, dando acesso a comandos administrativos como /ban, /kick, /warn etc. (isto é útil quando não quer que alguém tenha a capacidade de apagar mensagens!)
• /demod - Despromove um utilizador respondendo a, removendo do seu estatuto de moderação e revogando sua capacidade de usar comandos administrativos
• /staff - Mostrar o criador, administradores e moderadores do grupo numa lista bem formatada
]],
['11'] = [[
• /report - Encaminha a mensagem de resposta para todos os administradores e os alerta da situação atual
• /setlink <URL> - Define o endereço do grupo para o URL fornecido, que será enviado sempre que alguém usar /link
• /links <texto> - Listas brancas todos os endereços Telegram encontrados no texto fornecido (inclui endereços de @utilizador)
]],
['12'] = 'Abaixo estão alguns links que pode achar úteis:',
['13'] = 'Desenvolvimento',
['14'] = 'Canal',
['15'] = 'Suporte',
['16'] = 'FAQ',
['17'] = 'Código Fonte',
['18'] = 'Doar',
['19'] = 'Rate',
['20'] = 'Registo de Administração',
['21'] = 'Definições de administrador',
['22'] = 'Plugins',
['23'] = [[
<b>Olá %s! O meu nome é %s, é um prazer conhece-lo</b> %s
Eu entendo muitos comandos, que você pode aprender mais sobre pressionando o botão "Comandos" usando o teclado acoplado.
%s <b>Dica:</b> Use o botão "Definições" para alterar o modo como eu trabalho%s!
%s <b>Find me useful, or just want to help?</b> Donations are very much appreciated, use /donate for more information!
]],
['24'] = 'em'
},
['id'] = {
['1'] = 'Desculpe, mas eu não reconheço esse utilizador. Ensine-me quem ele é, encaminhando uma mensagem dele a mim ou faça com que ele me enviem uma mensagem.',
['2'] = 'Grupo consultado:',
['3'] = 'Este grupo:',
['4'] = 'Clique para enviar o resultado!'
},
['imdb'] = {
['1'] = 'Anterior',
['2'] = 'Seguinte',
['3'] = 'Está na pagina %s de %s!'
},
['import'] = {
['1'] = 'Eu não reconheço esse grupo!',
['2'] = 'Isso não é um super grupo, portanto não consigo importar nenhuma configuração dele!',
['3'] = 'Configurações administrativas importadas e plugins alternados com sucesso de %s para %s!'
},
['info'] = {
['1'] = [[
```
Redis:
%s Ficheiro de Configuração: %s
%s Modo: %s
%s Porta TCP: %s
%s Versão: %s
%s Tempo de atividade: %s days
%s ID do Processo: %s
%s Keys Expiradas: %s
%s Contagem de Utilizadores: %s
%s Contagem de Grupos: %s
Sistema:
%s OS: %s
```
]]
},
['instagram'] = {
['1'] = '@%s no Instagram'
},
['ipsw'] = {
['1'] = '<b>%s</b> iOS %s\n\n<code>MD5 sum: %s\nSHA1 sum: %s\nTamanho do ficheiro: %s GB</code>\n\n<i>%s %s</i>',
['2'] = 'Este firmware não está mais sendo assinado!',
['3'] = 'Este firmware ainda está sendo assinado!',
['4'] = 'Selecione o seu modelo:',
['5'] = 'Selecione a versão do firmware:',
['6'] = 'Selecione seu tipo de dispositivo:',
['7'] = 'iPod Touch',
['8'] = 'iPhone',
['9'] = 'iPad',
['10'] = 'Apple TV'
},
['ispwned'] = {
['1'] = 'Essa conta foi encontrada nos seguintes fugas de informação:'
},
['itunes'] = {
['1'] = 'Nome:',
['2'] = 'Artista:',
['3'] = 'Álbum:',
['4'] = 'Faixa:',
['5'] = 'Disco:',
['6'] = 'A consulta original não pôde ser encontrada, provavelmente apagou a mensagem original.',
['7'] = 'A capa pode ser encontrada abaixo:',
['8'] = 'Introduza uma consulta de pesquisa (Ou seja, o que quer que eu procure no iTunes, Ex: "Green Day American Idiot" ira mostrar informações sobre o primeiro resultado para American Idiot dos Green Day).',
['9'] = 'Obter Capa do Álbum'
},
['kick'] = {
['1'] = 'Qual utilizador gostaria que eu expulsasse? Pode especificar este utilizador por seu @utilizador ou ID numérico.',
['2'] = 'Eu não consigo expulsar esse utilizador porque ele é um moderador ou administrador neste grupo.',
['3'] = 'Eu não consigo expulsar esse utilizador porque ele já deixou este grupo.',
['4'] = 'Não consigo expulsar esse utilizador porque ele já foi expulso deste grupo.',
['5'] = 'Eu preciso ter permissões administrativas para expulsar esse utilizador. Corrija este problema e tente novamente.'
},
['lastfm'] = {
['1'] = '%s\'s utilizador de last.fm foi definido para "%s".',
['2'] = 'O seu utilizador last.fm foi esquecido!',
['3'] = 'Não tem atualmente um utilizado do last.fm definido!',
['4'] = 'Especifique o utilizador do last.fm ou defina com /fmset.',
['5'] = 'Nenhum histórico foi encontrado para este utilizador.',
['6'] = '%s está atualmente a ouvir:\n',
['7'] = '%s ouviu ultimamente:\n',
['8'] = 'Desconhecido',
['9'] = 'Clique para enviar o resultado.'
},
['location'] = {
['1'] = 'Não tem uma localização definida. O que nova localização gostaria que fosse?'
},
['logchat'] = {
['1'] = 'Escreva o nome de utilizador ou ID numérico do grupo no qual deseja registar todas as ações administrativas.',
['2'] = 'A verificar se o grupo é válido...',
['3'] = 'Desculpe, parece que especificou um grupo inválido, ou especificou um grupo que eu ainda não adicionado. Corrija e tente novamente.',
['4'] = 'Não pode definir um utilizador como o seu grupo de registo!',
['5'] = 'Não parece ser administrador nesse grupo!',
['6'] = 'Parece que eu já estou registar ações administrativas nesse grupo! Use /logchat para especificar um novo.',
['7'] = 'Esse grupo é válido, vou tentar e enviar uma mensagem de teste para ele, apenas para garantir que tenho permissão para falar!',
['8'] = 'Olá mundo - esta é uma mensagem de teste para verificar minhas permissões de escrita - se estiver a ler isto, então tudo correu bem!',
['9'] = 'Tudo feito! De agora em diante, Quaisquer ações administrativas neste grupo serão registadas em %s - para mudar o grupo que quer que eu registe ações administrativas, basta enviar /logchat.'
},
['lua'] = {
['1'] = 'Digite uma string de Lua para executar!'
},
['lyrics'] = {
['1'] = 'Spotify',
['2'] = 'Mostrar letra',
['3'] = 'Introduza uma consulta de pesquisa (isto é, que musica/artista/letra quer que eu obtenha letras, Ex: "Green Day Basket Case" irá mostrar a letra para Basket Case dos Green Day).'
},
['minecraft'] = {
['1'] = '<b>%s mudou o seu utilizador %s vez</b>',
['2'] = '<b>%s mudou o seu utilizador %s vezes</b>',
['3'] = 'Anterior',
['4'] = 'Seguinte',
['5'] = 'Voltar',
['6'] = 'UUID',
['7'] = 'Avatar',
['8'] = 'Histórico de Utilizador',
['9'] = 'Selecione uma opção:',
['10'] = 'Escreva o nome de utilizador do jogador do Minecraft que gostaria de ver informações (Ex: enviando "Notch" irá ver as informações sobre o jogador Notch).',
['11'] = 'Os nomes de utilizadores do Minecraft têm entre 3 e 16 caracteres.'
},
['mute'] = {
['1'] = 'Que utilizador gostaria que ficasse silenciar? Pode especificar este utilizador pelo seu @utilizador ou ID numérico.',
['2'] = 'Não consigo silenciar este utilizador porque já estão silenciados neste grupo.',
['3'] = 'Não consigo silenciar este utilizador porque ele é um moderador ou administrador neste grupo.',
['4'] = 'Não consigo silenciar este utilizador porque ele já deixou (ou foi expulso) deste grupo.',
['5'] = 'Eu preciso ter permissões administrativas para silenciar este utilizador. Corrija este problema e tente novamente.'
},
['myspotify'] = {
['1'] = 'Profile',
['2'] = 'Following',
['3'] = 'Recently Played',
['4'] = 'Currently Playing',
['5'] = 'Top Tracks',
['6'] = 'Top Artists',
['7'] = 'You don\'t appear to be following any artists!',
['8'] = 'Your Top Artists',
['9'] = 'You don\'t appear to have any tracks in your library!',
['10'] = 'Your Top Tracks',
['11'] = 'You don\'t appear to be following any artists!',
['12'] = 'Artists You Follow',
['13'] = 'You don\'t appear to have recently played any tracks!',
['14'] = '<b>Recently Played</b>\n%s %s\n%s %s\n%s Listened to at %s:%s on %s/%s/%s.',
['15'] = 'The request has been accepted for processing, but the processing has not been completed.',
['16'] = 'You don\'t appear to be listening to anything right now!',
['17'] = 'Currently Playing',
['18'] = 'An error occured whilst re-authorising your Spotify account!',
['19'] = 'Successfully re-authorised your Spotify account! Processing your original request...',
['20'] = 'Re-authorising your Spotify account, please wait...',
['21'] = 'You need to authorise mattata in order to connect your Spotify account. Click [here](https://accounts.spotify.com/en/authorize?client_id=%s&response_type=code&redirect_uri=%s&scope=user-library-read,playlist-read-private,playlist-read-collaborative,user-read-private,user-read-email,user-follow-read,user-top-read,user-read-playback-state,user-read-recently-played,user-read-currently-playing,user-modify-playback-state) and press the green "OKAY" button to link mattata to your Spotify account. After you\'ve done that, send the link you were redirected to (it should begin with "%s", followed by a unique code) in reply to this message.',
['22'] = 'Playlists',
['23'] = 'Use Inline Mode',
['24'] = 'Lyrics',
['25'] = 'No devices were found.',
['26'] = 'You don\'t appear to have any playlists.',
['27'] = 'Your Playlists',
['28'] = '%s %s [%s tracks]',
['29'] = '%s %s [%s]\nSpotify %s user\n\n<b>Devices:</b>\n%s',
['30'] = 'Playing previous track...',
['31'] = 'You are not a premium user!',
['32'] = 'I could not find any devices.',
['33'] = 'Playing next track...',
['34'] = 'Resuming track...',
['35'] = 'Your device is temporarily unavailable...',
['36'] = 'No devices were found!',
['37'] = 'Pausing track...',
['38'] = 'Now playing',
['39'] = 'Shuffling your music...',
['40'] = 'That\'s not a valid volume. Please specify a number between 0 and 100.',
['41'] = 'The volume has been set to %s%%!',
['42'] = 'This message is using an old version of this plugin, please request a new one by sending /myspotify!'
},
['name'] = {
['1'] = 'O nome a qual respondo atualmente é "%s" - para alterar isso, use /name <texto> (onde <texto> o nome a qual quer que eu responda).',
['2'] = 'Meu novo nome precisa ter entre 2 e 32 caracteres!',
['3'] = 'Meu nome só pode conter caracteres alfanuméricos!',
['4'] = 'Vou agora responder a "%s", em vez de "%s" - para alterar isso, use /name <texto> (onde <text> o nome a qual quer que eu responda).'
},
['netflix'] = {
['1'] = 'Ver mais.'
},
['news'] = {
['1'] = '"<code>%s</code>" não é um padrão Lua válido.',
['2'] = 'Eu não consegui obter uma lista de fontes.',
['3'] = '<b>Fontes de notícias encontradas correspondentes</b> "<code>%s</code>":\n\n%s',
['4'] = '<b>Aqui estão as fontes de notícias disponíveis que pode usar com</b> /news<b>. Use</b> /nsources &lt;pesquisa&gt; <b>para pesquisar a lista de fontes de notícias para um conjunto mais específico de resultados. As pesquisas são combinadas usando padrões Lua</b>\n\n%s',
['5'] = 'Não tem uma fonte de notícias preferida. Use /setnews <source> para definir uma. Veja a lista de fontes usando /nsources, ou restringir os resultados usando /nsources <pesquisa>.',
['6'] = 'A sua fonte de notícias preferida atual é %s. Use /setnews <source> para alterar isso. Veja a lista de fontes usando /nsources, ou restringir os resultados usando /nsources <pesquisa>.',
['7'] = 'A sua fonte preferida já está definida para %s! Use /news para ver a história principal atual.',
['8'] = 'Isso não é uma fonte de notícias válida. Exibir uma lista de fontes usando /nsources, ou restringir os resultados usando /nsources <pesquisa>.',
['9'] = 'A sua fonte de notícias preferida foi atualizada para %s! Use /news para ver a história principal atual.',
['10'] = 'Isso não é uma fonte válida, use /nsources para ver uma lista de fontes disponíveis. Se tem uma fonte preferida, use /setnews <fonte> Para receber automaticamente notícias daquela fonte enviada quando envie /news, sem quaisquer argumentos necessários.',
['11'] = 'Ver mais.'
},
['nick'] = {
['1'] = 'O seu nick foi esquecido!',
['2'] = 'O seu nick foi definido como "%s"!'
},
['optout'] = {
['1'] = 'Optou por enviar os seus dados! Use /optout para excluir.',
['2'] = 'Optou por não enviar os seus dados! Use /optin para enviar.'
},
['paste'] = {
['1'] = 'Selecione um serviço para enviar copia:'
},
['pin'] = {
['1'] = 'Não definiu ainda uma mensagem afixada. Use /pin <texto> para definir uma. A formatação Markdown é suportada.',
['2'] = 'Aqui está a última mensagem gerada usando /pin.',
['3'] = 'Eu encontrei uma mensagem afixada existente na base de dados, mas a mensagem que enviei parece ter sido apagada, e não consigo mais encontra-la. Pode definir uma nova usando /pin <texto>. A formatação Markdown é suportada.',
['4'] = 'Ocorreu um erro ao atualizar a mensagem afixada. Ou o texto inserido continha um sintaxe Markdown inválido, ou a mensagem afixada foi apagada. Eu estou agora tentar e enviar-lhe uma mensagem afixada nova, que será capaz de encontrar abaixo - se precisar modifica-lo, depois de garantir que a mensagem ainda existe, use /pin <texto>.',
['5'] = 'Eu não consegui enviar esse texto porque ele contém um sintaxe Markdown inválido.',
['6'] = 'Clique aqui para ver a mensagem afixada, atualizado para contendo o texto que me enviou.'
},
['pokedex'] = {
['1'] = 'Nome: %s\nID: %s\nTipo: %s\nDescrição: %s'
},
['promote'] = {
['1'] = 'Não consigo promover este utilizador porque é moderador ou administrador deste grupo.',
['2'] = 'Não consigo promover este utilizador porque já saiu deste grupo.',
['3'] = 'Não consigo promover esse utilizador porque ele já foi expulso deste grupo.'
},
['quote'] = {
['1'] = 'Este utilizador desativou a funcionalidade de armazenamento de dados.',
['2'] = 'Não há citações guardadas para %s%s! Pode guardar um usando /save em resposta a uma mensagem que enviam.'
},
['report'] = {
['1'] = 'Please reply to the message you would like to report to the group\'s administrators.',
['2'] = 'You can\'t report your own messages, are you just trying to be funny?',
['3'] = '<b>%s needs help in %s!</b>',
['4'] = 'Click here to view the reported message.',
['5'] = 'I\'ve successfully reported that message to %s admin(s)!'
},
['save'] = {
['1'] = 'Este utilizador desativou a funcionalidade de armazenamento de dados.',
['2'] = 'Esta mensagem foi gravada na minha base de dados, e adicionado à lista de possíveis respostas para quando /quote è usado em resposta a %s%s!'
},
['sed'] = {
['1'] = '%s\n\n<i>%s não quis dizer isso!</i>',
['2'] = '%s\n\n<i>%s admitiu a sua derrota.</i>',
['3'] = '%s\n\n<i>%s não tem certeza se eles estavam errados...</i>',
['4'] = 'Vai-te lixar, <i>quando é que eu estou errado?</i>',
['5'] = '"<code>%s</code>" não é um modelo Lua válido.',
['6'] = '<b>%s quis dizer:</b>\n<i>%s</i>',
['7'] = 'Sim',
['8'] = 'Não',
['9'] = 'Não tenho certeza'
},
['setgrouplang'] = {
['1'] = 'This group\'s language has been set to %s!',
['2'] = 'This group\'s language is currently %s.\nPlease note that some strings may not be translated as of yet. If you\'d like to change your language, select one using the keyboard below:',
['3'] = 'The option to force users to use the same language in this group is currently disabled. This setting should be toggled from /administration but, to make things easier for you, I\'ve included a button below.',
['4'] = 'Enable',
['5'] = 'Disable'
},
['setlang'] = {
['1'] = 'O seu idioma foi definido para %s!',
['2'] = 'O seu idioma é atualmente %s.\nTome nota que algumas sequencias de caracteres podem não estar traduzidas. Se quiser alterar seu idioma, selecione um usando o teclado abaixo:'
},
['setlink'] = {
['1'] = 'Não é um URL valido.',
['2'] = 'Endereço definido com sucesso!'
},
['setrules'] = {
['1'] = 'Formato Markdown invalido.',
['2'] = 'Regras definidas com sucesso!'
},
['setwelcome'] = {
['1'] = 'O que mensagem gostaria de boas-vindas que fosse? O texto que especificar será formato em Markdown e enviado toda vez que um utilizador se juntar ao grupo (A mensagem de boas-vindas pode ser desativada no menu de administração, acessível via /administration). Pode usar espaços reservados para personalizar automaticamente a mensagem de boas-vindas para cada utilizador. Use $user_id para inserir o ID numérico do utilizador, $chat_id para inserir o ID numérico do grupo, $name para inserir o nome do utilizador, $title para inserir o título do grupo e $username para inserir o nome de utilizador do utilizador (Se o utilizador não tiver um @utilizador, o seu nome será usado em vez disso, para evitar é melhor usar isso com $name).',
['2'] = 'Ocorreu um erro ao formatar a mensagem, verifique a sintaxe de Markdown e tente novamente.',
['3'] = 'A mensagem de boas-vindas para %s foi atualizada com sucesso!'
},
['share'] = {
['1'] = 'Partilhar'
},
['shorten'] = {
['1'] = 'Selecione um URL shortener usando os botões abaixo:'
},
['shsh'] = {
['1'] = 'Eu não consegui obter qualquer blobs SHSH para esse ECID, assegure-se de que é válido e os guardou usando https://tsssaver.1conan.com.',
['2'] = 'Os blobs SHSH para esse dispositivo estão disponíveis para as seguintes versões do iOS:\n',
['3'] = 'Transferir .zip'
},
['statistics'] = {
['1'] = 'No messages have been sent in this chat!',
['2'] = '<b>Statistics for:</b> %s\n\n%s\n<b>Total messages sent:</b> %s',
['3'] = 'The statistics for this chat have been reset!',
['4'] = 'I could not reset the statistics for this chat. Perhaps they have already been reset?'
},
['steam'] = {
['1'] = 'O seu nome de utilizador do Steam foi definido para "%s".',
['2'] = '"%s" não é um nome de utilizador Steam valido.',
['3'] = '%s é utilizador do Steam desde %s, em %s. Desligou a ultima vez %s, em %s. Clique <a href="%s">aqui</a> para ver o perfil no Steam.',
['4'] = '%s, AKA "%s",'
},
['trust'] = {
['1'] = 'I cannot trust this user because they are a moderator or an administrator of this chat.',
['2'] = 'I cannot trust this user because they have already left this chat.',
['3'] = 'I cannot trust this user because they have already been kicked from this chat.'
},
['unmute'] = {
['1'] = 'Que utilizador gostaria que removesse silenciar? Pode especificar este utilizador pelo seu @utilizador ou ID numérico.',
['2'] = 'Não consigo remover silenciar a este utilizador porque não está atualmente silenciado neste grupo.',
['3'] = 'Não consigo remover silenciar a este utilizador porque ele é um moderador ou administrador neste grupo.',
['4'] = 'Não consigo remover silenciar a este utilizador porque ele já deixou (ou foi expulso) deste grupo.',
},
['untrust'] = {
['1'] = 'Which user would you like me to untrust? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot untrust this user because they are a moderator or an administrator in this chat.',
['3'] = 'I cannot untrust this user because they have already left this chat.',
['4'] = 'I cannot untrust this user because they have already been kicked from this chat.'
},
['upload'] = {
['1'] = 'Responda a mensagem do ficheiro que pretende transferir para o servidor. Deve ser <= 20 MB.',
['2'] = 'Ficheiro é demasiado grande. Deve ser <= 20 MB.',
['3'] = 'Não consegui obter esse ficheiro, é provavelmente muito antigo.',
['4'] = 'Ocorreu um erro ao recuperar esse ficheiro.',
['5'] = 'Ficheiro transferido para o servidor com sucesso - pode ser encontrado em <code>%s</code>!'
},
['voteban'] = {
['1'] = 'Qual utilizador gostaria de abrir uma votação para banir? Pode especificar este utilizador pelo seu @utilizador ou ID numérico.',
['2'] = 'Não consigo criar uma votação para este utilizador porque ele é um moderador ou administrador neste grupo.',
['3'] = 'Não consigo criar uma votação para este utilizador porque ele já deixaram (ou foi expulso) deste grupo.',
['4'] = '%s [%s] deve ser banido por %s? %s voto a favor para banir imediatamente, e %s votos contra para fechar esta votação.',
['5'] = 'Sim [%s]',
['6'] = 'Não [%s]',
['7'] = 'O povo falou. E baniu %s [%s] por %s porque %s pessoas votaram a favor.',
['8'] = 'O montante de votos a favor necessários foi atingido, no entanto, não foi pode banir %s - talvez deixou o grupo ou foi promovido desde que abrimos a votação para banir? É isso ou não tenho mais os privilégios administrativos necessários para executar esta ação!',
['9'] = 'O povo falou. E não foi banido %s [%s] por %s porque %s pessoa decidiram votar contra.',
['10'] = 'Votou a favor na decisão de banir %s [%s]!',
['11'] = 'O seu voto atual foi retirado, use os botões novamente para reenviar o seu voto.',
['12'] = 'Votou contra na decisão de banir %s [%s]!',
['13'] = 'A vote-ban has already been opened for this user!'
},
['weather'] = {
['1'] = 'Ainda não tem uma localização definida. Use /setloc <localização> para definir uma.',
['2'] = 'Está atualmente %s (parece %s) em %s. %s'
},
['welcome'] = {
['1'] = 'Group Rules'
},
- ['whitelist'] = {
+ ['allowlist'] = {
['1'] = 'Qual utilizador gostaria de adicionar a lista branca? Pode especificar este utilizador pelo seu @utilizador ou ID numérico.',
['2'] = 'Não consigo adicionar a lista branca esse utilizador porque ele é um moderador ou administrador neste grupo.',
['3'] = 'Não consigo adicionar a lista branca esse utilizador porque ele já deixou este grupo.',
['4'] = 'Não consigo adicionar a lista branca esse utilizador porque ele já foi banido neste grupo.'
},
['wikipedia'] = {
['1'] = 'Ver mais.'
},
['youtube'] = {
['1'] = 'Anterior',
['2'] = 'Seguinte',
['3'] = 'Está na pagina %s de %s!'
}
}
\ No newline at end of file
diff --git a/languages/scottish.lua b/languages/scottish.lua
index 3c2354f..59641bd 100644
--- a/languages/scottish.lua
+++ b/languages/scottish.lua
@@ -1,730 +1,730 @@
-- This is a language file for mattata
-- Language: scottish
-- Author: LKD70
-- DO NOT CHANGE ANYTHING THAT BEGINS OR ENDS WITH A %
-- THESE ARE PLACEHOLDERS!
-- DO NOT CHANGE ANY MARKDOWN/HTML FORMATTING!
-- IF YOU ARE UNSURE, ASK ON TELEGRAM (t.me/mattataDev)
return {
['errors'] = {
['connection'] = 'Connection mistak.',
['results'] = 'A coudna airt oot ony results for that.',
['supergroup'] = 'This commaund can anely be used in supergruips.',
['admin'] = 'Ye need tae be a moderator ore an administrator in thes tauk in maun tae use thes commaund.',
['unknown'] = 'A daena recognise that usar. If ye wud like tae lear me who thei be, forrit a message from them tae any tauk that Am in.',
['generic'] = 'A mistak occured!',
['use'] = 'You are not allowed to use this!',
['private'] = 'You can only use this command in private chat!'
},
['addcommand'] = {
['1'] = 'Please specify the command in the format <code>/command - description</code>',
['2'] = 'I couldn\'t retrieve my commands!',
['3'] = 'The command description can\'t be longer than 256 characters!',
['4'] = 'An unknown error occurred! I couldn\'t add your command!',
['5'] = 'Success! Command added.'
},
['addrule'] = {
['1'] = 'Please specify the rule you would like to add!',
['2'] = 'You don\'t have any rules to add to! Please set group rules using /setrules!',
['3'] = 'I couldn\'t add that rule, as it would make the length of the rules longer than Telegram\'s 4096 character limit!',
['4'] = 'I couldn\'t add that rule, it appears it contains invalid Markdown formatting!',
['5'] = 'Successfully updated the rules!'
},
['addslap'] = {
['1'] = 'You can only use this command in groups!',
['2'] = 'The slap cannot contain curly braces apart from placeholders!',
['3'] = 'The slap cannot be any longer than 256 characters in length!',
['4'] = 'I\'ve successfully added that slap as a possibility for /slap in this group!',
['5'] = 'You must include placeholders in your slap. Use {ME} for the person executing and {THEM} for the victim.'
},
['administration'] = {
['1'] = 'Enable Administration',
['2'] = 'Disable Administration',
['3'] = 'Anti-Spam Settings',
['4'] = 'Warning Settings',
['5'] = 'Vote-Ban Settings',
['6'] = 'Welcome New Users?',
['7'] = 'Send Rules On Join?',
['8'] = 'Send Rules In Group?',
['9'] = 'Back',
['10'] = 'Next',
['11'] = 'Word Filter',
['12'] = 'Anti-Bot',
['13'] = 'Anti-Link',
['14'] = 'Log Actions?',
['15'] = 'Anti-RTL',
['16'] = 'Anti-Spam Action',
['17'] = 'Ban',
['18'] = 'Kick',
['19'] = 'Delete Commands?',
['20'] = 'Force Group Language?',
['21'] = 'Send Settings In Group?',
['22'] = 'Delete Reply On Action?',
['23'] = 'Require Captcha?',
['24'] = 'Use Inline Captcha?',
['25'] = 'Ban SpamWatch-flagged users?',
['26'] = 'Number of warnings until %s:',
['27'] = 'Upvotes needed to ban:',
['28'] = 'Downvotes needed to dismiss:',
['29'] = 'Deleted %s, and its matching link from the database!',
['30'] = 'There were no entries found in the database matching "%s"!',
['31'] = 'You\'re not an administrator in that chat!',
['32'] = 'The minimum number of upvotes required for a vote-ban is %s.',
['33'] = 'The maximum number of upvotes required for a vote-ban is %s.',
['34'] = 'The minimum number of downvotes required for a vote-ban is %s.',
['35'] = 'The maximum number of downvotes required for a vote-ban is %s.',
['36'] = 'The maximum number of warnings is %s.',
['37'] = 'The minimum number of warnings is %s.',
['38'] = 'You can add one or more words to the word filter by using /filter <word(s)>',
['39'] = 'You will no longer be reminded that the administration plugin is disabled. To enable it, use /administration.',
['40'] = 'That\'s not a valid chat!',
['41'] = 'You don\'t appear to be an administrator in that chat!',
['42'] = 'My administrative functionality can only be used in groups/channels! If you\'re looking for help with using my administrative functionality, check out the "Administration" section of /help! Alternatively, if you wish to manage the settings for a group you administrate, you can do so here by using the syntax /administration <chat>.',
['43'] = 'Use the keyboard below to adjust the administration settings for <b>%s</b>:',
['44'] = 'Please send me a [private message](https://t.me/%s), so that I can send you this information.',
['45'] = 'I have sent you the information you requested via private chat.',
['46'] = 'Remove Channel Pins?',
['47'] = 'Remove Other Pins?',
['48'] = 'Remove Pasted Code?',
['49'] = 'Prevent Inline Bots?',
['50'] = 'Kick Media On Join?',
['51'] = 'Enable Plugins For Admins?',
['52'] = 'Kick URLs On Join?'
},
['afk'] = {
['1'] = 'Sorry, Am afraid thes feature is anely available tae usars with a public @usarname!',
['2'] = '%s has returned after being awa for %s!',
['3'] = 'Jot',
['4'] = '%s is now awa.%s'
},
['antispam'] = {
['1'] = 'Disable',
['2'] = 'Enable',
['3'] = 'Disable limit',
['4'] = 'Enable limits on %s',
['5'] = 'All Administration Settings',
['6'] = '%s [%s] has kicked %s [%s] from %s [%s] for hitting the configured anti-spam limit for [%s] media.',
['7'] = 'Kicked %s for hitting the configured antispam limit for [%s] media.',
['8'] = 'The maximum limit is 100.',
['9'] = 'The minimum limit is 1.',
['10'] = 'Modify the anti-spam settings for %s below:',
['11'] = 'Hey %s, if you\'re going to send code that is longer than %s characters in length, please do so using /paste in <a href="https://t.me/%s">private chat with me</a>!',
['12'] = '%s <code>[%s]</code> has %s %s <code>[%s]</code> from %s <code>[%s]</code> for sending Telegram invite link(s).\n#chat%s #user%s',
['13'] = '%s %s for sending Telegram invite link(s).',
- ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to whitelist it, use /whitelistlink <links>.',
+ ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to allowlist it, use /allowlink <links>.',
['15'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending media within their first few messages.\n#chat%s #user%s',
['16'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending a URL within their first few messages.\n#chat%s #user%s'
},
['appstore'] = {
['1'] = 'veu on iTunes',
['2'] = 'rating',
['3'] = 'ratings'
},
['authspotify'] = {
['1'] = 'You are already authorised using that account.',
['2'] = 'Authorising, please wait...',
['3'] = 'A connection error occured. Are you sure you replied with the correct link? It should look like',
['4'] = 'Successfully authorised your Spotify account!'
},
['avatar'] = {
['1'] = 'A coudna get the profile photaes for that usar, pleese mak siccar ye specified a valid usarname ore numerical ID.',
['2'] = 'That usar daesna have any profile photos.',
['3'] = 'That usar daesna have that many profile photaes!',
['4'] = 'That user has opted-out of data-collecting functionality, therefore I am not able to show you any of their profile photos.',
['5'] = 'User: %s\nPhoto: %s/%s\nSend /avatar %s [offset] to @%s to view a specific photo of this user',
['6'] = 'User: %s\nPhoto: %s/%s\nUse /avatar %s [offset] to view a specific photo of this user'
},
['ban'] = {
['1'] = 'Which usar wud ye like me tae ban? Ye can specify thes usar by thair @usarname ore numerical ID.',
['2'] = 'A cannae ban thes usar becawis thei be a moderator ore an administrator in thes tauk.',
['3'] = 'A cannae ban thes usar becawis thei have alrady left thes tauk.',
['4'] = 'A cannae ban thes usar becawis thei have alrady been banned from thes tauk.',
['5'] = 'A need tae have administrative permissions in maun tae ban thes usar. Pleese mend thes issue, and pree again.',
['6'] = '%s <code>[%s]</code> has banned %s <code>[%s]</code> from %s <code>[%s]</code>%s.\n%s %s',
['7'] = '%s has banned %s%s.'
},
['bash'] = {
['1'] = 'Pleese specify a commaund tae run!',
['2'] = 'Success!'
},
- ['blacklist'] = {
- ['1'] = 'Which usar wud ye like me tae blacklist? Ye can specify thes usar by thair @usarname ore numerical ID.',
- ['2'] = 'A cannae blacklist thes usar becawis thei be a moderator ore an administrator in thes tauk.',
- ['3'] = 'A cannae blacklist thes usar becawis thei have alrady left thes tauk.',
- ['4'] = 'A cannae blacklist thes usar becawis thei have alrady been banned from thes tauk.',
- ['5'] = '%s <code>[%s]</code> has blacklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
- ['6'] = '%s has blacklisted %s from using %s%s.'
- },
- ['blacklistchat'] = {
- ['1'] = '%s has now been blacklisted, and A will leave whenever A am added there!',
- ['2'] = '%s is a usar, thes commaund is anely for blacklisting tauks such as gruips and channels!',
+ ['blocklist'] = {
+ ['1'] = 'Which usar wud ye like me tae blocklist? Ye can specify thes usar by thair @usarname ore numerical ID.',
+ ['2'] = 'A cannae blocklist thes usar becawis thei be a moderator ore an administrator in thes tauk.',
+ ['3'] = 'A cannae blocklist thes usar becawis thei have alrady left thes tauk.',
+ ['4'] = 'A cannae blocklist thes usar becawis thei have alrady been banned from thes tauk.',
+ ['5'] = '%s <code>[%s]</code> has blocklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
+ ['6'] = '%s has blocklisted %s from using %s%s.'
+ },
+ ['blocklistchat'] = {
+ ['1'] = '%s has now been blocklisted, and A will leave whenever A am added there!',
+ ['2'] = '%s is a usar, thes commaund is anely for blocklisting tauks such as gruips and channels!',
['3'] = '%s daesna appeir tae be a valid tauk!'
},
['bugreport'] = {
['1'] = 'Success! Your bug report has been sent. The ID of thes report is #%s.',
['2'] = 'There was a problem whilst reporting that bug! Ha, the irony!'
},
['calc'] = {
['1'] = 'Click tae send the result.',
['2'] = '"%s" was an unexpected word!',
['3'] = 'You cannot have a unit before a number!'
},
['captionbotai'] = {
['1'] = 'A really cannae describe that picture!'
},
['cats'] = {
['1'] = 'Meow!'
},
['channel'] = {
['1'] = 'Ye be not allowed tae use thes!',
['2'] = 'Ye daena appeir tae be an administrator in that tauk anymore!',
['3'] = 'A coudna send yer message, be ye sure A still have permission tae send messages in that tauk?',
['4'] = 'Your message has been sent!',
['5'] = 'A was unable tae retrieve a list of administrators for that tauk!',
['6'] = 'Ye daena appeir tae be an administrator in that tauk!',
['7'] = 'Pleese specify the message tae send, using the syntax /channel <channel> <message>.',
['8'] = 'Are ye sure ye want tae send thes message? This is how it will look:',
['9'] = 'Yes, Am sure!',
['10'] = 'That message contains invalid Markdoun formatting! Pleese correct yer syntax and pree again.'
},
['chatroulette'] = {
['1'] = 'Hey! Please don\'t send messages longer than %s characters. We don\'t want to annoy the other user!',
['2'] = '*Anonymous said:*\n```\n%s\n```\nTo end your session, send /endchat.',
['3'] = 'I\'m afraid I lost connection from the other user! To begin a new chat, please send /chatroulette!',
['4'] = 'The other person you were chatting with has ended the session. To start a new one, send /chatroulette.',
['5'] = 'Successfully ended your session. To start a new one, send /chatroulette.',
['6'] = 'I have successfully removed you from the list of available users.',
['7'] = 'You don\'t have a session set up at the moment. To start one, send /chatroulette.',
['8'] = 'Finding you a session, please wait...',
['9'] = 'I\'m afraid there aren\'t any available users right now, but I have added you to the list of available users! To stop this completely, please send /endchat.',
['10'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.',
['11'] = 'I\'m afraid the user who I tried to pair you with has since blocked me. Please try and send /chatroulette again to try and connect to me!',
['12'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.'
},
['commandstats'] = {
['1'] = 'No commands have been sent in this chat!',
['2'] = '<b>Command statistics for:</b> %s\n\n%s\n<b>Total commands sent:</b> %s',
['3'] = 'The command statistics for this chat have been reset!',
['4'] = 'I could not reset the command statistics for this chat. Perhaps they have already been reset?'
},
['control'] = {
['1'] = 'Pfft, ye wish!',
['2'] = '%s is reloading...'
},
['copypasta'] = {
['1'] = 'The replied-to text musn\'t be any longer than %s characters!'
},
['coronavirus'] = {
['1'] = [[*COVID-19 Statistics for:* %s
*New confirmed cases:* %s
*Total confirmed cases:* %s
*New deaths:* %s
*Total deaths:* %s
*New recovered cases:* %s
*Total recovered cases:* %s]]
},
['counter'] = {
['1'] = 'A coudna add a cownter tae that message!'
},
['custom'] = {
['1'] = 'Success! That message will now be sent every time somebody uses %s!',
['2'] = 'The trigger "%s" does not exist!',
['3'] = 'The trigger "%s" has been deleted!',
['4'] = 'Ye daena have any custom triggers set!',
['5'] = 'Custom commands for %s:\n',
['6'] = 'To create a new, custom commaund, use the following syntax:\n/custom new #trigger <value>. tae list all current triggers, use /custom list. tae delete a trigger, use /custom del #trigger.'
},
['delete'] = {
['1'] = 'I could not delete that message. Perhaps the message is too old or non-existent?'
},
['demote'] = {
['1'] = 'Which usar wud ye like me tae demote? Ye can specify thes usar by thair @usarname ore numerical ID.',
['2'] = 'A cannae demote thes usar becawis thei be not a moderator ore an administrator in thes tauk.',
['3'] = 'A cannae demote thes usar becawis thei have alrady left thes tauk.',
['4'] = 'A cannae demote thes usar becawis thei have alrady been kicked from thes tauk.'
},
['doge'] = {
['1'] = 'Pleese enter the text ye want tae Doge-ify. Each sentence should be separated using slashes ore new lines.'
},
['donate'] = {
['1'] = '<b>Hello, %s!</b>\n\nIf you\'re feeling generous, you can contribute to the mattata project by making a monetary donation of any amount. This will go towards server costs and any time and resources used to develop mattata. This is an optional act, however it is greatly appreciated and your name will also be listed publically on mattata\'s GitHub page.\n\nIf you\'re still interested, you can donate <a href="https://paypal.me/wrxck">here</a>. Thank you for your continued support!'
},
['exec'] = {
['1'] = 'Pleese select the language ye wud like tae execute yer code in:',
['2'] = 'A mistak occured! The connection timed-out. Were ye preeing tae make me lag?',
['3'] = 'Ye have selected "%s" – be ye sure?',
['4'] = 'Back',
['5'] = 'Am sure',
['6'] = 'Pleese enter a snippet of code that ye wud like tae run. Ye daena need tae specify the language, we will do that afterwards!',
['7'] = 'Pleese select the language ye wud like tae execute yer code in:'
},
['facebook'] = {
['1'] = 'A mistak occured!',
['2'] = 'Pleese enter the name of the Facebook usar ye wud like tae get the profile picture of.',
['3'] = 'veu @%s on Facebook'
},
['fact'] = {
['1'] = 'Generate Another'
},
['fban'] = {
['1'] = 'Which user would you like me to Fed-ban? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot Fed-ban this user because they are a moderator or an administrator in this chat.'
},
['flickr'] = {
['1'] = 'Ye serched for:',
['2'] = 'Pleese enter a serch query (that is, what ye want me tae serch Flickr for, i.e. "Big Ben" will return a photograph of Big Ben in London).',
['3'] = 'More Results'
},
['game'] = {
['1'] = 'Total wyns: %s\nTotal losses: %s\nBalance: %s mattacoins',
['2'] = 'Join Gemm',
['3'] = 'This gemm has alrady ended!',
['4'] = 'It\'s not yer turn!',
['5'] = 'Ye be not part of thes gemm!',
['6'] = 'Ye cannae go here!',
['7'] = 'Ye be alrady part of thes gemm!',
['8'] = 'This gemm has alrady started!',
['9'] = '%s [%s] is playing against %s [%s]\nIt is currently %s\'s turn!',
['10'] = '%s won the gemm against %s!',
['11'] = '%s drew the gemm against %s!',
['12'] = 'Waiting for opponent...',
['13'] = 'Tic-Tac-Toe',
['14'] = 'Click tae send the gemm tae yer tauk!',
['15'] = 'Statistics for %s:\n',
['16'] = 'Play Tic-Tac-Toe!'
},
- ['gblacklist'] = {
- ['1'] = 'Pleese reply-to the usar ye\'d like tae globally blacklist, ore specify them by usarname/ID.',
+ ['gblocklist'] = {
+ ['1'] = 'Pleese reply-to the usar ye\'d like tae globally blocklist, ore specify them by usarname/ID.',
['2'] = 'A coudna get information about "%s", pleese check it\'s a valid usarname/ID and pree again.',
['3'] = 'That\'s a %s, not a usar!'
},
['gif'] = {
['1'] = 'Pleese enter a serch query (that is, what ye want me tae serch GIPHY for, i.e. "cat" will return a GIF of a cat).'
},
- ['gwhitelist'] = {
- ['1'] = 'Pleese reply-to the usar ye\'d like tae globally whitelist, ore specify them by usarname/ID.',
+ ['gallowlist'] = {
+ ['1'] = 'Pleese reply-to the usar ye\'d like tae globally allowlist, ore specify them by usarname/ID.',
['2'] = 'A coudna get information about "%s", pleese check it\'s a valid usarname/ID and pree again.',
['3'] = 'That\'s a %s, not a usar!'
},
['hackernews'] = {
['1'] = 'Top Stories from Hacker News:'
},
['help'] = {
['1'] = 'No results found!',
['2'] = 'There were no features found matching "%s", pleese pree and be more specific!',
['3'] = '\n\nArguments: <required> [optional]\n\nSerch for a feature ore get help with a commaund by using my inline serch functionality - just mention me in any tauk using the syntax @%s <serch query>.',
['4'] = 'Previous',
['5'] = 'Next',
['6'] = 'Back',
['7'] = 'Serch',
['8'] = 'Ye be on page %s of %s!',
['9'] = [[
A can perform many administrative actions in yer gruips, just add me as an administrator and send /administration tae adjust the settings for yer gruip.
Here be some administrative commands and a brief comment regarding what thei do:
• /pin <text> - Send a Markdoun-formatted message which can be edited by using the same commaund with different text, tae save ye from having tae re-pin a message if ye can't edit it (which happens if the message is older than 48 hours)
• /ban - Ban a usar by replying tae one of thair messages, ore by specifying them by usarname/ID
• /kick - Kick (ban and then unban) a usar by replying tae one of thair messages, ore by specifying them by usarname/ID
• /unban - Unban a usar by replying tae one of thair messages, ore by specifying them by usarname/ID
• /setrules <text> - Set the given Markdoun-formatted text as the gruip rules, which will be sent whenever somebody uses /rules
]],
['10'] = [[
• /setwelcome - Set the given Markdoun-formatted text as a welcome message that will be sent every time a usar joins yer gruip (the welcome message can be disabled in the administration menu, accessible via /administration). Ye can use placeholders tae automatically customise the welcome message for each usar. Use $usar\_id tae insert the usar's numerical ID, $chat\_id tae insert the tauk's numerical ID, $name tae insert the usar's name, $title tae insert the tauk title and $usarname tae insert the usar's usarname (if the usar doesn't have an @usarname, thair name will be used instead, so it is best tae avoid using thes with $name)
• /warn - Warn a usar, and ban them when thei hit the maximum number of warnings
• /mod - Promote the replied-to usar, giving them access tae administrative commands such as /ban, /kick, /warn etc. (this is useful when ye don't want somebody tae have the ability tae delete messages!)
• /demod - Demote the replied-to usar, stripping them from thair moderation status and revoking thair ability tae use administrative commands
• /staff - veu the gruip's creator, administrators, and moderators in a neatly-formatted list
]],
['11'] = [[
• /report - Forwards the replied-to message tae all administrators and alerts them of the current situation
• /setlink <URL> - Set the gruip's link tae the given URL, which will be sent whenever somebody uses /link
-• /links <text> - Whitelists all of the Telegram links found in the given text (includes @usarname links)
+• /links <text> - Allowlists all of the Telegram links found in the given text (includes @usarname links)
]],
['12'] = 'Below be some links ye might find useful:',
['13'] = 'Development',
['14'] = 'Channel',
['15'] = 'Support',
['16'] = 'FAQ',
['17'] = 'Source',
['18'] = 'Donate',
['19'] = 'Rate',
['20'] = 'Administration Log',
['21'] = 'Admin Settings',
['22'] = 'Plugins',
['23'] = [[
<b>Hi %s! My name's %s, it's a pleasure tae meet ye</b> %s
A understand many commands, which ye can learn more about by pressing the "Commands" button using the attached keyboard.
%s <b>Tip:</b> Use the "Settings" button tae change how A work%s!
%s <b>Find me useful, or just want to help?</b> Donations are very much appreciated, use /donate for more information!
]],
['24'] = 'in'
},
['id'] = {
['1'] = 'Am sorry, but A daena recognise that usar. tae lear me who thei be, forrit a message from them tae me ore get them tae send me a message.',
['2'] = 'Queried Chat:',
['3'] = 'This Chat:',
['4'] = 'Click tae send the result!'
},
['imdb'] = {
['1'] = 'Previous',
['2'] = 'Next',
['3'] = 'Ye be on page %s of %s!'
},
['import'] = {
['1'] = 'A daena recognise that tauk!',
['2'] = 'That\'s not a supergruip, therefore A cannae import any settings from it!',
['3'] = 'Successfully imported administrative settings & toggled plugins from %s tae %s!'
},
['info'] = {
['1'] = [[
```
Redis:
%s Config File: %s
%s Mode: %s
%s TCP Port: %s
%s Version: %s
%s Uptime: %s days
%s Process ID: %s
%s Expired Keys: %s
%s Usar Cownt: %s
%s Gruip Cownt: %s
System:
%s OS: %s
```
]]
},
['instagram'] = {
['1'] = '@%s on Instagram'
},
['ipsw'] = {
['1'] = '<b>%s</b> iOS %s\n\n<code>MD5 sum: %s\nSHA1 sum: %s\nFile size: %s GB</code>\n\n<i>%s %s</i>',
['2'] = 'This firmwhere is no longer being signed!',
['3'] = 'This firmwhere is still being signed!',
['4'] = 'Pleese select yer model:',
['5'] = 'Pleese select yer firmwhere version:',
['6'] = 'Pleese select yer device type:',
['7'] = 'iPod Touch',
['8'] = 'iPhone',
['9'] = 'iPad',
['10'] = 'Apple TV'
},
['ispwned'] = {
['1'] = 'That account was found in the following leaks:'
},
['itunes'] = {
['1'] = 'Name:',
['2'] = 'Artist:',
['3'] = 'Album:',
['4'] = 'Track:',
['5'] = 'Disc:',
['6'] = 'The original query could not be found, ye\'ve probably deleted the original message.',
['7'] = 'The artwork can be found below:',
['8'] = 'Pleese enter a serch query (that is, what ye want me tae serch iTunes for, i.e. "Green Day American Idiot" will return information about the first result for American Idiot by Green Day).',
['9'] = 'Get Album Artwork'
},
['kick'] = {
['1'] = 'Which usar wud ye like me tae keek? Ye can specify thes usar by thair @usarname ore numerical ID.',
['2'] = 'A cannae keek thes usar becawis thei be a moderator ore an administrator in thes tauk.',
['3'] = 'A cannae keek thes usar becawis thei have alrady left thes tauk.',
['4'] = 'A cannae keek thes usar becawis thei have alrady been keeked from thes tauk.',
['5'] = 'A need tae have administrative permissions in maun tae keek thes usar. Pleese amend thes issue, and pree again.'
},
['lastfm'] = {
['1'] = '%s\'s last.fm usarname has been set tae "%s".',
['2'] = 'Your last.fm usarname has been forgotten!',
['3'] = 'Ye daena currently have a last.fm usarname set!',
['4'] = 'Pleese specify yer last.fm usarname ore set it with /fmset.',
['5'] = 'No history was found for thes usar.',
['6'] = '%s is currently listening to:\n',
['7'] = '%s last listened to:\n',
['8'] = 'Unknown',
['9'] = 'Click tae send the result.'
},
['location'] = {
['1'] = 'Ye daena have a location set. What wud ye like yer new location tae be?'
},
['logchat'] = {
['1'] = 'Pleese enter the usarname ore numerical ID of the tauk ye wish tae log all administrative actions into.',
['2'] = 'Checking tae see whether that tauk is valid...',
['3'] = 'Am sorry, it appeirs ye\'ve either specified an invalid tauk, ore ye\'ve specified a tauk A haven\'t been added tae yet. Pleese rectify thes and pree again.',
['4'] = 'Ye can\'t set a usar as yer log tauk!',
['5'] = 'Ye daena appeir tae be an administrator in that tauk!',
['6'] = 'It seems Am alrady logging administrative actions into that tauk! Use /logchat tae specify a new one.',
['7'] = 'That tauk is valid, Am now going tae pree and send a test message tae it, just tae ensure A have permission tae post!',
['8'] = 'Hello, World - thes is a test message tae check my posting permissions - if ye\'re reading thes, then everything went OK!',
['9'] = 'All done! From now on, any administrative actions in thes tauk will be logged into %s - tae change the tauk ye want me tae log administrative actions into, just send /logchat.'
},
['lua'] = {
['1'] = 'Pleese enter a string of Lua tae execute!'
},
['lyrics'] = {
['1'] = 'Spotify',
['2'] = 'Show Lyrics',
['3'] = 'Pleese enter a serch query (that is, what song/artist/lyrics ye want me tae get lyrics for, i.e. "Green Day Basket Case" will return the lyrics for the song Basket Case by Green Day).'
},
['minecraft'] = {
['1'] = '<b>%s has changed his/her usarname %s time</b>',
['2'] = '<b>%s has changed his/her usarname %s times</b>',
['3'] = 'Previous',
['4'] = 'Next',
['5'] = 'Back',
['6'] = 'UUID',
['7'] = 'Avatar',
['8'] = 'Usarname History',
['9'] = 'Pleese select an option:',
['10'] = 'Pleese enter the usarname of the Minecraft player ye wud like tae view information about (i.e. sending "Notch" will view information about the player Notch).',
['11'] = 'Minecraft usarnames be between 3 and 16 characters long.'
},
['mute'] = {
['1'] = 'Which user would you like me to mute? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot mute this user because they are already muted in this chat.',
['3'] = 'I cannot mute this user because they are a moderator or an administrator in this chat.',
['4'] = 'I cannot mute this user because they have already left (or been kicked from) this chat.',
['5'] = 'I need to have administrative permissions in order to mute this user. Please amend this issue, and try again.'
},
['myspotify'] = {
['1'] = 'Profile',
['2'] = 'Following',
['3'] = 'Recently Played',
['4'] = 'Currently Playing',
['5'] = 'Top Tracks',
['6'] = 'Top Artists',
['7'] = 'You don\'t appear to be following any artists!',
['8'] = 'Your Top Artists',
['9'] = 'You don\'t appear to have any tracks in your library!',
['10'] = 'Your Top Tracks',
['11'] = 'You don\'t appear to be following any artists!',
['12'] = 'Artists You Follow',
['13'] = 'You don\'t appear to have recently played any tracks!',
['14'] = '<b>Recently Played</b>\n%s %s\n%s %s\n%s Listened to at %s:%s on %s/%s/%s.',
['15'] = 'The request has been accepted for processing, but the processing has not been completed.',
['16'] = 'You don\'t appear to be listening to anything right now!',
['17'] = 'Currently Playing',
['18'] = 'An error occured whilst re-authorising your Spotify account!',
['19'] = 'Successfully re-authorised your Spotify account! Processing your original request...',
['20'] = 'Re-authorising your Spotify account, please wait...',
['21'] = 'You need to authorise mattata in order to connect your Spotify account. Click [here](https://accounts.spotify.com/en/authorize?client_id=%s&response_type=code&redirect_uri=%s&scope=user-library-read,playlist-read-private,playlist-read-collaborative,user-read-private,user-read-email,user-follow-read,user-top-read,user-read-playback-state,user-read-recently-played,user-read-currently-playing,user-modify-playback-state) and press the green "OKAY" button to link mattata to your Spotify account. After you\'ve done that, send the link you were redirected to (it should begin with "%s", followed by a unique code) in reply to this message.',
['22'] = 'Playlists',
['23'] = 'Use Inline Mode',
['24'] = 'Lyrics',
['25'] = 'No devices were found.',
['26'] = 'You don\'t appear to have any playlists.',
['27'] = 'Your Playlists',
['28'] = '%s %s [%s tracks]',
['29'] = '%s %s [%s]\nSpotify %s user\n\n<b>Devices:</b>\n%s',
['30'] = 'Playing previous track...',
['31'] = 'You are not a premium user!',
['32'] = 'I could not find any devices.',
['33'] = 'Playing next track...',
['34'] = 'Resuming track...',
['35'] = 'Your device is temporarily unavailable...',
['36'] = 'No devices were found!',
['37'] = 'Pausing track...',
['38'] = 'Now playing',
['39'] = 'Shuffling your music...',
['40'] = 'That\'s not a valid volume. Please specify a number between 0 and 100.',
['41'] = 'The volume has been set to %s%%!',
['42'] = 'This message is using an old version of this plugin, please request a new one by sending /myspotify!'
},
['name'] = {
['1'] = 'The name A currently respond tae is "%s" - tae change thes, use /name <text> (where <text> is what ye want me tae respond to).',
['2'] = 'My new name needs tae be between 2 and 32 characters long!',
['3'] = 'My name may anely contain alphanumeric characters!',
['4'] = 'A will now respond tae "%s", instead of "%s" - tae change thes, use /name <text> (where <text> is what ye want me tae respond to).'
},
['netflix'] = {
['1'] = 'Read more.'
},
['news'] = {
['1'] = '"<code>%s</code>" isn\'t a valid Lua pattern.',
['2'] = 'A coudna retrieve a list of sources.',
['3'] = '<b>News sources found matching</b> "<code>%s</code>":\n\n%s',
['4'] = '<b>Here be the current available news sources ye can use with</b> /news<b>. Use</b> /nsources &lt;query&gt; <b>to serch the list of news sources for a more specific set of results. Serches be matched using Lua patterns</b>\n\n%s',
['5'] = 'Ye daena have a preferred news source. Use /setnews <source> tae set one. veu a list of sources using /nsources, ore narrow doun the results by using /nsources <query>.',
['6'] = 'Your current preferred news source is %s. Use /setnews <source> tae change it. veu a list of sources using /nsources, ore narrow doun the results by using /nsources <query>.',
['7'] = 'Your preferred source is alrady set tae %s! Use /news tae view the current top story.',
['8'] = 'That\'s not a valid news source. veu a list of sources using /nsources, ore narrow doun the results by using /nsources <query>.',
['9'] = 'Your preferred news source has been updated tae %s! Use /news tae view the current top story.',
['10'] = 'That\'s not a valid source, use /nsources tae view a list of available sources. If ye have a preferred source, use /setnews <source> tae automatically have news from that source sent when ye send /news, without any arguments needed.',
['11'] = 'Read more.'
},
['nick'] = {
['1'] = 'Your nickname has now been forgotten!',
['2'] = 'Your nickname has been set tae "%s"!'
},
['optout'] = {
['1'] = 'Ye have opted-in tae having data ye send collected! Use /optout tae opt-out.',
['2'] = 'Ye have opted-out of having data ye send collected! Use /optin tae opt-in.'
},
['paste'] = {
['1'] = 'Pleese select a service tae upload yer paste to:'
},
['pin'] = {
['1'] = 'You haven\'t set a pin before. Use /pin <text> to set one. Markdown formatting is supported.',
['2'] = 'Here is the last message generated using /pin.',
['3'] = 'I found an existing pin in the database, but the message I sent it in seems to have been deleted, and I can\'t find it anymore. You can set a new one with /pin <text>. Markdown formatting is supported.',
['4'] = 'There was an error whilst updating your pin. Either the text you entered contained invalid Markdown syntax, or the pin has been deleted. I\'m now going to try and send you a new pin, which you\'ll be able to find below - if you need to modify it then, after ensuring the message still exists, use /pin <text>.',
['5'] = 'I couldn\'t send that text because it contains invalid Markdown syntax.',
['6'] = 'Click here to see the pin, updated to contain the text you gave me.'
},
['pokedex'] = {
['1'] = 'Name: %s\nID: %s\nType: %s\nDescription: %s'
},
['promote'] = {
['1'] = 'A cannae promote thes usar becawis thei be a moderator ore an administrator of thes tauk.',
['2'] = 'A cannae promote thes usar becawis thei have alrady left thes tauk.',
['3'] = 'A cannae promote thes usar becawis thei have alrady been kicked from thes tauk.'
},
['quote'] = {
['1'] = 'This usar has opted out of data-storing functionality.',
['2'] = 'There be no saved quotes for %s%s! Ye can save one by using /save in reply tae a message thei send.'
},
['report'] = {
['1'] = 'Please reply to the message you would like to report to the group\'s administrators.',
['2'] = 'You can\'t report your own messages, are you just trying to be funny?',
['3'] = '<b>%s needs help in %s!</b>',
['4'] = 'Click here to view the reported message.',
['5'] = 'I\'ve successfully reported that message to %s admin(s)!'
},
['save'] = {
['1'] = 'This usar has opted out of data-storing functionality.',
['2'] = 'That message has been saved in my database, and added tae the list of possible responses for when /quote is used in reply tae %s%s!'
},
['sed'] = {
['1'] = '%s\n\n<i>%s didn\'t mean tae say thes!</i>',
['2'] = '%s\n\n<i>%s has admitted defeat.</i>',
['3'] = '%s\n\n<i>%s isn\'t sure if thei were mistaken...</i>',
['4'] = 'Screw ye, <i>when am A ever wrong?</i>',
['5'] = '"<code>%s</code>" isn\'t a valid Lua pattern.',
['6'] = '<b>Hi, %s, did ye mean:</b>\n<i>%s</i>',
['7'] = 'Yes',
['8'] = 'No',
['9'] = 'Not sure'
},
['setgrouplang'] = {
['1'] = 'This group\'s language has been set to %s!',
['2'] = 'This group\'s language is currently %s.\nPlease note that some strings may not be translated as of yet. If you\'d like to change your language, select one using the keyboard below:',
['3'] = 'The option to force users to use the same language in this group is currently disabled. This setting should be toggled from /administration but, to make things easier for you, I\'ve included a button below.',
['4'] = 'Enable',
['5'] = 'Disable'
},
['setlang'] = {
['1'] = 'Your language has been set tae %s!',
['2'] = 'Your language is currently %s.\nPleese note that some strings may not be translated as of yet. If ye\'d like tae change yer language, select one using the keyboard below:'
},
['setlink'] = {
['1'] = 'That\'s not a valid URL.',
['2'] = 'Link set successfully!'
},
['setrules'] = {
['1'] = 'Invalid Markdown formatting.',
['2'] = 'Successfully set the new rules!'
},
['setwelcome'] = {
['1'] = 'What wud ye like the welcome message tae be? The text ye specify will be Markdoun-formatted and sent every time a usar joins the tauk (the welcome message can be disabled in the administration menu, accessible via /administration). Ye can use placeholders tae automatically customise the welcome message for each usar. Use $usar_id tae insert the usar\'s numerical ID, $chat_id tae insert the tauk\'s numerical ID, $name tae insert the usar\'s name, $title tae insert the tauk\'s title and $usarname tae insert the usar\'s usarname (if the usar daesna have an @usarname, thair name will be used instead, so it is best tae avoid using thes in conjunction with $name).',
['2'] = 'There was a mistak formatting yer message, pleese check yer Markdoun syntax and pree again.',
['3'] = 'The welcome message for %s has successfully been updated!'
},
['share'] = {
['1'] = 'Shbe'
},
['shorten'] = {
['1'] = 'Pleese select a URL shortener using the buttons below:'
},
['shsh'] = {
['1'] = 'A coudna fetch any SHSH blobs for that ECID, pleese ensure it\'s valid and ye have saved them using https://tsssaver.1conan.com.',
['2'] = 'SHSH blobs for that device be available for the following versions of iOS:\n',
['3'] = 'Dounload .zip'
},
['statistics'] = {
['1'] = 'No messages have been sent in this chat!',
['2'] = '<b>Statistics for:</b> %s\n\n%s\n<b>Total messages sent:</b> %s',
['3'] = 'The statistics for this chat have been reset!',
['4'] = 'I could not reset the statistics for this chat. Perhaps they have already been reset?'
},
['steam'] = {
['1'] = 'Your Steam usarname has been set tae "%s".',
['2'] = '"%s" isn\'t a valid Steam usarname.',
['3'] = '%s has been a usar on Steam since %s, on %s. They last logged off at %s, on %s. Click <a href="%s">here</a> tae view thair Steam profile.',
['4'] = '%s, AKA "%s",'
},
['trust'] = {
['1'] = 'I cannot trust this user because they are a moderator or an administrator of this chat.',
['2'] = 'I cannot trust this user because they have already left this chat.',
['3'] = 'I cannot trust this user because they have already been kicked from this chat.'
},
['unmute'] = {
['1'] = 'Which user would you like me to unmute? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot unmute this user because they are not currently muted in this chat.',
['3'] = 'I cannot unmute this user because they are a moderator or an administrator in this chat.',
['4'] = 'I cannot unmute this user because they have already left (or been kicked from) this chat.'
},
['untrust'] = {
['1'] = 'Which user would you like me to untrust? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot untrust this user because they are a moderator or an administrator in this chat.',
['3'] = 'I cannot untrust this user because they have already left this chat.',
['4'] = 'I cannot untrust this user because they have already been kicked from this chat.'
},
['upload'] = {
['1'] = 'Pleese reply tae the file ye\'d like tae dounload tae the server. It must be <= 20 MB.',
['2'] = 'That file is too large. It must be <= 20 MB.',
['3'] = 'A coudna get thes file, it\'s probably too old.',
['4'] = 'There was a mistak whilst retrieving thes file.',
['5'] = 'Successfully dounloaded the file tae the server - it can be found at <code>%s</code>!'
},
['voteban'] = {
['1'] = 'Which user would you like to open up a vote-ban for? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot setup a vote-ban for this user because they are a moderator or an administrator in this chat.',
['3'] = 'I cannot setup a vote-ban for this user because they have already left (or been kicked from) this chat.',
['4'] = 'Should %s [%s] be banned from %s? %s upvotes are required for an immediate ban, and %s downvotes are required for this vote to be closed.',
['5'] = 'Yes [%s]',
['6'] = 'No [%s]',
['7'] = 'The people have spoken. I have banned %s [%s] from %s because %s people voted for me to do so.',
['8'] = 'The required upvote amount was reached, however, I was unable to ban %s - perhaps they\'ve left the group or been promoted since we opened the vote to ban them? It\'s either that, or I no longer have the administrative privileges required in order to perform this action!',
['9'] = 'The people have spoken. I haven\'t banned %s [%s] from %s because the required %s people downvoted the decision to ban them.',
['10'] = 'You upvoted the decision to ban %s [%s]!',
['11'] = 'Your current vote has been retracted, use the buttons again to re-submit your vote.',
['12'] = 'You downvoted the decision to ban %s [%s]!',
['13'] = 'A vote-ban has already been opened for this user!'
},
['weather'] = {
['1'] = 'Ye daena have a location set. Use /setloc <location> tae set one.',
['2'] = 'It\'s currently %s (feels like %s) in %s. %s'
},
['welcome'] = {
['1'] = 'Group Rules'
},
- ['whitelist'] = {
- ['1'] = 'Which user would you like me to whitelist? You can specify this user by their @username or numerical ID.',
- ['2'] = 'I cannot whitelist this user because they are a moderator or an administrator in this chat.',
- ['3'] = 'I cannot whitelist this user because they have already left this chat.',
- ['4'] = 'I cannot whitelist this user because they have already been banned from this chat.'
+ ['allowlist'] = {
+ ['1'] = 'Which user would you like me to allowlist? You can specify this user by their @username or numerical ID.',
+ ['2'] = 'I cannot allowlist this user because they are a moderator or an administrator in this chat.',
+ ['3'] = 'I cannot allowlist this user because they have already left this chat.',
+ ['4'] = 'I cannot allowlist this user because they have already been banned from this chat.'
},
['wikipedia'] = {
['1'] = 'Read more.'
},
['youtube'] = {
['1'] = 'Previous',
['2'] = 'Next',
['3'] = 'Ye be on page %s of %s!'
}
}
\ No newline at end of file
diff --git a/languages/tr_tr.lua b/languages/tr_tr.lua
index c15a186..7dd33a8 100644
--- a/languages/tr_tr.lua
+++ b/languages/tr_tr.lua
@@ -1,730 +1,730 @@
-- This is a language file for mattata
-- Language: tr-tr
-- Author: By_Azade
-- DO NOT CHANGE ANYTHING THAT BEGINS OR ENDS WITH A %
-- THESE ARE PLACEHOLDERS!
-- DO NOT CHANGE ANY MARKDOWN/HTML FORMATTING!
-- IF YOU ARE UNSURE, ASK ON TELEGRAM (t.me/mattataDev)
return {
['errors'] = {
['connection'] = 'Bağlantı Hatası',
['results'] = 'Bunun için herhangi bir sonuç bulamadım.',
['supergroup'] = 'Bu komut sadece grupta kullanılır.',
['admin'] = 'Bu komutu kullanabilmeniz için grupta admin veya moderatör olmalısınız.',
['unknown'] = 'Bu kullanıcıyı tanımıyorum. Eğer onu bana tanıtmak isterseniz, mesajını bana yönlendirin.',
['generic'] = 'Hata oluştu!',
['use'] = 'Bunu kullanmanıza izi yok!',
['private'] = 'You can only use this command in private chat!'
},
['addcommand'] = {
['1'] = 'Please specify the command in the format <code>/command - description</code>',
['2'] = 'I couldn\'t retrieve my commands!',
['3'] = 'The command description can\'t be longer than 256 characters!',
['4'] = 'An unknown error occurred! I couldn\'t add your command!',
['5'] = 'Success! Command added.'
},
['addrule'] = {
['1'] = 'Please specify the rule you would like to add!',
['2'] = 'You don\'t have any rules to add to! Please set group rules using /setrules!',
['3'] = 'I couldn\'t add that rule, as it would make the length of the rules longer than Telegram\'s 4096 character limit!',
['4'] = 'I couldn\'t add that rule, it appears it contains invalid Markdown formatting!',
['5'] = 'Successfully updated the rules!'
},
['addslap'] = {
['1'] = 'You can only use this command in groups!',
['2'] = 'The slap cannot contain curly braces apart from placeholders!',
['3'] = 'The slap cannot be any longer than 256 characters in length!',
['4'] = 'I\'ve successfully added that slap as a possibility for /slap in this group!',
['5'] = 'You must include placeholders in your slap. Use {ME} for the person executing and {THEM} for the victim.'
},
['administration'] = {
['1'] = 'Enable Administration',
['2'] = 'Disable Administration',
['3'] = 'Anti-Spam Settings',
['4'] = 'Warning Settings',
['5'] = 'Vote-Ban Settings',
['6'] = 'Welcome New Users?',
['7'] = 'Send Rules On Join?',
['8'] = 'Send Rules In Group?',
['9'] = 'Back',
['10'] = 'Next',
['11'] = 'Word Filter',
['12'] = 'Anti-Bot',
['13'] = 'Anti-Link',
['14'] = 'Log Actions?',
['15'] = 'Anti-RTL',
['16'] = 'Anti-Spam Action',
['17'] = 'Ban',
['18'] = 'Kick',
['19'] = 'Delete Commands?',
['20'] = 'Force Group Language?',
['21'] = 'Send Settings In Group?',
['22'] = 'Delete Reply On Action?',
['23'] = 'Require Captcha?',
['24'] = 'Use Inline Captcha?',
['25'] = 'Ban SpamWatch-flagged users?',
['26'] = 'Number of warnings until %s:',
['27'] = 'Upvotes needed to ban:',
['28'] = 'Downvotes needed to dismiss:',
['29'] = 'Deleted %s, and its matching link from the database!',
['30'] = 'There were no entries found in the database matching "%s"!',
['31'] = 'You\'re not an administrator in that chat!',
['32'] = 'The minimum number of upvotes required for a vote-ban is %s.',
['33'] = 'The maximum number of upvotes required for a vote-ban is %s.',
['34'] = 'The minimum number of downvotes required for a vote-ban is %s.',
['35'] = 'The maximum number of downvotes required for a vote-ban is %s.',
['36'] = 'The maximum number of warnings is %s.',
['37'] = 'The minimum number of warnings is %s.',
['38'] = 'You can add one or more words to the word filter by using /filter <word(s)>',
['39'] = 'You will no longer be reminded that the administration plugin is disabled. To enable it, use /administration.',
['40'] = 'That\'s not a valid chat!',
['41'] = 'You don\'t appear to be an administrator in that chat!',
['42'] = 'My administrative functionality can only be used in groups/channels! If you\'re looking for help with using my administrative functionality, check out the "Administration" section of /help! Alternatively, if you wish to manage the settings for a group you administrate, you can do so here by using the syntax /administration <chat>.',
['43'] = 'Use the keyboard below to adjust the administration settings for <b>%s</b>:',
['44'] = 'Please send me a [private message](https://t.me/%s), so that I can send you this information.',
['45'] = 'I have sent you the information you requested via private chat.',
['46'] = 'Remove Channel Pins?',
['47'] = 'Remove Other Pins?',
['48'] = 'Remove Pasted Code?',
['49'] = 'Prevent Inline Bots?',
['50'] = 'Kick Media On Join?',
['51'] = 'Enable Plugins For Admins?',
['52'] = 'Kick URLs On Join?'
},
['afk'] = {
['1'] = 'Üzgünüm, Bu özellik sadece aktif kullanıcılar için @kullanıcıadı şeklinde kullanılır!',
['2'] = '%s klavyeden uzaklaşarak tekrar geri döndü %s!',
['3'] = 'Not',
['4'] = '%s şuan klavyeden uzaklaştı.%s'
},
['antispam'] = {
['1'] = 'Kapalı',
['2'] = 'Açık',
['3'] = 'Sınırı devre dışı bırak',
['4'] = 'Sınırları etkinleştir %s',
['5'] = 'Tüm Yönetim Ayarları',
['6'] = '%s [%s] Anti-spam medya limitine ulaşıldığı %s [%s] için %s [%s] gruptan atıldı [%s] .',
['7'] = 'Atıldı %s anti-spam medya limitini aştığı için [%s] .',
['8'] = 'Maksimum sınır 100.',
['9'] = 'Minimum sınır is 1.',
['10'] = 'Aşağıdan %s anti-spam ayarlarını değiştirin:',
['11'] = 'Hey %s, if you\'re going to send code that is longer than %s characters in length, please do so using /paste in <a href="https://t.me/%s">private chat with me</a>!',
['12'] = '%s <code>[%s]</code> has %s %s <code>[%s]</code> from %s <code>[%s]</code> for sending Telegram invite link(s).\n#chat%s #user%s',
['13'] = '%s %s for sending Telegram invite link(s).',
- ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to whitelist it, use /whitelistlink <links>.',
+ ['14'] = 'Hey, I noticed you\'ve got anti-link enabled and you\'re currently not allowing your users to mention a chat you\'ve just mentioned, if you\'d like to allowlist it, use /allowlink <links>.',
['15'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending media within their first few messages.\n#chat%s #user%s',
['16'] = 'Kicked %s <code>[%s]</code> from %s <code>[%s]</code> for sending a URL within their first few messages.\n#chat%s #user%s'
},
['appstore'] = {
['1'] = 'iTunes de görüntüle',
['2'] = 'rating',
['3'] = 'ratings'
},
['authspotify'] = {
['1'] = 'You are already authorised using that account.',
['2'] = 'Authorising, please wait...',
['3'] = 'A connection error occured. Are you sure you replied with the correct link? It should look like',
['4'] = 'Successfully authorised your Spotify account!'
},
['avatar'] = {
['1'] = 'Bu kullanıcı için profil fotoğraflarını alamadım, lütfen geçerli bir kullanıcı adı veya sayısal kimlik belirttiğinizden emin olun.',
['2'] = 'Bu kullanıcının profil fotoğrafı yok..',
['3'] = 'Bu kullanıcının pek çok profil fotoğrafı yok!',
['4'] = 'Bu kullanıcı, veri toplama işlevini devre dışı bıraktı, bu nedenle profil fotoğraflarından hiçbirini size gösteremiyorum.',
['5'] = 'User: %s\nPhoto: %s/%s\nSend /avatar %s [offset] to @%s to view a specific photo of this user',
['6'] = 'User: %s\nPhoto: %s/%s\nUse /avatar %s [offset] to view a specific photo of this user'
},
['ban'] = {
['1'] = 'Hangi kullanıcı banlamamı istersiniz? Bu kullanıcıyı @kulanıcıadı şeklinde veya kullanıcı IDsi ile belirtebilirsin.',
['2'] = 'Bu kullanıcıyı, bu sohbette bir moderatör veya yönetici oldukları için banlayamam.',
['3'] = 'Bu sohbetten ayrıldığı için bu kullanıcıyı banyalamam.',
['4'] = 'Bu sohbetten zaten banlandıkları için bu kullanıcıyı banlayamam.',
['5'] = 'Bu kullanıcıyı banlamam için admin izinlerine sahip olmam gerekiyor. Lütfen bu sorunu düzeltip tekrar deneyin.',
['6'] = '%s <code>[%s]</code> has banned %s <code>[%s]</code> from %s <code>[%s]</code>%s.\n%s %s',
['7'] = '%s has banned %s%s.'
},
['bash'] = {
['1'] = 'Lütfen çalıştırılacak bir komut belirtin!',
['2'] = 'Başarılı!'
},
- ['blacklist'] = {
+ ['blocklist'] = {
['1'] = 'Hangi kullanıcıyı kara listeye almamı istersiniz?? Bu kullanıcıyı @kulanıcıadı şeklinde veya kullanıcı IDsi ile belirtebilirsin.',
['2'] = 'Bu kullanıcıyı, bu sohbette bir moderatör veya yönetici oldukları için kara listeye alamam.',
['3'] = 'Bu sohbetten ayrıldığı için bu kullanıcıyı kara listeye alamam.',
['4'] = 'Bu sohbetten banlandığı için bu kullanıcıyı kara listeye alamam.',
- ['5'] = '%s <code>[%s]</code> has blacklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
- ['6'] = '%s has blacklisted %s from using %s%s.'
+ ['5'] = '%s <code>[%s]</code> has blocklisted %s <code>[%s]</code> from using %s <code>[%s]</code> in %s <code>[%s]</code>%s.\n%s %s',
+ ['6'] = '%s has blocklisted %s from using %s%s.'
},
- ['blacklistchat'] = {
+ ['blocklistchat'] = {
['1'] = '%s şimdi kara listeye alındı!',
['2'] = '%s bir kullanıcıysa, bu komut sadece gruplar ve kanallar gibi sohbetleri kara listeye almak için kullanılır!',
['3'] = '%s Geçerli bir sohbet gibi gözükmüyor!'
},
['bugreport'] = {
['1'] = 'Başarılı! Hata raporunuz gönderilmiştir. Bu raporun kimliği #%s.',
['2'] = 'Bu hatayı bildirirken bir sorun oluştu! Ha, ironi!'
},
['calc'] = {
['1'] = 'Sonuç göndermek için tıklayın.',
['2'] = '"%s" was an unexpected word!',
['3'] = 'You cannot have a unit before a number!'
},
['captionbotai'] = {
['1'] = 'Bu resmi gerçekten tarif edemiyorum!'
},
['cats'] = {
['1'] = 'Miyavvv!'
},
['channel'] = {
['1'] = 'Bunu kullanmanıza izin verilmiyor!',
['2'] = 'Bu sohbette artık yönetici gibi görünmüyorsunuz!',
['3'] = 'Mesajınızı gönderemedim, hala sohbet mesajı gönderme iznim var mı?',
['4'] = 'Mesajınız gönderildi!',
['5'] = 'Sohbet yöneticilerinin listesini alamadım!',
['6'] = 'Sohbette bir yönetici gibi görünmüyorsun!',
['7'] = 'Lütfen, gönderilecek mesajı /channel <kanal> <mesaj> sözdizimini kullanarak belirtin.',
['8'] = 'Bu mesajı göndermek istediğinizden emin misiniz? Nasıl görüneceği ise şöyledir:',
['9'] = 'Evet eminim!',
['10'] = 'Bu mesaj geçersiz Markdown biçimlendirme içeriyor! Lütfen sözdiziminizi düzeltin ve tekrar deneyin.'
},
['chatroulette'] = {
['1'] = 'Hey! Please don\'t send messages longer than %s characters. We don\'t want to annoy the other user!',
['2'] = '*Anonymous said:*\n```\n%s\n```\nTo end your session, send /endchat.',
['3'] = 'I\'m afraid I lost connection from the other user! To begin a new chat, please send /chatroulette!',
['4'] = 'The other person you were chatting with has ended the session. To start a new one, send /chatroulette.',
['5'] = 'Successfully ended your session. To start a new one, send /chatroulette.',
['6'] = 'I have successfully removed you from the list of available users.',
['7'] = 'You don\'t have a session set up at the moment. To start one, send /chatroulette.',
['8'] = 'Finding you a session, please wait...',
['9'] = 'I\'m afraid there aren\'t any available users right now, but I have added you to the list of available users! To stop this completely, please send /endchat.',
['10'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.',
['11'] = 'I\'m afraid the user who I tried to pair you with has since blocked me. Please try and send /chatroulette again to try and connect to me!',
['12'] = 'I have successfully paired you with another user to chat to! Please remember to be kind to them! To end the chat, send /endchat.'
},
['commandstats'] = {
['1'] = 'Bu sohbette hiçbir komut gönderilmedi!',
['2'] = '<b>Komut için istatistikler:</b> %s\n\n%s\n<b>Toplam göderilen komutlar:</b> %s',
['3'] = 'Bu sohbetin komut istatistikleri sıfırlandı!',
['4'] = 'Bu sohbetin komut istatistiklerini sıfırlayamadım. Belki de daha önce sıfırlanmışlardır?'
},
['control'] = {
['1'] = 'Pfft, dilersen!',
['2'] = '%s Yeniden yükleniyor...'
},
['copypasta'] = {
['1'] = 'Yanıtlanan metin, %s karakterlerden uzun olmamalıdır.!'
},
['coronavirus'] = {
['1'] = [[*COVID-19 Statistics for:* %s
*New confirmed cases:* %s
*Total confirmed cases:* %s
*New deaths:* %s
*Total deaths:* %s
*New recovered cases:* %s
*Total recovered cases:* %s]]
},
['counter'] = {
['1'] = 'Bu mesaja sayaç ekleyemedim!'
},
['custom'] = {
['1'] = 'Başarılı! Bu mesaj şimdi birileri her kullandığı zaman gönderilecek %s!',
['2'] = 'Tetikleyici "%s" yok!',
['3'] = 'Tetikleyici "%s" silindi!',
['4'] = 'Herhangi bir özel tetikleyici ayarlamadın!',
['5'] = 'Özel komutlar %s:\n',
['6'] = 'Yeni ve özel bir komut oluşturmak için şu sözdizimini kullanın:\n/custom new #tetikleyici <değer>.Tüm tetikleyiciler listesi için, /custom list komutunu kullanın. Tetikleyiciyi silmek için ise, /custom del #trigger komutunu kullanın.'
},
['delete'] = {
['1'] = 'Bu mesajı silemedim. Belki de mesaj çok eskidir veya mevcut değildir?'
},
['demote'] = {
['1'] = 'Hangi kullanıcının yetkisini almamı istersin ? Bu kullanıcıyı @kulanıcıadı şeklinde veya kullanıcı IDsi ile belirtebilirsin.',
['2'] = 'Bu kullanıcıyı, bu sohbette bir moderatör veya yönetici olmadığı için yetkisini almam mümkün değil.',
['3'] = 'Bu sohbetten zaten ayrıldıı, bu kullanıcının yetkisini alamam.',
['4'] = 'Bu kullanıcı daha önce bu sohbetten atılmış ulduğu için yetkisini almam mümkün değil.'
},
['doge'] = {
['1'] = 'Lütfen Dogeify istediğiniz metni girin. Her cümle eğik çizgi veya yeni satırlar kullanılarak ayrılmalıdır.'
},
['donate'] = {
['1'] = '<b>Hello, %s!</b>\n\nIf you\'re feeling generous, you can contribute to the mattata project by making a monetary donation of any amount. This will go towards server costs and any time and resources used to develop mattata. This is an optional act, however it is greatly appreciated and your name will also be listed publically on mattata\'s GitHub page.\n\nIf you\'re still interested, you can donate <a href="https://paypal.me/wrxck">here</a>. Thank you for your continued support!'
},
['exec'] = {
['1'] = 'Lütfen kodunuzu yürütmek istediğiniz dili seçin:',
['2'] = 'Bir hata oluştu! Bağlantı zaman aşımına uğradı. Beni geride bırakmaya mı çalışıyordun?',
['3'] = 'Seçtiniz "%s" – emin misin?',
['4'] = 'Geri',
['5'] = 'Eminim',
['6'] = 'Çalıştırmak istediğiniz kod parçacığını yazınız.Dili belirtmeniz gerekmiyor, bunu daha sonra yapacağız!',
['7'] = 'Lütfen kodunuzu yürütmek istediğiniz dili seçin:'
},
['facebook'] = {
['1'] = 'Bir hata oluştu!',
['2'] = 'Lütfen profil resmini almak istediğiniz Facebook kullanıcısının adını girin.',
['3'] = 'Facebook da %s görüntüle'
},
['fact'] = {
['1'] = 'Başka Bir Tane Oluştur'
},
['fban'] = {
['1'] = 'Which user would you like me to Fed-ban? You can specify this user by their @username or numerical ID.',
['2'] = 'I cannot Fed-ban this user because they are a moderator or an administrator in this chat.'
},
['flickr'] = {
['1'] = 'Aradığınız:',
['2'] = 'Lütfen bir arama sorgusu girin (Yani, Flickrı aramamı ne için istiyorsun, Örnek: "Kalem" kalem fotoğragları gösterilecek).',
['3'] = 'Daha fazla sonuç'
},
['game'] = {
['1'] = 'Toplam kazanç: %s\nToplam kayıp: %s\nKalan: %s mattacoins',
['2'] = 'Oyuna Katıl',
['3'] = 'Bu oyun zaten bitti!',
['4'] = 'Senin sıran değil!',
['5'] = 'Bu oyunun bir parçası değilsin!',
['6'] = 'Bu oyuna giremezsiniz!',
['7'] = 'Zaten bu oyunun bir parçasısın!',
['8'] = 'Bu oyun zaten başladı!',
['9'] = '%s [%s] e karşı oynuyor %s [%s]\nŞuanda by %s\'s senin sıran!',
['10'] = '%s e karşı oyunu kazandı %s!',
['11'] = '%s e karşı oyundan çekildi %s!',
['12'] = 'Rakip bekleniyor...',
['13'] = 'Tic-Tac-Toe',
['14'] = 'Oyunu sohbete göndermek için tıklayın!',
['15'] = 'Oyun istatistiği %s:\n',
['16'] = 'Tic-Tac-Toe oyna!'
},
- ['gblacklist'] = {
+ ['gblocklist'] = {
['1'] = 'Lütfen genel kara listeye eklemek istediğiniz kullanıcıyı yanıtlayın veya kullanıcı adı veya kimlik numarasına göre belirtin.',
['2'] = 'Hakkında bilgi alamadım "%s", lütfen geçerli bir kullanıcı adı veya kimliğini kontrol edin ve tekrar deneyin.',
['3'] = 'Bu bir %s kullanıcı değil'
},
['gif'] = {
['1'] = 'Lütfen bir arama sorgusu girin (GIPHY de ne aramak istediğini belirt , örnek: "kedi" kedi ile ilgili olan GIF ler gösterilecek).'
},
- ['gwhitelist'] = {
+ ['gallowlist'] = {
['1'] = 'Lütfen genel olarak beyaz listeye eklemek isteyen kullanıcıyı yanıtlayın, kullanıcı adı veya kimlik numarasına göre belirtin.',
['2'] = 'Hakkında bilgi alamadım "%s", lütfen geçerli bir kullanıcı adı veya kimliğini kontrol edin ve tekrar deneyin.',
['3'] = 'Bu bir %s kullanıcı değil'
},
['hackernews'] = {
['1'] = 'Hacker Haberlerinden En Çok Okunan Hikayeler:'
},
['help'] = {
['1'] = 'Sonuç bulunamadı!',
['2'] = '"%s" ile eşleşen hiçbir özellik bulunamadı, lütfen daha spesifik olmaya çalışın ve deneyin.!',
['3'] = '\n\nDeğişken: <required> [opsiyonel]\n\nSatır içi arama işlevselliğini kullanarak bir özellik arayın veya bir komutla yardım alın - @%s <arama sorgusu> sözdizimini kullanarak herhangi bir sohbetten bahsedin.',
['4'] = 'Önceki',
['5'] = 'Sonraki',
['6'] = 'Geri',
['7'] = 'Ara',
['8'] = '%s sayfanın %s sayfasındasın',
['9'] = [[
Gruplarınızda birçok idari işlem yapabilirim, Beni yönetici olarak eklemelisin ve grubunuzun ayarlarını yapmak için /administrator komutunu göndermelisin.
İşte bazı idari komutlar ve yaptıklarıyla ilgili kısa bir açıklama:
• /pin <yazı> - Aynı komutla farklı metni kullanarak düzenlenebilen Markdown formatlı bir mesaj gönderin, Bir mesajı düzenleyemiyorsanız bundan kurtulmak için yeniden sabitlemeniz gerekmez (Mesaj 48 saatten fazla sabit kalamaz)
• /ban - Bir kullanıcıyı, mesajlarından birine yanıt vererek veya kullanıcı adı / kimlik numarasıyla belirterek banla
• /kick - Bir kullanıcıyı mesajlarından birine yanıt vererek veya kullanıcı adı / kimlik numarasıyla belirterek bir kullanıcıyı banlayın (aynı şekilde unban komutu)
• /unban - Bir kullanıcıyı mesajlarından birine yanıt vererek veya kullanıcı adı / kimlik numarasıyla belirterek bir kullanıcının banını kaldırın
• /setrules <yazı> - Verilen Markdown formatlı metni, birisi kullandığı zaman gönderilecek olan grup kuralları olarak ayarlayın, /rules komutunu kullanarak
]],
['10'] = [[
• /setwelcome - Kullanıcının gruba katıldığı her zaman gösterilecek olan bir hoş geldin mesajı belirtin. (hoş geldin mesajı admin menüsünden kapalı olabilir, /administration komutu ile kontrol edin). Her kullanıcı için hoş geldiniz mesajını otomatik olarak özelleştirmek için yer tutucularını kullanabilirsiniz. Kullanıcının sayısal kimliğini eklemek için $user_id kullanın,sohbetin sayısal kimliğini eklemek için $chat_id, kullanıcının adını eklemek için $name, grubun ismini eklemek için $title ve kullanıcının kullanıcı adını eklemek için $username (eğer kullanıcının kullanıcı adı (@kullanıcıadı) yoksa, bunun yerine isimleri kullanılacak, bu yüzden $name ile birlikte kullanılmamalıdır.)
• /warn - Bir kullanıcıyı uyarmak ve maksimum uyarı sayısına ulaştığında onları banlamak için kullanılır
• /mod - Yanıtlanan kullanıcıya moderatör yetkisi verir, /ban, /kick, /warn vb komutları kullanabilir.(Bu, birisinin mesajlarını silmeyi istemiyorsanız kullanışlıdır!)
• /demod - Yanıtlanan kullanıcınn moderatör yetkisini alır, moderatör komutlarını kullanamaz.
• /staff - Grubun kurucusunu, adminlerini, ve moderatörlerinin listesini gösterir.
]],
['11'] = [[
• /report - Yanıtlanan mesajı direk olarak admine rapor edip yönderir.
• /setlink <URL> - Grubun bağlantısını verilen URL'yi ayarlayın; /link bu komutu, biri kullanıldığında URL gönderilir.
• /links <yazı> - Verilen metinde bulunan tüm Telegram bağlantılarını beyaz listeye ekler ( @kullanıcıadı şeklinde olanları da)
]],
['12'] = 'Aşağıda yararlı bulabileceğiniz bazı bağlantılar verilmiştir.:',
['13'] = 'Geliştirme',
['14'] = 'Kanal',
['15'] = 'Destek',
['16'] = 'SSS',
['17'] = 'Kaynak',
['18'] = 'Bağışta bulunmak',
['19'] = 'Oylamak',
['20'] = 'Yönetim Günlüğü',
['21'] = 'Admin Ayarları',
['22'] = 'Eklentiler',
['23'] = [[
<b>Merhaba %s! Benim adım %s, sizinle tanışmak bir şeref idi</b> %s
Bir çok komutu anlıyorum, hangi komutu öğrenmek istiyorsan satır içinde "Komutlar" butonunu seçin.
%s <b>İpucu:</b> "Ayarlar" butonuna tıklayarak nasıl çalıştığımı öğrenin%s!
%s <b>Beni kullanışlı mı buldun, yoksa yardıma ihtiyaç mı var ?</b>Bağışlar çok takdir edilmektedir, /donate komutunu kullanarak daha fazla bilgi elde et!
]],
['24'] = 'içinde'
},
['id'] = {
['1'] = 'Üzgünüm ama o kullanıcıyı tanımıyorum. Bana kim olduğunu öğretmek istersen, onun bir measjını bana ilet.',
['2'] = 'Sorgulanan Sohbet:',
['3'] = 'Bu sohbet:',
['4'] = 'Sonuç göndermek için tıklayın!'
},
['imdb'] = {
['1'] = 'Önceki',
['2'] = 'Sonraki',
['3'] = '%s sayfanın %s sayfasındasın!'
},
['import'] = {
['1'] = 'Bu sohbeti tanımıyorum!',
['2'] = 'Bu bir supergroup değil, bu nedenle herhangi bir ayarları aktaramıyorum!',
['3'] = '%s dan %s adresinden yönetim ayarlarını ve geçiş yapmış eklentileri başarıyla içe aktardı.!'
},
['info'] = {
['1'] = [[
```
Dağıtım:
%s Yapılandırma Dosyası: %s
%s Mod: %s
%s TCP Port: %s
%s Versyon: %s
%s Çalışma süresi: %s days
%s Çalışma kimliği: %s
%s Süresi Dolmuş Anahtarlar: %s
%s Kullanıcı Sayısı: %s
%s Grup Sayısı: %s
Sistem:
%s İşletim sistemi: %s
```
]]
},
['instagram'] = {
['1'] = '@%s İnstagram'
},
['ipsw'] = {
['1'] = '<b>%s</b> iOS %s\n\n<code>MD5 toplamı: %s\nSHA1 toplamı: %s\nDosya boyutu: %s GB</code>\n\n<i>%s %s</i>',
['2'] = 'Bu yazılım artık imzalanmıyor!',
['3'] = 'Bu yazılım hala imzalanıyor!',
['4'] = 'Lütfen modelinizi seçin:',
['5'] = 'Lütfen bellenim sürümünüzü seçin:',
['6'] = 'Lütfen aygıt türünü seçin:',
['7'] = 'iPod Touch',
['8'] = 'iPhone',
['9'] = 'iPad',
['10'] = 'Apple TV'
},
['ispwned'] = {
['1'] = 'Bu hesap aşağıdaki sızıntılarda bulundu:'
},
['itunes'] = {
['1'] = 'İsim:',
['2'] = 'Sanatçı:',
['3'] = 'Albüm:',
['4'] = 'Parça:',
['5'] = 'Disk:',
['6'] = 'Orijinal sorgu bulunamadı, muhtemelen orijinal iletiyi silindiniz.',
['7'] = 'Sanat aşağıda bulunabilir:',
['8'] = 'Lütfen bir arama sorgusu girin (iTunes de aramak istediğin sorguyu gir, örnek: "Aykut Kuşkaya-Kaldırımlar" Aykut Kuşkaya - Kaldırımlar parçası aranacak.).',
['9'] = 'Albüm Kapağını Getir'
},
['kick'] = {
['1'] = 'Hangi kullanıcıyı gruptan atmak istersiniz? Bu kullanıcıyı @kulanıcıadı şeklinde veya kullanıcı IDsi ile belirtebilirsin.',
['2'] = 'Bu kullanıcıyı, bu sohbette bir moderatör veya yönetici olduğu için gruptan atamam.',
['3'] = 'Bu kullanıcıyı, bu sohbeden ayrıldığı için gruptan atamam.',
['4'] = 'Bu kullanıcıyı, bu sohbetten çoktan atıldıkları için gruptan atamam.',
['5'] = 'Bu kullanıcıyı gruptan atmak için admin izinlerine sahip olmam gerekiyor. Lütfen bu sorunu düzeltip tekrar deneyin.'
},
['lastfm'] = {
['1'] = '%s\'s last.fm kullanıcı adı ayarlandı "%s".',
['2'] = 'last.fm kullanıcı adın unutuldu!',
['3'] = 'Şu anda bir last.fm kullanıcı adınız yok!',
['4'] = 'Lütfen last.fm kullanıcı adınızı belirtin veya /fmset ile ayarlayın.',
['5'] = 'Bu kullanıcı için geçmiş bulunamadı.',
['6'] = '%s Şu anda bunu dinliyorsun:\n',
['7'] = '%s en son dinlenilen:\n',
['8'] = 'Bilinmeyen',
['9'] = 'Sonuç göndermek için tıklayın.'
},
['location'] = {
['1'] = 'Ayarlanmış konumunuz yok. Yeni konum ayarlamak ister misiniz?'
},
['logchat'] = {
['1'] = 'Lütfen tüm idari işlemleri kaydetmek istediğiniz sohbetin kullanıcı adını veya sayısal kimliğini girin.',
['2'] = 'Bu sohbetin geçerli olup olmadığını kontrol et...',
['3'] = 'Maalesef geçersiz bir sohbet belirttiniz veya henüz eklenmediğim bir sohbet belirttiniz. Lütfen bunu düzeltin ve tekrar deneyin.',
['4'] = 'Bir kullanıcıyı günlük sohbetiniz olarak ayarlayamazsınız!',
['5'] = 'Sohbette bir yönetici gibi görünmüyorsun!',
['6'] = 'Görünen o ki sohbetime zaten idari işlemler yapıyorum! /logchat komutunu kullanarak bir tane oluştur.',
['7'] = 'Bu sohbet geçerlidir, şimdi göndermeye izinim olduğundan emin olmak için ona bir test mesajı göndermeye çalışacağım!',
['8'] = 'Merhaba, Dünya - bu,mesaj gönderme izinlerini kontrol etmek için bir test mesajıdır - Eğer bunu okursanız, her şey yolundadır.',
['9'] = 'Hepsi tamam! Şu andan itibaren, bu sohbetteki herhangi bir idari işlemler giriş yapabilir %s - Benim için yönetimsel işlemleri kaydetmek istediğim sohbeti değiştirmek için, /logchat komutunu kullanın.'
},
['lua'] = {
['1'] = 'Lütfen yürütülecek bir Lua dizgesi girin!'
},
['lyrics'] = {
['1'] = 'Spotify',
['2'] = 'Şarkı sözlerini göster',
['3'] = 'Lütfen bir arama sorgusu girin (aramak istediğin şarkı sözlerini belirt, örnek: "Ankaranın Bağları" Ankaranın bağları şarkı sözlerini getirecek.).'
},
['minecraft'] = {
['1'] = '<b>%s kullanıcı adını değiştirdi %s time</b>',
['2'] = '<b>%s kullanıcı adını %s kere değiştirdi </b>',
['3'] = 'Önceki',
['4'] = 'Sonraki',
['5'] = 'Geri',
['6'] = 'UUID',
['7'] = 'Resim',
['8'] = 'Kullanıcı adı geçmişi',
['9'] = 'Lütfen özellik seçiniz:',
['10'] = 'Lütfen Minecraft oyuncusunun kullanıcı adını giriniz. (örnek: "By_Azade" By_Azade hakkında bilgi verecel).',
['11'] = 'Minecraft usernames are between 3 and 16 characters long.'
},
['mute'] = {
['1'] = 'Hangi kullanıcıyı susturmak istersiniz? Bu kullanıcıyı @kulanıcıadı şeklinde veya kullanıcı IDsi ile belirtebilirsin.',
['2'] = 'Bu sohbette zaten sessiz oldukları için bu kullanıcıyı susturamıyorum',
['3'] = 'Bu sohbette bir moderatör ya da yönetici oldukları için bu kullanıcıyı susturamıyorum.',
['4'] = 'Bu kullanıcıyı zaten bu sohbetten ayrılmış (veya oradan atılmış) bu yüzden susturamıyorum.',
['5'] = 'Bu kullanıcıyı susturmak için admin izinlerine sahip olmam gerekiyor. Lütfen bu sorunu düzeltip tekrar deneyin.'
},
['myspotify'] = {
['1'] = 'Profil',
['2'] = 'Takip Edilenler',
['3'] = 'Önceden Oynatılanlar',
['4'] = 'Şu Anda Oynatılıyor',
['5'] = 'En İyi Parçalarınız',
['6'] = 'En İyi Sanatçılarınız',
['7'] = 'Herhangi bir sanatçıyı takip ediyor gibi görünmüyorsun!',
['8'] = 'En İyi Sanatçılarınız',
['9'] = 'Kütüphanenizde herhangi bir parçanın bulunmadığı anlaşılıyor!',
['10'] = 'En İyi Parçalarınız',
['11'] = 'Herhangi bir sanatçıyı takip ediyor gibi görünmüyorsun!',
['12'] = 'Takip Edilen Sanatçılar',
['13'] = 'Yakın zamanda herhangi bir parça çalmış görünmüyorsun!',
['14'] = '<b>Son Oynatılan</b>\n%s %s\n%s %s\n%s Dinlendi %s:%s on %s/%s/%s.',
['15'] = 'İstek işleme için kabul edildi, ancak işlem tamamlanmadı.',
['16'] = 'Şu an bir şey dinliyor görünmüyorsun!',
['17'] = 'Şu Anda Oynatılıyor',
['18'] = 'Spotify hesabınızı yeniden yetkilendirirken bir hata oluştu.!',
['19'] = 'Spotify hesabınız başarılı bir şekilde yeniden yetkilendirildi! İsteğinizi işleme koyabilirsiniz....',
['20'] = 'Spotify hesabınızı yeniden yetkilendirilecek, lütfen bekleyin...',
['21'] = 'Spotify hesabınızı bağlamak için mattatayı yetkilendirmeniz gerekir. Tıklayın [buraya](https://accounts.spotify.com/en/authorize?client_id=%s&response_type=code&redirect_uri=%s&scope=user-library-read,playlist-read-private,playlist-read-collaborative,user-read-private,user-read-email,user-follow-read,user-top-read,user-read-playback-state,user-read-recently-played,user-read-currently-playing,user-modify-playback-state) Mattatayı Spotify hesabınıza bağlamak için yeşil "Tamam" düğmesine basın. Bunu yaptıktan sonra, yönlendirilen bağlantıyı şu adrese gönderin: ("%s" ile başlamalı ve onu benzersiz bir kod takip etmelidir).',
['22'] = 'Çalma listeleri',
['23'] = 'Satıriçi Modu Kullan',
['24'] = 'Şarkı sözleri',
['25'] = 'Hiç aygıt bulunamadı.',
['26'] = 'Hiçbir çalma listenizin yokmuş gibi görünüyor.',
['27'] = 'Senin Oynatma Listen',
['28'] = '%s %s [%s parçalar]',
['29'] = '%s %s [%s]\nSpotify %s kullanıcı\n\n<b>aygıtları:</b>\n%s',
['30'] = 'Önceki parçayı çalınıyor...',
['31'] = 'Premium kullanıcı değilsiniz!',
['32'] = 'Herhangi bir cihaz bulamadım.',
['33'] = 'Bir sonraki parçayı çalınıyor...',
['34'] = 'Parça yeniden başlatılıyor...',
['35'] = 'Cihazınız geçici olarak kullanılamıyor...',
['36'] = 'Hiç aygıt bulunamadı!',
['37'] = 'Parçayı durduruyor...',
['38'] = 'Şimdi oynuyor',
['39'] = 'Shuffling your music...',
['40'] = 'Bu geçerli bir ses değil. Lütfen 0 ile 100 arasında bir sayı belirtin.',
['41'] = 'Ses seviyesi ayarlandı %s%%!',
['42'] = 'Bu ileti bu eklentinin eski bir sürümünü kullanıyor, lütfen /myspotify komutunu kullanarak yeni bir tane isteyin.!'
},
['name'] = {
['1'] = 'Şu anda yanıtladığım isim "%s" - bunu değiştirmek için, /name <yazı> komutunu kullanın (Buradaki <yazı> bemin cevap vermemi istediğiniz şeydir).',
['2'] = 'Yeni adım 2 ila 32 karakter uzunluğunda olmalıdır!',
['3'] = 'İsmim yalnızca alfasayısal karakterler içerebilir!',
['4'] = 'Şimdi "% s" yerine "% s" ye yanıt vereceğim - bunu değiştirmek için, /name <yazı> komutunu kullanın (Buradaki <yazı> benim cevap vermemi istediğiniz şeydir).'
},
['netflix'] = {
['1'] = 'Daha Fazla Bilgi Edinin'
},
['news'] = {
['1'] = '"<code>%s</code>" Geçerli bir Lua kalıbı değil.',
['2'] = 'Bir kaynak listesi alınamadı..',
['3'] = '<b>Eşleşen haber kaynakları bulundu</b> "<code>%s</code>":\n\n%s',
['4'] = '<b>Aşağıdakilerle birlikte kullanabileceğiniz mevcut haber kaynakları</b> /news komutunu kullanarak./nsources komutunu <b>kullanın.</b> &lt;kaynak&gt; <b>daha spesifik bir sonuç kümesi için haber kaynakları listesinde arama yapmalısın. Aramalar Lua kalıpları kullanılarak eşleştirilir</b>\n\n%s',
['5'] = 'Tercih ettiğiniz bir haber kaynağınız yok. /setnews <kaynak> komutunu kullanarak bir tane ayarla. Kaynakların listesini görmek için /nsources komutunu kullan, veya kaynakları daraltmak için /nsources <kaynak> komutunu kullanabilirsin.',
['6'] = 'Tercih ettiğiniz mevcut haber kaynağı %s. /setnews <kaynak> komutunu kullanarak değiştirebilirsin. /nsources komutunu kullanarak kaynakları görüntüleyebilirsin, veya kaynakları daraltmak için /nsources <kaynak> komutunu kullanabilirsin.',
['7'] = 'Tercih ettiğiniz kaynak zaten %s! Geçerli hikayeyi görüntülemek için /news komutunu kullanın.',
['8'] = 'Bu geçerli bir haber kaynağı değil./nsources komutunu kullanarak bir kaynak listesi görüntüle, veya sonuçları daraltmak için /nsources <sorgu> komutunu kullan.',
['9'] = 'Tercih ettiğiniz haber kaynağı güncellendi %s! Geçerli hikayeyi görüntülemek için /news komutunu kullanın.',
['10'] = 'Bu geçerli bir kaynak değil, /nsources komutunu kullanarak aktif kaynakları görüntüleyin.Tercih ettiğiniz bir kaynağınız varsa, /setnews <kaynak> /news komutunu kullanarak gönderdiğinizde o kaynaktan gönderilen haberler otomatik olarak alınır, Herhangi bir argüman gerekmeden.',
['11'] = 'Daha Fazla Bilgi Edinin'
},
['nick'] = {
['1'] = 'Takma adınız şimdi unutuldu!',
['2'] = 'Takma adınız "%s"!'
},
['optout'] = {
['1'] = 'Toplanan verileri göndermeyi için seçtiniz! /optout komutunu kullanın.',
['2'] = 'Toplanan verileri göndermekten vazgeçtiniz! Etkinleştirmek için /optin komutunu kullanın.'
},
['paste'] = {
['1'] = 'Lütfen yapıştırma dosyanızı yüklemek için bir hizmet seçin:'
},
['pin'] = {
['1'] = 'Daha önce bir mesaj sabitlemediniz. /pin <yazı> komutunu kullanarak bir tane oluşturun.Yazı tipi türlerini destekler.',
['2'] = 'İşte son mesajı kullanarak üretilen /pin.',
['3'] = 'Veritabanında varolan bir pin buldum, Ancak gönderdiğim mesaj silindi gibi görünüyor, ve artık onu bulamıyorum. /pin <yazı> komutunu kullanrak yeni bir tane oluşturabilirsin. Yazı tipi türlerini destekler.',
['4'] = 'Mesajı sabitlerken bir hata oluştu. Girdiğiniz metnin geçersiz yazı tipi türü içerdiği için sabitlenen mesaj silindi. Şimdi, size aşağıda bulabileceğiniz yeni bir pin göndermeye çalışacağım - Onu değiştirmeniz gerekiyorsa, mesaj hala mevcut olduğundan emin olduktan sonra, /pin <yazı> komutunu kullanın.',
['5'] = 'Geçersiz yazı tipi formatı içerdiğinden bu metni gönderemedim.',
['6'] = 'Sabitlenen mesajı görüntüle, güncellenen mesajı görüntülemek için tıklayın.'
},
['pokedex'] = {
['1'] = 'İsim: %s\nKimlik: %s\nTip: %s\nAçıklama: %s'
},
['promote'] = {
['1'] = 'Admini veya moderatörü yetkilendiremezsin.',
['2'] = 'Bu kullanıcıyı yetkilendiremiyorum çünkü bu sohbetten ayrılmış durumda.',
['3'] = 'Bu kullanıcıyı yetkilendiremiyorum çünkü bu sohbetten çoktan atılmış durumda.'
},
['quote'] = {
['1'] = 'Bu kullanıcı, veri saklama işlevini devre dışı bıraktı.',
['2'] = 'Bunun için kayıtlı söz yok! Onların gönderdikleri bir mesajı /save komutunu kullanarak kaydedebilirsiniz.'
},
['report'] = {
['1'] = 'Lütfen grubun yöneticilerine bildirmek istediğiniz iletiyi yanıtlayın.',
['2'] = 'Kendi mesajlarınızı bildiremezsiniz, sadece komik olmaya mı çalışıyorsunuz?',
['3'] = '<b>%s içinde yardıma ihtiyacı var %s!</b>',
['4'] = 'Bildirilen mesajı görüntülemek için burayı tıklayın.',
['5'] = 'Bu mesajı %s admin(ler) e başarıyla rapor ettim.!'
},
['save'] = {
['1'] = 'Bu kullanıcı, veri saklama işlevini devre dışı bıraktı.',
['2'] = 'Bu mesaj benim veritabanıma kaydedildi ve /quote cevabında kullanıldığında olası yanıtların listesine eklendi. %s%s!'
},
['sed'] = {
['1'] = '%s\n\n<i>%s Bunu söylemek istememiştim!</i>',
['2'] = '%s\n\n<i>%s Yenilgiyi kabul etti.</i>',
['3'] = '%s\n\n<i>%s Yanılıyor mu bilmiyorlar mı ...</i>',
['4'] = 'Kahretsin, <i>Ne zamandır yanılıyorum?</i>',
['5'] = '"<code>%s</code>" Geçerli bir Lua kalıbı değil.',
['6'] = '<b>Merhaba, %s, bunu mu demek istedin:</b>\n<i>%s</i>',
['7'] = 'Evet',
['8'] = 'Hayır',
['9'] = 'Emin değilim'
},
['setgrouplang'] = {
['1'] = 'Bu grubun dili şu şekilde ayarlandı: %s!',
['2'] = 'Bu grubun dili şu anda %s.\nLütfen bazı dizelerin henüz tercüme edilmediğine dikkat ediniz. Dilinizi değiştirmek isterseniz, aşağıdaki klavyeyi kullanarak birini seçin:',
['3'] = 'Kullanıcıları bu grupta aynı dili kullanmaya zorlama seçeneği şu anda devre dışı. Bu ayar /administrator den değiştirilmelidir, ancak işleri sizin için daha kolay hale getirmek için aşağıda bir düğme ekledim.',
['4'] = 'Etkin',
['5'] = 'Devre dışı'
},
['setlang'] = {
['1'] = 'Diliniz ayarlandı %s!',
['2'] = 'Diliniz şuanda %s.\nLütfen bazı dizelerin henüz tercüme edilmediğine dikkat ediniz. Dilinizi değiştirmek isterseniz, aşağıdaki klavyeyi kullanarak birini seçin:'
},
['setlink'] = {
['1'] = 'Doğru bir URL değil.',
['2'] = 'Link başarılı bir şekilde ayarlandı!'
},
['setrules'] = {
['1'] = 'Bilinmeyen yazı tipi formatı.',
['2'] = 'Yeni kural başarılı bir şekilde kaydedildi!'
},
['setwelcome'] = {
['1'] = 'Hoşgeldiniz mesajında ne yapmak istersiniz? Belirttiğiniz metin Markdown formatında olacak ve bir kullanıcı sohbete her katıldığında gönderilecektir (Hoş Geldiniz mesajı yönetim menüsünde devre dışı bırakılabilir, /administration üzerinden erişilebilir). Her kullanıcı için hoş geldiniz mesajını otomatik olarak özelleştirmek için yer tutucularını kullanabilirsiniz. Kullanıcının sayısal kimliğini eklemek için $user_id kullanın,sohbetin sayısal kimliğini eklemek için $chat_id, kullanıcının adını eklemek için $name, grubun ismini eklemek için $title ve kullanıcının kullanıcı adını eklemek için $username (eğer kullanıcının kullanıcı adı (@kullanıcıadı) yoksa, bunun yerine isimleri kullanılacak, bu yüzden $name ile birlikte kullanılmamalıdır.).',
['2'] = 'Mesajınızı biçimlendirirken bir hata oluştu, lütfen yazı türünü kontrol edin ve tekrar deneyin.',
['3'] = 'Hoş geldin mesajı %s başarılı bir şekilde güncellendi!'
},
['share'] = {
['1'] = 'Paylaş'
},
['shorten'] = {
['1'] = 'Lütfen aşağıdaki butonları kullanarak bir URL kısaltıcı seçin:'
},
['shsh'] = {
['1'] = 'ECID için herhangi bir SHSH blobunu getiremedim, Lütfen geçerli olduğundan ve bunları kullanarak kaydettiğinizden emin olun https://tsssaver.1conan.com.',
['2'] = 'SHSH Bu cihazın blobları, iOSun aşağıdaki sürümleri için kullanılabilir:\n',
['3'] = 'İndir .zip'
},
['statistics'] = {
['1'] = 'Bu sohbette hiç mesaj gönderilmedi!',
['2'] = '<b>Statistics for:</b> %s\n\n%s\n<b>Total messages sent:</b> %s',
['3'] = 'Bu sohbet istatistikleri sıfırlandı!',
['4'] = 'Bu sohbetin istatistiklerini sıfırlayamadım. Belki daha önce resetlendi?'
},
['steam'] = {
['1'] = 'Steam kullanıcı adın ayarlandı "%s".',
['2'] = '"%s" Steam kullanıcı adı değil.',
['3'] = '%s Steam kullanıcısı %s, açık %s. En son kapattılanlar %s, açık %s. Tıkla <a href="%s">here</a> Steam profilini görüntüle.',
['4'] = '%s, AKA "%s",'
},
['trust'] = {
['1'] = 'Admini ve moderatörü güvenli olarak işaretleyemem.',
['2'] = 'Bu kullanıcıyı güvenli olarak işaretleyemem,kullanıcı gruptan ayrılmış.',
['3'] = 'Bu kullanıcıyı güvenli olarak işaretleyemem, kullanıcı gruptan atılmış'
},
['unmute'] = {
['1'] = 'Hangi kullanıcının sesini açmak istiyorsun? Bu kullanıcıyı @kulanıcıadı şeklinde veya kullanıcı IDsi ile belirtebilirsin.',
['2'] = 'Bu kullanıcının sesini açamam, kullanıcının sesi kapanmamış.',
['3'] = 'Adminin veya moderatörün sesini kapatamam.',
['4'] = 'Bu kullanıcının sesini açamam, kullanıcı gruptan ayrılmış.'
},
['untrust'] = {
['1'] = 'Hangi kullanıcıyı güvenilmeyen yapmak istiyorsun ? Bu kullanıcıyı @kulanıcıadı şeklinde veya kullanıcı IDsi ile belirtebilirsin.',
['2'] = 'Admin ve moderatörü güvenilmeyenler olarak ekleyemem.',
['3'] = 'Bu kullanıcıyı güvenilmeyenler listesine ekleyemem, kullanıcı gruptan ayrılmış.',
['4'] = 'Bu kullanıcıyı güvenilmeyenler listesine ekleyemem, kullanıcı gruptan atılmış.'
},
['upload'] = {
['1'] = 'Please reply to the file you\'d like to download to the server. It must be <= 20 MB.',
['2'] = 'Dosya çok büyük boyutta. 20MBdan küçük olmalı <= 20 MB.',
['3'] = 'Bu dosyayı alamıyorum, muhtemelen çok eski.',
['4'] = 'Bu dosyayı alınırken bir hata meydana geldi.',
['5'] = 'Dosyayı sunucudan başarılı bir şekilde indirdiniz - bulunabilir <code>%s</code>!'
},
['voteban'] = {
['1'] = 'Hangi kullanıcı için oyla-banla özelliği kullanmak istiyorsun? Bu kullanıcıyı @kulanıcıadı şeklinde veya kullanıcı IDsi ile belirtebilirsin.',
['2'] = 'Admin için oyla-banla özelliği kullanılmaz',
['3'] = 'Oyla-banla özelliğini kullanamıyorum, kullanıcı gruptan ayılmış veya banlanmış.',
['4'] = '[%s] Buradan banlanması gerekir mi %s? %s hemen yasaklanması için oylama gerekir, ve %s bunun için en az oylama kapalı olmalıdır',
['5'] = 'Evet [%s]',
['6'] = 'Hayır [%s]',
['7'] = '[%s] Buradan %s %s banlandı %s çünkü %s insanlar bunun için oy kullandılar.',
['8'] = 'En yüksek oy miktarına ulaşıldı, ancak, banlayamam %s - belki onlar oylama yapılmadan önce gruptan ayrılmışlardır? Bu eylemi gerçekleştirmek için yetkiniz yok',
['9'] = 'Onları %s [%s] banlayamam %s çünkü %s insanlar banlamak için karar vermemişler.',
['10'] = 'Banlamak için oy kullandın %s [%s]!',
['11'] = 'Oyun geri çekildi, butonu kullanarak tekrar oy kullanabilirsin.',
['12'] = 'Banlama kararı alındı %s [%s]!',
['13'] = 'A vote-ban has already been opened for this user!'
},
['weather'] = {
['1'] = 'Konum ayarlamadın. /setloc <konum> komutunu kullanarak bir tane ayarla.',
['2'] = 'Şu anda %s (hissedilen sıcaklık %s) %s. %s'
},
['welcome'] = {
['1'] = 'Grup Kuralları'
},
- ['whitelist'] = {
+ ['allowlist'] = {
['1'] = 'Hangi kullanıcıyı beyaz listeye almak istiyorsun? Bir kullanıcıyı özel olarak @kullanıcıadı şeklinde veya kullanıcı kimliği ile belirtebilirsin.',
['2'] = 'Admini veya moderatörü beyaz listeye alamam.',
['3'] = 'Bu kullanıcıyı beyaz listeye alamam, kullanıcı sohbetten ayrılmış.',
['4'] = 'Bu kullanıcıyı beyaz listeye alamam kullanıcı sohbetten banlanmış'
},
['wikipedia'] = {
['1'] = 'Daha fazla bilgi edinin.'
},
['youtube'] = {
['1'] = 'Önceki',
['2'] = 'Sonraki',
['3'] = '%s sayfanın %s sayfasındasın!'
}
}
diff --git a/libs/utils.lua b/libs/utils.lua
index 628265e..7168fb4 100644
--- a/libs/utils.lua
+++ b/libs/utils.lua
@@ -1,515 +1,515 @@
local utils = {}
-local redis = dofile('libs/redis.lua')
+local redis = require('libs.redis')
local configuration = require('configuration')
local mattata = {}
local api = {}
local tools = {}
function utils:init()
mattata = self
api = self.api
tools = self.tools
return utils
end
function utils.is_trusted_user(chat_id, user_id)
if redis:sismember('administration:' .. chat_id .. ':trusted', user_id) then
return true
end
return false
end
function utils.get_user_count()
return #redis:keys('user:*:info')
end
function utils.get_group_count()
return #redis:keys('chat:*:info')
end
function utils.get_user_language(user_id)
return redis:hget('chat:' .. user_id .. ':settings', 'language') or 'en_gb'
end
function utils.get_log_chat(chat_id)
local chat = redis:hget('chat:' .. chat_id .. ':settings', 'log chat')
if chat ~= false and chat ~= nil then
return chat
end
return configuration.log_channel or false
end
function utils.set_captcha(chat_id, user_id, text, id)
local hash = string.format('chat:%s:captcha:%s', tostring(chat_id), tostring(user_id))
redis:hset(hash, 'id', id)
redis:hset(hash, 'text', text)
redis:set('captcha:' .. chat_id .. ':' .. user_id, true)
redis:expire('captcha:' .. chat_id .. ':' .. user_id, 300)
return true
end
function utils.get_captcha_id(chat_id, user_id)
return redis:hget('chat:' .. chat_id .. ':captcha:' .. user_id, 'id') or false
end
function utils.get_captcha_text(chat_id, user_id)
return redis:hget('chat:' .. chat_id .. ':captcha:' .. user_id, 'text') or false
end
function utils.delete_redis_hash(hash, field)
return redis:hdel(hash, field)
end
function utils.wipe_redis_captcha(chat_id, user_id)
local hash = string.format('chat:%s:captcha:%s', tostring(chat_id), tostring(user_id))
redis:hdel(hash, 'id')
redis:hdel(hash, 'text')
return true
end
function utils.get_missing_languages(delimiter)
local missing_languages = redis:smembers('mattata:missing_languages')
if not missing_languages then
return false
end
local output = {}
for _, v in pairs(missing_languages) do
table.insert(output, v)
end
delimiter = delimiter or ', '
return table.concat(output, delimiter)
end
function utils.purge_user(user)
if type(user) ~= 'table' then
return false
end
user = user.from or user
redis:hdel('user:' .. user.id .. ':info', 'id')
if user.username or redis:hget('user:' .. user.id .. ':info', 'username') then
redis:hdel('user:' .. user.id .. ':info', 'username')
local all = redis:smembers('user:' .. user.id .. ':usernames')
for _, v in pairs(all) do
redis:srem('user:' .. user.id .. ':usernames', v)
end
redis:del('username:' .. user.id)
end
redis:hdel('user:' .. user.id .. ':info', 'first_name')
if user.name or redis:hget('user:' .. user.id .. ':info', 'name') then
redis:hdel('user:' .. user.id .. ':info', 'name')
end
if user.last_name or redis:hget('user:' .. user.id .. ':info', 'last_name') then
redis:hdel('user:' .. user.id .. ':info', 'last_name')
end
if user.language_code or redis:hget('user:' .. user.id .. ':info', 'language_code') then
redis:hdel('user:' .. user.id .. ':info', 'language_code')
end
return true
end
function utils.get_list(name)
name = tostring(name)
local length = redis:llen(name)
return redis:lrange(name, 0, tonumber(length) - 1)
end
function utils.get_inline_help(input, offset)
offset = offset and tonumber(offset) or 0
local inline_help = {}
local count = offset + 1
local plugin_list = mattata.plugin_list
for _, plugin in pairs(mattata.administrative_plugin_list) do
if not tools.table_contains(plugin_list, plugin) then
table.insert(plugin_list, plugin)
end
end
table.sort(plugin_list)
for k, v in pairs(plugin_list) do
-- The bot API only accepts a maximum of 50 results, hence we need the offset.
if k > offset and k < offset + 50 then
v = v:gsub('\n', ' ')
if v:match('^/.- %- .-$') and v:lower():match(input) then
table.insert(inline_help,
{
['type'] = 'article',
['id'] = tostring(count),
['title'] = v:match('^(/.-) %- .-$'),
['description'] = v:match('^/.- %- (.-)$'),
['input_message_content'] = {
['message_text'] = utf8.char(8226) .. ' ' .. v:match('^(/.-) %- .-$') .. ' - ' .. v:match('^/.- %- (.-)$')
}
})
count = count + 1
end
end
end
return inline_help
end
function utils.string_to_time(str, is_temp_ban)
if not str then
return false
end
str = tostring(str):gsub('%s', '')
local base_date = {
['year'] = 1970,
['month'] = 1,
['day'] = 1,
['hour'] = 0,
['min'] = 0,
['sec'] = 0
}
local units = {
['y'] = 'year',
['year'] = 'year',
['years'] = 'year',
['mo'] = 'month',
['month'] = 'month',
['months'] = 'month',
['w'] = '7day',
['week'] = '7day',
['weeks'] = '7day',
['d'] = 'day',
['day'] = 'day',
['days'] = 'day',
['h'] = 'hour',
['hour'] = 'hour',
['hours'] = 'hour',
['m'] = 'min',
['min'] = 'min',
['mins'] = 'min',
['minute'] = 'min',
['minutes'] = 'min',
['s'] = 'sec',
['sec'] = 'sec',
['secs'] = 'sec',
['second'] = 'sec',
['seconds'] = 'sec'
}
for number, unit in str:gmatch('(%d+)(%a+)') do
local amount, field = units[unit]:match('^(%d*)(%a+)$')
base_date[field] = base_date[field] + tonumber(number) * (tonumber(amount) or 1)
end
local final_length = os.time(base_date)
if is_temp_ban and final_length <= 59 then
return false
end
return final_length
end
function utils.get_user_setting(chat_id, user_id, setting)
if not chat_id or not user_id or not setting then
return false
elseif not redis:hexists('user:' .. user_id .. ':' .. chat_id .. ':settings', tostring(setting)) then
return false
end
return true
end
function utils.is_group(message)
if not message or not message.chat or not message.chat.type or message.chat.type == 'private' then
return false
end
return true
end
function utils.input(s)
local mentioned_user = false
if not s then
return false
elseif type(s) == 'table' then
if s.entities and #s.entities >= 2 and s.entities[2].type == 'text_mention' then
mentioned_user = tostring(s.entities[2].user.id)
end
s = s.text
end
if s:lower():match('^mattata search %a+ for .-$') then
return s:lower():match('^mattata search %a+ for (.-)$')
elseif not s:lower():match('^[%%/%%!%%$%%^%%?%%&%%%%]') then
return s
end
local input = s:find(' ')
if not input then
return false
end
s = s:sub(input + 1)
input = s:find(' ')
if mentioned_user then
s = input and mentioned_user .. ' ' .. s:sub(input + 1) or mentioned_user
end
return s
end
function utils.get_input(message, has_reason)
local input = utils.input(message)
if message.reply then
if not message.reply.from or message.reply.forward_from then
return false
elseif has_reason and input then
return message.reply.from.id, input
end
return message.reply.from.id
elseif not input then
return false
elseif has_reason and input:find(' ') then
return input:match('^(.-) '), input:match(' (.-)$')
end
return input
end
function utils.get_chat_id(chat)
if not chat then
return false
end
local success = api.get_chat(chat)
if not success or not success.result then
return false
end
return success.result.id
end
function utils.get_setting(chat_id, setting)
if not chat_id or not setting then
return false
end
return redis:hget('chat:' .. chat_id .. ':settings', tostring(setting))
end
function utils.get_value(chat_id, value)
if not chat_id or not value then
return false
end
return redis:hget('chat:' .. chat_id .. ':info', tostring(value))
end
function utils.set_value(chat_id, key, value)
if not chat_id or not key or not value then
return false
end
return redis:hset('chat:' .. chat_id .. ':info', tostring(key), tostring(value))
end
function utils.log_error(error_message)
error_message = tostring(error_message):gsub('%%', '%%%%')
local output = string.format('%s[31m[Error] %s%s[0m', string.char(27), error_message, string.char(27))
print(output)
end
function utils.set_command_action(chat_id, message_id, command)
local hash = string.format('action:%s:%s', chat_id, message_id)
return redis:set(hash, command)
end
function utils.increase_administrative_action(chat_id, user_id, action, increase_by)
if not increase_by or tonumber(increase_by) == nil then
increase_by = 1
end
local hash = string.format('chat:%s:%s', chat_id, user_id)
return redis:hincrby(hash, action, increase_by)
end
-function utils.is_whitelisted_link(link)
+function utils.is_allowlisted_link(link)
if link == 'username' or link == 'isiswatch' or link == 'mattata' or link == 'telegram' then
return true
end
return false
end
function utils.is_valid(message) -- Performs basic checks on the message object to see if it's fit
-- for its purpose. If it's valid, this function will return `true` - otherwise it will return `false`.
if not message then -- If the `message` object is nil, then we'll ignore it.
return false, 'No `message` object exists!'
elseif message.date < os.time() - 7 then -- We don't want to process old messages, so anything
-- older than the current system time (giving it a leeway of 7 seconds).
return false, 'This `message` object is too old!'
elseif not message.from then -- If the `message.from` object doesn't exist, this will likely
-- break some more code further down the line!
return false, 'No `message.from` object exists!'
end
return true
end
function utils.get_chat_members(chat_id)
return redis:smembers('chat:' .. chat_id .. ':users')
end
function utils.is_privacy_enabled(user_id)
return redis:exists('user:' .. user_id .. ':opt_out')
end
function utils.uses_administration(chat_id)
return utils.get_setting(chat_id, 'use administration')
end
-function utils.is_plugin_allowed(plugin, is_blacklisted)
- if not is_blacklisted then
+function utils.is_plugin_allowed(plugin, is_blocklisted)
+ if not is_blocklisted then
return true
end
- for _, p in pairs(configuration.blacklist_plugin_exceptions) do
+ for _, p in pairs(configuration.blocklist_plugin_exceptions) do
if p == plugin then
return true
end
end
return false
end
function utils.command_action(chat_id, message_id)
if not chat_id or not message_id then
return false
end
return string.format('action:%s:%s', chat_id, message_id)
end
function utils.is_fed_admin(fed_id, user_id)
if not fed_id or not user_id then
return false
end
return redis:sismember('fedadmins:' .. fed_id, user_id)
end
function utils.is_fed_creator(fed_id, user_id)
if not fed_id or not user_id then
return false
end
local creator = redis:hget('fed:' .. fed_id, 'creator')
return tonumber(user_id) == tonumber(creator) and true or false
end
function utils.is_user_fedbanned(chat_id, user_id)
if not chat_id or not user_id then
return false
end
local feds = redis:smembers('chat:' .. chat_id .. ':feds')
if #feds == 0 then
return false
end
for _, fed in pairs(feds) do
if redis:sismember('fedbans:' .. fed, user_id) then
return true
end
end
return false
end
function utils.has_fed(user_id, fed_id)
if not user_id then
return false
end
local feds = redis:smembers('feds:' .. user_id)
if #feds > 0 then
if fed_id then
for _, fed in pairs(feds) do
if fed_id == fed then
return true, fed
end
end
return false
end
return true, feds[1], true
end
return false
end
function utils.fed_ban_chat_member(chat_id, user_id, fed_list)
if not chat_id or not user_id then
return false
end
fed_list = type(fed_list) == 'table' and fed_list or { fed_list }
api.ban_chat_member(chat_id, user_id)
local success
for _, fed in pairs(fed_list) do
success = redis:sadd('fedbans:' .. fed, user_id)
end
return success
end
function utils.fed_unban_chat_member(chat_id, user_id, fed_list)
if not chat_id or not user_id then
return false
end
fed_list = type(fed_list) == 'table' and fed_list or { fed_list }
local success
api.unban_chat_member(chat_id, user_id)
for _, fed in pairs(fed_list) do
success = redis:srem('fedbans:' .. fed, user_id)
end
return success
end
function utils.is_fed_banned(fed_id, user_id)
if not fed_id or not user_id then
return false
end
return redis:sismember('fedbans:' .. fed_id, user_id) and true or false
end
function utils.get_feds(chat_id)
if not chat_id then
return false
end
return redis:smembers('chat:' .. chat_id .. ':feds')
end
function utils.get_fed_bans(fed_id)
if not fed_id then
return false
end
return #redis:smembers('fedbans:' .. fed_id)
end
-function utils.fed_whitelist(chat_id, user_id)
+function utils.fed_allowlist(chat_id, user_id)
if not chat_id or not user_id then
return false
end
- return redis:sadd('fedwhitelist:' .. chat_id, user_id)
+ return redis:sadd('fedallowlist:' .. chat_id, user_id)
end
-function utils.is_user_fed_whitelisted(chat_id, user_id)
+function utils.is_user_fed_allowlisted(chat_id, user_id)
if not chat_id or not user_id then
return false
end
- return redis:sismember('fedwhitelist:' .. chat_id, user_id) and true or false
+ return redis:sismember('fedallowlist:' .. chat_id, user_id) and true or false
end
function utils.is_duplicate(tab, val)
local seen = {}
local duplicated = {}
for i = 1, #tab do
local element = tab[i]
if seen[element] then
duplicated[element] = true
else
seen[element] = true
end
end
if val and duplicated[val] then
return true
elseif val then
return false
end
return duplicated
end
function utils.is_valid_url(url, parts, any)
if not url:match('^[Hh][Tt][Tt][Pp][Ss]?://') and not any then
url = 'http://' .. url
end
-- Thanks to https://stackoverflow.com/questions/23590304/finding-a-url-in-a-string-lua-pattern
local url, protocol, subdomain, tld, colon, port, slash, path = string.match(url, '^(([%w_.~!*:@&+$/?%%#-]-)(%w[-.%w]*%.)(%w+)(:?)(%d*)(/?)([%w_.~!*:@&+$/?%%#=-]*))$')
if parts then
return {
['url'] = url,
['protocol'] = protocol,
['subdomain'] = subdomain,
['tld'] = tld,
['colon'] = colon,
['port'] = port,
['slash'] = slash,
['path'] = path
}
end
return url and true or false, url
end
return utils
\ No newline at end of file
diff --git a/mattata.lua b/mattata.lua
index c53d4c7..4df6fe8 100644
--- a/mattata.lua
+++ b/mattata.lua
@@ -1,1371 +1,1372 @@
--[[
_ _ _
_ __ ___ __ _| |_| |_ __ _| |_ __ _
| '_ ` _ \ / _` | __| __/ _` | __/ _` |
| | | | | | (_| | |_| || (_| | || (_| |
|_| |_| |_|\__,_|\__|\__\__,_|\__\__,_|
- v1.2
+ v1.3
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
See LICENSE for details
]]
local mattata = {}
local https = require('ssl.https')
local ltn12 = require('ltn12')
local json = require('dkjson')
local redis = dofile('libs/redis.lua')
local configuration = require('configuration')
local api = require('telegram-bot-lua.core').configure(configuration.bot_token)
local tools = require('telegram-bot-lua.tools')
local socket = require('socket')
local utils = dofile('libs/utils.lua')
local html = require('htmlEntities')
local plugin_list = {}
local administrative_plugin_list = {}
local inline_plugin_list = {}
function mattata:init()
self.info = api.info -- Set the bot's information to the object fetched from the Telegram bot API.
mattata.info = api.info
self.plugins = {} -- Make a table for the bot's plugins.
self.api = api
self.tools = tools
self.configuration = configuration
self.beta_plugins = {}
for k, v in ipairs(configuration.plugins) do -- Iterate over all of the configured plugins.
local true_path = v
for _, p in pairs(configuration.administrative_plugins) do
if v == p then
true_path = 'administration.' .. v
end
end
for _, p in pairs(configuration.beta_plugins) do
if v == p then
table.insert(self.beta_plugins, v)
end
end
local plugin = require('plugins.' .. true_path) -- Load each plugin.
if not plugin then
error('Invalid plugin: ' .. true_path)
elseif mattata.is_duplicate(configuration.plugins, v) then
error('Duplicate plugin: ' .. v)
end
plugin.is_administrative = true_path:match('^administration%.') and true or false
self.plugins[k] = plugin
self.plugins[k].name = v
if self.beta_plugins[v] then
plugin.is_beta_plugin = true
end
if plugin.init then -- If the plugin has an `init` function, run it.
plugin.init(self, configuration)
end
plugin.is_administrative = (self.plugins[k].name == 'administration' or true_path:match('^administration%.')) and true or false
-- By default, a plugin doesn't have inline functionality; but, if it does, set it to `true` appropriately.
plugin.is_inline = plugin.on_inline_query and true or false
plugin.commands = plugin.commands or {} -- If the plugin hasn't got any commands configured, then set a blank
-- table, so when it comes to iterating over the commands later on, the bot won't encounter any problems.
if plugin.help and not plugin.is_beta_plugin then -- If the plugin has help documentation, then insert it into other tables (where necessary).
if plugin.is_administrative then
table.insert(administrative_plugin_list, plugin.help)
else
table.insert(plugin_list, plugin.help)
if plugin.is_inline then -- If the plugin is inline and has documentation, then insert the documentation into
-- the `inline_plugin_list` table.
table.insert(inline_plugin_list, plugin.help)
end
end
plugin.help = 'Usage:\n' .. plugin.help:gsub('%. (Alias)', '.\n%1') -- Make the plugin's documentation style all nicely unified, for consistency.
end
self.plugin_list = plugin_list
self.inline_plugin_list = inline_plugin_list
self.administrative_plugin_list = administrative_plugin_list
end
print(configuration.connected_message)
local info_message = '\tUsername: @' .. self.info.username .. '\n\tName: ' .. self.info.name .. '\n\tID: ' .. self.info.id
print('\n' .. info_message .. '\n')
if redis:get('mattata:version') ~= configuration.version then
local success = dofile('migrate.lua')
print(success)
end
self.version = configuration.version
-- Make necessary database changes if the version has changed.
if not redis:get('mattata:version') or redis:get('mattata:version') ~= self.version then
redis:set('mattata:version', self.version)
end
self.last_update = self.last_update or 0 -- If there is no last update known, make it 0 so the bot doesn't encounter any problems when it tries to add the necessary increment.
self.last_backup = self.last_backup or os.date('%V')
self.last_cron = self.last_cron or os.date('%M')
local init_message = '<pre>' .. configuration.connected_message .. '\n\n' .. mattata.escape_html(info_message) .. '\n\n\tPlugins loaded: ' .. #configuration.plugins - #configuration.administrative_plugins .. '\n\tAdministrative plugins loaded: ' .. #configuration.administrative_plugins .. '</pre>'
mattata.send_message(configuration.log_chat, init_message:gsub('\t', ''), 'html')
for _, admin in pairs(configuration.admins) do
mattata.send_message(admin, init_message:gsub('\t', ''), 'html')
end
local shutdown = redis:get('mattata:shutdown')
if shutdown then
local chat_id, message_id = shutdown:match('^(%-?%d+):(%d*)$')
mattata.edit_message_text(chat_id, message_id, 'Successfully rebooted!')
redis:del('mattata:shutdown')
end
return true
end
-- Set a bunch of function aliases, for consistency & compatibility.
for i, v in pairs(api) do
mattata[i] = v
end
for i, v in pairs(tools) do
mattata[i] = v
end
for i, v in pairs(utils) do
if i ~= 'init' then
mattata[i] = v
end
end
function mattata:run(_, token)
-- mattata's main long-polling function which repeatedly checks the Telegram bot API for updates.
-- The objects received in the updates are then further processed through object-specific functions.
token = token or configuration.bot_token
assert(token, 'You need to enter your Telegram bot API token in configuration.lua, or pass it as the second argument when using the mattata:run() function!')
mattata.is_running = mattata.init(self) -- Initialise the bot.
utils.init(self, configuration)
while mattata.is_running do -- Perform the main loop whilst the bot is running.
local success = api.get_updates( -- Check the Telegram bot API for updates.
configuration.updates.timeout,
self.last_update + 1,
configuration.updates.limit,
json.encode(
{
'message',
'edited_message',
'inline_query',
'callback_query'
}
),
configuration.use_beta_endpoint or false
)
if success and success.result then
for _, v in ipairs(success.result) do
self.last_update = v.update_id
self.execution_time = socket.gettime()
if v.message or v.edited_message then
if v.edited_message then
v.message = v.edited_message
v.edited_message = nil
v.message.old_date = v.message.date
v.message.date = v.message.edit_date
v.message.edit_date = nil
v.message.is_edited = true
else
v.message.is_edited = false
end
if v.message.reply_to_message then
v.message.reply = v.message.reply_to_message -- Make the `update.message.reply_to_message`
-- object `update.message.reply` to make any future handling easier.
v.message.reply_to_message = nil -- Delete the old value by setting its value to nil.
end
mattata.on_message(self, v.message)
if configuration.debug then
print(
string.format(
'%s[36m[Update #%s] Message%s from %s to %s: %s%s[0m',
string.char(27),
v.update_id,
v.message.is_edited and ' edit' or '',
v.message.from.id,
v.message.chat.id,
v.message.text,
string.char(27)
)
)
end
elseif v.inline_query then
mattata.on_inline_query(self, v.inline_query)
if configuration.debug then
print(
string.format(
'%s[35m[Update #%s] Inline query from %s%s[0m',
string.char(27),
v.update_id,
v.inline_query.from.id,
string.char(27)
)
)
end
elseif v.callback_query then
if v.callback_query.message and v.callback_query.message.reply_to_message then
v.callback_query.message.reply = v.callback_query.message.reply_to_message
v.callback_query.message.reply_to_message = nil
end
mattata.on_callback_query(self, v.callback_query.message, v.callback_query)
if configuration.debug then
print(
string.format(
'%s[33m[Update #%s] Callback query from %s%s[0m',
string.char(27),
v.update_id,
v.callback_query.from.id,
string.char(27)
)
)
end
end
self.result_time = socket.gettime() - self.execution_time
if configuration.debug then
print('Update #' .. v.update_id .. ' took ' .. self.result_time .. ' seconds to process.')
end
end
else
mattata.log_error('There was an error retrieving updates from the Telegram bot API!')
end
if self.last_backup ~= os.date('%V') then -- If it's been a week since the last backup, perform another backup.
self.last_backup = os.date('%V') -- Set the last backup time to now, since we're
-- now performing one!
print(io.popen('./backup.sh'):read('*all'))
end
if self.last_cron ~= os.date('%M') then -- Perform minutely CRON jobs.
self.last_cron = os.date('%M')
for i = 1, #self.plugins do
local plugin = self.plugins[i]
if plugin and plugin.cron then
local cron_success, res = pcall(function()
plugin.cron(self, configuration)
end)
if not cron_success then
mattata.exception(self, res, 'CRON: ' .. i, configuration.log_chat)
end
end
end
end
end
print(self.info.first_name .. ' is shutting down...')
end
function mattata:on_message(message)
-- If the message is old or is missing necessary fields/values, then we'll stop and allow the bot to start processing the next update(s).
- -- If the message was sent from a blacklisted chat, then we'll stop because we don't want the bot to respond there.
+ -- If the message was sent from a blocklisted chat, then we'll stop because we don't want the bot to respond there.
if not mattata.is_valid(message) then
return false
- elseif redis:get('blacklisted_chats:' .. message.chat.id) then
+ elseif redis:get('blocklisted_chats:' .. message.chat.id) then
return mattata.leave_chat(message.chat.id)
end
message = mattata.sort_message(message) -- Process the message.
- self.is_user_blacklisted, self.is_globally_blacklisted, self.is_globally_banned = mattata.is_user_blacklisted(message)
+ self.is_user_blocklisted, self.is_globally_blocklisted, self.is_globally_banned = mattata.is_user_blocklisted(message)
-- We only want this functionality if the bot owner has been granted API permission to SpamWatch!
- self.is_spamwatch_blacklisted = configuration.keys.spamwatch ~= '' and mattata.is_spamwatch_blacklisted(message) or false
+ self.is_spamwatch_blocklisted = configuration.keys.spamwatch ~= '' and mattata.is_spamwatch_blocklisted(message) or false
if self.is_globally_banned and message.chat.type ~= 'private' then -- Only for the worst of the worst
mattata.ban_chat_member(message.chat.id, message.from.id)
end
local language = require('languages.' .. mattata.get_user_language(message.from.id))
if mattata.is_group(message) and mattata.get_setting(message.chat.id, 'force group language') then
language = require('languages.' .. (mattata.get_value(message.chat.id, 'group language') or 'en_gb'))
end
self.language = language
if mattata.process_spam(message, configuration) then
return false
end
- -- Perform the following actions if the user isn't blacklisted.
- if not self.is_user_blacklisted then
+ -- Perform the following actions if the user isn't blocklisted.
+ if not self.is_user_blocklisted then
mattata.process_afk(message)
mattata.process_language(self, message)
if message.text then
message = mattata.process_natural_language(self, message)
end
message = mattata.process_stickers(message)
message = mattata.check_links(message, false, true, false, true)
message = mattata.process_deeplinks(message)
-- If the user isn't current AFK, and they say they're going to be right back, we can
-- assume that they are now going to be AFK, so we'll help them out and set them that
-- way by making the message text the /afk command, which will later trigger the plugin.
if (message.text:lower():match('^i?\'?l?l? ?[bg][rt][bg].?$') and not redis:hget('afk:' .. message.from.id, 'since')) then
message.text = '/afk'
end
-- A boolean value to decide later on, whether the message is intended for the current plugin from the iterated table.
end
self.is_command = false
self.is_command_done = false
self.is_allowed_beta_access = false
self.is_telegram = false
-- If the message is one of those pesky Telegram channel pins, it won't send a service message. We'll trick it.
if message.from.id == 777000 and message.forward_from_chat and message.forward_from_chat.type == 'channel' then
self.is_telegram = true
message.is_service_message = true
message.service_message = 'pinned_message'
message.pinned_message = {
['text'] = message.text,
['date'] = message.date,
['chat'] = message.chat,
['from'] = message.from,
['message_id'] = message.message_id,
['entities'] = message.entities,
['forward_from_message_id'] = message.forward_from_message_id,
['forward_from_chat'] = message.forward_from_chat,
['forward_date'] = message.forward_date
}
end
-- This is the main loop which iterates over configured plugins and runs the appropriate functions.
for _, plugin in ipairs(self.plugins) do
if plugin.is_beta_plugin and mattata.is_global_admin(message.from.id) then
self.is_allowed_beta_access = true
end
if not plugin.is_beta_plugin or (plugin.is_beta_plugin and self.is_allowed_beta_access) then
local commands = #plugin.commands or {}
for i = 1, commands do
- if message.text:match(plugin.commands[i]) and mattata.is_plugin_allowed(plugin.name, self.is_user_blacklisted, configuration) and not self.is_command_done and not self.is_telegram and (not message.is_edited or mattata.is_global_admin(message.from.id)) then
+ if message.text:match(plugin.commands[i]) and mattata.is_plugin_allowed(plugin.name, self.is_user_blocklisted, configuration) and not self.is_command_done and not self.is_telegram and (not message.is_edited or mattata.is_global_admin(message.from.id)) then
self.is_command = true
message.command = plugin.commands[i]:match('([%w_%-]+)')
if plugin.on_message and not mattata.is_plugin_disabled(plugin.name, message) then
local success, result = pcall(function()
return plugin.on_message(self, message, configuration, language)
end)
if not success then
mattata.exception(self, result, string.format('%s: %s', message.from.id, message.text), configuration.log_chat)
end
if mattata.get_setting(message.chat.id, 'delete commands') and self.is_command and not redis:sismember('chat:' .. message.chat.id .. ':no_delete', tostring(plugin.name)) and not message.is_natural_language then
mattata.delete_message(message.chat.id, message.message_id)
end
self.is_command_done = true
end
end
end
end
-- Allow plugins to handle new chat participants.
if message.new_chat_members and plugin.on_member_join and not mattata.is_plugin_disabled(plugin.name, message) then
local success, result = pcall(function()
return plugin.on_member_join(self, message, configuration, language)
end)
if not success then
mattata.exception(self, result, string.format('%s: %s', message.from.id, message.text),
configuration.log_chat)
end
end
-- Allow plugins to handle every new message (handy for anti-spam).
if (message.text or message.is_media) and plugin.on_new_message and not mattata.is_plugin_disabled(plugin.name, message) then
local success, result = pcall(function()
return plugin.on_new_message(self, message, configuration, language)
end)
if not success then
mattata.exception(self, result, string.format('%s: %s', message.from.id, message.text or tostring(message.media_type),
configuration.log_chat))
end
end
-- Allow plugins to handle service messages, and pass the type of service message before the message object.
if message.is_service_message and plugin.on_service_message and not mattata.is_plugin_disabled(plugin.name, message) then
local success, result = pcall(function()
return plugin.on_service_message(self, message.service_message:gsub('_', ' '), message, configuration, language)
end)
if not success then
mattata.exception(self, result, string.format('%s: %s', message.from.id, message.text or tostring(message.media_type),
configuration.log_chat))
end
end
end
mattata.process_message(self, message, language)
self.is_done = true
+ self.is_command_done = false
self.is_ai = false
return
end
function mattata:on_inline_query(inline_query)
if not inline_query.from then
return false, 'No `inline_query.from` object was found!'
- elseif redis:get('global_blacklist:' .. inline_query.from.id) then
- return false, 'This user is globally blacklisted!'
+ elseif redis:get('global_blocklist:' .. inline_query.from.id) then
+ return false, 'This user is globally blocklisted!'
end
local language = require('languages.' .. mattata.get_user_language(inline_query.from.id))
inline_query.offset = inline_query.offset and tonumber(inline_query.offset) or 0
for _, plugin in ipairs(self.plugins) do
local plugins = plugin.commands or {}
for i = 1, #plugins do
local command = plugin.commands[i]
if not inline_query then
return false, 'No `inline_query` object was found!'
end
if inline_query.query:match(command)
and plugin.on_inline_query
then
local success, result = pcall(
function()
return plugin.on_inline_query(self, inline_query, configuration, language)
end
)
if not success then
local exception = string.format('%s: %s', inline_query.from.id, inline_query.query)
mattata.exception(self, result, exception, configuration.log_chat)
return false, result
elseif not result then
return api.answer_inline_query(
inline_query.id,
api.inline_result()
:id()
:type('article')
:title(configuration.errors.results)
:description(plugin.help)
:input_message_content(api.input_text_message_content(plugin.help))
)
end
end
end
end
if not inline_query.query or inline_query.query:gsub('%s', '') == '' then
local offset = inline_query.offset and tonumber(inline_query.offset) or 0
local list = mattata.get_inline_list(self.info.username, offset)
if #list == 0 then
local title = 'No more results found!'
local description = 'There were no more inline features found. Use @' .. self.info.username .. ' <query> to search for more information about commands matching the given search query.'
return mattata.send_inline_article(inline_query.id, title, description)
end
return mattata.answer_inline_query(inline_query.id, json.encode(list), 0, false, tostring(offset + 50))
end
local help = require('plugins.help')
return help.on_inline_query(self, inline_query, configuration, language)
end
function mattata:on_callback_query(message, callback_query)
if not callback_query.from then return false end
if not callback_query.message or not callback_query.message.chat then
message = {
['chat'] = {},
['message_id'] = callback_query.inline_message_id,
['from'] = callback_query.from
}
else
message = callback_query.message
message.exists = true
end
local language = require('languages.' .. mattata.get_user_language(callback_query.from.id))
if message.chat.id and mattata.is_group(message) and mattata.get_setting(message.chat.id, 'force group language') then
language = require('languages.' .. (mattata.get_value(message.chat.id, 'group language') or 'en_gb'))
end
self.language = language
- if redis:get('global_blacklist:' .. callback_query.from.id) and not callback_query.data:match('^join_captcha') and not mattata.is_global_admin(callback_query.from.id) then
- return false, 'This user is globally blacklisted!'
+ if redis:get('global_blocklist:' .. callback_query.from.id) and not callback_query.data:match('^join_captcha') and not mattata.is_global_admin(callback_query.from.id) then
+ return false, 'This user is globally blocklisted!'
elseif message and message.exists then
if message.reply and message.chat.type ~= 'channel' and callback_query.from.id ~= message.reply.from.id and not callback_query.data:match('^game:') and not mattata.is_global_admin(callback_query.from.id) then
local output = 'Only ' .. message.reply.from.first_name .. ' can use this!'
return mattata.answer_callback_query(callback_query.id, output)
end
end
for _, plugin in ipairs(self.plugins) do
if not callback_query.data or not callback_query.from then
return false
elseif plugin.name == callback_query.data:match('^(.-):.-$') and plugin.on_callback_query then
callback_query.data = callback_query.data:match('^[%a_]+:(.-)$')
if not callback_query.data then
plugin = callback_query.data
callback_query = ''
end
local success, result = pcall(
function()
return plugin.on_callback_query(self, callback_query, message or false, configuration, language)
end
)
if not success then
mattata.send_message(configuration.admins[1], json.encode(callback_query, {indent=true}))
-- mattata.answer_callback_query(callback_query.id, language['errors']['generic'])
local exception = string.format('%s: %s', callback_query.from.id, callback_query.data)
mattata.exception(self, result, exception, configuration.log_chat)
return false, result
end
end
end
return true
end
mattata.send_message = api.send_message
-- A variant of mattata.send_message(), optimised for sending a message as a reply that forces a
-- reply back from the user.
function mattata.send_force_reply(message, text, parse_mode, disable_web_page_preview, token)
local success = api.send_message(
message,
text,
parse_mode,
disable_web_page_preview,
false,
message.message_id,
'{"force_reply":true,"selective":true}',
token
)
return success
end
function mattata.get_chat(chat_id, only_api, token)
local success = api.get_chat(chat_id, token)
if only_api then -- stops antispam using usernames stored in the database
return success
elseif success and success.result and success.result.type and success.result.type == 'private' then
mattata.process_user(success.result)
elseif success and success.result then
mattata.process_chat(success.result)
end
return success
end
function mattata.is_plugin_disabled(plugin, message, is_administrative)
if not plugin or not message then
return false
elseif type(message) == 'table' and message.chat.type == 'supergroup' and mattata.is_group_admin(message.chat.id, message.from.id) and mattata.get_setting(message.chat.id, 'enable plugins for admins') then
return false
end
is_administrative = is_administrative or false
plugin = plugin:lower():gsub('^administration/', '')
if type(message) == 'table' and message.chat then
message = message.chat.id
end
if mattata.table_contains(configuration.permanent_plugins, plugin) then
return false
end
if is_administrative and not mattata.get_setting(message, 'use administration') and plugin ~= 'administration' then
return true
end
local exists = redis:sismember('disabled_plugins:' .. message, plugin)
return exists and true or false
end
function mattata:exception(err, message, log_chat)
local output = string.format(
'[%s]\n%s: %s\n%s\n',
os.date('%X'),
self.info.username,
mattata.escape_html(err) or '',
mattata.escape_html(message)
)
if log_chat then
return mattata.send_message(
log_chat,
string.format('<pre>%s</pre>', output),
'html'
)
end
return output
end
function mattata.is_group_admin(chat_id, user_id, is_real_admin)
if not chat_id or not user_id then
return false
elseif mattata.is_global_admin(chat_id) or mattata.is_global_admin(user_id) then
return true
elseif not is_real_admin and mattata.is_group_mod(chat_id, user_id) then
return true
end
local user, res = mattata.get_chat_member(chat_id, user_id)
if not user or not user.result then
return false, res
elseif user.result.status == 'creator' or user.result.status == 'administrator' then
return true, res
end
return false, user.result.status
end
function mattata.is_group_mod(chat_id, user_id)
if not chat_id or not user_id then
return false
elseif redis:sismember('administration:' .. chat_id .. ':mods', user_id) then
return true
end
return false
end
function mattata.process_chat(chat)
chat.id_str = tostring(chat.id)
if chat.type == 'private' then
return mattata.process_user(chat)
end
if not redis:hexists('chat:' .. chat.id .. ':info', 'id') then
print(
string.format(
'%s[34m[+] Added the chat %s to the database!%s[0m',
string.char(27),
chat.username and '@' .. chat.username or chat.id,
string.char(27)
)
)
end
redis:hset('chat:' .. chat.id .. ':info', 'title', chat.title)
redis:hset('chat:' .. chat.id .. ':info', 'type', chat.type)
if chat.username then
chat.username = chat.username:lower()
redis:hset('chat:' .. chat.id .. ':info', 'username', chat.username)
redis:set('username:' .. chat.username, chat.id)
if not redis:sismember('chat:' .. chat.id .. ':usernames', chat.username) then
redis:sadd('chat:' .. chat.id .. ':usernames', chat.username)
end
end
redis:hset('chat:' .. chat.id .. ':info', 'id', chat.id)
return chat
end
function mattata.process_user(user)
if not user then return user end
if not user.id or not user.first_name then return false end
redis:hset('user:' .. user.id .. ':info', 'id', user.id)
local new = false
user.name = user.first_name
if user.last_name then
user.name = user.name .. ' ' .. user.last_name
end
if not redis:hget('user:' .. user.id .. ':info', 'id') and configuration.debug then
print(
string.format(
'%s[34m[+] Added the user %s to the database!%s%s[0m',
string.char(27),
user.username and '@' .. user.username or user.id,
user.language_code and ' Language: ' .. user.language_code or '',
string.char(27)
)
)
new = true
elseif configuration.debug then
print(
string.format(
'%s[34m[+] Updated information about the user %s in the database!%s%s[0m',
string.char(27),
user.username and '@' .. user.username or user.id,
user.language_code and ' Language: ' .. user.language_code or '',
string.char(27)
)
)
end
redis:hset('user:' .. user.id .. ':info', 'type', 'private')
redis:hset('user:' .. user.id .. ':info', 'name', user.name)
redis:hset('user:' .. user.id .. ':info', 'first_name', user.first_name)
if user.last_name then
redis:hset('user:' .. user.id .. ':info', 'last_name', user.last_name)
else
redis:hdel('user:' .. user.id .. ':info', 'last_name')
end
if user.username then
user.username = user.username:lower()
redis:hset('user:' .. user.id .. ':info', 'username', user.username)
redis:set('username:' .. user.username, user.id)
if not redis:sismember('user:' .. user.id .. ':usernames', user.username) then
redis:sadd('user:' .. user.id .. ':usernames', user.username)
end
else
redis:hdel('user:' .. user.id .. ':info', 'username')
end
if user.language_code then
if mattata.does_language_exist(user.language_code) and not redis:hget('chat:' .. user.id .. ':settings', 'language') then
-- If a translation exists for the user's language code, and they haven't selected
-- a language already, then set it as their primary language!
redis:hset('chat:' .. user.id .. ':settings', 'language', user.language_code)
end
redis:hset('user:' .. user.id .. ':info', 'language_code', user.language_code)
else
redis:hdel('user:' .. user.id .. ':info', 'language_code')
end
redis:hset('user:' .. user.id .. ':info', 'is_bot', tostring(user.is_bot))
if new then
redis:hset('user:' .. user.id .. ':info', 'id', user.id)
end
if redis:get('nick:' .. user.id) then
user.first_name = redis:get('nick:' .. user.id)
user.name = user.first_name
user.last_name = nil
end
return user, new
end
function mattata.sort_message(message)
message.is_natural_language = false
message.text = message.text or message.caption or '' -- Ensure there is always a value assigned to message.text.
message.text = message.text:gsub('^/(%a+)%_', '/%1 ')
if message.text:match('^[/!#]start .-$') then -- Allow deep-linking through the /start command.
message.text = '/' .. message.text:match('^[/!#]start (.-)$')
end
message.is_media = mattata.is_media(message)
message.media_type = mattata.media_type(message)
message.file_id = mattata.file_id(message)
message.is_service_message, message.service_message = mattata.service_message(message)
if message.caption_entities then
message.entities = message.caption_entities
message.caption_entities = nil
end
if message.from.language_code then
message.from.language_code = message.from.language_code:lower():gsub('%-', '_') -- make it fit with the names of our language files
if message.from.language_code:len() == 2 and message.from.language_code ~= 'en' then
message.from.language_code = message.from.language_code .. '_' .. message.from.language_code
elseif message.from.language_code:len() == 2 or message.from.language_code == 'root' then -- not sure why but some english users were having `root` return as their language
message.from.language_code = 'en_us'
end
end
message.reply = message.reply and mattata.sort_message(message.reply) or nil
if message.from then
message.from = mattata.process_user(message.from)
end
if message.reply then
message.reply.from = mattata.process_user(message.reply.from)
end
if message.forward_from then
message.forward_from = mattata.process_user(message.forward_from)
end
if message.chat and message.chat.type ~= 'private' then
-- Add the user to the set of users in the current chat.
if configuration.administration.store_chat_members and message.from then
if not redis:sismember('chat:' .. message.chat.id .. ':users', message.from.id) then
redis:sadd('chat:' .. message.chat.id .. ':users', message.from.id)
end
end
if message.new_chat_members then
message.chat = mattata.process_chat(message.chat)
for i = 1, #message.new_chat_members do
if configuration.administration.store_chat_users then
redis:sadd('chat:' .. message.chat.id .. ':users', message.new_chat_members[i].id) -- add users to the chat's set in the database
end
message.new_chat_members[i] = mattata.process_user(message.new_chat_members[i])
end
elseif message.left_chat_member then -- if they've left the chat then there's no need for them to be in the set anymore
message.chat = mattata.process_chat(message.chat)
message.left_chat_member = mattata.process_user(message.left_chat_member)
if configuration.administration.store_chat_users then
redis:srem('chat:' .. message.chat.id .. ':users', message.left_chat_member.id)
end
end
end
if message.text and message.chat and message.reply and message.reply.from and message.reply.from.id == api.info.id then
local action = redis:get('action:' .. message.chat.id .. ':' .. message.reply.message_id)
-- If an action was saved for the replied-to message (as part of a multiple step command), then
-- we'll get information about the action.
if action then
message.text = action .. ' ' .. message.text -- Concatenate the saved action's command
-- with the new `message.text`.
message.reply = nil -- This caused some issues with administrative commands which would
-- prioritise replied-to users over users given by arguments.
redis:del(action) -- Delete the action for this message, since we've done what we needed to do
-- with it now.
end
end
if message.entities then
for n, entities in pairs(message.entities) do
if entities.type == 'text_mention' then
message.text = message.text:gsub(message.entities[n].user.first_name, message.entities[n].user.id)
end
end
end
return message
end
function mattata.is_global_admin(id)
for _, v in pairs(configuration.admins) do
if id == v then
return true
end
end
return false
end
function mattata.get_user(input, force_api, is_id_plugin, cache_only)
if tonumber(input) == nil and input then -- check it's not an ID
input = input:match('^%@?(.-)$')
input = redis:get('username:' .. input:lower())
end
if not input or tonumber(input) == nil then -- if it's still not an ID then we'll give up
return false
end
local user = redis:hgetall('user:' .. tostring(input) .. ':info')
if is_id_plugin and user.id then
local success = mattata.get_chat(user.id) -- Try and get latest info about the user for the ID plugin
if success then
return success
end
end
if user.username and not cache_only then
local scrape, scrape_res = https.request('https://t.me/' .. user.username)
if scrape_res == 200 then
local bio = scrape:match('%<div class="tgme_page_description "%>(.-)%</div%>')
if bio then
bio = bio:gsub('%b<>', '')
bio = html.decode(bio)
user.bio = bio
end
end
end
if user.id then
return {
['result'] = {
['id'] = tonumber(user.id),
['type'] = user.type,
['name'] = user.name,
['first_name'] = user.first_name,
['last_name'] = user.last_name,
['username'] = user.username,
['is_bot'] = user.is_bot,
['bio'] = user.bio
}
}
end
if force_api then
return mattata.get_chat(input)
end
return false
end
function mattata.get_inline_list(username, offset)
offset = offset and tonumber(offset) or 0
local inline_list = {}
table.sort(inline_plugin_list)
for k, v in pairs(inline_plugin_list) do
if k > offset and k < offset + 50 then -- The bot API only accepts a maximum of 50 results, hence we need the offset.
v = v:gsub('\n', ' ')
table.insert(
inline_list,
mattata.inline_result()
:type('article')
:id(tostring(k))
:title(v:match('^(/.-) %- .-$'))
:description(v:match('^/.- %- (.-)$'))
:input_message_content(
mattata.input_text_message_content(
string.format(
'• %s - %s\n\nTo use this command inline, you must use the syntax:\n@%s %s',
v:match('^(/.-) %- .-$'),
v:match('^/.- %- (.-)$'),
username,
v:match('^(/.-) %- .-$')
)
)
)
:reply_markup(
mattata.inline_keyboard():row(
mattata.row():switch_inline_query_button('Show me how!', v:match('^(/.-) '))
)
)
)
end
end
return inline_list
end
function mattata.get_help(is_administrative, chat_id)
local list_to_use = is_administrative == true and administrative_plugin_list or plugin_list
local help = {}
local count = 1
table.sort(list_to_use)
for _, v in pairs(list_to_use) do
if v:match('^/.- %- .-$') then
-- Do some replacement for plugins that have different primary commands to their plugin name.
local to_match = v:gsub('/np', '/lastfm'):gsub('/r/', '/reddit '):gsub('/s/', '/sed '):gsub('(/cat)', '%1s')
local plugin = to_match:match('^/([%w_]+) .-$')
if not chat_id or not mattata.is_plugin_disabled(plugin, chat_id) then
local command, description = v:match('^(.-) %- (.-)$')
local parameters = ' '
if not command then mattata.send_message(configuration.admins[1], v) end
if command:match(' [%[<]') then
command, parameters = command:match('^(.-)( .-)$')
parameters = '<code>' .. mattata.escape_html(parameters) .. '</code> '
end
local output = command .. parameters .. '- <em>' .. mattata.escape_html(description) .. '</em>'
table.insert(help, utf8.char(8226) .. ' ' .. output)
count = count + 1
end
end
end
return help
end
function mattata.format_time(seconds)
if not seconds or tonumber(seconds) == nil then
return false
end
seconds = tonumber(seconds) -- Make sure we're handling a numerical value
local minutes = math.floor(seconds / 60)
if minutes == 0 then
return seconds ~= 1 and seconds .. ' seconds' or seconds .. ' second'
elseif minutes < 60 then
return minutes ~= 1 and minutes .. ' minutes' or minutes .. ' minute'
end
local hours = math.floor(seconds / 3600)
if hours == 0 then
return minutes ~= 1 and minutes .. ' minutes' or minutes .. ' minute'
elseif hours < 24 then
return hours ~= 1 and hours .. ' hours' or hours .. ' hour'
end
local days = math.floor(seconds / 86400)
if days == 0 then
return hours ~= 1 and hours .. ' hours' or hours .. ' hour'
elseif days < 7 then
return days ~= 1 and days .. ' days' or days .. ' day'
end
local weeks = math.floor(seconds / 604800)
if weeks == 0 then
return days ~= 1 and days .. ' days' or days .. ' day'
else
return weeks ~= 1 and weeks .. ' weeks' or weeks .. ' week'
end
end
function mattata.does_language_exist(language)
return pcall( -- nice and simple, perform a pcall to require the language, and if it errors then it doesn't exist
function()
return require('languages.' .. language)
end
)
end
function mattata.save_to_file(content, file_path)
if not content then
return false
end
file_path = file_path or ('/tmp/temp_' .. os.time() .. '.txt')
local file = io.open(file_path, 'w+')
file:write(tostring(content))
file:close()
return true
end
function mattata.insert_keyboard_row(keyboard, first_text, first_callback, second_text, second_callback, third_text, third_callback)
-- todo: get rid of this function as it's dirty, who only allows 3 buttons in a row??
table.insert(
keyboard['inline_keyboard'],
{
{
['text'] = first_text,
['callback_data'] = first_callback
},
{
['text'] = second_text,
['callback_data'] = second_callback
},
{
['text'] = third_text,
['callback_data'] = third_callback
}
}
)
return keyboard
end
-function mattata.is_user_blacklisted(message)
+function mattata.is_user_blocklisted(message)
if not message or not message.from or not message.chat then
return false, false, false
elseif mattata.is_global_admin(message.from.id) then
return false, false, false
end
local gbanned = redis:get('global_ban:' .. message.from.id) -- Check if the user is globally
- -- blacklisted from using the bot.
- local group = redis:get('group_blacklist:' .. message.chat.id .. ':' .. message.from.id) -- Check
- -- if the user is blacklisted from using the bot in the current group.
- local gblacklisted = redis:get('global_blacklist:' .. message.from.id)
- return group, gblacklisted, gbanned
+ -- blocklisted from using the bot.
+ local group = redis:get('group_blocklist:' .. message.chat.id .. ':' .. message.from.id) -- Check
+ -- if the user is blocklisted from using the bot in the current group.
+ local gblocklisted = redis:get('global_blocklist:' .. message.from.id)
+ return group, gblocklisted, gbanned
end
-function mattata.is_spamwatch_blacklisted(message, force_check)
+function mattata.is_spamwatch_blocklisted(message, force_check)
if tonumber(message) ~= nil then -- Add support for passing just the user ID too!
message = {
['from'] = {
['id'] = tonumber(message)
}
}
elseif not message or not message.from then
return false, nil, 'No valid message object was passed! It needs to have a message.from as well!', 404
end
- local is_cached = redis:get('not_blacklisted:' .. message.from.id)
+ local is_cached = redis:get('not_blocklisted:' .. message.from.id)
if is_cached and not force_check then -- We don't want to perform an HTTPS call every time the bot sees a chat!
- return false, nil, 'That user is cached as not blacklisted!', 404
+ return false, nil, 'That user is cached as not blocklisted!', 404
end
local response = {}
local _ = https.request(
{
['url'] = 'https://api.spamwat.ch/banlist/' .. message.from.id,
['method'] = 'GET',
['headers'] = {
['Authorization'] = 'Bearer ' .. configuration.keys.spamwatch
},
['sink'] = ltn12.sink.table(response)
}
)
response = table.concat(response)
local jdat = json.decode(response)
if not jdat then
return false, nil, 'The server appears to be offline', 521
elseif jdat.error then
if jdat.code == 404 then -- The API returns a 404 code when the user isn't in the SpamWatch database
- redis:set('not_blacklisted:' .. message.from.id, true)
- redis:expire('not_blacklisted:' .. message.from.id, 604800) -- Let the key last a week!
+ redis:set('not_blocklisted:' .. message.from.id, true)
+ redis:expire('not_blocklisted:' .. message.from.id, 604800) -- Let the key last a week!
end
return false, jdat, jdat.error, jdat.code
elseif jdat.id then
return true, jdat, 'Success', 200
end
return false, jdat, 'Error!', jdat.code or 404
end
function mattata.process_afk(message) -- Checks if the message references an AFK user and tells the
-- person mentioning them that they are marked AFK. If a user speaks and is currently marked as AFK,
-- then the bot will announce their return along with how long they were gone for.
if message.from.username
and redis:hget('afk:' .. message.from.id, 'since')
and not mattata.is_plugin_disabled('afk', message)
and not message.text:match('^[/!#]afk')
and not message.text:lower():match('^i?\'?l?l? ?[bg][rt][bg].?$')
then
local since = os.time() - tonumber(redis:hget('afk:' .. message.from.id, 'since'))
redis:hdel('afk:' .. message.from.id, 'since')
redis:hdel('afk:' .. message.from.id, 'note')
local keys = redis:keys('afk:' .. message.from.id .. ':replied:*')
if #keys > 0 then
for _, key in pairs(keys) do
redis:del(key)
end
end
local output = message.from.first_name .. ' has returned, after being /AFK for ' .. mattata.format_time(since) .. '.'
mattata.send_message(message.chat.id, output)
elseif (message.text:match('@[%w_]+') -- If a user gets mentioned, check to see if they're AFK.
or message.reply) and not redis:get('afk:' .. message.from.id .. ':replied:' .. message.chat.id) then
local username = message.reply and message.reply.from.id or message.text:match('@([%w_]+)')
local success = mattata.get_user(username)
if not success or not success.result or not success.result.id then
return false
end
local exists = redis:hexists('afk:' .. success.result.id, 'since')
if success and success.result and exists then -- If all the checks are positive, the mentioned user is AFK, so we'll tell the person mentioning them that this is the case!
if message.reply then
redis:set('afk:' .. message.from.id .. ':replied:' .. message.chat.id, true)
end
mattata.send_reply(message, success.result.first_name .. ' is currently AFK!')
end
end
end
function mattata.process_stickers(message)
if message.chat.type == 'supergroup' and message.sticker then
-- Process each sticker to see if they are one of the configured, command-performing stickers.
for _, v in pairs(configuration.stickers.ban) do
if message.sticker.file_unique_id == v then
message.text = '/ban'
end
end
for _, v in pairs(configuration.stickers.warn) do
if message.sticker.file_unique_id == v then
message.text = '/warn'
end
end
for _, v in pairs(configuration.stickers.kick) do
if message.sticker.file_unique_id == v then
message.text = '/kick'
end
end
end
return message
end
function mattata:process_natural_language(message)
local text = message.text:lower()
local name = self.info.first_name:lower()
if text:match(name .. '.- ban @?[%w_-]+ ?') then
message.text = '/ban ' .. text:match(name .. '.- ban (@?[%w_-]+) ?')
elseif text:match(name .. '.- warn @?[%w_-]+ ?') then
message.text = '/warn ' .. text:match(name .. '.- warn (@?[%w_-]+) ?')
elseif text:match(name .. '.- kick @?[%w_-]+ ?') then
message.text = '/kick ' .. text:match(name .. '.- kick (@?[%w_-]+) ?')
elseif text:match(name .. '.- unban @?[%w_-]+ ?') then
message.text = '/unban ' .. text:match(name .. '.- unban (@?[%w_-]+) ?')
elseif text:match(name .. '.- resume my music') then
local myspotify = require('plugins.myspotify')
local success = myspotify.reauthorise_account(message.from.id, configuration)
local output = success and myspotify.play(message.from.id) or 'An error occured whilst trying to connect to your Spotify account, are you sure you\'ve connected me to it?'
mattata.send_message(message.chat.id, output)
end
message.is_natural_language = true
return message
end
function mattata.process_spam(message)
if message.forward_from then return false end
local msg_count = tonumber(
redis:get('antispam:' .. message.chat.id .. ':' .. message.from.id) -- Check to see if the user
-- has already sent 1 or more messages to the current chat, in the past 5 seconds.
)
or 1 -- If this is the first time the user has posted in the past 5 seconds, we'll make it 1 accordingly.
redis:setex(
'antispam:' .. message.chat.id .. ':' .. message.from.id,
configuration.administration.global_antispam.ttl, -- set the TTL
msg_count + 1 -- Increase the current message count by 1.
)
if msg_count == configuration.administration.global_antispam.message_warning_amount -- If the user has sent x messages in the past y seconds, send them a warning.
-- and not mattata.is_global_admin(message.from.id)
and message.chat.type == 'private' then
-- Don't run the antispam plugin if the user is configured as a global admin in `configuration.lua`.
- mattata.send_reply( -- Send a warning message to the user who is at risk of being blacklisted for sending
+ mattata.send_reply( -- Send a warning message to the user who is at risk of being blocklisted for sending
-- too many messages.
message,
string.format(
'Hey %s, please don\'t send that many messages, or you\'ll be forbidden to use me for 24 hours!',
message.from.username and '@' .. message.from.username or message.from.name
)
)
- elseif msg_count == configuration.administration.global_antispam.message_blacklist_amount -- If the user has sent x messages in the past y seconds, blacklist them globally from
+ elseif msg_count == configuration.administration.global_antispam.message_blocklist_amount -- If the user has sent x messages in the past y seconds, blocklist them globally from
-- using the bot for 24 hours.
- -- and not mattata.is_global_admin(message.from.id) -- Don't blacklist the user if they are configured as a global
+ -- and not mattata.is_global_admin(message.from.id) -- Don't blocklist the user if they are configured as a global
-- admin in `configuration.lua`.
then
- redis:set('global_blacklist:' .. message.from.id, true)
- if configuration.administration.global_antispam.blacklist_length ~= -1 and configuration.administration.global_antispam.blacklist_length ~= 'forever' then
- redis:expire('global_blacklist:' .. message.from.id, configuration.administration.global_antispam.blacklist_length)
+ redis:set('global_blocklist:' .. message.from.id, true)
+ if configuration.administration.global_antispam.blocklist_length ~= -1 and configuration.administration.global_antispam.blocklist_length ~= 'forever' then
+ redis:expire('global_blocklist:' .. message.from.id, configuration.administration.global_antispam.blocklist_length)
end
return mattata.send_reply(
message,
string.format(
- 'Sorry, %s, but you have been blacklisted from using me for the next 24 hours because you have been spamming!',
+ 'Sorry, %s, but you have been blocklisted from using me for the next 24 hours because you have been spamming!',
message.from.username and '@' .. message.from.username or message.from.name
)
)
end
return false
end
function mattata:process_language(message)
if message.from.language_code then
if not mattata.does_language_exist(message.from.language_code) then
if not redis:sismember('mattata:missing_languages', message.from.language_code) then -- If we haven't stored the missing language file, add it into the database.
redis:sadd('mattata:missing_languages', message.from.language_code)
end
if (message.text == '/start' or message.text == '/start@' .. self.info.username) and message.chat.type == 'private' then
mattata.send_message(
message.chat.id,
'It appears that I haven\'t got a translation in your language (' .. message.from.language_code .. ') yet. If you would like to voluntarily translate me into your language, please join <a href="https://t.me/mattataDev">my official development group</a>. Thanks!',
'html'
)
end
elseif redis:sismember('mattata:missing_languages', message.from.language_code) then
-- If the language file is found, yet it's recorded as missing in the database, it's probably
-- new, so it is deleted from the database to prevent confusion when processing this list!
redis:srem('mattata:missing_languages', message.from.language_code)
end
end
end
function mattata.process_deeplinks(message)
if message.text:match('^/[%a_]+_%-%d+$') and message.chat.type == 'private' then
message.text = message.text:gsub('^(/[%a_]+)_(.-)$', '%1 %2')
end
return message
end
function mattata.toggle_setting(chat_id, setting, value)
value = (type(value) ~= 'string' and tostring(value) ~= 'nil') and value or true
if not chat_id or not setting then
return false
elseif not redis:hexists('chat:' .. chat_id .. ':settings', tostring(setting)) then
return redis:hset('chat:' .. chat_id .. ':settings', tostring(setting), value)
end
return redis:hdel('chat:' .. chat_id .. ':settings', tostring(setting))
end
function mattata.get_usernames(user_id)
if not user_id then
return false
elseif tonumber(user_id) == nil then
user_id = tostring(user_id):match('^@(.-)$') or tostring(user_id)
user_id = redis:get('username:' .. user_id:lower())
if not user_id then
return false
end
end
return redis:smembers('user:' .. user_id .. ':usernames')
end
-function mattata.check_links(message, get_links, only_valid, whitelist, return_message, delete)
+function mattata.check_links(message, get_links, only_valid, allowlist, return_message, delete)
message.is_invite_link = false
local links = {}
if message.entities then
for i = 1, #message.entities do
if message.entities[i].type == 'text_link' then
message.text = message.text .. ' ' .. message.entities[i].url
end
end
end
for n in message.text:gmatch('%@[%w_]+') do
table.insert(links, n:match('^%@([%w_]+)$'))
end
for n in message.text:gmatch('[Tt]%.[Mm][Ee]/[Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]/[%w_]+') do
table.insert(links, n:match('/([Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]/[%w_]+)$'))
end
for n in message.text:gmatch('[Tt]%.[Mm][Ee]/[%w_]+') do
if not n:match('/[Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]$') then
table.insert(links, n:match('/([%w_]+)$'))
end
end
for n in message.text:gmatch('[Tt][Ee][Ll][Ee][Gg][Rr][Aa][Mm]%.[Mm][Ee]/[Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]/[%w_]+') do
table.insert(links, n:match('/([Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]/[%w_]+)$'))
end
for n in message.text:gmatch('[Tt][Ee][Ll][Ee][Gg][Rr][Aa][Mm]%.[Mm][Ee]/[%w_]+') do
if not n:match('/[Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]$') then
table.insert(links, n:match('/([%w_]+)$'))
end
end
for n in message.text:gmatch('[Tt][Ee][Ll][Ee][Gg][Rr][Aa][Mm]%.[Dd][Oo][Gg]/[Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]/[%w_]+') do
table.insert(links, n:match('/([Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]/[%w_]+)$'))
end
for n in message.text:gmatch('[Tt][Ee][Ll][Ee][Gg][Rr][Aa][Mm]%.[Dd][Oo][Gg]/[%w_]+') do
if not n:match('/[Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]$') then
table.insert(links, n:match('/([%w_]+)$'))
end
end
for n in message.text:gmatch('[Tt][Gg]://[Jj][Oo][Ii][Nn]%?[Ii][Nn][Vv][Ii][Tt][Ee]=[%w_]+') do
table.insert(links, '[Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]/' .. n:match('=([%w_]+)$'))
end
for n in message.text:gmatch('[Tt][Gg]://[Rr][Ee][Ss][Oo][Ll][Vv][Ee]%?[Dd][Oo][Mm][Aa][Ii][Nn]=[%w_]+') do
table.insert(links, n:match('=([%w_]+)$'))
end
- if whitelist then
+ if allowlist then
local count = 0
for _, v in pairs(links) do
v = v:match('^[Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]') and v or v:lower()
if delete then
- redis:del('whitelisted_links:' .. message.chat.id .. ':' .. v)
+ redis:del('allowlisted_links:' .. message.chat.id .. ':' .. v)
else
- redis:set('whitelisted_links:' .. message.chat.id .. ':' .. v, true)
+ redis:set('allowlisted_links:' .. message.chat.id .. ':' .. v, true)
end
count = count + 1
end
return string.format(
'%s link%s ha%s been %s in this chat!',
count,
count == 1 and '' or 's',
count == 1 and 's' or 've',
- delete and 'blacklisted' or 'whitelisted'
+ delete and 'blocklisted' or 'allowlisted'
)
end
local checked = {}
local valid = {}
for _, v in pairs(links) do
- if not redis:get('whitelisted_links:' .. message.chat.id .. ':' .. v:lower()) and not mattata.is_whitelisted_link(v:lower()) then
+ if not redis:get('allowlisted_links:' .. message.chat.id .. ':' .. v:lower()) and not mattata.is_allowlisted_link(v:lower()) then
if v:match('^[Jj][Oo][Ii][Nn][Cc][Hh][Aa][Tt]/') then
message.is_invite_link = true
if only_valid then
local str, res = https.request('https://t.me/' .. v)
if res == 200 and str and str:match('tgme_page_title') then
table.insert(valid, v)
end
end
if not get_links then
return return_message and message or true
end
elseif not mattata.table_contains(checked, v:lower()) then
if not mattata.get_user(v:lower()) then
local success = mattata.get_chat('@' .. v:lower(), true)
if success and success.result and success.result.type ~= 'private' and success.result.id ~= message.chat.id then
message.is_invite_link = true
if not get_links then
return return_message and message or true
end
table.insert(valid, v:lower())
end
table.insert(checked, v:lower())
end
end
end
end
if get_links then
if only_valid then
return valid
end
return checked
end
return return_message and message or false
end
function mattata:process_message(message, language)
local break_cycle = false
if not message.chat then
return true
- elseif self.is_command and not mattata.is_plugin_disabled('commandstats', message.chat.id) and not self.is_blacklisted then
+ elseif self.is_command and not mattata.is_plugin_disabled('commandstats', message.chat.id) and not self.is_blocklisted then
local command = message.text:match('^([!/#][%w_]+)')
if command then
redis:incr('commandstats:' .. message.chat.id .. ':' .. command)
if not redis:sismember('chat:' .. message.chat.id .. ':commands', command) then
redis:sadd('chat:' .. message.chat.id .. ':commands', command)
end
end
end
- if message.chat and message.chat.type ~= 'private' and not mattata.service_message(message) and not mattata.is_plugin_disabled('statistics', message) and not mattata.is_privacy_enabled(message.from.id) and not self.is_blacklisted then
+ if message.chat and message.chat.type ~= 'private' and not mattata.service_message(message) and not mattata.is_plugin_disabled('statistics', message) and not mattata.is_privacy_enabled(message.from.id) and not self.is_blocklisted then
redis:incr('messages:' .. message.from.id .. ':' .. message.chat.id)
end
if message.new_chat_members and mattata.get_setting(message.chat.id, 'use administration') and mattata.get_setting(message.chat.id, 'antibot') and not mattata.is_group_admin(message.chat.id, message.from.id) and not mattata.is_global_admin(message.from.id) then
local kicked = {}
local usernames = {}
for _, v in pairs(message.new_chat_members) do
if v.username and v.username:lower():match('bot$') and v.id ~= message.from.id and v.id ~= self.info.id and tostring(v.is_bot) == 'true' then
local success = mattata.kick_chat_member(message.chat.id, v.id)
if success then
table.insert(kicked, mattata.escape_html(v.first_name) .. ' [' .. v.id .. ']')
table.insert(usernames, '@' .. v.username)
end
end
end
if #kicked > 0 and #usernames > 0 and #kicked == #usernames then
local log_chat = mattata.get_log_chat(message.chat.id)
mattata.send_message(log_chat, string.format('<pre>%s [%s] has kicked %s from %s [%s] because anti-bot is enabled.</pre>', mattata.escape_html(self.info.first_name), self.info.id, table.concat(kicked, ', '), mattata.escape_html(message.chat.title), message.chat.id), 'html')
return mattata.send_message(message, string.format('Kicked %s because anti-bot is enabled.', table.concat(usernames, ', ')))
end
end
if message.chat.type == 'supergroup' and mattata.get_setting(message.chat.id, 'use administration') and mattata.get_setting(message.chat.id, 'word filter') and not mattata.is_group_admin(message.chat.id, message.from.id) and not mattata.is_global_admin(message.from.id) then
local words = redis:smembers('word_filter:' .. message.chat.id)
if words and #words > 0 then
for _, v in pairs(words) do
local text = message.text:lower()
if text:match('^' .. v:lower() .. '$') or text:match('^' .. v:lower() .. ' ') or text:match(' ' .. v:lower() .. ' ') or text:match(' ' .. v:lower() .. '$') then
mattata.delete_message(message.chat.id, message.message_id)
local action = mattata.get_setting(message.chat.id, 'ban not kick') and mattata.ban_chat_member or mattata.kick_chat_member
local success = action(message.chat.id, message.from.id)
if success then
if mattata.get_setting(message.chat.id, 'log administrative actions') then
local log_chat = mattata.get_log_chat(message.chat.id)
mattata.send_message(log_chat, string.format('<pre>%s [%s] has kicked %s [%s] from %s [%s] for sending one or more prohibited words.</pre>', mattata.escape_html(self.info.first_name), self.info.id, mattata.escape_html(message.from.first_name), message.from.id, mattata.escape_html(message.chat.title), message.chat.id), 'html')
end
mattata.send_message(message.chat.id, string.format('Kicked %s for sending one or more prohibited words.', message.from.username and '@' .. message.from.username or message.from.first_name))
break_cycle = true
end
end
end
if break_cycle then return true end
end
end
if message.new_chat_members and message.chat.type ~= 'private' and mattata.get_setting(message.chat.id, 'use administration') and mattata.get_setting(message.chat.id, 'welcome message') and not mattata.get_setting(message.chat.id, 'require captcha') then
if message.new_chat_members[1].id == self.info.id or (message.new_chat_members[1].username and message.new_chat_members[1].username:match('[Bb][Oo][Tt]$')) then
return false -- we don't want to send a welcome message if it's us or another bot (we're going to assume normal users don't have a username ending in bot...)
end
local chat_member = mattata.get_chat_member(message.chat.id, message.new_chat_members[1].id)
if chat_member.result.can_send_messages == false then
return mattata.delete_message(message.chat.id, message.message_id)
end
local name = message.new_chat_members[1].first_name
local first_name = mattata.escape_markdown(name)
if message.new_chat_members[1].last_name then
name = name .. ' ' .. message.new_chat_members[1].last_name
end
name = name:gsub('%%', '%%%%')
name = mattata.escape_markdown(name)
local title = message.chat.title:gsub('%%', '%%%%')
title = mattata.escape_markdown(title)
local username = message.new_chat_members[1].username and '@' .. message.new_chat_members[1].username or name
local welcome_message = mattata.get_value(message.chat.id, 'welcome message') or configuration.join_messages
if type(welcome_message) == 'table' then -- if it's a configured selection of welcome messages we'll just pick a random one
welcome_message = welcome_message[math.random(#welcome_message)]:gsub('NAME', name)
end
welcome_message = welcome_message:gsub('%$user_id', message.new_chat_member.id):gsub('%$chat_id', message.chat.id):gsub('%$first_name', first_name):gsub('%$name', name):gsub('%$title', title):gsub('%$username', username)
local keyboard = nil
if mattata.get_setting(message.chat.id, 'send rules on join') then
keyboard = mattata.inline_keyboard():row(mattata.row():url_button(utf8.char(128218) .. ' ' .. language['welcome']['1'], 'https://t.me/' .. self.info.username .. '?start=' .. message.chat.id .. '_rules'))
end
return mattata.send_message(message, welcome_message, 'markdown', true, false, nil, keyboard)
end
return false
end
return mattata
\ No newline at end of file
diff --git a/plugins/administration/whitelistbot.lua b/plugins/administration/allowbot.lua
similarity index 60%
copy from plugins/administration/whitelistbot.lua
copy to plugins/administration/allowbot.lua
index 6d3ee62..0e9256f 100644
--- a/plugins/administration/whitelistbot.lua
+++ b/plugins/administration/allowbot.lua
@@ -1,53 +1,53 @@
---[[
- Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
- This code is licensed under the MIT. See LICENSE for details.
-]]
-
-local whitelistbot = {}
-local mattata = require('mattata')
-local redis = require('libs.redis')
-
-function whitelistbot:init()
- whitelistbot.commands = mattata.commands(self.info.username):command('whitelistbot'):command('whitelistbots'):command('wb').table
- whitelistbot.help = '/whitelistbot <bots> - Whitelists the given bots in the current chat. Requires administrative privileges. Aliases: /whitelistbots, /wb.'
- whitelistbot.example_bots = { 'gif', 'imdb', 'wiki', 'music', 'youtube', 'bold', 'sticker', 'vote', 'like', 'gamee', 'coub', 'pic', 'vid', 'bing' }
-end
-
-function whitelistbot:on_new_message(message, configuration, language)
- if message.chat.type ~= 'supergroup' then
- return false
- elseif mattata.get_setting(message.chat.id, 'prevent inline bots') and message.via_bot and not mattata.is_group_admin(message.chat.id, message.from.id) then
- return mattata.delete_message(message.chat.id, message.message_id)
- end
-end
-
-function whitelistbot:on_message(message, configuration, language)
- if not mattata.is_group_admin(message.chat.id, message.from.id) then
- return mattata.send_reply(message, language.errors.admin)
- end
- local input = mattata.input(message.text)
- if not input then
- return mattata.send_reply(message, 'Please specify the @usernames of the bots you\'d like to whitelist.')
- elseif not input:match('@?[%w_]') then
- return mattata.send_reply(message, 'Please make sure you\'re specifying valid bot usernames!')
- end
- local bots = {}
- for bot in input:gmatch('@?([%w_]+bot)') do
- table.insert(bots, bot)
- end
- for _, bot in pairs(whitelistbot.example_bots) do
- if input:match('@?' .. bot) then
- table.insert(bots, bot)
- end
- end
- if #bots == 0 then
- return mattata.send_reply(message, 'Please make sure you\'re specifying valid bot usernames!')
- end
- for _, bot in pairs(bots) do
- redis:sadd('whitelisted_bots:' .. message.chat.id, bot)
- end
- local output = string.format('Successfully whitelisted the following bots in this chat: %s', table.concat(bots, ', '))
- return mattata.send_reply(message, output)
-end
-
-return whitelistbot
\ No newline at end of file
+--[[
+ Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
+ This code is licensed under the MIT. See LICENSE for details.
+]]
+
+local allowbot = {}
+local mattata = require('mattata')
+local redis = require('libs.redis')
+
+function allowbot:init()
+ allowbot.commands = mattata.commands(self.info.username):command('allowbot'):command('allowbots'):command('wb').table
+ allowbot.help = '/allowbot <bots> - Allowlists the given bots in the current chat. Requires administrative privileges. Aliases: /allowbots, /wb.'
+ allowbot.example_bots = { 'gif', 'imdb', 'wiki', 'music', 'youtube', 'bold', 'sticker', 'vote', 'like', 'gamee', 'coub', 'pic', 'vid', 'bing' }
+end
+
+function allowbot:on_new_message(message, configuration, language)
+ if message.chat.type ~= 'supergroup' then
+ return false
+ elseif mattata.get_setting(message.chat.id, 'prevent inline bots') and message.via_bot and not mattata.is_group_admin(message.chat.id, message.from.id) then
+ return mattata.delete_message(message.chat.id, message.message_id)
+ end
+end
+
+function allowbot:on_message(message, configuration, language)
+ if not mattata.is_group_admin(message.chat.id, message.from.id) then
+ return mattata.send_reply(message, language.errors.admin)
+ end
+ local input = mattata.input(message.text)
+ if not input then
+ return mattata.send_reply(message, 'Please specify the @usernames of the bots you\'d like to allowlist.')
+ elseif not input:match('@?[%w_]') then
+ return mattata.send_reply(message, 'Please make sure you\'re specifying valid bot usernames!')
+ end
+ local bots = {}
+ for bot in input:gmatch('@?([%w_]+bot)') do
+ table.insert(bots, bot)
+ end
+ for _, bot in pairs(allowbot.example_bots) do
+ if input:match('@?' .. bot) then
+ table.insert(bots, bot)
+ end
+ end
+ if #bots == 0 then
+ return mattata.send_reply(message, 'Please make sure you\'re specifying valid bot usernames!')
+ end
+ for _, bot in pairs(bots) do
+ redis:sadd('allowlisted_bots:' .. message.chat.id, bot)
+ end
+ local output = string.format('Successfully allowlisted the following bots in this chat: %s', table.concat(bots, ', '))
+ return mattata.send_reply(message, output)
+end
+
+return allowbot
\ No newline at end of file
diff --git a/plugins/administration/allowedlinks.lua b/plugins/administration/allowedlinks.lua
index 5b3767d..310c494 100644
--- a/plugins/administration/allowedlinks.lua
+++ b/plugins/administration/allowedlinks.lua
@@ -1,35 +1,35 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local allowedlinks = {}
local mattata = require('mattata')
local redis = require('libs.redis')
function allowedlinks:init()
allowedlinks.commands = mattata.commands(self.info.username):command('allowedlinks'):command('al').table
allowedlinks.help = '/allowedlinks - View the Telegram invite links you\'re allowed to send in this chat. Alias: /al.'
end
function allowedlinks:on_message(message, _, language)
if message.chat.type ~= 'supergroup' then
return mattata.send_reply(message, language.errors.supergroup)
elseif not mattata.get_setting(message.chat.id, 'antilink') then
- return mattata.send_reply(message, 'You\'re as free as a bird! Feel free to send any links in this chat (make sure you check the `/rules` first!). Admins can setup anti-link by using `/settings`, enabling `Anti-Link` and sending `/whitelistlink <links>`.', true)
+ return mattata.send_reply(message, 'You\'re as free as a bird! Feel free to send any links in this chat (make sure you check the `/rules` first!). Admins can setup anti-link by using `/settings`, enabling `Anti-Link` and sending `/allowlink <links>`.', true)
end
- local allowed = redis:keys('whitelisted_links:' .. message.chat.id .. ':*')
+ local allowed = redis:keys('allowlisted_links:' .. message.chat.id .. ':*')
local output = { 'You\'re allowed to send the following links in this group:\n' }
if #allowed == 0 then
- return mattata.send_reply(message, 'There are no whitelisted groups here. Admins can whitelist Telegram links (or @username) by sending `/whitelistlink <links>`.', true)
+ return mattata.send_reply(message, 'There are no allowlisted groups here. Admins can allowlist Telegram links (or @username) by sending `/allowlink <links>`.', true)
end
for _, link in pairs(allowed) do
- link = link:match('^whitelisted_links:' .. tostring(message.chat.id):gsub('%-', '%%-') .. ':(.-)$')
+ link = link:match('^allowlisted_links:' .. tostring(message.chat.id):gsub('%-', '%%-') .. ':(.-)$')
link = 't.me/' .. link
table.insert(output, mattata.symbols.bullet .. ' ' .. link)
end
output = table.concat(output, '\n')
return mattata.send_reply(message, output, nil, true)
end
return allowedlinks
\ No newline at end of file
diff --git a/plugins/administration/whitelistlink.lua b/plugins/administration/allowlink.lua
similarity index 58%
copy from plugins/administration/whitelistlink.lua
copy to plugins/administration/allowlink.lua
index 28ab1e0..2ef6c9b 100644
--- a/plugins/administration/whitelistlink.lua
+++ b/plugins/administration/allowlink.lua
@@ -1,30 +1,30 @@
---[[
- Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
- This code is licensed under the MIT. See LICENSE for details.
-]]
-
-local whitelistlink = {}
-local mattata = require('mattata')
-
-function whitelistlink:init()
- whitelistlink.commands = mattata.commands(self.info.username):command('whitelistlink'):command('wl').table
- whitelistlink.help = '/whitelistlink <links> - Whitelists the given links in the current chat. Requires administrative privileges. Use /whitelistlink -del <links> to Alias: /wl.'
-end
-
-function whitelistlink:on_message(message)
- if not mattata.is_group_admin(message.chat.id, message.from.id) then
- return false
- end
- local input = mattata.input(message.text)
- local delete = false
- if not input then
- return mattata.send_reply(message, 'Please specify the URLs or @usernames you\'d like to whitelist.')
- elseif input:match('^%-del .-$') then
- input = input:match('^%-del (.-)$')
- delete = true
- end
- local output = mattata.check_links(message, false, false, true, false, delete)
- return mattata.send_reply(message, output)
-end
-
-return whitelistlink
\ No newline at end of file
+--[[
+ Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
+ This code is licensed under the MIT. See LICENSE for details.
+]]
+
+local allowlink = {}
+local mattata = require('mattata')
+
+function allowlink:init()
+ allowlink.commands = mattata.commands(self.info.username):command('allowlink'):command('wl').table
+ allowlink.help = '/allowlink <links> - Allowlists the given links in the current chat. Requires administrative privileges. Use /allowlink -del <links> to Alias: /wl.'
+end
+
+function allowlink:on_message(message)
+ if not mattata.is_group_admin(message.chat.id, message.from.id) then
+ return false
+ end
+ local input = mattata.input(message.text)
+ local delete = false
+ if not input then
+ return mattata.send_reply(message, 'Please specify the URLs or @usernames you\'d like to allowlist.')
+ elseif input:match('^%-del .-$') then
+ input = input:match('^%-del (.-)$')
+ delete = true
+ end
+ local output = mattata.check_links(message, false, false, true, false, delete)
+ return mattata.send_reply(message, output)
+end
+
+return allowlink
\ No newline at end of file
diff --git a/plugins/administration/whitelist.lua b/plugins/administration/allowlist.lua
similarity index 85%
copy from plugins/administration/whitelist.lua
copy to plugins/administration/allowlist.lua
index 7824499..be1044c 100644
--- a/plugins/administration/whitelist.lua
+++ b/plugins/administration/allowlist.lua
@@ -1,167 +1,167 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
-local whitelist = {}
+local allowlist = {}
local mattata = require('mattata')
local redis = require('libs.redis')
-function whitelist:init()
- whitelist.commands = mattata.commands(self.info.username):command('whitelist').table
- whitelist.help = '/whitelist [user] - Whitelists a user to use the bot in the current chat. This command can only be used by moderators and administrators of a supergroup.'
+function allowlist:init()
+ allowlist.commands = mattata.commands(self.info.username):command('allowlist').table
+ allowlist.help = '/allowlist [user] - Allowlists a user to use the bot in the current chat. This command can only be used by moderators and administrators of a supergroup.'
end
-function whitelist:on_message(message, configuration, language)
+function allowlist:on_message(message, configuration, language)
if message.chat.type ~= 'supergroup'
then
return mattata.send_reply(
message,
language['errors']['supergroup']
)
elseif not mattata.is_group_admin(
message.chat.id,
message.from.id
)
then
return mattata.send_reply(
message,
language['errors']['admin']
)
end
local reason = false
local input = message.reply
and (
message.reply.from.username
or tostring(message.reply.from.id)
)
or mattata.input(message.text)
if not input
then
local success = mattata.send_force_reply(
message,
- language['whitelist']['1']
+ language['allowlist']['1']
)
if success
then
redis:set(
string.format(
'action:%s:%s',
message.chat.id,
success.result.message_id
),
- '/whitelist'
+ '/allowlist'
)
end
return
elseif not message.reply
then
if input:match('^.- .-$')
then
reason = input:match(' (.-)$')
input = input:match('^(.-) ')
end
elseif mattata.input(message.text)
then
reason = mattata.input(message.text)
end
if tonumber(input) == nil
and not input:match('^%@')
then
input = '@' .. input
end
local user = mattata.get_user(input)
or mattata.get_chat(input) -- Resolve the username/ID to a user object.
if not user
then
return mattata.send_reply(
message,
language['errors']['unknown']
)
elseif user.result.id == self.info.id
then
return
end
user = user.result
local status = mattata.get_chat_member(
message.chat.id,
user.id
)
if not status
then
return mattata.send_reply(
message,
language['errors']['generic']
)
elseif mattata.is_group_admin(
message.chat.id,
user.id
)
or status.result.status == 'creator'
or status.result.status == 'administrator'
- then -- We won't try and whitelist moderators and administrators.
+ then -- We won't try and allowlist moderators and administrators.
return mattata.send_reply(
message,
- language['whitelist']['2']
+ language['allowlist']['2']
)
elseif status.result.status == 'left'
or status.result.status == 'kicked'
then -- Check if the user is in the group or not.
return mattata.send_reply(
message,
status.result.status == 'left'
- and language['whitelist']['3']
- or language['whitelist']['4']
+ and language['allowlist']['3']
+ or language['allowlist']['4']
)
end
- redis:del('group_whitelist:' .. message.chat.id .. ':' .. user.id)
+ redis:del('group_allowlist:' .. message.chat.id .. ':' .. user.id)
redis:hincrby(
string.format(
'chat:%s:%s',
message.chat.id,
user.id
),
- 'whitelists',
+ 'allowlists',
1
)
if redis:hget(
string.format(
'chat:%s:settings',
message.chat.id
),
'log administrative actions'
) then
mattata.send_message(
mattata.get_log_chat(message.chat.id),
string.format(
- '<pre>%s%s [%s] has whitelisted %s%s [%s] in %s%s [%s]%s.</pre>',
+ '<pre>%s%s [%s] has allowlisted %s%s [%s] in %s%s [%s]%s.</pre>',
message.from.username and '@' or '',
message.from.username or mattata.escape_html(message.from.first_name),
message.from.id,
user.username and '@' or '',
user.username or mattata.escape_html(user.first_name),
user.id,
message.chat.username and '@' or '',
message.chat.username or mattata.escape_html(message.chat.title),
message.chat.id,
reason and ', for ' .. reason or ''
),
'html'
)
end
mattata.unban_chat_member(message.chat.id, user.id) -- attempt to unban the user too
return mattata.send_message(
message.chat.id,
string.format(
- '<pre>%s%s has whitelisted %s%s%s.</pre>',
+ '<pre>%s%s has allowlisted %s%s%s.</pre>',
message.from.username and '@' or '',
message.from.username or mattata.escape_html(message.from.first_name),
user.username and '@' or '',
user.username or mattata.escape_html(user.first_name),
reason and ', for ' .. reason or ''
),
'html'
)
end
-return whitelist
\ No newline at end of file
+return allowlist
\ No newline at end of file
diff --git a/plugins/administration/anticrypto.lua b/plugins/administration/anticrypto.lua
index bbcdefb..02c885f 100644
--- a/plugins/administration/anticrypto.lua
+++ b/plugins/administration/anticrypto.lua
@@ -1,62 +1,65 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local anticrypto = {}
local mattata = require('mattata')
local redis = require('libs.redis')
function anticrypto:on_new_message(message, configuration)
- if message.chat.type ~= 'supergroup' or not redis:sismember('anticrypto:groups', message.chat.id) or tonumber(redis:get('messages:' .. message.from.id .. ':' .. message.chat.id)) > 20 or not message.photo or (mattata.is_group_admin(message.chat.id, message.from.id) and not mattata.is_global_admin(message.from.id)) then
+ if 1+1 == 2 then return false end
+ if message.chat.type ~= 'supergroup' or tonumber(redis:get('messages:' .. message.from.id .. ':' .. message.chat.id)) > 20 or not message.photo or (mattata.is_group_admin(message.chat.id, message.from.id) and not mattata.is_global_admin(message.from.id)) then
+ return false
+ elseif not redis:sismember('anticrypto:groups', message.chat.id) then
return false
end
local file_id = message.photo[#message.photo].file_id
local file = mattata.get_file(file_id)
if not file then
return false
end
local file_name = file.result.file_path
local file_path = string.format('https://api.telegram.org/file/bot%s/%s', configuration.bot_token, file_name)
file = mattata.download_file(file_path, file_name:match('/(.-)$'), configuration.download_location)
if not file then
return false
end
local command = string.format('tesseract --tessdata-dir /home/matt/matticatebot/tesseract/ --oem 3 %s stdout', file)
local exec = io.popen(command)
local contents = exec:read('*all')
exec:close()
os.execute('rm ' .. file)
local matches = {
'[Tt][Ee][Ss][LlTt][Aa]',
'[Bb][Ii][Tt][Cc][Oo][Ii][Nn]',
'[AaEe]Ll][Oo][Nn] ?[Mm][Nn]?[Uu][Ss][Kk]',
'[Gg][Ii][Vv][Ee][Aa][Ww][Aa][Yy]',
'[Ff][Ii][Nn][Aa][Nn][Cc][Ii][Aa][Ll]',
'[Dd][Rr][Oo][Pp][EeAa][LlI][Oo][Nn]'
}
for _, match in pairs(matches) do
if contents:match(match) then
local punishment = mattata.get_setting(message.chat.id, 'ban not kick')
local action = punishment and mattata.ban_chat_member or mattata.kick_chat_member
action(message.chat.id, message.from.id)
punishment = punishment and 'banned' or 'kicked'
local bot_username = mattata.get_formatted_user(self.info.id, self.info.first_name, 'html')
local offender_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
local output
if mattata.get_setting(message.chat.id, 'log administrative actions') then
local log_chat = mattata.get_log_chat(message.chat.id)
output = '%s <code>[%s]</code> has %s %s <code>[%s]</code> from %s <code>[%s]</code> for sending crypto-spam.\n%s %s'
output = string.format(output, bot_username, self.info.id, punishment, offender_username, message.from.id, mattata.escape_html(message.chat.title), message.chat.id, '#chat' .. tostring(message.chat.id):gsub('^-100', ''), '#user' .. message.from.id)
mattata.send_message(log_chat, output, 'html')
else
output = string.format('%s %s for sending crypto-spam.', punishment:gsub('^%l', string.upper), offender_username)
mattata.send_message(message.chat.id, output, 'html')
end
return mattata.delete_message(message.chat.id, message.message_id)
end
end
return mattata.send_message(configuration.admins[1], contents)
end
return anticrypto
\ No newline at end of file
diff --git a/plugins/administration/antispam.lua b/plugins/administration/antispam.lua
index e6f1ce8..20c8150 100644
--- a/plugins/administration/antispam.lua
+++ b/plugins/administration/antispam.lua
@@ -1,303 +1,303 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local antispam = {}
local mattata = require('mattata')
local redis = require('libs.redis')
function antispam:init(configuration)
antispam.commands = mattata.commands(self.info.username):command('antispam').table
antispam.media_types = {
'text',
'forwarded',
'sticker',
'photo',
'video',
'location',
'voice',
'game',
'venue',
'video note',
'invoice',
'contact',
'dice',
'poll'
}
antispam.default_values = {
['text'] = configuration.administration.default.antispam.text,
['forwarded'] = configuration.administration.default.antispam.forwarded,
['sticker'] = configuration.administration.default.antispam.sticker,
['photo'] = configuration.administration.default.antispam.photo,
['video'] = configuration.administration.default.antispam.video,
['location'] = configuration.administration.default.antispam.location,
['voice'] = configuration.administration.default.antispam.voice,
['game'] = configuration.administration.default.antispam.game,
['venue'] = configuration.administration.default.antispam.venue,
['video note'] = configuration.administration.default.antispam.video_note,
['invoice'] = configuration.administration.default.antispam.invoice,
['contact'] = configuration.administration.default.antispam.contact,
['dice'] = configuration.administration.default.antispam.dice,
['poll'] = configuration.administration.default.antispam.poll
}
end
function antispam.on_member_join(_, message)
for _, user in pairs(message.new_chat_members) do
redis:set('join_time:' .. user.id .. ':' .. message.chat.id, os.time())
end
end
function antispam:on_new_message(message, configuration, language)
if message.from.id == 777000 then
return false
end
-- Thanks to GingerPlusPlus for the idea
if message.chat.type ~= 'private' and mattata.get_setting(message.chat.id, 'remove pasted code') then
if message.entities then
for _, entity in pairs(message.entities) do
if (entity.type == 'pre' or entity.type == 'code') and entity.length > configuration.administration.global_antispam.max_code_length and not mattata.is_group_admin(message.chat.id, message.from.id) then
local success = mattata.delete_message(message.chat.id, message.message_id)
if success then
local name = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
local output = string.format(language['antispam']['11'], name, configuration.administration.global_antispam.max_code_length, self.info.username:lower())
return mattata.send_message(message.chat.id, output, 'html', true)
end
return false
end
end
end
end
if message.chat.type == 'supergroup' and mattata.get_setting(message.chat.id, 'antilink') and message.is_invite_link then
if not mattata.is_group_admin(message.chat.id, message.from.id) and not mattata.is_global_admin(message.from.id) and message.is_invite_link then
local action = mattata.get_setting(message.chat.id, 'ban not kick') and mattata.ban_chat_member or mattata.kick_chat_member
local punishment = mattata.get_setting(message.chat.id, 'ban not kick') and 'banned' or 'kicked'
local success = action(message.chat.id, message.from.id)
local output
if success then
local banned_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
if mattata.get_setting(message.chat.id, 'log administrative actions') then
local log_chat = mattata.get_log_chat(message.chat.id)
local admin_username = mattata.get_formatted_user(self.info.id, self.info.first_name, 'html')
output = string.format(language['antispam']['12'], admin_username, self.info.id, punishment, banned_username, message.from.id, mattata.escape_html(message.chat.title), message.chat.id, tostring(message.chat.id):gsub('^%-100', ''), message.from.id)
mattata.send_message(log_chat, output, 'html')
else
output = string.format(language['antispam']['13'], punishment:gsub('^%l', string.upper), banned_username)
mattata.send_message(message.chat.id, output, 'html')
end
mattata.delete_message(message.chat.id, message.message_id)
return
end
else
- local whitelisted = true
+ local allowlisted = true
local links = mattata.check_links(message, true, true)
if links and #links > 0 then
for _, link in pairs(links) do
- if not redis:get('whitelisted_links:' .. message.chat.id .. ':' .. link) and not mattata.table_contains(configuration.administration.allowed_links, link:lower()) then
- whitelisted = false
+ if not redis:get('allowlisted_links:' .. message.chat.id .. ':' .. link) and not mattata.table_contains(configuration.administration.allowed_links, link:lower()) then
+ allowlisted = false
break
end
end
end
- if not whitelisted and not message.text:match('^[!/#]whitelistlink') and not message.text:match('^[!/#]wl') then
+ if not allowlisted and not message.text:match('^[!/#]allowlink') and not message.text:match('^[!/#]wl') then
return mattata.send_reply(message, language['antispam']['14'])
end
end
end
local messages = redis:get('messages:' .. message.from.id .. ':' .. message.chat.id) or 0
local join_time = redis:get('join_time:' .. message.from.id .. ':' .. message.chat.id)
if message.chat.type == 'supergroup' and not mattata.is_group_admin(message.chat.id, message.from.id) and messages <= 3 and join_time and mattata.get_setting(message.chat.id, 'kick urls on join') and message.entities then
for _, entity in pairs(message.entities) do
if entity.type == 'url' then
redis:del('messages:' .. message.from.id .. ':' .. message.chat.id)
local log_actions = mattata.get_setting(message.chat.id, 'log administrative actions')
local log_chat = mattata.get_log_chat(message.chat.id)
local kicked_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
local output = string.format(language['antispam']['16'], kicked_username, message.from.id, mattata.escape_html(message.chat.title), message.chat.id, tostring(message.chat.id):gsub('^%-100', ''), message.from.id)
for _, entities in pairs(message.entities) do
if entities.type == 'url' then
mattata.delete_message(message.chat.id, message.message_id)
if log_actions then
mattata.send_message(log_chat, output, 'html')
end
return mattata.kick_chat_member(message.chat.id, message.from.id)
end
end
end
end
end
if message.chat.type == 'supergroup' and (message.entities or message.photo or message.document) and mattata.get_setting(message.chat.id, 'kick media on join') and messages <= 2 and not mattata.is_group_admin(message.chat.id, message.from.id) and join_time then
redis:del('messages:' .. message.from.id .. ':' .. message.chat.id)
local log_actions = mattata.get_setting(message.chat.id, 'log administrative actions')
local log_chat = mattata.get_log_chat(message.chat.id)
local kicked_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
local output = string.format(language['antispam']['15'], kicked_username, message.from.id, mattata.escape_html(message.chat.title), message.chat.id, tostring(message.chat.id):gsub('^%-100', ''), message.from.id)
if message.photo or message.document then
mattata.delete_message(message.chat.id, message.message_id)
if log_actions then
mattata.send_message(log_chat, output, 'html')
end
return mattata.kick_chat_member(message.chat.id, message.from.id)
end
end
end
function antispam.get_keyboard(chat_id, language)
local status = redis:hget('chat:' .. chat_id .. ':settings', 'antispam') and true or false
local caption = status and language['antispam']['1'] or language['antispam']['2']
local keyboard = {
['inline_keyboard'] = {}
}
table.insert(keyboard.inline_keyboard, {{
['text'] = caption,
['callback_data'] = 'antispam:' .. chat_id .. ':' .. caption:lower()
}})
if status then
for _, media in pairs(antispam.media_types) do
local current = mattata.get_value(chat_id, media .. ' limit') or antispam.default_values[media]
if not mattata.get_setting(chat_id, 'allow ' .. media) then
table.insert(keyboard.inline_keyboard, {{
['text'] = media:gsub('^%l', string.upper),
['callback_data'] = 'antispam:nil'
}, {
['text'] = '-',
['callback_data'] = 'antispam:' .. chat_id .. ':limit:' .. media .. ':' .. tonumber(current) - 1
}, {
['text'] = tostring(current),
['callback_data'] = 'antispam:nil'
}, {
['text'] = '+',
['callback_data'] = 'antispam:' .. chat_id .. ':limit:' .. media .. ':' .. tonumber(current) + 1
}, {
['text'] = language['antispam']['3'],
['callback_data'] = 'antispam:' .. chat_id .. ':toggle:' .. media
}})
else
table.insert(keyboard.inline_keyboard, {{
['text'] = media:gsub('^%l', string.upper),
['callback_data'] = 'antispam:nil'
}, {
['text'] = string.format(language['antispam']['4'], media),
['callback_data'] = 'antispam:' .. chat_id .. ':toggle:' .. media
}})
end
end
end
table.insert(keyboard.inline_keyboard, {{
['text'] = mattata.symbols.back .. ' ' .. language['antispam']['5'],
['callback_data'] = 'administration:' .. chat_id .. ':page:1'
}})
return keyboard
end
function antispam.is_user_spamming(message)
if message.media_type == '' or mattata.get_setting(message.chat.id, 'allow ' .. message.media_type) then
return false
end
local limit = mattata.get_value(message.chat.id, message.media_type .. ' limit') or antispam.default_values[message.media_type]
local current = redis:get('antispam:' .. message.media_type .. ':' .. message.chat.id .. ':' .. message.from.id) or 1
redis:setex('antispam:' .. message.media_type .. ':' .. message.chat.id .. ':' .. message.from.id, 5, tonumber(current) + 1)
if tonumber(current) == tonumber(limit) then
return true, message.media_type
elseif message.media_type == 'rtl' and mattata.get_setting(message.chat.id, 'antirtl') then
return true, 'rtl'
end
return false
end
function antispam:process_message(message, _, language)
if message.chat.type ~= 'supergroup' then
return false, 'The chat is not a supergroup!'
elseif mattata.is_group_admin(message.chat.id, message.from.id) then
return false, 'That user is an administrator in this chat!'
elseif mattata.is_global_admin(message.from.id) then
return false, 'That user is a global admin!'
elseif not mattata.get_setting(message.chat.id, 'use administration') then
return false, 'The administration plugin is switched off in this chat!'
elseif not mattata.get_setting(message.chat.id, 'antispam') then
return false, 'The antispam plugin is switched off in this chat!'
end
local is_spamming, media_type = antispam.is_user_spamming(message)
if not is_spamming then
return false, 'This user is not spamming!'
end
local action = mattata.get_setting(message.chat.id, 'ban not kick') and mattata.ban_chat_member or mattata.kick_chat_member
local success, error_message = action(message.chat.id, message.from.id)
if not success then
return false, error_message
elseif mattata.get_setting(message.chat.id, 'log administrative actions') then
mattata.send_message(
mattata.get_log_chat(message.chat.id),
string.format(
'<pre>' .. language['antispam']['6'] .. '</pre>',
mattata.escape_html(self.info.first_name),
self.info.id,
mattata.escape_html(message.from.first_name),
message.from.id,
mattata.escape_html(message.chat.title),
message.chat.id,
media_type
),
'html'
)
end
return mattata.send_message(
message,
string.format(
language['antispam']['7'],
message.from.username and '@' .. message.from.username or message.from.first_name,
media_type
)
)
end
function antispam.on_callback_query(_, callback_query, message, _, language)
local chat_id = (message and message.chat and message.chat.type == 'supergroup') and message.chat.id or callback_query.data:match('^(%-%d+):?')
if not chat_id then
mattata.answer_callback_query(callback_query.id, language['errors']['generic'])
return false, 'No chat ID was found!'
elseif not mattata.is_group_admin(chat_id, callback_query.from.id) then
mattata.answer_callback_query(callback_query.id, language['errors']['admin'])
return false, 'That user is not an admin/mod in this chat!'
end
if callback_query.data:match('^%-%d+:limit:.-:.-$') then
local spam_type, limit = callback_query.data:match('^%-%d+:limit:(.-):(.-)$')
if tonumber(limit) > 100 then
local output = language['antispam']['8']
mattata.answer_callback_query(callback_query.id, output)
return false, output
elseif tonumber(limit) < 1 then
local output = language['antispam']['9']
mattata.answer_callback_query(callback_query.id, output)
return false, output
elseif tonumber(limit) == nil then
return false, 'The limit given wasn\'t of type "number"!'
end
redis:hset('chat:' .. chat_id .. ':info', spam_type .. ' limit', tonumber(limit))
elseif callback_query.data:match('^%-%d+:toggle:.-$') then
local spam_type = callback_query.data:match('^%-%d+:toggle:(.-)$')
mattata.toggle_setting(chat_id, 'allow ' .. spam_type)
elseif callback_query.data:match('^%-%d+:disable$') then
redis:hdel('chat:' .. chat_id .. ':settings', 'antispam')
elseif callback_query.data:match('^%-%d+:enable$') then
redis:hset('chat:' .. chat_id .. ':settings', 'antispam', true)
end
local keyboard = antispam.get_keyboard(chat_id, language)
return mattata.edit_message_reply_markup(message.chat.id, message.message_id, nil, keyboard)
end
function antispam.on_message(_, message, _, language)
if message.chat.type ~= 'supergroup' then
mattata.send_reply(message, language['errors']['supergroup'])
return false, 'The chat is not a supergroup!'
elseif not mattata.is_group_admin(message.chat.id, message.from.id) then
mattata.send_reply(message, language['errors']['admin'])
return false, 'That user is not an admin/mod in this chat!'
end
local output = string.format(language['antispam']['10'], message.chat.title)
local keyboard = antispam.get_keyboard(message.chat.id, language)
return mattata.send_message(message.chat.id, output, nil, true, false, nil, keyboard)
end
return antispam
\ No newline at end of file
diff --git a/plugins/administration/blacklist.lua b/plugins/administration/blacklist.lua
index e424cca..9bbaa82 100644
--- a/plugins/administration/blacklist.lua
+++ b/plugins/administration/blacklist.lua
@@ -1,77 +1,77 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
-local blacklist = {}
+local blocklist = {}
local mattata = require('mattata')
local redis = require('libs.redis')
-function blacklist:init()
- blacklist.commands = mattata.commands(self.info.username):command('blacklist').table
- blacklist.help = '/blacklist [user] - Blacklists a user from using the bot in the current chat. This command can only be used by moderators and administrators of a supergroup.'
+function blocklist:init()
+ blocklist.commands = mattata.commands(self.info.username):command('blocklist').table
+ blocklist.help = '/blocklist [user] - Blocklists a user from using the bot in the current chat. This command can only be used by moderators and administrators of a supergroup.'
end
-function blacklist:on_message(message, _, language)
+function blocklist:on_message(message, _, language)
if message.chat.type ~= 'supergroup' then
return mattata.send_reply(message, language.errors.supergroup)
elseif not mattata.is_group_admin(message.chat.id, message.from.id) then
return mattata.send_reply(message, language.errors.admin)
end
local reason = false
local input = message.reply and message.reply.from.id or mattata.input(message.text)
if not input then
- local success = mattata.send_force_reply(message, language['blacklist']['1'])
+ local success = mattata.send_force_reply(message, language['blocklist']['1'])
if success then
- mattata.set_command_action(message.chat.id, success.result.message_id, '/blacklist')
+ mattata.set_command_action(message.chat.id, success.result.message_id, '/blocklist')
end
return
elseif not message.reply then
if input:match('^.- .-$') then
input, reason = input:match('^(.-) (.-)$')
end
elseif mattata.input(message.text) then
reason = mattata.input(message.text)
end
if tonumber(input) == nil and not input:match('^%@') then
input = '@' .. input
end
local user = mattata.get_user(input) -- Resolve the username/ID to a user object.
if not user then
return mattata.send_reply(message, language.errors.unknown)
elseif user.result.id == self.info.id then
return
end
user = user.result
local status = mattata.get_chat_member(message.chat.id, user.id)
if not status then
return mattata.send_reply(message, language.errors.generic)
- elseif mattata.is_group_admin(message.chat.id, user.id) then -- We won't try and blacklist moderators and administrators.
- return mattata.send_reply(message, language['blacklist']['2'])
+ elseif mattata.is_group_admin(message.chat.id, user.id) then -- We won't try and blocklist moderators and administrators.
+ return mattata.send_reply(message, language['blocklist']['2'])
elseif status.result.status == 'left' or status.result.status == 'kicked' then -- Check if the user is in the group or not.
- local output = status.result.status == 'left' and language['blacklist']['3'] or language['blacklist']['4']
+ local output = status.result.status == 'left' and language['blocklist']['3'] or language['blocklist']['4']
return mattata.send_reply(message, output)
end
- redis:set('group_blacklist:' .. message.chat.id .. ':' .. user.id, true)
- mattata.increase_administrative_action(message.chat.id, user.id, 'blacklists')
+ redis:set('group_blocklist:' .. message.chat.id .. ':' .. user.id, true)
+ mattata.increase_administrative_action(message.chat.id, user.id, 'blocklists')
reason = reason and ', for ' .. reason or ''
local admin_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
- local blacklisted_username = mattata.get_formatted_user(user.id, user.first_name, 'html')
+ local blocklisted_username = mattata.get_formatted_user(user.id, user.first_name, 'html')
local bot_username = mattata.get_formatted_user(self.info.id, self.info.first_name, 'html')
local output
if mattata.get_setting(message.chat.id, 'log administrative actions') then
local log_chat = mattata.get_log_chat(message.chat.id)
- output = string.format(language['blacklist']['5'], admin_username, message.from.id, blacklisted_username, user.id, bot_username, self.info.id, mattata.escape_html(message.chat.title), message.chat.id, reason, '#chat' .. tostring(message.chat.id):gsub('^-100', ''), '#user' .. user.id)
+ output = string.format(language['blocklist']['5'], admin_username, message.from.id, blocklisted_username, user.id, bot_username, self.info.id, mattata.escape_html(message.chat.title), message.chat.id, reason, '#chat' .. tostring(message.chat.id):gsub('^-100', ''), '#user' .. user.id)
mattata.send_message(log_chat, output, 'html')
else
- output = string.format(language['blacklist']['6'], admin_username, blacklisted_username, bot_username, reason)
+ output = string.format(language['blocklist']['6'], admin_username, blocklisted_username, bot_username, reason)
mattata.send_message(message.chat.id, output, 'html')
end
if message.reply and mattata.get_setting(message.chat.id, 'delete reply on action') then
mattata.delete_message(message.chat.id, message.reply.message_id)
mattata.delete_message(message.chat.id, message.message_id)
end
return
end
-return blacklist
\ No newline at end of file
+return blocklist
\ No newline at end of file
diff --git a/plugins/administration/blacklist.lua b/plugins/administration/blocklist.lua
similarity index 76%
copy from plugins/administration/blacklist.lua
copy to plugins/administration/blocklist.lua
index e424cca..6e49490 100644
--- a/plugins/administration/blacklist.lua
+++ b/plugins/administration/blocklist.lua
@@ -1,77 +1,77 @@
---[[
- Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
- This code is licensed under the MIT. See LICENSE for details.
-]]
-
-local blacklist = {}
-local mattata = require('mattata')
-local redis = require('libs.redis')
-
-function blacklist:init()
- blacklist.commands = mattata.commands(self.info.username):command('blacklist').table
- blacklist.help = '/blacklist [user] - Blacklists a user from using the bot in the current chat. This command can only be used by moderators and administrators of a supergroup.'
-end
-
-function blacklist:on_message(message, _, language)
- if message.chat.type ~= 'supergroup' then
- return mattata.send_reply(message, language.errors.supergroup)
- elseif not mattata.is_group_admin(message.chat.id, message.from.id) then
- return mattata.send_reply(message, language.errors.admin)
- end
- local reason = false
- local input = message.reply and message.reply.from.id or mattata.input(message.text)
- if not input then
- local success = mattata.send_force_reply(message, language['blacklist']['1'])
- if success then
- mattata.set_command_action(message.chat.id, success.result.message_id, '/blacklist')
- end
- return
- elseif not message.reply then
- if input:match('^.- .-$') then
- input, reason = input:match('^(.-) (.-)$')
- end
- elseif mattata.input(message.text) then
- reason = mattata.input(message.text)
- end
- if tonumber(input) == nil and not input:match('^%@') then
- input = '@' .. input
- end
- local user = mattata.get_user(input) -- Resolve the username/ID to a user object.
- if not user then
- return mattata.send_reply(message, language.errors.unknown)
- elseif user.result.id == self.info.id then
- return
- end
- user = user.result
- local status = mattata.get_chat_member(message.chat.id, user.id)
- if not status then
- return mattata.send_reply(message, language.errors.generic)
- elseif mattata.is_group_admin(message.chat.id, user.id) then -- We won't try and blacklist moderators and administrators.
- return mattata.send_reply(message, language['blacklist']['2'])
- elseif status.result.status == 'left' or status.result.status == 'kicked' then -- Check if the user is in the group or not.
- local output = status.result.status == 'left' and language['blacklist']['3'] or language['blacklist']['4']
- return mattata.send_reply(message, output)
- end
- redis:set('group_blacklist:' .. message.chat.id .. ':' .. user.id, true)
- mattata.increase_administrative_action(message.chat.id, user.id, 'blacklists')
- reason = reason and ', for ' .. reason or ''
- local admin_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
- local blacklisted_username = mattata.get_formatted_user(user.id, user.first_name, 'html')
- local bot_username = mattata.get_formatted_user(self.info.id, self.info.first_name, 'html')
- local output
- if mattata.get_setting(message.chat.id, 'log administrative actions') then
- local log_chat = mattata.get_log_chat(message.chat.id)
- output = string.format(language['blacklist']['5'], admin_username, message.from.id, blacklisted_username, user.id, bot_username, self.info.id, mattata.escape_html(message.chat.title), message.chat.id, reason, '#chat' .. tostring(message.chat.id):gsub('^-100', ''), '#user' .. user.id)
- mattata.send_message(log_chat, output, 'html')
- else
- output = string.format(language['blacklist']['6'], admin_username, blacklisted_username, bot_username, reason)
- mattata.send_message(message.chat.id, output, 'html')
- end
- if message.reply and mattata.get_setting(message.chat.id, 'delete reply on action') then
- mattata.delete_message(message.chat.id, message.reply.message_id)
- mattata.delete_message(message.chat.id, message.message_id)
- end
- return
-end
-
-return blacklist
\ No newline at end of file
+--[[
+ Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
+ This code is licensed under the MIT. See LICENSE for details.
+]]
+
+local allowlist = {}
+local mattata = require('mattata')
+local redis = require('libs.redis')
+
+function allowlist:init()
+ allowlist.commands = mattata.commands(self.info.username):command('allowlist').table
+ allowlist.help = '/allowlist [user] - Blocklists a user from using the bot in the current chat. This command can only be used by moderators and administrators of a supergroup.'
+end
+
+function allowlist:on_message(message, _, language)
+ if message.chat.type ~= 'supergroup' then
+ return mattata.send_reply(message, language.errors.supergroup)
+ elseif not mattata.is_group_admin(message.chat.id, message.from.id) then
+ return mattata.send_reply(message, language.errors.admin)
+ end
+ local reason = false
+ local input = message.reply and message.reply.from.id or mattata.input(message.text)
+ if not input then
+ local success = mattata.send_force_reply(message, language['allowlist']['1'])
+ if success then
+ mattata.set_command_action(message.chat.id, success.result.message_id, '/allowlist')
+ end
+ return
+ elseif not message.reply then
+ if input:match('^.- .-$') then
+ input, reason = input:match('^(.-) (.-)$')
+ end
+ elseif mattata.input(message.text) then
+ reason = mattata.input(message.text)
+ end
+ if tonumber(input) == nil and not input:match('^%@') then
+ input = '@' .. input
+ end
+ local user = mattata.get_user(input) -- Resolve the username/ID to a user object.
+ if not user then
+ return mattata.send_reply(message, language.errors.unknown)
+ elseif user.result.id == self.info.id then
+ return
+ end
+ user = user.result
+ local status = mattata.get_chat_member(message.chat.id, user.id)
+ if not status then
+ return mattata.send_reply(message, language.errors.generic)
+ elseif mattata.is_group_admin(message.chat.id, user.id) then -- We won't try and allowlist moderators and administrators.
+ return mattata.send_reply(message, language['allowlist']['2'])
+ elseif status.result.status == 'left' or status.result.status == 'kicked' then -- Check if the user is in the group or not.
+ local output = status.result.status == 'left' and language['allowlist']['3'] or language['allowlist']['4']
+ return mattata.send_reply(message, output)
+ end
+ redis:set('group_allowlist:' .. message.chat.id .. ':' .. user.id, true)
+ mattata.increase_administrative_action(message.chat.id, user.id, 'allowlists')
+ reason = reason and ', for ' .. reason or ''
+ local admin_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
+ local allowlisted_username = mattata.get_formatted_user(user.id, user.first_name, 'html')
+ local bot_username = mattata.get_formatted_user(self.info.id, self.info.first_name, 'html')
+ local output
+ if mattata.get_setting(message.chat.id, 'log administrative actions') then
+ local log_chat = mattata.get_log_chat(message.chat.id)
+ output = string.format(language['allowlist']['5'], admin_username, message.from.id, allowlisted_username, user.id, bot_username, self.info.id, mattata.escape_html(message.chat.title), message.chat.id, reason, '#chat' .. tostring(message.chat.id):gsub('^-100', ''), '#user' .. user.id)
+ mattata.send_message(log_chat, output, 'html')
+ else
+ output = string.format(language['allowlist']['6'], admin_username, allowlisted_username, bot_username, reason)
+ mattata.send_message(message.chat.id, output, 'html')
+ end
+ if message.reply and mattata.get_setting(message.chat.id, 'delete reply on action') then
+ mattata.delete_message(message.chat.id, message.reply.message_id)
+ mattata.delete_message(message.chat.id, message.message_id)
+ end
+ return
+end
+
+return allowlist
\ No newline at end of file
diff --git a/plugins/administration/channel.lua b/plugins/administration/channel.lua
index 2f2444d..aa726db 100644
--- a/plugins/administration/channel.lua
+++ b/plugins/administration/channel.lua
@@ -1,93 +1,94 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local channel = {}
local mattata = require('mattata')
local socket = require('socket')
local json = require('dkjson')
local redis = require('libs.redis')
function channel:init()
channel.commands = mattata.commands(self.info.username):command('channel'):command('ch'):command('msg').table
channel.help = '/channel <channel> <message> - Sends a message to a Telegram channel/group. The channel/group can be specified via ID or username. Messages can be formatted with Markdown. Users can only send messages to channels/groups they own/administrate. Aliases: /ch, /msg.'
end
function channel:on_callback_query(callback_query, message, configuration, language)
local request = redis:hget('temp:channel', callback_query.data)
if not request then
return false
end
request = json.decode(request)
if request.from ~= callback_query.from.id then
return mattata.answer_callback_query(callback_query.id, language['channel']['1'])
elseif not mattata.is_group_admin(request.target, request.from) then
return mattata.answer_callback_query(callback_query.id, language['channel']['2'])
end
local success = mattata.send_message(request.target, request.text, 'markdown')
if not success then
return mattata.edit_message_text(message.chat.id, message.message_id, language['channel']['3'])
end
redis:hdel('temp:channel', callback_query.data)
return mattata.edit_message_text(message.chat.id, message.message_id, language['channel']['4'])
end
function channel:on_message(message, configuration, language)
if message.chat.type == 'channel' then
return false
end
local input = mattata.input(message)
if not input then
return mattata.send_reply(message, channel.help)
end
local target = mattata.get_word(input)
if tonumber(target) == nil and not target:match('^@') then
target = '@' .. target
end
target = mattata.get_chat_id(target) or target
local admin_list = mattata.get_chat_administrators(target)
if not admin_list and not mattata.is_global_admin(message.from.id) then
return mattata.send_reply(message, language['channel']['5'])
elseif not mattata.is_global_admin(message.from.id) then -- Make configured owners an exception.
local is_admin = false
for _, admin in ipairs(admin_list.result) do
if admin.user.id == message.from.id then
is_admin = true
end
end
if not is_admin then
return mattata.send_reply(message, language['channel']['6'])
end
end
local text = input:match(' (.-)$')
if not text then
return mattata.send_reply(message, language['channel']['7'])
end
local request_id = tostring(socket.gettime()):gsub('%D', '')
local keyboard = json.encode({
['inline_keyboard'] = {
{
{
['text'] = language['channel']['9'],
['callback_data'] = 'channel:' .. request_id
}
}
}
})
local temp_text = '*' .. language['channel']['8'] .. '*\n\n' .. text
local success = mattata.send_message(message.chat.id, temp_text, 'markdown', true, false, nil, keyboard)
if not success then
return mattata.send_reply(message, language['channel']['10'])
end
local payload = json.encode({
['target'] = target,
['text'] = text,
['from'] = message.from.id
})
redis:hset('temp:channel', request_id, payload)
return success
end
return channel
\ No newline at end of file
diff --git a/plugins/administration/fadmins.lua b/plugins/administration/fadmins.lua
new file mode 100644
index 0000000..cc2269f
--- /dev/null
+++ b/plugins/administration/fadmins.lua
@@ -0,0 +1,50 @@
+--[[
+ Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
+ This code is licensed under the MIT. See LICENSE for details.
+]]
+
+local fadmins = {}
+local mattata = require('mattata')
+local redis = require('libs.redis')
+
+function fadmins:init()
+ fadmins.commands = mattata.commands(self.info.username):command('fadmins'):command('fa').table
+ fadmins.help = '/fadmins [Fed UUID] - View a list of users who are admins in your Fed. If you have multiple Feds, you will need to specify the Fed by its UUID. Alias: /fa.'
+end
+
+function fadmins.on_message(_, message)
+ local input = mattata.input(message.text)
+ input = (input and input:match('^%w+%-%w+%-%w+%-%w+%-%w+$')) and input or false
+ local feds = redis:keys('fed:*')
+ local owned = {}
+ for _, fed in pairs(feds) do
+ if mattata.is_fed_creator(fed:match('^fed:(.-)$'), message.from.id) then
+ table.insert(owned, fed:match('^fed:(.-)$'))
+ end
+ end
+ if input and mattata.table_contains(owned, input) then
+ feds = redis:smembers('fedadmins:' .. input)
+ elseif #owned == 0 then
+ return mattata.send_reply(message, 'You don\'t own any Feds! To create your own, use /newfed <Fed name>.')
+ elseif input then
+ return mattata.send_reply(message, 'I\'m afraid it looks like you don\'t own that Fed, therefore you can\'t view the list of admins for it!')
+ else
+ if #owned > 1 then
+ return mattata.send_reply(message, 'You own multiple Feds! You need to specify which Fed you want to view the admins for by using /fadmins <Fed UUID>. To view a list of Feds you own, use /myfeds.')
+ end
+ feds = redis:smembers('fedadmins:' .. owned[1])
+ input = owned[1]
+ end
+ local title = redis:hget('fed:' .. input, 'title')
+ local output = { 'The following users are admin in <b>' .. mattata.escape_html(title) .. '</b>:\n' }
+ for _, admin in pairs(feds) do
+ local user = mattata.get_user(admin).result
+ local name = mattata.get_formatted_user(user.id, user.first_name, 'html')
+ table.insert(output, mattata.symbols.bullet .. ' ' .. name .. ' <code>[' .. user.id .. ']</code>' )
+ end
+ table.insert(output, '\nTo promote more users, use <code>/fpromote [user] ' .. input .. '</code>')
+ output = table.concat(output, '\n')
+ return mattata.send_reply(message, output, 'html')
+end
+
+return fadmins
\ No newline at end of file
diff --git a/plugins/administration/fwhitelist.lua b/plugins/administration/fallowlist.lua
similarity index 68%
rename from plugins/administration/fwhitelist.lua
rename to plugins/administration/fallowlist.lua
index ca469fa..ae16c3c 100644
--- a/plugins/administration/fwhitelist.lua
+++ b/plugins/administration/fallowlist.lua
@@ -1,82 +1,81 @@
---[[
- Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
- This code is licensed under the MIT. See LICENSE for details.
-]]
-
-local fwhitelist = {}
-local mattata = require('mattata')
-local redis = require('libs.redis')
-
-function fwhitelist:init()
- fwhitelist.commands = mattata.commands(self.info.username):command('fwhitelist'):command('fedban'):command('fb').table
- fwhitelist.help = '/fwhitelist [user] - Whitelists a user from the current chat\'s Feds. Only works per chat, not per fed. This command can only be used by Fed admins. Alias: /fw.'
-end
-
-function fwhitelist:on_message(message, configuration, language)
- if message.chat.type ~= 'supergroup' then
- local output = language['errors']['supergroup']
- return mattata.send_reply(message, output)
- end
- local fed_ids = mattata.get_feds(message.chat.id)
- if #fed_ids == 0 then
- return mattata.send_reply(message, 'This group isn\'t part of a fed. Ask a group admin to join one!')
- end
- local user = message.reply and message.reply.from.id or mattata.input(message.text)
- if not user then
- local output = 'You need to specify the user you\'d like to whitelist from the Fed, either by username/ID or in reply.'
- local success = mattata.send_force_reply(message, output)
- if success then
- mattata.set_command_action(message.chat.id, success.result.message_id, '/fwhitelist')
- end
- return
- end
- if tonumber(user) == nil and not user:match('^%@') then
- user = '@' .. user
- end
- local user_object = mattata.get_user(user) -- resolve the username/ID to a user object
- if not user_object then
- local output = language['errors']['unknown']
- return mattata.send_reply(message, output)
- elseif user_object.result.id == self.info.id then
- return false -- don't let the bot Fed-whitelist itself
- end
- user_object = user_object.result
- local status = mattata.get_chat_member(message.chat.id, user_object.id)
- local is_admin = mattata.is_group_admin(message.chat.id, user_object.id)
- if not status then
- local output = language['errors']['generic']
- return mattata.send_reply(message, output)
- elseif is_admin or status.result.status == ('creator' or 'administrator') then -- we won't try and Fed-whitelist moderators and administrators.
- local output = 'I can\'t whitelist that user from the Fed because they\'re an admin in one of the groups!'
- return mattata.send_reply(message, output)
- end
- mattata.fed_whitelist(message.chat.id, user_object.id)
- if mattata.get_setting(message.chat.id, 'log administrative actions') then
- local log_chat = mattata.get_log_chat(message.chat.id)
- local admin_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
- local whitelisted_username = mattata.get_formatted_user(user_object.id, user_object.first_name, 'html')
- local output = '%s <code>[%s]</code> has Fed-whitelisted %s <code>[%s]</code> from %s <code>[%s]</code>.'
- if #fed_ids > 1 then
- output = '%s <code>[%s]</code> has Fed-whitelisted %s <code>[%s]</code> from %s in the following Feds:<pre>%s</pre>'
- output = string.format(output, admin_username, message.from.id, whitelisted_username, user_object.id, mattata.escape_html(message.chat.title), table.concat(fed_ids, '\n'))
- else
- output = string.format(output, admin_username, message.from.id, whitelisted_username, user_object.id, mattata.escape_html(message.chat.title), message.chat.id)
- end
- mattata.send_message(message.chat.id, output, 'html')
- end
- if message.reply and mattata.get_setting(message.chat.id, 'delete reply on action') then
- mattata.delete_message(message.chat.id, message.reply.message_id)
- end
- local admin_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
- local whitelisted_username = mattata.get_formatted_user(user_object.id, user_object.first_name, 'html')
- local output = '%s has Fed-whitelisted %s.'
- if #fed_ids > 1 then
- output = '%s has Fed-whitelisted %s; in the following Feds:<pre>%s</pre>'
- output = string.format(output, admin_username, whitelisted_username, table.concat(fed_ids, '\n'))
- else
- output = string.format(output, admin_username, whitelisted_username)
- end
- return mattata.send_message(message.chat.id, output, 'html')
-end
-
-return fwhitelist
\ No newline at end of file
+--[[
+ Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
+ This code is licensed under the MIT. See LICENSE for details.
+]]
+
+local fallowlist = {}
+local mattata = require('mattata')
+
+function fallowlist:init()
+ fallowlist.commands = mattata.commands(self.info.username):command('fallowlist'):command('fal').table
+ fallowlist.help = '/fallowlist [user] - Allowlists a user from the current chat\'s Feds. Only works per chat, not per fed. This command can only be used by Fed admins. Alias: /fal.'
+end
+
+function fallowlist:on_message(message, configuration, language)
+ if message.chat.type ~= 'supergroup' then
+ local output = language['errors']['supergroup']
+ return mattata.send_reply(message, output)
+ end
+ local fed_ids = mattata.get_feds(message.chat.id)
+ if #fed_ids == 0 then
+ return mattata.send_reply(message, 'This group isn\'t part of a fed. Ask a group admin to join one!')
+ end
+ local user = message.reply and message.reply.from.id or mattata.input(message.text)
+ if not user then
+ local output = 'You need to specify the user you\'d like to allowlist from the Fed, either by username/ID or in reply.'
+ local success = mattata.send_force_reply(message, output)
+ if success then
+ mattata.set_command_action(message.chat.id, success.result.message_id, '/fallowlist')
+ end
+ return
+ end
+ if tonumber(user) == nil and not user:match('^%@') then
+ user = '@' .. user
+ end
+ local user_object = mattata.get_user(user) -- resolve the username/ID to a user object
+ if not user_object then
+ local output = language['errors']['unknown']
+ return mattata.send_reply(message, output)
+ elseif user_object.result.id == self.info.id then
+ return false -- don't let the bot Fed-allowlist itself
+ end
+ user_object = user_object.result
+ local status = mattata.get_chat_member(message.chat.id, user_object.id)
+ local is_admin = mattata.is_group_admin(message.chat.id, user_object.id)
+ if not status then
+ local output = language['errors']['generic']
+ return mattata.send_reply(message, output)
+ elseif is_admin or status.result.status == ('creator' or 'administrator') then -- we won't try and Fed-allowlist moderators and administrators.
+ local output = 'I can\'t allowlist that user from the Fed because they\'re an admin in one of the groups!'
+ return mattata.send_reply(message, output)
+ end
+ mattata.fed_allowlist(message.chat.id, user_object.id)
+ if mattata.get_setting(message.chat.id, 'log administrative actions') then
+ local log_chat = mattata.get_log_chat(message.chat.id)
+ local admin_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
+ local allowlisted_username = mattata.get_formatted_user(user_object.id, user_object.first_name, 'html')
+ local output = '%s <code>[%s]</code> has Fed-allowlisted %s <code>[%s]</code> from %s <code>[%s]</code>.'
+ if #fed_ids > 1 then
+ output = '%s <code>[%s]</code> has Fed-allowlisted %s <code>[%s]</code> from %s in the following Feds:<pre>%s</pre>'
+ output = string.format(output, admin_username, message.from.id, allowlisted_username, user_object.id, mattata.escape_html(message.chat.title), table.concat(fed_ids, '\n'))
+ else
+ output = string.format(output, admin_username, message.from.id, allowlisted_username, user_object.id, mattata.escape_html(message.chat.title), message.chat.id)
+ end
+ mattata.send_message(message.chat.id, output, 'html')
+ end
+ if message.reply and mattata.get_setting(message.chat.id, 'delete reply on action') then
+ mattata.delete_message(message.chat.id, message.reply.message_id)
+ end
+ local admin_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
+ local allowlisted_username = mattata.get_formatted_user(user_object.id, user_object.first_name, 'html')
+ local output = '%s has Fed-allowlisted %s.'
+ if #fed_ids > 1 then
+ output = '%s has Fed-allowlisted %s; in the following Feds:<pre>%s</pre>'
+ output = string.format(output, admin_username, allowlisted_username, table.concat(fed_ids, '\n'))
+ else
+ output = string.format(output, admin_username, allowlisted_username)
+ end
+ return mattata.send_message(message.chat.id, output, 'html')
+end
+
+return fallowlist
\ No newline at end of file
diff --git a/plugins/administration/fban.lua b/plugins/administration/fban.lua
index 46289bf..aec6349 100644
--- a/plugins/administration/fban.lua
+++ b/plugins/administration/fban.lua
@@ -1,131 +1,131 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local fban = {}
local mattata = require('mattata')
local redis = require('libs.redis')
function fban:init()
fban.commands = mattata.commands(self.info.username):command('fban'):command('fedban'):command('fb').table
fban.help = '/fban [user] - Bans a user from the current chat and the Fed the group is part of. This command can only be used by Fed admins. Aliases: /fedban, /fb.'
end
function fban.on_new_message(_, message)
if message.chat.type ~= 'supergroup' then
return false
- elseif mattata.is_user_fedbanned(message.chat.id, message.from.id) and not mattata.is_user_fed_whitelisted(message.chat.id, message.from.id) then
+ elseif mattata.is_user_fedbanned(message.chat.id, message.from.id) and not mattata.is_user_fed_allowlisted(message.chat.id, message.from.id) then
mattata.send_message(message.chat.id, 'Banned ' .. message.from.first_name .. ', because they\'ve been banned in one of this group\'s Feds!')
return mattata.ban_chat_member(message.chat.id, message.from.id)
end
return false
end
function fban:on_message(message, _, language)
if message.chat.type ~= 'supergroup' then
local output = language['errors']['supergroup']
return mattata.send_reply(message, output)
end
local fed_ids = mattata.get_feds(message.chat.id)
if #fed_ids == 0 then
return mattata.send_reply(message, 'This group isn\'t part of a fed. Ask a group admin to join one!')
end
local is_admin_feds = {}
for _, fed in pairs(fed_ids) do
if mattata.is_fed_admin(fed, message.from.id) then
table.insert(is_admin_feds, fed)
end
end
if #is_admin_feds == 0 then
return mattata.send_reply(message, 'You need to be a Fed admin in at least one of this group\'s Feds in order to be able to use this command!')
end
local reason = false
local user = false
local input = mattata.input(message)
-- check the message object for any users this command
-- is intended to be executed on
if message.reply then
user = message.reply.from.id
if input then
reason = input
end
elseif input and input:match(' ') then
user, reason = input:match('^(.-) (.-)$')
elseif input then
user = input
end
if not user then
local output = 'You need to specify the user you\'d like to ban from the Fed, either by username/ID or in reply.'
local success = mattata.send_force_reply(message, output)
if success then
mattata.set_command_action(message.chat.id, success.result.message_id, '/fban')
end
return
end
if reason and type(reason) == 'string' and reason:match('^[Ff][Oo][Rr] ') then
reason = reason:match('^[Ff][Oo][Rr] (.-)$')
end
if tonumber(user) == nil and not user:match('^%@') then
user = '@' .. user
end
local user_object = mattata.get_user(user) or mattata.get_chat(user) -- resolve the username/ID to a user object
if not user_object then
local output = language['errors']['unknown']
return mattata.send_reply(message, output)
elseif user_object.result.id == self.info.id then
return false -- don't let the bot Fed-ban itself
end
user_object = user_object.result
local status = mattata.get_chat_member(message.chat.id, user_object.id)
local is_admin = mattata.is_group_admin(message.chat.id, user_object.id)
if not status then
local output = language['errors']['generic']
return mattata.send_reply(message, output)
elseif is_admin then -- we won't try and Fed-ban moderators and administrators.
local output = 'I can\'t ban that user from the Fed because they\'re an admin in one of the groups!'
return mattata.send_reply(message, output)
end
local success = mattata.fed_ban_chat_member(message.chat.id, user_object.id, is_admin_feds) -- attempt to Fed-ban the user from the group
if not success then
mattata.send_reply(message, 'I couldn\'t ban that user in this group, because it appears I don\'t have permission to! I have still added them to the Fed-ban list(s) though!')
end
for _, fed in pairs(is_admin_feds) do
mattata.increase_administrative_action(message.chat.id, user_object.id, 'fbans')
redis:hset('fedban:' .. fed .. ':' .. user_object.id, 'banned_by', message.from.id)
redis:hset('fedban:' .. fed .. ':' .. user_object.id, 'time', os.time())
if reason then
redis:hset('fedban:' .. fed .. ':' .. user_object.id, 'reason', reason)
end
redis:sadd('fedbans:' .. fed, tonumber(user_object.id))
end
reason = reason and ', for ' .. reason or ''
local admin_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
local banned_username = mattata.get_formatted_user(user_object.id, user_object.first_name, 'html')
if mattata.get_setting(message.chat.id, 'log administrative actions') then
local log_chat = mattata.get_log_chat(message.chat.id)
local output = '%s <code>[%s]</code> has Fed-banned %s <code>[%s]</code> from %s <code>[%s]</code>%s.\n%s %s'
if #is_admin_feds > 1 then
output = '%s <code>[%s]</code> has Fed-banned %s <code>[%s]</code> from %s in the following Feds:<pre>%s</pre>\n%s %s'
output = string.format(output, admin_username, message.from.id, banned_username, user_object.id, mattata.escape_html(message.chat.title), table.concat(is_admin_feds, '\n'), '#chat' .. tostring(message.chat.id):gsub('^-100', ''), '#user' .. user_object.id)
else
output = string.format(output, admin_username, message.from.id, banned_username, user_object.id, mattata.escape_html(message.chat.title), message.chat.id, reason, '#chat' .. tostring(message.chat.id):gsub('^-100', ''), '#user' .. user_object.id)
end
mattata.send_message(log_chat, output, 'html')
else
local output = '%s has Fed-banned %s%s.'
if #is_admin_feds > 1 then
output = '%s has Fed-banned %s%s; in the following Feds:<pre>%s</pre>'
output = string.format(output, admin_username, banned_username, reason, table.concat(is_admin_feds, '\n'))
else
output = string.format(output, admin_username, banned_username, reason)
end
mattata.send_message(message.chat.id, output, 'html')
end
if message.reply and mattata.get_setting(message.chat.id, 'delete reply on action') then
mattata.delete_message(message.chat.id, message.reply.message_id)
end
return mattata.delete_message(message.chat.id, message.message_id)
end
return fban
\ No newline at end of file
diff --git a/plugins/administration/join_captcha.lua b/plugins/administration/join_captcha.lua
index 256eeff..ce1894c 100644
--- a/plugins/administration/join_captcha.lua
+++ b/plugins/administration/join_captcha.lua
@@ -1,147 +1,154 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local join_captcha = {}
local mattata = require('mattata')
local redis = require('libs.redis')
local captcha_lib = require('captcha')
-function join_captcha:cron()
+function join_captcha.cron()
local keys = redis:keys('chat:*:captcha:*')
for _, key in pairs(keys) do
local chat_id, user_id = key:match('^chat:(%-?%d+):captcha:(%d+)$')
if not redis:get('captcha:' .. chat_id .. ':' .. user_id) then
local message_id = redis:hget(key, 'id')
mattata.delete_message(chat_id, message_id)
local user = mattata.get_user(user_id, nil, nil, true)
local kicked_user = mattata.get_formatted_user(user_id, user.result.first_name, 'html')
local action = mattata.get_setting(chat_id, 'ban not kick')
local punishment = action and 'Banned' or 'Kicked'
if punishment == 'Banned' then
action = mattata.ban_chat_member
else action = mattata.kick_chat_member end
local success = action(chat_id, user_id)
if not success then
mattata.wipe_redis_captcha(chat_id, user_id)
else
local output = punishment .. ' ' .. kicked_user .. ' <code>[' .. user_id .. ']</code> %sbecause they didn\'t complete the CAPTCHA within 5 minutes!'
if mattata.get_setting(chat_id, 'log administrative actions') then
local chat = mattata.get_chat(chat_id)
local log_output = output
if chat then
local title = mattata.escape_html(chat.result.title)
title = 'from ' .. title .. ' <code>[' .. chat.result.id .. ']</code> '
log_output = string.format(log_output, title)
log_output = log_output .. '\n#chat' .. tostring(chat.result.id):gsub('^%-100', '') .. ' #user' .. user_id
else
log_output = string.format(log_output, '')
end
mattata.send_message(mattata.get_log_chat(chat_id), log_output, 'html')
else
output = string.format(output, '')
mattata.send_message(chat_id, output, 'html')
end
mattata.wipe_redis_captcha(chat_id, user_id)
end
end
end
end
function join_captcha.on_callback_query(_, callback_query, message)
if not callback_query.data:match('^.-:.-:.-$') then
return false
end
local chat_id, user_id, guess = callback_query.data:match('^(.-):(.-):(.-)$')
if callback_query.from.id ~= tonumber(user_id) then
return mattata.answer_callback_query(callback_query.id, 'This isn\'t your CAPTCHA!')
end
local correct = mattata.get_captcha_text(chat_id, callback_query.from.id)
local message_id = mattata.get_captcha_id(chat_id, callback_query.from.id)
local default_permissions = mattata.get_chat(message.chat.id)
if guess:lower() == correct:lower() then
local success
if not default_permissions then
success = mattata.restrict_chat_member(chat_id, callback_query.from.id, 'forever', true, true, true, true, true, false, false, false)
else
success = mattata.restrict_chat_member(chat_id, callback_query.from.id, 'forever', default_permissions.result.permissions)
end
if not success then
return mattata.send_message(message.chat.id, 'I could not give a user their permissions. You may have to do this manually!')
end
mattata.wipe_redis_captcha(chat_id, callback_query.from.id)
mattata.answer_callback_query(callback_query.id, 'Success! You may now speak!')
return mattata.delete_message(chat_id, message_id)
else
if mattata.get_setting(chat_id, 'log administrative actions') then
local failed_username = mattata.get_formatted_user(callback_query.from.id, callback_query.from.first_name, 'html')
local chat_title = mattata.escape_html(message.chat.title)
local output = '%s <code>[%s]</code> failed the CAPTCHA in %s <code>[%s]</code>. They guessed <code>%s</code> but the correct answer was <code>%s</code>.\n#chat%s #user%s'
output = string.format(output, failed_username, user_id, chat_title, chat_id, guess, correct, tostring(chat_id):gsub('^%-100', ''), user_id)
local log_chat = mattata.get_log_chat(chat_id)
mattata.send_message(log_chat, output, 'html')
end
mattata.wipe_redis_captcha(chat_id, callback_query.from.id)
mattata.answer_callback_query(callback_query.id, 'You got it wrong! Re-join the group and try again, or consult an admin if you wish to be unmuted!')
return mattata.delete_message(chat_id, message_id)
end
end
function join_captcha.on_member_join(_, message, configuration)
- if mattata.get_setting(message.chat.id, 'require captcha') and not message.new_chat_participant.is_bot then
- if mattata.get_captcha_id(message.chat.id, message.new_chat_participant.id) then
- return mattata.send_reply(message, 'You still need to complete your CAPTCHA in order to speak!')
- end
- local chat_member = mattata.get_chat_member(message.chat.id, message.new_chat_participant.id)
- if not chat_member then -- we can't even get info about the user? abort! abort!
- return false
- end
- local download_location = configuration.download_location
- if download_location:match('/$') then
- download_location = download_location:match('^(.-)/$')
- end
- local new_captcha = captcha_lib.new()
- new_captcha:setlength(7)
- new_captcha:setfontsize(45)
- new_captcha:setpath(download_location)
- new_captcha:setformat('jpg')
- new_captcha:setfontsfolder(configuration.fonts_directory)
- local generated_captcha = new_captcha:generate()
- local username = message.new_chat_participant.username and '@' .. message.new_chat_participant.username or false
- local msg = string.format('Hey, [%s](tg://user?id=%s)! Please enter the above CAPTCHA using the buttons below before you can speak! You will be removed in 5 minutes if you don\'t do this.', username or mattata.escape_markdown(message.new_chat_participant.first_name), message.new_chat_participant.id)
- local correct = generated_captcha:match('^' .. download_location .. '/(.-)%.jpg$')
- local captchas = mattata.random_string(8, 5)
- table.insert(captchas, correct)
- table.sort(captchas)
- local callback_data = string.format('join_captcha:%s:%s', message.chat.id, message.new_chat_participant.id)
- local keyboard = mattata.inline_keyboard():row(
- mattata.row()
- :callback_data_button(captchas[1], callback_data .. ':' .. captchas[1])
- :callback_data_button(captchas[2], callback_data .. ':' .. captchas[2])
- :callback_data_button(captchas[3], callback_data .. ':' .. captchas[3])
- ):row(
- mattata.row()
- :callback_data_button(captchas[4], callback_data .. ':' .. captchas[4])
- :callback_data_button(captchas[5], callback_data .. ':' .. captchas[5])
- :callback_data_button(captchas[6], callback_data .. ':' .. captchas[6])
- )
- local success = mattata.send_photo(message.chat.id, generated_captcha, msg, 'markdown', false, nil, keyboard)
- if not success then
- error('No success!')
- os.execute('rm ' .. generated_captcha)
- return false
- end
+ if not mattata.get_setting(message.chat.id, 'require captcha') or message.new_chat_participant.is_bot then
+ return false
+ elseif mattata.get_captcha_id(message.chat.id, message.new_chat_participant.id) then
+ return mattata.send_reply(message, 'You still need to complete your CAPTCHA in order to speak!')
+ end
+ local chat_member = mattata.get_chat_member(message.chat.id, message.new_chat_participant.id)
+ if not chat_member then -- we can't even get info about the user? abort! abort!
+ return false
+ end
+ local download_location = configuration.download_location
+ if download_location:match('/$') then
+ download_location = download_location:match('^(.-)/$')
+ end
+ local new_captcha = captcha_lib.new()
+ local size = mattata.get_setting(message.chat.id, 'captcha size') or configuration.administration.captcha.size.default
+ size = math.floor(size)
+ local length = mattata.get_setting(message.chat.id, 'captcha length') or configuration.administration.captcha.length.default
+ length = math.floor(length)
+ local captchas = configuration.administration.captcha.files
+ local current = mattata.get_setting(message.chat.id, 'captcha font') or 1
+ current = math.floor(current)
+ local font = captchas[current] or captchas[1]
+ new_captcha:setlength(length)
+ new_captcha:setfontsize(size)
+ new_captcha:setpath(download_location)
+ new_captcha:setformat('jpg')
+ new_captcha:setfontsfolder(configuration.fonts_directory .. '/' .. font)
+ local generated_captcha, correct = new_captcha:generate()
+ local username = message.new_chat_participant.username and '@' .. message.new_chat_participant.username or false
+ local msg = string.format('Hey, [%s](tg://user?id=%s)! Please enter the above CAPTCHA using the buttons below before you can speak! You will be removed in 5 minutes if you don\'t do this.\n_Click to expand the image on Android devices!_', username or mattata.escape_markdown(message.new_chat_participant.first_name), message.new_chat_participant.id)
+ captchas = mattata.random_string(length, 5)
+ table.insert(captchas, correct)
+ table.sort(captchas)
+ local callback_data = string.format('join_captcha:%s:%s', message.chat.id, message.new_chat_participant.id)
+ local keyboard = mattata.inline_keyboard():row(
+ mattata.row()
+ :callback_data_button(captchas[1], callback_data .. ':' .. captchas[1])
+ :callback_data_button(captchas[2], callback_data .. ':' .. captchas[2])
+ :callback_data_button(captchas[3], callback_data .. ':' .. captchas[3])
+ ):row(
+ mattata.row()
+ :callback_data_button(captchas[4], callback_data .. ':' .. captchas[4])
+ :callback_data_button(captchas[5], callback_data .. ':' .. captchas[5])
+ :callback_data_button(captchas[6], callback_data .. ':' .. captchas[6])
+ )
+ local success = mattata.send_photo(message.chat.id, generated_captcha, msg, 'markdown', false, nil, keyboard)
+ if not success then
+ error('No success!')
os.execute('rm ' .. generated_captcha)
- local restrict = mattata.restrict_chat_member(message.chat.id, message.new_chat_participant.id, 'forever', false, false, false, false, false, false, false, false)
- if restrict then
- mattata.set_captcha(message.chat.id, message.new_chat_participant.id, correct, success.result.message_id)
- mattata.delete_message(message.chat.id, message.message_id)
- else
- error('Could not restrict ChatMember!')
- end
- return
+ return false
+ end
+ os.execute('rm ' .. generated_captcha)
+ local restrict = mattata.restrict_chat_member(message.chat.id, message.new_chat_participant.id, 'forever', false, false, false, false, false, false, false, false)
+ if restrict then
+ mattata.set_captcha(message.chat.id, message.new_chat_participant.id, correct, success.result.message_id)
+ mattata.delete_message(message.chat.id, message.message_id)
+ else
+ error('Could not restrict ChatMember!')
end
+ return
end
return join_captcha
\ No newline at end of file
diff --git a/plugins/administration/myfeds.lua b/plugins/administration/myfeds.lua
new file mode 100644
index 0000000..ac12228
--- /dev/null
+++ b/plugins/administration/myfeds.lua
@@ -0,0 +1,52 @@
+--[[
+ Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
+ This code is licensed under the MIT. See LICENSE for details.
+]]
+
+local myfeds = {}
+local mattata = require('mattata')
+local redis = require('libs.redis')
+
+function myfeds:init()
+ myfeds.commands = mattata.commands(self.info.username):command('myfeds'):command('mf').table
+ myfeds.help = '/myfeds - View a list of Feds you own/administrate. Alias: /mf.'
+end
+
+function myfeds.on_message(_, message)
+ local feds = redis:keys('fed:*')
+ local admins = redis:keys('fedadmins:*')
+ local owned = {}
+ local administrate = {}
+ local output = { '<b>You currently own the following Feds:</b>\n' }
+ for _, fed in pairs(feds) do
+ if redis:hget(fed, 'creator') == tostring(message.from.id) then
+ table.insert(owned, fed:match('^fed:(.-)$'))
+ end
+ end
+ if #owned == 0 then
+ table.insert(output, '<em>None</em>')
+ else
+ for _, fed in pairs(owned) do
+ local title = redis:hget('fed:' .. fed, 'title')
+ table.insert(output, '<em>' .. mattata.escape_html(title) .. '</em> <code>[' .. fed .. ']</code>')
+ end
+ end
+ for _, fed in pairs(admins) do
+ if redis:sismember(fed, message.from.id) and not mattata.is_fed_creator(fed:match('^fedadmins:(.-)$'), message.from.id) then
+ table.insert(administrate, fed:match('^fedadmins:(.-)$'))
+ end
+ end
+ table.insert(output, '\n<b>You currently administrate the following Feds:</b>\n')
+ if #administrate == 0 then
+ table.insert(output, '<em>None</em>')
+ else
+ for _, fed in pairs(administrate) do
+ local title = redis:hget('fed:' .. fed, 'title')
+ table.insert(output, '<em>' .. mattata.escape_html(title) .. '</em> <code>[' .. fed .. ']</code>')
+ end
+ end
+ output = table.concat(output, '\n')
+ return mattata.send_reply(message, output, 'html')
+end
+
+return myfeds
\ No newline at end of file
diff --git a/plugins/administration/nodelete.lua b/plugins/administration/nodelete.lua
index 86744a0..5d82d9c 100644
--- a/plugins/administration/nodelete.lua
+++ b/plugins/administration/nodelete.lua
@@ -1,59 +1,59 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local nodelete = {}
local mattata = require('mattata')
local redis = require('libs.redis')
function nodelete:init()
nodelete.commands = mattata.commands(self.info.username):command('nodelete').table
- nodelete.help = '/nodelete [add | del] <plugins> - Allows the given plugins to retain the commands they were executed with by whitelisting them from the "delete commands" administrative setting. Multiple plugins can be specified.'
+ nodelete.help = '/nodelete [add | del] <plugins> - Allows the given plugins to retain the commands they were executed with by allowlisting them from the "delete commands" administrative setting. Multiple plugins can be specified.'
end
function nodelete:on_message(message, configuration, language)
local input = mattata.input(message.text)
if message.chat.type ~= 'supergroup' then
return mattata.send_reply(
message,
language['errors']['supergroup']
)
elseif not mattata.is_group_admin(message.chat.id, message.from.id) then
return mattata.send_reply(
message,
language['errors']['admin']
)
elseif not input or not input:match('^add .-$') and not input:match('^del .-$') then
return mattata.send_reply(message, nodelete.help)
end
local plugins = {}
local process_type, input = input:match('([ad][de][dl]) (.-)$')
for plugin in input:gmatch('[%w_]+') do
for k, v in pairs(configuration.plugins) do
if v:lower() == plugin:lower()then
table.insert(plugins, plugin)
end
end
end
if #plugins < 1 then
return mattata.send_reply(message, 'No matching plugins were found!')
end
local total = #plugins
local success = {}
for k, v in pairs(plugins) do
- if process_type == 'add' and not redis:sismember('chat:' .. message.chat.id .. ':no_delete', v) then -- Check to make sure the plugin isn't already whitelisted from having
+ if process_type == 'add' and not redis:sismember('chat:' .. message.chat.id .. ':no_delete', v) then -- Check to make sure the plugin isn't already allowlisted from having
-- its commands deleted.
redis:sadd('chat:' .. message.chat.id .. ':no_delete', v)
table.insert(success, v)
- elseif process_type == 'del' and redis:sismember('chat:' .. message.chat.id .. ':no_delete', v) then -- Check to make sure the plugin has already been whitelisted from having
+ elseif process_type == 'del' and redis:sismember('chat:' .. message.chat.id .. ':no_delete', v) then -- Check to make sure the plugin has already been allowlisted from having
-- its commands deleted.
redis:srem('chat:' .. message.chat.id .. ':no_delete', v)
table.insert(success, v)
end
end
local output = process_type == 'del' and 'Commands will now be deleted for ' .. total .. ' plugins!' or 'Commands will no longer be deleted for ' .. total .. ' plugins!'
return mattata.send_reply(message, output)
end
return nodelete
\ No newline at end of file
diff --git a/plugins/administration/setcaptcha.lua b/plugins/administration/setcaptcha.lua
new file mode 100644
index 0000000..c797cfe
--- /dev/null
+++ b/plugins/administration/setcaptcha.lua
@@ -0,0 +1,186 @@
+--[[
+ Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
+ This code is licensed under the MIT. See LICENSE for details.
+]]
+
+local setcaptcha = {}
+local mattata = require('mattata')
+local redis = require('libs.redis')
+
+function setcaptcha:init()
+ setcaptcha.commands = mattata.commands(self.info.username):command('setcaptcha').table
+ setcaptcha.help = '/setcaptcha - Allows admins to configure CAPTCHA settings.'
+end
+
+function setcaptcha.on_callback_query(_, callback_query, message, configuration, language)
+ local action, new, chat_id = callback_query.data:match('^(.-):(.-):(.-)$')
+ if not action or not new or not chat_id then
+ return mattata.answer_callback_query(callback_query.id)
+ elseif not mattata.is_group_admin(chat_id, callback_query.from.id) then
+ return mattata.answer_callback_query(callback_query.id, language.errors.admin)
+ end
+ new = tonumber(new)
+ local captchas = configuration.administration.captcha.files
+ local length = mattata.get_setting(chat_id, 'captcha length') or configuration.administration.captcha.length.default
+ length = math.floor(length)
+ local next_length = length + 1
+ local prev_length = length - 1
+ local size = mattata.get_setting(chat_id, 'captcha size') or configuration.administration.captcha.size.default
+ size = math.floor(size)
+ local next_size = size + 1
+ local prev_size = size - 1
+ local current = mattata.get_setting(chat_id, 'captcha font') or 1
+ current = math.floor(current)
+ local font_name = captchas[current] or captchas[1]
+ local next_font_pos = current + 1
+ local prev_font_pos = current - 1
+ if action == 'font' then
+ if tonumber(new) < 1 then
+ new = #captchas
+ elseif tonumber(new) > #captchas then
+ new = 1
+ end
+ font_name = captchas[new]
+ if not font_name then
+ return mattata.answer_callback_query(callback_query.from.id, 'This font is no longer available!')
+ end
+ redis:hset('chat:' .. chat_id .. ':settings', 'captcha font', new)
+ if next_font_pos > #captchas then
+ next_font_pos = 1
+ end
+ prev_font_pos = new - 1
+ if prev_font_pos < 1 then
+ prev_font_pos = #captchas
+ end
+ elseif action == 'length' then
+ if tonumber(new) < configuration.administration.captcha.length.min then
+ new = configuration.administration.captcha.length.max
+ elseif tonumber(new) > configuration.administration.captcha.length.max then
+ new = configuration.administration.captcha.length.min
+ end
+ redis:hset('chat:' .. chat_id .. ':settings', 'captcha length', new)
+ length = new
+ next_length = new + 1
+ if next_length > configuration.administration.captcha.length.max then
+ next_length = configuration.administration.captcha.length.min
+ end
+ prev_length = new - 1
+ if prev_length < configuration.administration.captcha.length.min then
+ prev_length = configuration.administration.captcha.length.max
+ end
+ elseif action == 'size' then
+ if tonumber(new) < configuration.administration.captcha.size.min then
+ new = configuration.administration.captcha.size.max
+ elseif tonumber(new) > configuration.administration.captcha.size.max then
+ new = configuration.administration.captcha.size.min
+ end
+ redis:hset('chat:' .. chat_id .. ':settings', 'captcha size', new)
+ size = new
+ next_size = new + 1
+ if next_size > configuration.administration.captcha.size.max then
+ next_size = configuration.administration.captcha.size.min
+ end
+ prev_size = new - 1
+ if prev_size < configuration.administration.captcha.size.min then
+ prev_size = configuration.administration.captcha.size.max
+ end
+ end
+ font_name = font_name:gsub('^%l', string.upper):gsub('%.[to]tf$', '')
+ local keyboard = mattata.inline_keyboard():row(
+ mattata.row():callback_data_button('CAPTCHA Length', 'setcaptcha')
+ ):row(
+ mattata.row()
+ :callback_data_button(utf8.char(11013), 'setcaptcha:length:' .. prev_length .. ':' .. chat_id)
+ :callback_data_button(length, 'setcaptcha')
+ :callback_data_button(utf8.char(10145), 'setcaptcha:length:' .. next_length .. ':' .. chat_id)
+ ):row(
+ mattata.row():callback_data_button('Font Size', 'setcaptcha')
+ ):row(
+ mattata.row()
+ :callback_data_button(utf8.char(11013), 'setcaptcha:size:' .. prev_size .. ':' .. chat_id)
+ :callback_data_button(size, 'setcaptcha')
+ :callback_data_button(utf8.char(10145), 'setcaptcha:size:' .. next_size .. ':' .. chat_id)
+ ):row(
+ mattata.row():callback_data_button('Font Family', 'setcaptcha')
+ ):row(
+ mattata.row()
+ :callback_data_button(utf8.char(11013), 'setcaptcha:font:' .. prev_font_pos .. ':' .. chat_id)
+ :callback_data_button(font_name, 'setcaptcha')
+ :callback_data_button(utf8.char(10145), 'setcaptcha:font:' .. next_font_pos .. ':' .. chat_id)
+ ):row(
+ mattata.row():callback_data_button('Done', 'dismiss')
+ )
+ return mattata.edit_message_reply_markup(message.chat.id, message.message_id, nil, keyboard)
+end
+
+function setcaptcha:on_message(message, configuration, language)
+ if message.chat.type ~= 'supergroup' then
+ return mattata.send_reply(message, language.errors.supergroup)
+ elseif not mattata.is_group_admin(message.chat.id, message.from.id) then
+ return mattata.send_reply(message, language.errors.admin)
+ end
+ local captcha = configuration.administration.captcha
+ local length = mattata.get_setting(message.chat.id, 'captcha length') or configuration.administration.captcha.length.default
+ length = math.floor(length)
+ local next_length = length + 1
+ local prev_length = length - 1
+ local size = mattata.get_setting(message.chat.id, 'captcha size') or configuration.administration.captcha.size.default
+ size = math.floor(size)
+ local next_size = size + 1
+ local prev_size = size - 1
+ local font_file = mattata.get_setting(message.chat.id, 'captcha font') or 1
+ font_file = math.floor(font_file)
+ local font_name = configuration.administration.captcha.files[tonumber(font_file)]
+ font_name = font_name:gsub('^%l', string.upper):gsub('%.[to]tf$', '')
+ local font_pos = 1
+ for pos, font in pairs(captcha.files) do
+ if font == font_file then
+ font_pos = pos
+ end
+ end
+ local next_font_pos = font_pos + 1
+ if next_font_pos > #captcha.files then
+ next_font_pos = 1
+ end
+ local prev_font_pos = font_pos - 1
+ if prev_font_pos < 1 then
+ prev_font_pos = #captcha.files
+ end
+ local keyboard = mattata.inline_keyboard():row(
+ mattata.row():callback_data_button('CAPTCHA Length', 'setcaptcha')
+ ):row(
+ mattata.row()
+ :callback_data_button(utf8.char(11013), 'setcaptcha:length:' .. prev_length .. ':' .. message.chat.id)
+ :callback_data_button(length, 'setcaptcha')
+ :callback_data_button(utf8.char(10145), 'setcaptcha:length:' .. next_length .. ':' .. message.chat.id)
+ ):row(
+ mattata.row():callback_data_button('Font Size', 'setcaptcha')
+ ):row(
+ mattata.row()
+ :callback_data_button(utf8.char(11013), 'setcaptcha:size:' .. prev_size .. ':' .. message.chat.id)
+ :callback_data_button(size, 'setcaptcha')
+ :callback_data_button(utf8.char(10145), 'setcaptcha:size:' .. next_size .. ':' .. message.chat.id)
+ ):row(
+ mattata.row():callback_data_button('Font Family', 'setcaptcha')
+ ):row(
+ mattata.row()
+ :callback_data_button(utf8.char(11013), 'setcaptcha:font:' .. prev_font_pos .. ':' .. message.chat.id)
+ :callback_data_button(font_name, 'setcaptcha')
+ :callback_data_button(utf8.char(10145), 'setcaptcha:font:' .. next_font_pos .. ':' .. message.chat.id)
+ ):row(
+ mattata.row():callback_data_button('Done', 'dismiss')
+ )
+ local output = 'Use the keyboard below to adjust the CAPTCHA settings in <b>%s</b>:'
+ output = string.format(output, mattata.escape_html(message.chat.title))
+ if mattata.get_setting(message.chat.id, 'settings in group') then
+ return mattata.send_message(message.chat.id, output, 'html', true, false, nil, keyboard)
+ else
+ local success = mattata.send_message(message.from.id, output, 'html', true, false, nil, keyboard)
+ if not success then
+ return mattata.send_reply(message, 'You need to [private message me](https://t.me/' .. self.info.username:lower() .. ') before I can send you this!', true, true)
+ end
+ return mattata.send_reply(message, 'I\'ve sent you the CAPTCHA configuration panel [via private message](https://t.me/' .. self.info.username:lower() .. ')!', true, true)
+ end
+end
+
+return setcaptcha
\ No newline at end of file
diff --git a/plugins/administration/triggers.lua b/plugins/administration/triggers.lua
index 861ce16..89dd003 100644
--- a/plugins/administration/triggers.lua
+++ b/plugins/administration/triggers.lua
@@ -1,113 +1,114 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local triggers = {}
local mattata = require('mattata')
local redis = require('libs.redis')
function triggers:init()
triggers.commands = mattata.commands(self.info.username):command('triggers'):command('trigger'):command('custom'):command('addtrigger'):command('deltrigger').table
triggers.help = '/triggers - Allows admins to view existing word triggers. Use /addtrigger <trigger> <value> to add one, and /deltrigger <trigger> to delete one. Each chat is allowed 8 word triggers, with a maximum of 16 characters per word trigger and 256 characters per response. Trigger words can be alpha-numerical, and may have hashtags at the start. Aliases: /trigger, /custom.'
end
function triggers:on_new_message(message)
if message.command or message.is_media or self.is_ai then
return false
end
local matches = redis:hgetall('triggers:' .. message.chat.id)
if not next(matches) == 0 then
return false
end
for trigger, value in pairs(matches) do
if message.text:lower():match(trigger:lower()) then
local trail
if trigger:lower() == 'ayy' and value:lower() == 'lmao' then
trail = message.text:lower():match('(ayy+)'):gsub('^ay', '')
value = 'lma' .. string.rep('o', trail:len())
elseif trigger:lower() == 'lmao' and value:lower() == 'ayy' then
trail = message.text:lower():match('(lmao+)'):gsub('^lma', '')
value = 'ay' .. string.rep('y', trail:len())
end
if value:len() > 4096 then
value = value:sub(1, 4096)
end
if not message.is_edited then
local success = mattata.send_message(message.chat.id, '<pre>' .. mattata.escape_html(value) .. '</pre>', 'html')
if success then
redis:set('bot:' .. message.chat.id .. ':' .. message.message_id, success.result.message_id)
end
+ return success
else
local message_id = redis:get('bot:' .. message.chat.id .. ':' .. message.message_id)
if message_id then
- mattata.edit_message_text(message.chat.id, message_id, '<pre>' .. mattata.escape_html(value) .. '</pre>', 'html')
+ return mattata.edit_message_text(message.chat.id, message_id, '<pre>' .. mattata.escape_html(value) .. '</pre>', 'html')
end
end
end
end
return
end
function triggers:on_message(message)
self.is_done = true
if message.chat.type == 'private' or not mattata.is_group_admin(message.chat.id, message.from.id) then
return false
elseif message.command == 'triggers' then
local matches = redis:hgetall('triggers:' .. message.chat.id)
if not next(matches) then
return mattata.send_reply(message, 'This chat doesn\'t have any triggers set up. To add one, use /addtrigger <trigger> <value>.')
end
local output = 'Triggers for <b>%s</b>\n\n%s'
local all = {}
for trigger, value in pairs(matches) do
local line = '<code>%s</code>: <i>%s</i>'
line = string.format(line, mattata.escape_html(trigger), mattata.escape_html(value))
table.insert(all, line)
end
table.insert(all, '\nTo delete a trigger, use <code>/deltrigger &lt;trigger&gt;</code>')
all = table.concat(all, '\n')
output = string.format(output, mattata.escape_html(message.chat.title), all)
return mattata.send_reply(message, output, 'html')
elseif message.command == 'addtrigger' or message.command == 'trigger' or message.command == 'custom' then
local input = mattata.input(message.text)
if not input or not input:match('^#?%w+ .-$') then
return mattata.send_reply(message, triggers.help)
end
local trigger, value = input:match('^(#?%w+) (.-)$')
local count = 0
local is_duplicate = false
local all = redis:hgetall('triggers:' .. message.chat.id)
for _, v in ipairs(all) do
count = count + 1
if v == trigger then
is_duplicate = true
end
end
if is_duplicate then
return mattata.send_reply(message, 'That trigger already exists! To modify it, delete it first using /deltrigger ' .. trigger .. ', then use this command again!')
elseif count >= 8 then
return mattata.send_reply(message, 'You can\'t have more than 8 triggers! Please delete one using /deltrigger <trigger>. To view a list of this chat\'t triggers, use /triggers.')
end
if trigger:len() > 16 then
return mattata.send_reply(message, 'The trigger needs to be 1-16 characters long, and alpha-numerical.')
elseif value:len() > 256 then
return mattata.send_reply(message, 'The value must be no more than 256 characters long!')
end
redis:hset('triggers:' .. message.chat.id, trigger, value)
return mattata.send_reply(message, 'Successfully added that trigger! To view a list of triggers, send /triggers.')
elseif message.command == 'deltrigger' then
local input = mattata.input(message.text)
if not input or not input:match('^#?%w+$') then
return mattata.send_reply(message, 'Please specify the trigger you\'d like to delete! To view your existing triggers, send /triggers.')
end
local deleted = redis:hdel('triggers:' .. message.chat.id, input)
if deleted == 0 then
return mattata.send_reply(message, 'That trigger does not exist! Use /triggers to view a list of existing triggers for this chat.')
end
return mattata.send_reply(message, 'Successfully deleted that trigger!')
end
return false
end
return triggers
\ No newline at end of file
diff --git a/plugins/administration/whitelist.lua b/plugins/administration/whitelist.lua
index 7824499..be1044c 100644
--- a/plugins/administration/whitelist.lua
+++ b/plugins/administration/whitelist.lua
@@ -1,167 +1,167 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
-local whitelist = {}
+local allowlist = {}
local mattata = require('mattata')
local redis = require('libs.redis')
-function whitelist:init()
- whitelist.commands = mattata.commands(self.info.username):command('whitelist').table
- whitelist.help = '/whitelist [user] - Whitelists a user to use the bot in the current chat. This command can only be used by moderators and administrators of a supergroup.'
+function allowlist:init()
+ allowlist.commands = mattata.commands(self.info.username):command('allowlist').table
+ allowlist.help = '/allowlist [user] - Allowlists a user to use the bot in the current chat. This command can only be used by moderators and administrators of a supergroup.'
end
-function whitelist:on_message(message, configuration, language)
+function allowlist:on_message(message, configuration, language)
if message.chat.type ~= 'supergroup'
then
return mattata.send_reply(
message,
language['errors']['supergroup']
)
elseif not mattata.is_group_admin(
message.chat.id,
message.from.id
)
then
return mattata.send_reply(
message,
language['errors']['admin']
)
end
local reason = false
local input = message.reply
and (
message.reply.from.username
or tostring(message.reply.from.id)
)
or mattata.input(message.text)
if not input
then
local success = mattata.send_force_reply(
message,
- language['whitelist']['1']
+ language['allowlist']['1']
)
if success
then
redis:set(
string.format(
'action:%s:%s',
message.chat.id,
success.result.message_id
),
- '/whitelist'
+ '/allowlist'
)
end
return
elseif not message.reply
then
if input:match('^.- .-$')
then
reason = input:match(' (.-)$')
input = input:match('^(.-) ')
end
elseif mattata.input(message.text)
then
reason = mattata.input(message.text)
end
if tonumber(input) == nil
and not input:match('^%@')
then
input = '@' .. input
end
local user = mattata.get_user(input)
or mattata.get_chat(input) -- Resolve the username/ID to a user object.
if not user
then
return mattata.send_reply(
message,
language['errors']['unknown']
)
elseif user.result.id == self.info.id
then
return
end
user = user.result
local status = mattata.get_chat_member(
message.chat.id,
user.id
)
if not status
then
return mattata.send_reply(
message,
language['errors']['generic']
)
elseif mattata.is_group_admin(
message.chat.id,
user.id
)
or status.result.status == 'creator'
or status.result.status == 'administrator'
- then -- We won't try and whitelist moderators and administrators.
+ then -- We won't try and allowlist moderators and administrators.
return mattata.send_reply(
message,
- language['whitelist']['2']
+ language['allowlist']['2']
)
elseif status.result.status == 'left'
or status.result.status == 'kicked'
then -- Check if the user is in the group or not.
return mattata.send_reply(
message,
status.result.status == 'left'
- and language['whitelist']['3']
- or language['whitelist']['4']
+ and language['allowlist']['3']
+ or language['allowlist']['4']
)
end
- redis:del('group_whitelist:' .. message.chat.id .. ':' .. user.id)
+ redis:del('group_allowlist:' .. message.chat.id .. ':' .. user.id)
redis:hincrby(
string.format(
'chat:%s:%s',
message.chat.id,
user.id
),
- 'whitelists',
+ 'allowlists',
1
)
if redis:hget(
string.format(
'chat:%s:settings',
message.chat.id
),
'log administrative actions'
) then
mattata.send_message(
mattata.get_log_chat(message.chat.id),
string.format(
- '<pre>%s%s [%s] has whitelisted %s%s [%s] in %s%s [%s]%s.</pre>',
+ '<pre>%s%s [%s] has allowlisted %s%s [%s] in %s%s [%s]%s.</pre>',
message.from.username and '@' or '',
message.from.username or mattata.escape_html(message.from.first_name),
message.from.id,
user.username and '@' or '',
user.username or mattata.escape_html(user.first_name),
user.id,
message.chat.username and '@' or '',
message.chat.username or mattata.escape_html(message.chat.title),
message.chat.id,
reason and ', for ' .. reason or ''
),
'html'
)
end
mattata.unban_chat_member(message.chat.id, user.id) -- attempt to unban the user too
return mattata.send_message(
message.chat.id,
string.format(
- '<pre>%s%s has whitelisted %s%s%s.</pre>',
+ '<pre>%s%s has allowlisted %s%s%s.</pre>',
message.from.username and '@' or '',
message.from.username or mattata.escape_html(message.from.first_name),
user.username and '@' or '',
user.username or mattata.escape_html(user.first_name),
reason and ', for ' .. reason or ''
),
'html'
)
end
-return whitelist
\ No newline at end of file
+return allowlist
\ No newline at end of file
diff --git a/plugins/administration/whitelistbot.lua b/plugins/administration/whitelistbot.lua
index 6d3ee62..33151a2 100644
--- a/plugins/administration/whitelistbot.lua
+++ b/plugins/administration/whitelistbot.lua
@@ -1,53 +1,53 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
-local whitelistbot = {}
+local allowbot = {}
local mattata = require('mattata')
local redis = require('libs.redis')
-function whitelistbot:init()
- whitelistbot.commands = mattata.commands(self.info.username):command('whitelistbot'):command('whitelistbots'):command('wb').table
- whitelistbot.help = '/whitelistbot <bots> - Whitelists the given bots in the current chat. Requires administrative privileges. Aliases: /whitelistbots, /wb.'
- whitelistbot.example_bots = { 'gif', 'imdb', 'wiki', 'music', 'youtube', 'bold', 'sticker', 'vote', 'like', 'gamee', 'coub', 'pic', 'vid', 'bing' }
+function allowbot:init()
+ allowbot.commands = mattata.commands(self.info.username):command('allowbot'):command('allowbots'):command('wb').table
+ allowbot.help = '/allowbot <bots> - Allowlists the given bots in the current chat. Requires administrative privileges. Aliases: /allowbots, /wb.'
+ allowbot.example_bots = { 'gif', 'imdb', 'wiki', 'music', 'youtube', 'bold', 'sticker', 'vote', 'like', 'gamee', 'coub', 'pic', 'vid', 'bing' }
end
-function whitelistbot:on_new_message(message, configuration, language)
+function allowbot:on_new_message(message, configuration, language)
if message.chat.type ~= 'supergroup' then
return false
elseif mattata.get_setting(message.chat.id, 'prevent inline bots') and message.via_bot and not mattata.is_group_admin(message.chat.id, message.from.id) then
return mattata.delete_message(message.chat.id, message.message_id)
end
end
-function whitelistbot:on_message(message, configuration, language)
+function allowbot:on_message(message, configuration, language)
if not mattata.is_group_admin(message.chat.id, message.from.id) then
return mattata.send_reply(message, language.errors.admin)
end
local input = mattata.input(message.text)
if not input then
- return mattata.send_reply(message, 'Please specify the @usernames of the bots you\'d like to whitelist.')
+ return mattata.send_reply(message, 'Please specify the @usernames of the bots you\'d like to allowlist.')
elseif not input:match('@?[%w_]') then
return mattata.send_reply(message, 'Please make sure you\'re specifying valid bot usernames!')
end
local bots = {}
for bot in input:gmatch('@?([%w_]+bot)') do
table.insert(bots, bot)
end
- for _, bot in pairs(whitelistbot.example_bots) do
+ for _, bot in pairs(allowbot.example_bots) do
if input:match('@?' .. bot) then
table.insert(bots, bot)
end
end
if #bots == 0 then
return mattata.send_reply(message, 'Please make sure you\'re specifying valid bot usernames!')
end
for _, bot in pairs(bots) do
- redis:sadd('whitelisted_bots:' .. message.chat.id, bot)
+ redis:sadd('allowlisted_bots:' .. message.chat.id, bot)
end
- local output = string.format('Successfully whitelisted the following bots in this chat: %s', table.concat(bots, ', '))
+ local output = string.format('Successfully allowlisted the following bots in this chat: %s', table.concat(bots, ', '))
return mattata.send_reply(message, output)
end
-return whitelistbot
\ No newline at end of file
+return allowbot
\ No newline at end of file
diff --git a/plugins/administration/whitelistlink.lua b/plugins/administration/whitelistlink.lua
index 28ab1e0..92a88e8 100644
--- a/plugins/administration/whitelistlink.lua
+++ b/plugins/administration/whitelistlink.lua
@@ -1,30 +1,30 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
-local whitelistlink = {}
+local allowlink = {}
local mattata = require('mattata')
-function whitelistlink:init()
- whitelistlink.commands = mattata.commands(self.info.username):command('whitelistlink'):command('wl').table
- whitelistlink.help = '/whitelistlink <links> - Whitelists the given links in the current chat. Requires administrative privileges. Use /whitelistlink -del <links> to Alias: /wl.'
+function allowlink:init()
+ allowlink.commands = mattata.commands(self.info.username):command('allowlink'):command('wl').table
+ allowlink.help = '/allowlink <links> - Allowlists the given links in the current chat. Requires administrative privileges. Use /allowlink -del <links> to Alias: /wl.'
end
-function whitelistlink:on_message(message)
+function allowlink:on_message(message)
if not mattata.is_group_admin(message.chat.id, message.from.id) then
return false
end
local input = mattata.input(message.text)
local delete = false
if not input then
- return mattata.send_reply(message, 'Please specify the URLs or @usernames you\'d like to whitelist.')
+ return mattata.send_reply(message, 'Please specify the URLs or @usernames you\'d like to allowlist.')
elseif input:match('^%-del .-$') then
input = input:match('^%-del (.-)$')
delete = true
end
local output = mattata.check_links(message, false, false, true, false, delete)
return mattata.send_reply(message, output)
end
-return whitelistlink
\ No newline at end of file
+return allowlink
\ No newline at end of file
diff --git a/plugins/administration/wordfilter.lua b/plugins/administration/wordfilter.lua
index 02b23ce..b85d774 100644
--- a/plugins/administration/wordfilter.lua
+++ b/plugins/administration/wordfilter.lua
@@ -1,46 +1,87 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local wordfilter = {}
local mattata = require('mattata')
local redis = require('libs.redis')
function wordfilter:init()
wordfilter.commands = mattata.commands(self.info.username):command('wordfilter').table
wordfilter.help = '/wordfilter - View a list of words which have been added to the chat\'s word filter.'
+ wordfilter.bytes = {
+ ['a'] = { 197, 229, 506, 507, 7680, 7681, 7834, 258, 259, 7862, 7863, 7854, 7855, 7856, 7857, 7858, 7859, 7860, 7861, 514, 515, 194, 226, 7852, 7853, 7844, 7845, 7846, 7847, 7850, 7851, 7848, 7849, 7842, 7843, 461, 462, 570, 11365, 550, 551, 480, 481, 7840, 7841, 196, 228, 478, 479, 192, 224, 512, 513, 193, 225, 256, 257, 256, 257, 195, 227, 260, 261, 260, 261, 260, 261, 7567, 65313, 65345 },
+ ['b'] = { 7682, 7683, 7684, 7685, 7686, 7687, 579, 384, 7532, 7552, 385, 595, 386, 387, 65314, 65346 },
+ ['c'] = { 231, 199, 231, 231, 269, 268, 269, 269, 265, 264, 263, 262, 7689, 7688, 267, 266, 572, 571, 42899, 42898, 65315, 65347 },
+ ['d'] = { 271, 270, 273, 272, 396, 545, 7691, 7690, 7693, 7695, 7697, 7699, 598, 393, 599, 394, 240, 208, 240, 65316, 65348 },
+ ['e'] = { 275, 274, 233, 201, 233, 283, 282, 283, 232, 200, 232, 517, 234, 202, 281, 280, 281, 235, 203, 279, 278, 7865, 7864, 7869, 7868, 277, 519, 553, 281, 7701, 7703, 7702, 7705, 7707, 7709, 279, 234, 234, 7867, 7866, 7875, 7874, 7873, 7877, 7876, 7871, 7870, 7879, 7878, 7865, 7864, 7865, 7864, 65317, 65349 },
+ ['f'] = { 402, 401, 7711, 7710, 64256, 64257, 64258, 64259, 64260, 65318, 65350 },
+ ['g'] = { 501, 500, 289, 288, 285, 284, 487, 486, 287, 286, 291, 290, 485, 484, 8513, 8370, 8458, 65319, 65351 },
+ ['h'] = { 543, 542, 293, 292, 295, 294, 7721, 7720, 7723, 7722, 7830, 7715, 7714, 7717, 7716, 7718, 7719, 405, 502, 11368, 11367, 11382, 11381, 65320, 65352 },
+ ['i'] = { 305, 299, 298, 237, 205, 464, 463, 301, 300, 236, 204, 238, 206, 304, 303, 302, 239, 207, 7726, 7727, 237, 205, 236, 204, 297, 296, 7881, 7880, 7883, 7882, 65321, 65353 },
+ ['j'] = { 308, 309, 65322, 65354 },
+ ['k'] = { 1050, 1082, 1036, 1116, 1178, 1179, 1180, 1181, 1082, 11277, 11325, 922, 954, 954, 922, 1008, 65323, 65355 },
+ ['l'] = { 314, 313, 317, 7737, 7736, 7735, 7734, 318, 321, 322, 573, 410, 42825, 65324, 65356 },
+ ['m'] = { 7743, 7745, 7747, 7535, 65325, 65357 },
+ ['n'] = { 241, 209, 324, 326, 328, 626, 331, 414, 505, 565, 627, 7749, 7751, 7753, 7755, 65326, 65358 },
+ ['o'] = { 9386, 9438, 9412, 65327, 65359, 8338, 7439, 7441, 7484, 7506, 333, 332, 333, 332, 7763, 7762, 699, 243, 211, 243, 466, 465, 242, 210, 244, 212, 246, 214, 245, 213, 337, 336, 7763, 248, 216, 42827, 42826, 491, 490, 491, 490, 561, 560, 7759, 7758, 559, 558, 42829, 42828, 7887, 7886, 244, 212, 7891, 7890, 7893, 7892, 7895, 7894, 7889, 7888, 7897, 7896, 417, 416, 7901, 7900, 7903, 7902, 7905, 7904, 7899, 7898, 7907, 7906, 7885, 7884, 7885, 7884, 7885, 7884, 42805, 42804, 7444, 339, 338, 630, 42831, 42830, 546, 547, 7445, 65327, 65359 },
+ ['p'] = { 421, 7765, 7767, 65328, 65360 },
+ ['q'] = { 672, 586, 587, 1306, 1307, 42840, 42841, 984, 985, 120110, 120214, 8474, 1382, 491, 65329, 65361 },
+ ['r'] = { 174, 341, 344, 345, 529, 531, 636, 637, 638, 7769, 7771, 7773, 7775, 65330, 65362 },
+ ['s'] = { 350, 351, 348, 349, 537, 7784, 7785, 7780, 7781, 7776, 7777, 7782, 7783, 352, 353, 346, 347, 7779, 65331, 65363 },
+ ['t'] = { 427, 538, 539, 354, 355, 430, 648, 358, 359, 356, 357, 7786, 7787, 7788, 7789, 772, 7831, 7790, 7791, 65332, 65364 },
+ ['u'] = { 363, 362, 250, 218, 468, 467, 249, 217, 365, 364, 251, 219, 252, 220, 367, 366, 371, 370, 361, 360, 369, 368, 533, 532, 7795, 7794, 7797, 7796, 7799, 7798, 7801, 7800, 7803, 7802, 470, 469, 472, 471, 474, 473, 476, 475, 7911, 7910, 361, 360, 7909, 7908, 432, 431, 7915, 7914, 7917, 7916, 7919, 7918, 7913, 7912, 7921, 7920, 7531, 65333, 65365 },
+ ['v'] = { 7805, 7804, 7807, 7806, 42846, 65334, 65366 },
+ ['w'] = { 7810, 7811, 7808, 7809, 372, 373, 7832, 7812, 7813, 7814, 7815, 7816, 7817, 653, 684, 65335, 65367 },
+ ['x'] = { 1093, 1203, 1277, 1279, 926, 958, 935, 967, 885, 885, 967, 935, 967, 739, 215, 9587, 10005, 10006, 10799, 10007, 10008, 128500, 128502, 9746, 128501, 128503, 9747, 128937, 10060, 10062, 10761, 128473, 120091, 120117, 12584, 12490, 12513, 1488, 20034, 13317, 5815, 5816, 1604, 7821, 7820, 7819, 7818, 7565, 65336, 65368 },
+ ['y'] = { 11433, 11432, 1091, 1059, 1118, 1038, 1091, 1091, 1141, 1140, 933, 910, 910, 8029, 8025, 8027, 8031, 8170, 8168, 8169, 65337, 65369 },
+ ['z'] = { 11405, 11404, 918, 950, 918, 382, 381, 380, 379, 7826, 7827, 378, 7828, 7829, 7824, 7825, 377, 656, 657, 549, 437, 438, 20057, 20043, 8484, 65338, 65370 }
+ }
+end
+
+function wordfilter:on_new_message(message)
+ if message.chat.type == 'supergroup' and mattata.get_setting(message.chat.id, 'word filter') and not mattata.is_group_admin(message.chat.id, message.from.id) then
+ local base = message.text:lower()
+ for char, variations in pairs(wordfilter.bytes) do
+ for _, variation in pairs(variations) do
+ base = base:gsub(utf8.char(variation), char)
+ end
+ end
+ base = base:gsub('[^%w \n\t\r]', '') -- Trim everything apart from alpha-numerical characters and spaces.
+ local words = redis:smembers('word_filter:' .. message.chat.id)
+ if words and #words > 0 then
+ for _, v in pairs(words) do
+ if base:match('^' .. v:lower() .. '$') or base:match('^' .. v:lower() .. ' ') or base:match(' ' .. v:lower() .. ' ') or base:match(' ' .. v:lower() .. '$') then
+ mattata.delete_message(message.chat.id, message.message_id)
+ local action = mattata.get_setting(message.chat.id, 'ban not kick') and mattata.ban_chat_member or mattata.kick_chat_member
+ local success = action(message.chat.id, message.from.id)
+ if success then
+ if mattata.get_setting(message.chat.id, 'log administrative actions') then
+ local log_chat = mattata.get_log_chat(message.chat.id)
+ mattata.send_message(log_chat, string.format('<pre>%s [%s] has kicked %s [%s] from %s [%s] for sending one or more prohibited words.</pre>', mattata.escape_html(self.info.first_name), self.info.id, mattata.escape_html(message.from.first_name), message.from.id, mattata.escape_html(message.chat.title), message.chat.id), 'html')
+ end
+ mattata.send_message(message.chat.id, string.format('Kicked %s for sending one or more prohibited words.', message.from.username and '@' .. message.from.username or message.from.first_name))
+ self.is_command_done = true
+ break
+ end
+ end
+ end
+ end
+ end
end
function wordfilter:on_message(message, configuration, language)
- if message.chat.type ~= 'supergroup'
- then
- return mattata.send_reply(
- message,
- language['errors']['supergroup']
- )
- elseif not mattata.is_group_admin(
- message.chat.id,
- message.from.id
- )
- then
- return mattata.send_reply(
- message,
- language['errors']['admin']
- )
+ if message.chat.type ~= 'supergroup' then
+ mattata.send_reply(message, language.errors.supergroup)
+ elseif not mattata.is_group_admin(message.chat.id, message.from.id) then
+ return mattata.send_reply(message, language.errors.admin)
end
local words = redis:smembers('word_filter:' .. message.chat.id)
- if #words < 1
- then
- return mattata.send_reply(
- message,
- 'There are no words filtered in this chat. To add words to the filter, use /filter <word(s)>.'
- )
+ if #words < 1 then
+ return mattata.send_reply(message, 'There are no words filtered in this chat. To add words to the filter, use /filter <word(s)>.')
end
- return mattata.send_message(
- message.chat.id,
- 'Filtered words: ' .. table.concat(words, ', ')
- )
+ return mattata.send_message(message.chat.id, 'Filtered words: ' .. table.concat(words, ', '))
end
return wordfilter
\ No newline at end of file
diff --git a/plugins/ai.lua b/plugins/ai.lua
index 1522099..68baa3e 100644
--- a/plugins/ai.lua
+++ b/plugins/ai.lua
@@ -1,259 +1,44 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local ai = {}
local mattata = require('mattata')
-local https = require('ssl.https')
-local url = require('socket.url')
-local ltn12 = require('ltn12')
-local md5 = require('md5')
-
+local redis = require('libs.redis')
function ai:on_new_message(message)
if not message.text or message.is_command then
return false
elseif message.text and message.reply and message.reply.text and message.reply.from.id == self.info.id and not message.reply.entities then
return ai.on_message(self, message)
end
local triggers = {
'^' .. self.info.first_name:lower() .. ',? ',
'^@?' .. self.info.username:lower() .. ',? '
}
for _, trigger in pairs(triggers) do
if message.text:lower():match(trigger) then
return ai.on_message(self, message)
end
end
if message.chat.type == 'private' and not message.is_command and not message.text:match('^[/!#]') and message.text then
return ai.on_message(self, message)
end
return
end
-function ai.unescape(str)
- if not str then
- return false
- end
- str = str:gsub('%%(%x%x)', function(x)
- return tostring(tonumber(x, 16)):char()
- end)
- return str
-end
-
-function ai.cookie()
- local cookie = {}
- local _, res, headers = https.request({
- ['url'] = 'http://www.cleverbot.com/',
- ['method'] = 'GET'
- })
- if res ~= 200 then
- return false
- end
- local set = headers['set-cookie']
- local k, v = set:match('([^%s;=]+)=?([^%s;]*)')
- cookie[k] = v
- return cookie
-end
-
-function ai.talk(message, reply)
- if not message then
- return false
- end
- return ai.cleverbot(message, reply)
-end
-
-function ai.cleverbot(message, reply)
- local cookie = ai.cookie()
- if not cookie then
- return false
- end
- for k, v in pairs(cookie) do
- cookie[#cookie + 1] = k .. '=' .. v
- end
- local query = 'stimulus=' .. url.escape(message)
- if reply then
- query = query .. '&vText2=' .. url.escape(reply)
- end
- query = query .. '&cb_settings_scripting=no&islearning=1&icognoid=wsf&icognocheck='
- local icognocheck = md5.sumhexa(query:sub(8, 33))
- query = query .. icognocheck
- local agents = {
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
- 'Mozilla/5.0 CK={} (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
- 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763'
- }
- local agent = agents[math.random(#agents)]
- local old = https.TIMEOUT
- https.TIMEOUT = 2
- local _, res, headers = https.request({
- ['url'] = 'https://www.cleverbot.com/webservicemin?uc=UseOfficialCleverbotAPI&dl=en&flag=&user=&mode=1&alt=0&reac=&emo=&sou=website&xed=&',
- ['method'] = 'POST',
- ['headers'] = {
- ['Host'] = 'www.cleverbot.com',
- ['User-Agent'] = agent,
- ['Accept'] = '*/*',
- ['Accept-Language'] = 'en-US,en;q=0.5',
- ['Accept-Encoding'] = 'gzip, deflate',
- ['Referrer'] = 'https://www.cleverbot.com/',
- ['Content-Length'] = query:len(),
- ['Content-Type'] = 'text/plain;charset=UTF-8',
- ['Cookie'] = table.concat(cookie, ';'),
- ['DNT'] = '1'
- },
- ['source'] = ltn12.source.string(query)
- })
- https.TIMEOUT = old
- if res ~= 200 or not headers.cboutput then
- return false
- end
- local output = ai.unescape(headers.cboutput)
- if not output then
- return false
- end
- return output
-end
-
-function ai:process(message, reply)
- if not message then
- return ai.unsure()
- end
- local original_message = message
- message = message:lower()
- if message:match('^hi%s*') or message:match('^hello%s*') or message:match('^howdy%s*') or message:match('^hi.?$') or message:match('^hello.?$') or message:match('^howdy.?$') then
- return ai.greeting()
- elseif message:match('^bye%s*') or message:match('^good[%-%s]?bye%s*') or message:match('^bye$') or message:match('^good[%-%s]?bye$') then
- return ai.farewell()
- elseif message:match('%s*y?o?ur%s*name%s*') or message:match('^what%s*is%s*y?o?ur%s*name') then
- return string.format('My name is %s, what\'s yours?', self.info.first_name)
- elseif message:match('^do y?o?u[%s.]*') then
- return ai.choice(message)
- elseif message:match('^how%s*a?re?%s*y?o?u.?') or message:match('.?how%s*a?re?%s*y?o?u%s*') or message:match('.?how%s*a?re?%s*y?o?u.?$') or message:match('^a?re?%s*y?o?u%s*oka?y?.?$') or message:match('%s*a?re?%s*y?o?u%s*oka?y?.?$') then
- return ai.feeling()
- else
- return ai.talk(original_message, reply or false)
- end
-end
-
-function ai.greeting()
- local greetings = {
- 'Hello!',
- 'Hi.',
- 'How are you?',
- 'What\'s up?',
- 'Are you okay?',
- 'How\'s it going?',
- 'What\'s your name?',
- 'What are you up to?',
- 'Hello.',
- 'Hey!',
- 'Hey.',
- 'Howdy!',
- 'Howdy.',
- 'Hello there!',
- 'Hello there.'
- }
- return greetings[math.random(#greetings)]
-end
-
-function ai.farewell()
- local farewells = {
- 'Goodbye!',
- 'Bye.',
- 'I\'ll speak to you later, yeah?',
- 'See ya!',
- 'Oh, bye then.',
- 'Bye bye.',
- 'BUH-BYE!',
- 'Aw. See ya.'
- }
- return farewells[math.random(#farewells)]
-end
-
-function ai.unsure()
- local unsure = {
- 'What?',
- 'I really don\'t understand.',
- 'What are you trying to say?',
- 'Huh?',
- 'Um..?',
- 'Excuse me?',
- 'What does that mean?'
- }
- return unsure[math.random(#unsure)]
-end
-
-function ai.feeling()
- local feelings = {
- 'I am good thank you!',
- 'I am well.',
- 'Good, how about you?',
- 'Very well thank you; you?',
- 'Never better!',
- 'I feel great!'
- }
- return feelings[math.random(#feelings)]
-end
-
-function ai.choice(message)
- local generic_choices = {
- 'I do!',
- 'I do not.',
- 'Nah, of course not!',
- 'Why would I?',
- 'Um...',
- 'I sure do!',
- 'Yes, do you?',
- 'Nope!',
- 'Yeah!'
- }
- local personal_choices = {
- 'I love you!',
- 'I\'m sorry, but I don\'t really like you!',
- 'I really like you.',
- 'I\'m crazy about you!'
- }
- if message:match('%s*me.?$') then
- return personal_choices[math.random(#personal_choices)]
- end
- return generic_choices[math.random(#generic_choices)]
-end
-
-function ai.offline()
- local responses = {
- 'I don\'t feel like talking right now!',
- 'I don\'t want to talk at the moment.',
- 'Can we talk later?',
- 'I\'m not in the mood right now...',
- 'Leave me alone!',
- 'Please can I have some time to myself?',
- 'I really don\'t want to talk to anyone right now!',
- 'Please leave me in peace.',
- 'I don\'t wanna talk right now, I hope you understand.'
- }
- return responses[math.random(#responses)]
-end
-
function ai:on_message(message)
self.is_ai = true
- mattata.send_chat_action(message.chat.id, 'typing')
local text = message.text:gsub('^' .. self.info.first_name:lower() .. ',? ', ''):gsub('^@?' .. self.info.username:lower() .. ',? ', '')
text = text:gsub(self.info.first_name:lower(), 'you'):gsub('@?' .. self.info.username:lower(), 'you')
- local reply = false
+ local language = mattata.get_setting(message.chat.id, 'force group language') and 'en' or mattata.get_user_language(message.from.id):match('^(..)')
if message.reply and message.reply.text and message.reply.from.id == self.info.id and not message.reply.entities then
- reply = message.reply.text
- end
- local output = ai.process(self, text, reply)
- if not output then
- return false
- end
- local success = mattata.send_reply(message, output)
- if output:lower():match('g?o?o?d?bye') or output:lower():match('see ya') and not mattata.is_group_admin(message.chat.id, self.info.id) and mattata.is_group_admin(message.chat.id, message.from.id) then
- return mattata.leave_chat(message.chat.id)
+ redis:hset('ai:' .. message.chat.id .. ':' .. message.message_id, 'reply', message.reply.text)
end
- return success
+ redis:hset('ai:' .. message.chat.id .. ':' .. message.message_id, 'text', text)
+ redis:hset('ai:' .. message.chat.id .. ':' .. message.message_id, 'language', language)
+ return
end
return ai
\ No newline at end of file
diff --git a/plugins/administration/whitelistlink.lua b/plugins/allowlink.lua
similarity index 58%
copy from plugins/administration/whitelistlink.lua
copy to plugins/allowlink.lua
index 28ab1e0..3508bd1 100644
--- a/plugins/administration/whitelistlink.lua
+++ b/plugins/allowlink.lua
@@ -1,30 +1,31 @@
---[[
- Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
- This code is licensed under the MIT. See LICENSE for details.
-]]
-
-local whitelistlink = {}
-local mattata = require('mattata')
-
-function whitelistlink:init()
- whitelistlink.commands = mattata.commands(self.info.username):command('whitelistlink'):command('wl').table
- whitelistlink.help = '/whitelistlink <links> - Whitelists the given links in the current chat. Requires administrative privileges. Use /whitelistlink -del <links> to Alias: /wl.'
-end
-
-function whitelistlink:on_message(message)
- if not mattata.is_group_admin(message.chat.id, message.from.id) then
- return false
- end
- local input = mattata.input(message.text)
- local delete = false
- if not input then
- return mattata.send_reply(message, 'Please specify the URLs or @usernames you\'d like to whitelist.')
- elseif input:match('^%-del .-$') then
- input = input:match('^%-del (.-)$')
- delete = true
- end
- local output = mattata.check_links(message, false, false, true, false, delete)
- return mattata.send_reply(message, output)
-end
-
-return whitelistlink
\ No newline at end of file
+--[[
+ Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
+ This code is licensed under the MIT. See LICENSE for details.
+]]
+
+local allowlink = {}
+local mattata = require('mattata')
+
+function allowlink:init()
+ allowlink.commands = mattata.commands(self.info.username):command('allowlink'):command('wl').table
+ allowlink.help = '/allowlink <links> - Allowlists the given links in the current chat. Requires administrative privileges. Use /allowlink -del <links> to Alias: /wl.'
+end
+
+function allowlink:on_message(message)
+ if not mattata.is_group_admin(message.chat.id, message.from.id) then
+ return false
+ end
+ local input = mattata.input(message.text)
+ local delete = false
+ if not input then
+ return mattata.send_reply(message, 'Please specify the URLs or @usernames you\'d like to allowlist.')
+ elseif input:match('^%-del .-$') then
+ input = input:match('^%-del (.-)$')
+ delete = true
+ end
+ message.text = input
+ local output = mattata.check_links(message, false, false, true, false, delete)
+ return mattata.send_reply(message, output)
+end
+
+return allowlink
\ No newline at end of file
diff --git a/plugins/bing.lua b/plugins/bing.lua
index fa63208..c7ea48f 100644
--- a/plugins/bing.lua
+++ b/plugins/bing.lua
@@ -1,63 +1,64 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local bing = {}
local mattata = require('mattata')
local https = require('ssl.https')
local url = require('socket.url')
local ltn12 = require('ltn12')
local json = require('dkjson')
function bing:init(configuration)
assert(configuration.keys.bing, 'bing.lua requires an API key, and you haven\'t got one configured!')
bing.commands = mattata.commands(self.info.username):command('bing').table
bing.help = '/bing <query> - Searches Bing for the given search query and returns the top results.'
bing.key = configuration.keys.bing
end
function bing.on_message(_, message, configuration, language)
local input = mattata.input(message.text)
if not input then
return mattata.send_reply(message, bing.help)
end
local body = {}
local _, res = https.request({
['url'] = 'https://api.cognitive.microsoft.com/bing/v7.0/search?responseFilter=Webpages&safeSearch=Off&q=' .. url.escape(input),
['headers'] = {
['Ocp-Apim-Subscription-Key'] = bing.key,
['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko'
},
['sink'] = ltn12.sink.table(body),
})
if res ~= 200 then
return mattata.send_reply(message, language.errors.connection)
end
local jdat = json.decode(table.concat(body))
if not jdat.webPages then
return mattata.send_reply(message, language.errors.results)
end
local limit = message.chat.type == 'private' and configuration.limits.bing.private or configuration.limits.bing.public
if limit > #jdat.webPages.value and #jdat.webPages.value or limit == 0 then
return mattata.send_reply(message, language.errors.results)
end
local results = {}
local count = 0
for i = 1, limit do
if jdat.webPages.value[i].snippet:len() > 100 then
jdat.webPages.value[i].snippet = jdat.webPages.value[i].snippet:sub(1, 100) .. '...'
end
if count > limit - 4 then
table.insert(results, string.format('%s <a href="%s">%s</a>', mattata.symbols.bullet, jdat.webPages.value[i].url, mattata.escape_html(jdat.webPages.value[i].name)))
else
table.insert(results, string.format('%s <a href="%s">%s</a> <em>%s</em>', mattata.symbols.bullet, jdat.webPages.value[i].url, mattata.escape_html(jdat.webPages.value[i].name), mattata.escape_html(jdat.webPages.value[i].snippet)))
end
count = count + 1
end
local output = table.concat(results, '\n')
return mattata.send_message(message.chat.id, output, 'html')
end
return bing
\ No newline at end of file
diff --git a/plugins/blacklistchat.lua b/plugins/blacklistchat.lua
index 12cf31a..df713b5 100644
--- a/plugins/blacklistchat.lua
+++ b/plugins/blacklistchat.lua
@@ -1,36 +1,36 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
-local blacklistchat = {}
+local blocklistchat = {}
local mattata = require('mattata')
local redis = require('libs.redis')
-function blacklistchat:init()
- blacklistchat.commands = mattata.commands(self.info.username):command('blacklistchat').table
+function blocklistchat:init()
+ blocklistchat.commands = mattata.commands(self.info.username):command('blocklistchat').table
end
-function blacklistchat.on_message(_, message, _, language)
+function blocklistchat.on_message(_, message, _, language)
if not mattata.is_global_admin(message.from.id) then
return false
end
local input = mattata.input(message.text)
if not input then
return false
end
input = input:match('^@(.-)$') or input
local res = mattata.get_chat(input)
local output
if not res then
- output = string.format(language['blacklistchat']['3'], input)
+ output = string.format(language['blocklistchat']['3'], input)
elseif res.result.type == 'private' then
- output = string.format(language['blacklistchat']['2'], input)
+ output = string.format(language['blocklistchat']['2'], input)
else
- redis.set('blacklisted_chats:' .. input, true)
- output = string.format(language['blacklistchat']['1'], input)
+ redis.set('blocklisted_chats:' .. input, true)
+ output = string.format(language['blocklistchat']['1'], input)
end
return mattata.send_reply(message, output)
end
-return blacklistchat
\ No newline at end of file
+return blocklistchat
\ No newline at end of file
diff --git a/plugins/blacklistchat.lua b/plugins/blocklistchat.lua
similarity index 57%
copy from plugins/blacklistchat.lua
copy to plugins/blocklistchat.lua
index 12cf31a..9181847 100644
--- a/plugins/blacklistchat.lua
+++ b/plugins/blocklistchat.lua
@@ -1,36 +1,36 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
-local blacklistchat = {}
+local allowlistchat = {}
local mattata = require('mattata')
local redis = require('libs.redis')
-function blacklistchat:init()
- blacklistchat.commands = mattata.commands(self.info.username):command('blacklistchat').table
+function allowlistchat:init()
+ allowlistchat.commands = mattata.commands(self.info.username):command('allowlistchat').table
end
-function blacklistchat.on_message(_, message, _, language)
+function allowlistchat.on_message(_, message, _, language)
if not mattata.is_global_admin(message.from.id) then
return false
end
local input = mattata.input(message.text)
if not input then
return false
end
input = input:match('^@(.-)$') or input
local res = mattata.get_chat(input)
local output
if not res then
- output = string.format(language['blacklistchat']['3'], input)
+ output = string.format(language['allowlistchat']['3'], input)
elseif res.result.type == 'private' then
- output = string.format(language['blacklistchat']['2'], input)
+ output = string.format(language['allowlistchat']['2'], input)
else
- redis.set('blacklisted_chats:' .. input, true)
- output = string.format(language['blacklistchat']['1'], input)
+ redis.set('allowlisted_chats:' .. input, true)
+ output = string.format(language['allowlistchat']['1'], input)
end
return mattata.send_reply(message, output)
end
-return blacklistchat
\ No newline at end of file
+return allowlistchat
\ No newline at end of file
diff --git a/plugins/calc.lua b/plugins/calc.lua
index 6d48910..ad69cf6 100644
--- a/plugins/calc.lua
+++ b/plugins/calc.lua
@@ -1,192 +1,198 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local calc = {}
local mattata = require('mattata')
local http = require('socket.http')
local url = require('socket.url')
function calc:init()
calc.commands = mattata.commands(self.info.username):command('calc'):command('calculate'):command('calculator').table
calc.help = '/calc <expression> - Solves the given mathematical expression using mathjs.org.'
calc.aliases = {
['?'] = '/',
['divided by'] = '/',
['times by'] = '*',
['times'] = '*',
['multiplied by'] = '*',
[' x '] = '*',
['minus'] = '-',
['subtract'] = '-',
['take away'] = '-',
['to the power of'] = '^',
['raised to'] = '^',
- [' pi '] = math.pi,
+ ['π'] = math.pi,
+ ['pi'] = math.pi,
['plus'] = '+',
['added to'] = '+',
['add'] = '+',
['point'] = '.',
- ['dot'] = '.'
+ ['dot'] = '.',
+ ['percent'] = '%%',
+ ['percentage'] = '%%',
+ ['²'] = '^2'
}
calc.numbers = {
['zero'] = 0,
['one'] = 1,
['two'] = 2,
['three'] = 3,
['four'] = 4,
['five'] = 5,
['six'] = 6,
['seven'] = 7,
['eight'] = 8,
['nine'] = 9,
['ten'] = 10,
['eleven'] = 11,
['twelve'] = 12,
['thirteen'] = 13,
['fourteen'] = 14,
['fifteen'] = 15,
['sixteen'] = 16,
['seventeen'] = 17,
['eighteen'] = 18,
['nineteen'] = 19,
['twenty'] = 20,
['thirty'] = 30,
['forty'] = 40,
['fifty'] = 50,
['sixty'] = 60,
['seventy'] = 70,
['eighty'] = 80,
['ninety'] = 90
}
calc.units = {
['hundred'] = '100',
['thousand'] = '1000',
['million'] = '1000000',
['billion'] = '1000000000',
['trillion'] = '1000000000000',
['quadrillion'] = '1000000000000000',
['quintillion'] = '1000000000000000000',
['sextillion'] = '1000000000000000000000',
['septillion'] = '1000000000000000000000000',
['octillion'] = '1000000000000000000000000000',
['nonillion'] = '1000000000000000000000000000000',
['decillion'] = '1000000000000000000000000000000000',
['undecillion'] = '1000000000000000000000000000000000000',
['duodecillion'] = '1000000000000000000000000000000000000000',
['tredecillion'] = '1000000000000000000000000000000000000000000',
['quattuordecillion'] = '1000000000000000000000000000000000000000000000',
['quindecillion'] = '1000000000000000000000000000000000000000000000000',
['sexdecillion'] = '1000000000000000000000000000000000000000000000000000',
['septendecillion'] = '1000000000000000000000000000000000000000000000000000000',
['octodecillion'] = '1000000000000000000000000000000000000000000000000000000000',
['novemdecillion'] = '1000000000000000000000000000000000000000000000000000000000000',
['vigintillion'] = '1000000000000000000000000000000000000000000000000000000000000000'
}
calc.url = 'https://api.mathjs.org/v4/?expr='
end
function calc.convert(str, language)
str = str:lower()
local results = {}
local prev = nil
- for word in str:gmatch('%w+') do
+ for word in str:gmatch('[%w²π]+') do
if word ~= 'and' then -- don't process "and"
local top = #results
local number = tonumber(word)
if not number then
number = calc.numbers[word]
end
if number then
if prev == 'number' then
local prev_num = table.remove(results, top)
number = number + prev_num
end
table.insert(results, number)
prev = 'number'
else
local unit = tonumber(calc.units[word])
if not unit then
return false, string.format(language['calc']['2'], word)
end
prev = 'unit'
if top == 0 then
return false, language['calc']['3']
end
local interim = 0
while top > 0 and results[top] < unit do
interim = interim + table.remove(results, top)
top = #results
end
table.insert(results, interim * unit)
end
end
end
if #results == 0 then
return false, 'No number found!'
end
local final = 0
for _, res in ipairs(results) do
final = final + res
end
return final
end
function calc.process_input(input, language)
+ input = input:gsub('percent of', 'percent')
for k, v in pairs(calc.aliases) do
input = input:gsub(k, v)
end
for phrase in input:gmatch('[%w%s]+') do
local new, err = calc.convert(phrase, language)
if new then
input = input:gsub(phrase, new)
else
return false, err
end
end
return input
end
function calc.on_inline_query(_, inline_query, _, language)
local input = mattata.input(inline_query.query)
if not input then
return false
end
input = calc.process_input(input, language)
local str, res = http.request(calc.url .. url.escape(input))
if res ~= 200 or not str then
return false
end
local description = language['calc']['1']
local message_content = mattata.input_text_message_content(str)
local result = mattata.inline_result()
:type('article')
:id(1)
:title(str)
:description(description)
:input_message_content(message_content)
return mattata.answer_inline_query(inline_query.id, result)
end
function calc.on_message(_, message, _, language)
local input = mattata.input(message.text)
local err
if not input then
return mattata.send_reply(message, calc.help)
end
input, err = calc.process_input(input, language)
if not input then
return mattata.send_reply(message, err)
end
local str, res = http.request(calc.url .. url.escape(input))
if res ~= 200 then
local response = language['errors']['results']
return mattata.send_reply(message, response)
end
return mattata.send_message(message.chat.id, str)
end
return calc
\ No newline at end of file
diff --git a/plugins/cats.lua b/plugins/cats.lua
index ea62dd2..cfbdc5d 100644
--- a/plugins/cats.lua
+++ b/plugins/cats.lua
@@ -1,46 +1,47 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local cats = {}
local mattata = require('mattata')
local http = require('socket.http')
local json = require('dkjson')
function cats:init(configuration)
assert(configuration.keys.cats, 'cats.lua requires an API key, and you haven\'t got one configured!')
cats.commands = mattata.commands(self.info.username):command('cat').table
cats.help = '/cat - Sends a random photo of a cat.'
end
function cats.on_inline_query(_, inline_query, configuration, language)
local str, res = http.request('http://thecatapi.com/api/images/get?format=html&type=jpg&api_key=' .. configuration.keys.cats)
str = str:match('%<img src%=%"(.-)%"%>')
if res ~= 200 then
return
end
return mattata.answer_inline_query(inline_query.id, json.encode({{
['type'] = 'photo',
['id'] = '1',
['photo_url'] = tostring(str),
['thumb_url'] = tostring(str),
['caption'] = language['cats']['1']
}}))
end
function cats.on_message(_, message, configuration, language)
local str, res = http.request('http://thecatapi.com/api/images/get?format=html&type=jpg&api_key=' .. configuration.keys.cats)
if res ~= 200 then
return mattata.send_reply(message, language.errors.connection)
end
local photo = str:match('%<img src%=%"(.-)%"%>')
if not photo then
return mattata.send_reply(message, language.errors.unknown)
end
mattata.send_chat_action(message.chat.id, 'upload_photo')
return mattata.send_photo(message.chat.id, photo, language['cats']['1'])
end
return cats
\ No newline at end of file
diff --git a/plugins/currency.lua b/plugins/currency.lua
index cb7be94..4dd6d5f 100644
--- a/plugins/currency.lua
+++ b/plugins/currency.lua
@@ -1,43 +1,44 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local currency = {}
local mattata = require('mattata')
local https = require('ssl.https')
function currency:init()
currency.commands = mattata.commands(self.info.username):command('currency'):command('convert'):command('cash').table
currency.help = '/currency <amount> <from> to <to> - Converts exchange rates for various currencies via Google Finance. Aliases: /convert, /cash.'
currency.url = 'https://www.google.com/finance/converter?from=%s&to=%s&a=%s'
end
function currency.on_message(_, message, _, language)
local input = mattata.input(message.text:upper())
if input then
input = input:gsub('%$', 'USD'):gsub('€', 'EUR'):gsub('£', 'GBP')
end
if not input or not input:match('^.- %a%a%a TO %a%a%a$') then
return mattata.send_reply(message, currency.help)
end
local amount, from, to = input:match('^(.-) (%a%a%a) TO (%a%a%a)$')
amount = tonumber(amount) or 1
local result = 1
if from ~= to then
local str, res = https.request(string.format(currency.url, from, to, amount))
if res ~= 200 then
return mattata.send_reply(message, language.errors.connection)
end
str = str:match('<span class=bld>(.-) %u+</span>')
if not str then
return mattata.send_reply(message, language.errors.results)
end
result = string.format('%.2f', str)
end
result = string.format('%s %s = %s %s', amount, from, result, to)
return mattata.send_message(message.chat.id, result)
end
return currency
\ No newline at end of file
diff --git a/plugins/gblacklist.lua b/plugins/gblacklist.lua
index 64e74d3..00f6eec 100644
--- a/plugins/gblacklist.lua
+++ b/plugins/gblacklist.lua
@@ -1,46 +1,46 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
-local gblacklist = {}
+local gblocklist = {}
local mattata = require('mattata')
local redis = require('libs.redis')
-function gblacklist:init()
- gblacklist.commands = mattata.commands(self.info.username):command('gblacklist').table
+function gblocklist:init()
+ gblocklist.commands = mattata.commands(self.info.username):command('gblocklist').table
end
-function gblacklist:on_message(message, configuration, language)
+function gblocklist:on_message(message, configuration, language)
local input = mattata.input(message.text)
if not mattata.is_global_admin(message.from.id) then
return
elseif not message.reply and not input then
- return mattata.send_reply(message, language['gblacklist']['1'])
+ return mattata.send_reply(message, language['gblocklist']['1'])
elseif message.reply then
input = message.reply.from.id
end
if tonumber(input) == nil and not input:match('^@') then
input = '@' .. input
end
local resolved = mattata.get_user(input)
local output
if not resolved then
- output = string.format(language['gblacklist']['2'], input)
+ output = string.format(language['gblocklist']['2'], input)
return mattata.send_reply(message, output)
elseif resolved.result.type ~= 'private' then
- output = string.format(language['gblacklist']['3'], resolved.result.type)
+ output = string.format(language['gblocklist']['3'], resolved.result.type)
return mattata.send_reply(message, output)
end
if resolved.result.id == self.info.id or mattata.is_global_admin(resolved.result.id) then
return
end
- redis:set('global_blacklist:' .. resolved.result.id, true)
- output = string.format('%s [%s] has blacklisted %s [%s] from using %s.', message.from.first_name, message.from.id, resolved.result.first_name, resolved.result.id, self.info.first_name)
+ redis:set('global_blocklist:' .. resolved.result.id, true)
+ output = string.format('%s [%s] has blocklisted %s [%s] from using %s.', message.from.first_name, message.from.id, resolved.result.first_name, resolved.result.id, self.info.first_name)
if configuration.log_admin_actions and configuration.log_channel ~= '' then
mattata.send_message(configuration.log_channel, '<pre>' .. mattata.escape_html(output) .. '</pre>', 'html')
end
return mattata.send_message(message.chat.id, '<pre>' .. mattata.escape_html(output) .. '</pre>', 'html')
end
-return gblacklist
\ No newline at end of file
+return gblocklist
\ No newline at end of file
diff --git a/plugins/gwhitelist.lua b/plugins/gwhitelist.lua
index 8c9cdd0..a600f77 100644
--- a/plugins/gwhitelist.lua
+++ b/plugins/gwhitelist.lua
@@ -1,49 +1,49 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
-local gwhitelist = {}
+local gallowlist = {}
local mattata = require('mattata')
local redis = require('libs.redis')
-function gwhitelist:init()
- gwhitelist.commands = mattata.commands(self.info.username):command('gwhitelist').table
+function gallowlist:init()
+ gallowlist.commands = mattata.commands(self.info.username):command('gallowlist').table
end
-function gwhitelist:on_message(message, configuration, language)
+function gallowlist:on_message(message, configuration, language)
local input = mattata.input(message.text)
if not mattata.is_global_admin(message.from.id) then
return
elseif not message.reply and not input then
- return mattata.send_reply(message, language['gwhitelist']['1'])
+ return mattata.send_reply(message, language['gallowlist']['1'])
elseif message.reply then
input = message.reply.from.id
end
if tonumber(input) == nil and not input:match('^@') then
input = '@' .. input
end
local resolved = mattata.get_user(input) or mattata.get_chat(input)
local output
if not resolved then
- output = string.format(language['gwhitelist']['2'], input)
+ output = string.format(language['gallowlist']['2'], input)
return mattata.send_reply(message, output)
elseif resolved.result.type ~= 'private' then
- output = string.format(language['gwhitelist']['3'], resolved.result.type)
+ output = string.format(language['gallowlist']['3'], resolved.result.type)
return mattata.send_reply(message, output)
end
if resolved.result.id == self.info.id or mattata.is_global_admin(resolved.result.id) then
return
end
- redis:del('global_blacklist:' .. resolved.result.id)
+ redis:del('global_blocklist:' .. resolved.result.id)
local bot_username = mattata.get_formatted_user(self.info.id, self.info.first_name, 'html')
local our_username = mattata.get_formatted_user(message.from.id, message.from.first_name, 'html')
- local whitelisted_username = mattata.get_formatted_user(resolved.result.id, resolved.result.first_name, 'html')
- output = string.format('%s <code>[%s]</code> has whitelisted %s <code>[%s]</code> to use %s <code>[%s]</code>.', our_username, message.from.id, whitelisted_username, resolved.result.id, bot_username, self.info.id)
+ local allowlisted_username = mattata.get_formatted_user(resolved.result.id, resolved.result.first_name, 'html')
+ output = string.format('%s <code>[%s]</code> has allowlisted %s <code>[%s]</code> to use %s <code>[%s]</code>.', our_username, message.from.id, allowlisted_username, resolved.result.id, bot_username, self.info.id)
if configuration.log_admin_actions and configuration.log_channel ~= '' then
return mattata.send_message(configuration.log_channel, output, 'html')
end
return mattata.send_message(message.chat.id, output, 'html')
end
-return gwhitelist
\ No newline at end of file
+return gallowlist
\ No newline at end of file
diff --git a/plugins/hackernews.lua b/plugins/hackernews.lua
index d453cec..261623b 100644
--- a/plugins/hackernews.lua
+++ b/plugins/hackernews.lua
@@ -1,86 +1,87 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local hackernews = {}
local mattata = require('mattata')
local https = require('ssl.https')
local json = require('dkjson')
function hackernews:init()
hackernews.commands = mattata.commands(self.info.username)
:command('hackernews')
:command('hn').table
hackernews.help = '/hackernews - Sends the top stories from Hacker News. Alias: /hn.'
end
function hackernews.get_results(hackernews_topstories, hackernews_result, hackernews_article)
local results = {}
local jstr, res = https.request(hackernews_topstories)
if res ~= 200
then
return false
end
local jdat = json.decode(jstr)
for i = 1, 8
do
local result_jstr, result_res = https.request(hackernews_result:format(jdat[i]))
if result_res ~= 200
then
return false
end
local result_jdat = json.decode(result_jstr)
local result
if result_jdat.url
then
result = string.format(
'\n• <code>[</code><a href="%s">%s</a><code>]</code> <a href="%s">%s</a>',
mattata.escape_html(hackernews_article:format(result_jdat.id)),
result_jdat.id,
mattata.escape_html(result_jdat.url),
mattata.escape_html(result_jdat.title)
)
else
result = string.format(
'\n• <code>[</code><a href="%s">%s</a><code>]</code> %s',
mattata.escape_html(hackernews_article:format(result_jdat.id)),
result_jdat.id,
mattata.escape_html(result_jdat.title)
)
end
table.insert(
results,
result
)
end
return results
end
function hackernews:on_message(message, configuration, language)
local results = hackernews.get_results('https://hacker-news.firebaseio.com/v0/topstories.json', 'https://hacker-news.firebaseio.com/v0/item/%s.json', 'https://news.ycombinator.com/item?id=%s')
if not results
then
return mattata.send_reply(
message,
language['errors']['connection']
)
end
local result_count = message.chat.id == message.from.id
and 8
or 4
local output = '<b>' .. language['hackernews']['1'] .. '</b>'
for i = 1, result_count
do
output = output .. results[i]
end
mattata.send_chat_action(message.chat.id)
return mattata.send_message(
message.chat.id,
output,
'html'
)
end
return hackernews
\ No newline at end of file
diff --git a/plugins/lastfm.lua b/plugins/lastfm.lua
index d533dfb..2490a03 100644
--- a/plugins/lastfm.lua
+++ b/plugins/lastfm.lua
@@ -1,88 +1,89 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local lastfm = {}
local mattata = require('mattata')
local http = require('socket.http')
local url = require('socket.url')
local json = require('dkjson')
local redis = require('libs.redis')
function lastfm:init(configuration)
assert(configuration.keys.lastfm, 'lastfm.lua requires an API key, and you haven\'t got one configured!')
lastfm.commands = mattata.commands(self.info.username):command('lastfm'):command('np'):command('fmset').table
lastfm.help = '/np <username> - Returns what you are or were last listening to. If you specify a username, info will be returned for that username. /fmset <username> - Sets your last.fm username. Use /fmset -del to delete your current username.'
lastfm.url = 'http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&format=json&limit=1&api_key='
end
function lastfm.set_username(user_object, name, language)
redis:hset('user:' .. user_object.id .. ':info', 'lastfm', name)
return string.format(language['lastfm']['1'], user_object.first_name, name)
end
function lastfm.del_username(user_id, language)
if redis:hget('user:' .. user_id .. ':info', 'lastfm') then
redis:hdel('user:' .. user_id .. ':info', 'lastfm')
return language['lastfm']['2']
end
return language['lastfm']['3']
end
function lastfm.get_username(user_id)
return redis:hget('user:' .. user_id .. ':info', 'lastfm')
end
function lastfm:on_message(message, configuration, language)
local input = mattata.input(message.text)
if message.text:match('^[/!#]lastfm') then
return mattata.send_reply(message, lastfm.help)
elseif message.text:match('^[/!#]fmset') then
input = input or message.from.username
if not input then
return mattata.send_reply(message, lastfm.help)
elseif input == '-del' then
local output = lastfm.del_username(message.from.id, language)
return mattata.send_reply(message, output)
end
local output = lastfm.set_username(message.from, input, language)
return mattata.send_reply(message, output)
end
local username, output
if input then
username = input
elseif lastfm.get_username(message.from.id, language) then
username = lastfm.get_username(message.from.id)
else
return mattata.send_reply(message, language['lastfm']['4'])
end
local jstr, res = http.request(lastfm.url .. configuration.keys.lastfm .. '&user=' .. url.escape(username))
if res ~= 200 then
return mattata.send_reply(message, language['errors']['connection'])
end
local jdat = json.decode(jstr)
if jdat.error then
return mattata.send_reply(message, language['lastfm']['4'])
end
if not jdat or not jdat.recenttracks then
return mattata.send_reply(message.chat.id, language['lastfm']['5'])
end
jdat = jdat.recenttracks.track[1] or jdat.recenttracks.track
output = input and mattata.escape_html(input) or string.format('<a href="%s">%s</a>', 'https://last.fm/user/' .. url.escape(username), mattata.escape_html(message.from.first_name))
output = (jdat['@attr'] and jdat['@attr'].nowplaying) and string.format(language['lastfm']['6'], output) or string.format(language['lastfm']['7'], output)
local title = jdat.name or language['lastfm']['8']
local artist = jdat.artist and jdat.artist['#text'] or language['lastfm']['8']
if artist and title ~= jdat.name then
mattata.send_chat_action(message.chat.id)
return mattata.send_message(message.chat.id, output .. artist .. ' - ' .. title)
elseif jdat.image and jdat.image[1]['#text'] == '' then
return mattata.send_message(message.chat.id, output .. artist .. ' - ' .. title)
end
mattata.send_chat_action(message.chat.id, 'upload_photo')
output = output .. string.format('<a href="%s">%s</a>', jdat.url, artist .. ' - ' .. title)
return mattata.send_photo(message.chat.id, jdat.image[4]['#text'], output, 'html')
end
return lastfm
\ No newline at end of file
diff --git a/plugins/lua.lua b/plugins/lua.lua
index 9709291..f7f7354 100644
--- a/plugins/lua.lua
+++ b/plugins/lua.lua
@@ -1,66 +1,67 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local lua = {}
local mattata = require('mattata')
local json = require('dkjson')
function lua:init()
lua.commands = mattata.commands(self.info.username):command('lua').table
lua.error_message = function(error_message)
return 'Error:\n' .. tostring(error_message)
end
end
function lua:on_message(message, configuration, language)
if not mattata.is_global_admin(message.from.id) then
return
end
local input = mattata.input(message.text)
if not input then
local text = language['lua']['1']
return mattata.send_reply(message, text)
end
local output, success = load(
"local mattata = require('mattata')\n\z
local configuration = require('configuration')\n\z
local api = require('telegram-bot-lua.core').configure(configuration.bot_token)\n\z
local tools = require('telegram-bot-lua.tools')\n\z
local https = require('ssl.https')\n\z
local http = require('socket.http')\n\z
local url = require('socket.url')\n\z
local ltn12 = require('ltn12')\n\z
local json = require('dkjson')\n\z
local utf8 = require('lua-utf8')\n\z
local socket = require('socket')\n\z
local redis = require('libs.redis')\n\z
return function (self, message, configuration)\n" .. input .. '\nend')
if output == nil then
output = success
else
success, output = xpcall(
output(),
lua.error_message,
self,
message,
configuration
)
end
if output ~= nil and type(output) == 'table' then
output = json.encode(output, { ['indent'] = true })
elseif output == nil then
return false
end
return mattata.send_message(
message.chat.id,
'<pre>' .. mattata.escape_html(
tostring(output)
) .. '</pre>',
'html'
)
end
return lua
\ No newline at end of file
diff --git a/plugins/plugins.lua b/plugins/plugins.lua
index 7c8c784..12f2d47 100644
--- a/plugins/plugins.lua
+++ b/plugins/plugins.lua
@@ -1,321 +1,321 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local plugins = {}
local mattata = require('mattata')
local json = require('dkjson')
local redis = require('libs.redis')
local configuration = require('configuration')
function plugins:init()
plugins.commands = mattata.commands(self.info.username):command('plugins').table
plugins.help = '/plugins - Toggle the plugins you want to use in your chat with a slick inline keyboard, paginated and neatly formatted.'
end
function plugins.get_toggleable_plugins()
local toggleable = {}
for _, v in pairs(configuration.plugins) do
if not mattata.table_contains(configuration.administrative_plugins, v) then
- if v ~= 'plugins' and v ~= 'control' and v ~= 'bash' and v ~= 'lua' and v ~= 'gwhitelist' and v ~= 'gblacklist' and v ~= 'administration' then
+ if v ~= 'plugins' and v ~= 'control' and v ~= 'bash' and v ~= 'lua' and v ~= 'gallowlist' and v ~= 'gblocklist' and v ~= 'administration' then
v = v:gsub('_', ' ')
table.insert(toggleable, v)
end
end
end
table.sort(toggleable)
return toggleable
end
function plugins.get_keyboard(chat, page, columns, per_page)
page = page or 1
local toggleable = plugins.get_toggleable_plugins()
local page_count = math.floor(#toggleable / per_page)
if page_count < #toggleable / per_page then
page_count = page_count + 1
end
if page < 1 then
page = page_count
elseif page > page_count then
page = 1
end
local start_res = (page * per_page) - (per_page - 1)
local end_res = start_res + (per_page - 1)
if end_res > #toggleable then
end_res = #toggleable
end
local plugin = 0
local output = {}
for _, v in pairs(toggleable) do
v = v:lower()
plugin = plugin + 1
if plugin >= start_res and plugin <= end_res then
local status
if not mattata.is_plugin_disabled(v, chat) then
status = utf8.char(9989)
else
status = utf8.char(10060)
end
table.insert(output, {
['plugin'] = v,
['status'] = status
})
end
end
local keyboard = {
['inline_keyboard'] = {
{}
}
}
local columns_per_page = math.floor(#output / columns)
if columns_per_page < (#output / columns) then
columns_per_page = columns_per_page + 1
end
local rows_per_page = math.floor(#output / columns_per_page)
if rows_per_page < (#output / columns_per_page) then
rows_per_page = rows_per_page + 1
end
local current_row = 1
local count = 0
for n in pairs(output) do
count = count + 1
if count == (rows_per_page * current_row) + 1 then
current_row = current_row + 1
table.insert(
keyboard.inline_keyboard,
{}
)
end
table.insert(
keyboard.inline_keyboard[current_row],
{
['text'] = output[n].plugin:gsub('^%l', string.upper),
['callback_data'] = string.format(
'plugins:%s:%s:%s',
chat,
output[n].plugin,
page
)
}
)
table.insert(
keyboard.inline_keyboard[current_row],
{
['text'] = output[n].status,
['callback_data'] = string.format(
'plugins:%s:%s:%s',
chat,
output[n].plugin,
page
)
}
)
end
table.insert(
keyboard.inline_keyboard,
{
{
['text'] = utf8.char(8592) .. ' Previous',
['callback_data'] = string.format(
'plugins:%s:page:%s',
chat,
page - 1
)
},
{
['text'] = string.format(
'%s/%s',
page,
page_count
),
['callback_data'] = 'plugins:nil'
},
{
['text'] = 'Next ' .. utf8.char(8594),
['callback_data'] = string.format(
'plugins:%s:page:%s',
chat,
page + 1
)
}
}
)
table.insert(
keyboard.inline_keyboard,
{
{
['text'] = 'Disable All',
['callback_data'] = string.format(
'plugins:%s:disable_all:%s',
chat,
page
)
},
{
['text'] = 'Enable All',
['callback_data'] = string.format(
'plugins:%s:enable_all:%s',
chat,
page
)
}
}
)
table.insert(
keyboard.inline_keyboard,
{
{
['text'] = 'Back',
['callback_data'] = 'help:settings'
}
}
)
return keyboard
end
function plugins.on_callback_query(_, callback_query, message, _)
if not callback_query.data:match('^.-:.-:.-$') then
return
end
local chat, callback_type, page = callback_query.data:match('^(.-):(.-):(.-)$')
if (
mattata.get_chat(chat) and mattata.get_chat(chat).result.type ~= 'private'
) and not mattata.is_group_admin(
chat,
callback_query.from.id
) then
return mattata.answer_callback_query(
callback_query.id,
'You must be an administrator to use this!'
)
end
local toggle_status
if callback_type ~= 'page' then
local toggleable = plugins.get_toggleable_plugins()
if callback_type == 'enable_all' then
for _, v in pairs(toggleable) do
redis:srem('disabled_plugins:' .. chat, v)
end
toggle_status = 'All plugins enabled!'
elseif callback_type == 'disable_all' then
for _, v in pairs(toggleable) do
redis:sadd('disabled_plugins:' .. chat, v)
end
toggle_status = 'All plugins disabled!'
elseif callback_type == 'enable_via_message' or callback_type == 'enable' then
redis:srem('disabled_plugins:' .. chat, page)
return mattata.answer_callback_query(
callback_query.id,
page:gsub('^%l', string.upper) .. ' has been enabled!'
)
elseif callback_type == 'dismiss_disabled_message' then
redis:set(
string.format(
'chat:%s:dismiss_disabled_message:%s',
chat,
page
),
true
)
return mattata.answer_callback_query(
callback_query.id,
'You will no longer be notified about this plugin!'
)
else
if mattata.is_plugin_disabled(callback_type, chat) then
redis:srem('disabled_plugins:' .. chat, callback_type)
toggle_status = callback_type:gsub('^%l', string.upper) .. ' enabled!'
else
redis:sadd('disabled_plugins:' .. chat, callback_type)
toggle_status = callback_type:gsub('^%l', string.upper) .. ' disabled!'
end
end
end
local keyboard = plugins.get_keyboard(
chat,
tonumber(page),
2,
10
)
mattata.edit_message_reply_markup(
message.chat.id,
message.message_id,
nil,
json.encode(keyboard)
)
return mattata.answer_callback_query(callback_query.id, toggle_status)
end
function plugins:on_message(message)
if message.chat.type ~= 'private' and not mattata.is_group_admin(
message.chat.id,
message.from.id
) then
return mattata.send_reply(
message,
'You must be an administrator to use this!'
)
elseif message.chat.type == 'private' then
local input = mattata.input(message.text)
if input then
if tonumber(input) == nil and not input:match('^%@') then
input = '@' .. input
end
local resolved = mattata.get_chat(input)
if resolved and mattata.is_group_admin(
resolved.result.id,
message.from.id
) then
message.chat = resolved.result
elseif not resolved then
return mattata.send_reply(
message,
'That\'s not a valid chat!'
)
else
return mattata.send_reply(
message,
'You don\'t appear to be an administrator in that chat!'
)
end
end
end
local keyboard = plugins.get_keyboard(
message.chat.id,
1,
2,
10
)
local success = mattata.send_message(
message.from.id,
string.format(
'Toggle the plugins for <b>%s</b> using the keyboard below:',
message.chat.title and mattata.escape_html(message.chat.title) or mattata.escape_html(message.chat.first_name)
),
'html',
true,
false,
nil,
json.encode(keyboard)
)
if message.chat.type == 'private' then
return
elseif not success then
return mattata.send_reply(
message,
string.format(
'I couldn\'t send you the plugin management menu, you need to send me a [private message](https://t.me/%s?start=plugins%%20' .. message.chat.id .. ') first, then try using /plugins again.',
self.info.username:lower()
),
'markdown',
true
)
end
return mattata.send_reply(
message,
'I have sent you the plugin management menu via private chat.'
)
end
return plugins
\ No newline at end of file
diff --git a/plugins/pokedex.lua b/plugins/pokedex.lua
index c1e81e1..37109f9 100644
--- a/plugins/pokedex.lua
+++ b/plugins/pokedex.lua
@@ -1,84 +1,85 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local pokedex = {}
local mattata = require('mattata')
local http = require('socket.http')
local url = require('socket.url')
local json = require('dkjson')
function pokedex:init()
pokedex.commands = mattata.commands(self.info.username)
:command('pokedex')
:command('dex').table
pokedex.help = '/pokedex <query> - Returns a Pokedex entry from pokeapi.co. Alias: /dex.'
end
function pokedex:on_message(message, configuration, language)
local input = mattata.input(message.text:lower())
if not input
then
return mattata.send_reply(
message,
pokedex.help
)
end
local jstr, res = http.request('http://pokeapi.co/api/v1/pokemon/' .. url.escape(input))
if res ~= 200
then
return mattata.send_reply(
message,
language['errors']['connection']
)
end
local jdat = json.decode(jstr)
local name = jdat.name:gsub('^%l', string.upper)
local id = '#' .. jdat.national_id
local description_url = 'http://pokeapi.co' .. jdat.descriptions[math.random(#jdat.descriptions)].resource_uri
local description_jstr, description_res = http.request(description_url)
if description_res ~= 200
then
return mattata.send_reply(
message,
language['errors']['connection']
)
end
mattata.send_chat_action(
message.chat.id,
'upload_photo'
)
local description_jdat = json.decode(description_jstr)
local description = description_jdat.description
:gsub('POKMON', 'Pokémon')
:gsub('Pokmon', 'Pokémon')
:gsub('Pokemon', 'Pokémon')
:gsub('POKéMON', 'Pokémon')
local poke_type
for _, v in ipairs(jdat.types)
do
local type_name = v.name:gsub('^%l', string.upper)
if not poke_type
then
poke_type = type_name
else
poke_type = poke_type .. ' / ' .. type_name
end
end
poke_type = poke_type .. ' type'
return mattata.send_photo(
message.chat.id,
'https://img.pokemondb.net/artwork/' .. name:gsub('^%u', string.lower) .. '.jpg',
string.format(
language['pokedex']['1'],
name,
id,
poke_type,
description
)
)
end
return pokedex
\ No newline at end of file
diff --git a/plugins/pun.lua b/plugins/pun.lua
index 7485765..f6ae14a 100644
--- a/plugins/pun.lua
+++ b/plugins/pun.lua
@@ -1,148 +1,149 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local pun = {}
local mattata = require('mattata')
function pun:init()
pun.commands = mattata.commands(self.info.username):command('pun').table
pun.help = '/pun - Generates a random pun.'
end
local puns = {
'The person who invented the door-knock won the No-bell prize.',
'I couldn\'t work out how to fasten my seatbelt. Then it clicked.',
'Never trust atoms; they make up everything.',
'Singing in the shower is all fun and games until you get shampoo in your mouth - Then it becomes a soap opera.',
'I can\'t believe I got fired from the calendar factory. All I did was take a day off.',
'To the guy who invented zero: Thanks for nothing!',
'Enough with the cripple jokes! I just can\'t stand them.',
'I\'ve accidentally swallowed some Scrabble tiles. My next crap could spell disaster.',
'How does Moses make his tea? Hebrews it.',
'Did you hear about the guy who got hit in the head with a can of soda? He was lucky it was a soft drink.',
'When William joined the army he disliked the phrase \'fire at will\'.',
'There was a sign on the lawn at a rehab center that said \'Keep off the Grass\'.',
'I wondered why the baseball was getting bigger. Then it hit me.',
'I can hear music coming out of my printer. I think the paper\'s jamming again.',
'I have a few jokes about unemployed people, but none of them work',
'Want to hear a construction joke? I\'m working on it',
'I always take a second pair of pants when I go golfing, in case I get a hole in one.',
'I couldn\'t remember how to catch a boomerang, but then it came back to me.',
'I\'ve decided that my Wi-Fi router will be my valentine this year. I don\'t know why, we just have this connection.',
'A prisoner\'s favourite punctuation mark is the period. It marks the end of his sentence.',
'I used to go fishing with Skrillex, but he kept dropping the bass.',
'Two antennae met on a roof and got married. The wedding was okay, but the reception was incredible.',
'A book just fell on my head. I\'ve only got my shelf to blame.',
'I dropped my steak on the floor. Now it\'s ground beef.',
'I used to have a fear of hurdles, but I got over it.',
'The outcome of war does not prove who is right, but only who is left.',
'Darth Vader tries not to burn his food, but it always comes out a little on the dark side.',
'The store keeps calling me to buy more furniture, but all I wanted was a one night stand.',
'This girl said she recognized me from the vegetarian club, but I\'d never met herbivore.',
'Police arrested two kids yesterday, one was drinking battery acid, the other was eating fireworks. They charged one and let the other one off...',
'No more Harry Potter jokes guys. I\'m Sirius.',
'It was hard getting over my addiction to hokey pokey, but I\'ve turned myself around.',
'It takes a lot of balls to golf the way I do.',
'Why did everyone want to hang out with the mushroom? Because he was a fungi.',
'How much does a hipster weigh? An instagram.',
'I used to be addicted to soap, but I\'m clean now.',
'When life gives you melons, you\'re probably dyslexic.',
'What\'s with all the blind jokes? I just don\'t see the point.',
'If Apple made a car, would it have Windows?',
'Need an ark? I Noah guy.',
'The scarecrow won an award because he was outstanding in his field.',
'What\'s the difference between a man in a tux on a bicycle, and a man in a sweatsuit on a trycicle? A tire.',
'What do you do with a sick chemist? If you can\'t helium, and you can\'t curium, you\'ll just have to barium.',
'I\'m reading a book about anti-gravity. It\'s impossible to put down.',
'Trying to write with a broken pencil is pointless.',
'When TVs go on vacation, they travel to remote islands.',
'I was going to tell a midget joke, but it\'s too short.',
'Jokes about German sausages are the wurst.',
'How do you organize a space party? You planet.',
'Sleeping comes so naturally to me, I could do it with my eyes closed.',
'I\'m glad I learned sign language; it\'s pretty handy.',
'Atheism is a non-prophet organization.',
'Velcro: What a rip-off!',
'If they made a Minecraft movie, it would be a blockbuster.',
'I don\'t trust people with graph paper. They\'re always plotting something',
'I had a friend who was addicted to brake fluid. He says he can stop anytime.',
'The form said I had Type A blood, but it was a Type O.',
'I went to to the shop to buy eight Sprites - I came home and realised I\'d picked 7-Up.',
'There was an explosion at a pie factory. 3.14 people died.',
'A man drove his car into a tree and found out how a Mercedes bends.',
'The experienced carpenter really nailed it, but the new guy screwed everything up.',
'I didn\'t like my beard at first, but then it grew on me.',
'Smaller babies may be delivered by stork, but the heavier ones need a crane.',
'What\'s the definition of a will? It\'s a dead giveaway.',
'I was going to look for my missing watch, but I could never find the time.',
'I hate elevators, and I often take steps to avoid them.',
'Did you hear about the guy whose whole left side was cut off? He\'s all right now.',
'It\'s not that the man did not know how to juggle, he just didn\'t have the balls to do it.',
'I used to be a loan shark, but I lost interest',
'I don\'t trust these stairs; they\'re always up to something.',
'My friend\'s bakery burned down last night. Now his business is toast.',
'Don\'t trust people that perform acupuncture; they\'re back stabbers.',
'The man who survived mustard gas and pepper spray is now a seasoned veteran.',
'Police were called to a daycare where a three-year-old was resisting a rest.',
'When Peter Pan punches, they Neverland',
'The shoemaker did not deny his apprentice anything he needed. He gave him his awl.',
'I did a theatrical performance about puns. It was a play on words.',
'Show me a piano falling down a mineshaft and I\'ll show you A-flat minor.',
'Have you ever tried to eat a clock? It\'s very time consuming.',
'There was once a cross-eyed teacher who couldn\'t control his pupils.',
'A new type of broom came out and it is sweeping the nation.',
'I relish the fact that you\'ve mustard the strength to ketchup to me.',
'I knew a woman who owned a taser. Man, was she stunning!',
'What did the grape say when it got stepped on? Nothing - but it let out a little whine.',
'It was an emotional wedding. Even the cake was in tiers.',
'When a clock is hungry it goes back four seconds.',
'The dead batteries were given out free of charge.',
'Why are there no knock-knock jokes about America? Because freedom rings.',
'When the cannibal showed up late to dinner, they gave him the cold shoulder.',
'I should have been sad when my flashlight died, but I was delighted.',
'Why don\'t tennis players ever get married? Love means nothing to them.',
'Pterodactyls can\'t be heard going to the bathroom because the P is silent.',
'Mermaids make calls on their shell phones.',
'What do you call an aardvark with three feet? A yaardvark.',
'Captain Kirk has three ears: A right ear, a left ear, and a final front ear.',
'How do celebrities stay cool? They have a lot of fans.',
'Without geometry, life is pointless.',
'Did you hear about the cow who tried to jump over a barbed-wire fence? It ended in udder destruction.',
'The truth may ring like a bell, but it is seldom ever tolled.',
'I used to work for the IRS, but my job was too taxing.',
'I used to be a programmer, but then I lost my drive.',
'Pediatricians are doctors with little patients.',
'I finally fired my masseuse today. She always rubbed me the wrong way.',
'I stayed up all night wondering where the sun went. Then it dawned on me.',
'What\'s the difference between a man and his dog? The man wears a suit; the dog just pants.',
'A psychic midget who escapes from prison is a small medium at large.',
'I\'ve been to the dentist several times, so I know the drill.',
'The roundest knight at King Arthur\'s round table was Sir Cumference. He acquired his size from too much pi.',
'She was only a whiskey maker, but he loved her still.',
'Male deer have buck teeth.',
'Whiteboards are remarkable.',
'Visitors in Cuba are always Havana good time.',
'Why does electricity shock people? It doesn\'t know how to conduct itself.',
'Lancelot had a scary dream about his horse. It was a knight mare.',
'A tribe of cannibals captured a missionary and ate him. Afterwards, they all had violent food poisoning. This just goes to show that you can\'t keep a good man down.',
'Heaven for gamblers is a paradise.',
'Old wheels aren\'t thrown away, they\'re just retired.',
'Horses are very stable animals.',
'Bankers don\'t crash, they just lose their balance.',
'The career of a skier can go downhill very fast.',
'In democracy, it\'s your vote that counts. In feudalism, it\'s your count that votes.',
'A sea lion is nothing but an ionized seal.',
'The vegetables from my garden aren\'t that great. I guess you could say they\'re mediokra.'
}
function pun:on_message(message)
return mattata.send_message(
message.chat.id,
puns[math.random(#puns)]
)
end
return pun
\ No newline at end of file
diff --git a/plugins/reboot.lua b/plugins/reboot.lua
index 6b75b19..37bac1b 100644
--- a/plugins/reboot.lua
+++ b/plugins/reboot.lua
@@ -1,35 +1,37 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local reboot = {}
local mattata = require('mattata')
local redis = require('libs.redis')
function reboot:init()
reboot.commands = mattata.commands(self.info.username):command('reboot'):command('shutdown'):command('reload').table
end
function reboot:on_message(message)
if not mattata.is_global_admin(message.from.id) or message.date < (os.time() - 2) then
return false
end
- if message.command == 'reload' then
+ if message.text:match('^[/!#]reload') then
+ local success = mattata.send_message(message.chat.id, 'Reloading...')
for pkg, _ in pairs(package.loaded) do -- Disable all of mattata's plugins and languages.
if pkg:match('^plugins%.') or pkg:match('^languages%.') then
package.loaded[pkg] = nil
end
end
package.loaded['libs.utils'] = nil
package.loaded['configuration'] = nil
mattata.init(self)
+ return mattata.edit_message_text(message.chat.id, success.result.message_id, 'Successfully reloaded')
end
package.loaded['mattata'] = require('mattata')
mattata.is_running = false
local success = mattata.send_message(message.chat.id, 'Shutting down...')
redis:set('mattata:shutdown', tostring(message.chat.id) .. ':' .. tostring(success.result.message_id))
return success
end
return reboot
\ No newline at end of file
diff --git a/plugins/reddit.lua b/plugins/reddit.lua
index f73a9eb..ed49f5c 100644
--- a/plugins/reddit.lua
+++ b/plugins/reddit.lua
@@ -1,75 +1,76 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local reddit = {}
local mattata = require('mattata')
local https = require('ssl.https')
local url = require('socket.url')
local json = require('dkjson')
function reddit:init()
reddit.commands = mattata.commands(self.info.username, { '^/r/' }):command('r/'):command('reddit').table
reddit.help = '/r/subreddit - Returns the latest posts from the given subreddit.'
end
function reddit.format_results(posts)
local output = {}
if #posts == 0 then
return false
end
for k, v in pairs(posts) do
local post = v.data
local title = post.title
if title:len() > 250 then
title = mattata.trim(title:sub(1, 250)) .. '...'
end
local short_url = 'redd.it/' .. post.id
local result = '<a href="' .. mattata.escape_html(short_url) .. '">' .. mattata.escape_html(title) .. '</a>'
if post.domain and not post.is_self then
post.url = mattata.escape_html(post.url)
post.domain = mattata.escape_html(post.domain)
result = mattata.symbols.bullet .. ' <code>[</code><a href="' .. post.url .. '">' .. post.domain .. '</a><code>]</code> ' .. result
table.insert(output, result)
end
end
return table.concat(output, '\n')
end
function reddit:on_message(message, configuration, language)
local limit = message.chat.type ~= 'private' and 4 or 8
local input = mattata.input(message.text)
local subreddit = message.text:match('^/r/([%w][%w_]+)%s?')
if input and not subreddit then
subreddit = input
elseif not input and not subreddit then
return mattata.send_reply(message, reddit.help)
end
if not subreddit or subreddit:len() > 21 or subreddit:len() < 2 then
return mattata.send_reply(message, 'That\'s not a valid subreddit!')
end
local output = '<b>/r/' .. subreddit .. '</b>\n'
local request_url = 'https://www.reddit.com/.json?limit=' .. limit
if subreddit ~= 'all' then
request_url = 'https://www.reddit.com/r/' .. subreddit .. '/.json?limit=' .. limit
end
local old_timeout = https.TIMEOUT
https.TIMEOUT = 1
local jstr, res = https.request(request_url)
https.TIMEOUT = old_timeout
if res == 404 or res == 'wantread' then
return mattata.send_reply(message, language['errors']['results'])
elseif res ~= 200 then
return mattata.send_reply(message, language['errors']['connection'])
end
local jdat = json.decode(jstr)
if not jdat or not jdat.data or #jdat.data.children < 1 then
return mattata.send_reply(message, language['errors']['results'])
end
output = output .. reddit.format_results(jdat.data.children)
return mattata.send_message(message.chat.id, output, 'html', true)
end
return reddit
\ No newline at end of file
diff --git a/plugins/remind.lua b/plugins/remind.lua
index 601a152..e1824a7 100644
--- a/plugins/remind.lua
+++ b/plugins/remind.lua
@@ -1,196 +1,197 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local remind = {}
local mattata = require('mattata')
local json = require('dkjson')
local redis = require('libs.redis')
function remind:init()
remind.commands = mattata.commands(self.info.username)
:command('remind')
:command('reminders').table
remind.help = '/remind <duration> <message> - Repeats a message after a duration of time, in the format 2d3h. The maximum number of reminders at one time is 4 per chat, and each reminder must be between 1 hour and 182 days in duration. Reminders cannot be any more than 256 characters in length. Use /reminders to view your current reminders. An example use of this command would be: /remind 21d3h test, which would remind you in 21 days and 3 hours.'
end
function remind.get_reminders(message)
local reminders = {}
if redis:get('reminders') then
reminders = json.decode(
redis:get('reminders')
)
end
local this_chat = {}
local count = 0
for k, v in pairs(reminders) do
if v.chat and v.chat.id == message.chat.id then
local real_expiry = tonumber(v.expires) / 3600
table.insert(
this_chat,
string.format(
utf8.char(8226) .. ' %s <code>[Added by %s, expires in approx. %s hour%s]</code>',
mattata.escape_html(v.reminder),
mattata.escape_html(v.name),
mattata.round(
(
tonumber(v.expires) - os.time()
) / 3600,
2
),
mattata.round(
(
tonumber(v.expires) - os.time()
) / 3600,
2
) == 1 and '' or 's'
)
)
count = count + 1
end
end
if count == 0 then
return mattata.send_reply(
message,
'You don\'t have any reminders set up in this chat!'
)
end
return mattata.send_reply(
message,
string.format(
'You currently have %s reminder%s set up for %s:\n%s',
count,
count == 1 and '' or 's',
mattata.escape_html(message.chat.title),
table.concat(
this_chat,
'\n'
)
),
'html'
)
end
function remind:on_message(message)
if message.text:match('^[%/%!%$%^%?%&%%]reminders') then
return remind.get_reminders(message)
end
local input = mattata.input(message.text)
if not input or not input:match('^.- .-$') then
return mattata.send_reply(
message,
remind.help
)
end
local duration, reminder = input:match('^(.-) (.-)$')
-- Convert each unit of time into seconds.
local weeks = 0
if duration:match('%d[Ww]') then
weeks = tonumber(
duration:match('(%d*)[Ww]')
) * 604800
end
local days = 0
if duration:match('%d[Dd]') then
days = tonumber(
duration:match('(%d*)[Dd]')
) * 86400
end
local hours = 0
if duration:match('%d[Hh]') then
hours = tonumber(
duration:match('(%d*)[Hh]')
) * 3600
end
duration = days + hours
if duration <= 0 then
return mattata.send_reply(
message,
'The duration you specified isn\'t in a valid format. The duration of your reminder must be between 1 hour and 6 months, and in the format 5m1w12d3h, which would remind you in 5 months, 1 week, 12 days and 3 hours.'
)
elseif duration > 15724800 or duration < 1 then
return mattata.send_reply(
message,
'The duration of your reminder must be between 1 hour and 182 days.'
)
end
if utf8.len(reminder) > 256 then
return mattata.send_reply(
message,
'Your reminder must not be any longer than 256 characters.'
)
end
local reminders = {}
if redis:get('reminders') then
reminders = json.decode(
redis:get('reminders')
)
end
local count = 0
for k, v in pairs(reminders) do
if v.chat and v.chat.id == message.chat.id then
count = count + 1
end
end
if count >= 4 then
return mattata.send_reply(
message,
'You already have 4 reminders set up in this chat. Please wait for one to expire before you add any more!'
)
end
table.insert(
reminders,
{
['reminder'] = reminder,
['expires'] = os.time() + duration,
['chat'] = {
['id'] = message.chat.id,
['title'] = message.chat.title
},
['name'] = message.from.name or message.chat.title
}
)
redis:set(
'reminders',
json.encode(reminders)
)
duration = duration / 3600 -- Convert back to hours.
return mattata.send_reply(
message,
string.format(
'I will remind you in %s hour%s!',
mattata.round(duration),
tonumber(duration) == 1 and '' or 's'
)
)
end
function remind:cron()
local current_time = os.time()
local reminders = redis:get('reminders')
if not reminders then
return
end
reminders = json.decode(reminders)
for k, v in pairs(reminders) do
if current_time > v.expires then
mattata.send_message(
v.chat.id,
'Reminder: ' .. v.reminder
)
table.remove(
reminders,
k
)
end
end
redis:set(
'reminders',
json.encode(reminders)
)
return
end
return remind
\ No newline at end of file
diff --git a/plugins/sed.lua b/plugins/sed.lua
index 047b11e..6fa973e 100644
--- a/plugins/sed.lua
+++ b/plugins/sed.lua
@@ -1,120 +1,161 @@
--[[
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local sed = {}
local mattata = require('mattata')
-local json = require('dkjson')
+local re = require('re')
+local regex = require('rex_pcre')
function sed:init()
sed.commands = { '^%/?[sS]%/.-%/.-%/?$' }
sed.help = '/s/pattern/substitution - Replaces all occurences, of text matching a given Lua pattern, with the given substitution.'
+ sed.compiled = re.compile[[
+invocation <- 's/' {~ pcre ~} '/' {~ replace ~} ('/' modifiers)? !.
+pcre <- ( [^\/] / slash / '\' )*
+replace <- ( [^\/%$] / percent / slash / capture / '\' / '$' )*
+
+modifiers <- { flags? } {~ matches? ~} {~ probability? ~}
+
+flags <- ('i' / 'm' / 's' / 'x' / 'U' / 'X')+
+matches <- ('#' {[0-9]+}) -> '%1'
+probability <- ('%' {[0-9]+}) -> '%1'
+
+slash <- ('\' '/') -> '/'
+percent <- '%' -> '%%%%'
+capture <- ('$' {[0-9]+}) -> '%%%1'
+]]
end
function sed:on_callback_query(callback_query, message, configuration, language)
if not message.reply then
return mattata.delete_message(message.chat.id, message.message_id)
elseif mattata.is_global_admin(callback_query.from.id) then -- we'll pull a sneaky on them
callback_query.from = message.reply.from
elseif message.reply.from.id ~= callback_query.from.id then
return mattata.answer_callback_query(callback_query.id, 'That\'s not your place to say!')
end
local output = string.format(
'<b>%s:</b>\n%s',
message.text:match('^(.-):'),
message.text:match(':\n(.-)$')
)
if callback_query.data:match('^no$') then
output = string.format(
language['sed']['1'],
output,
mattata.escape_html(callback_query.from.first_name)
)
elseif callback_query.data:match('^yes$') then
output = string.format(
language['sed']['2'],
output,
mattata.escape_html(callback_query.from.first_name)
)
elseif callback_query.data:match('^maybe$') then
output = string.format(
language['sed']['3'],
output,
mattata.escape_html(callback_query.from.first_name)
)
end
return mattata.edit_message_text(
message.chat.id,
message.message_id,
output,
'html'
)
end
-function sed:on_message(message, configuration, language)
- message.text = message.text:gsub('\\%/', '%%fwd_slash%%')
- local matches, substitution = message.text:match('^/?[sS]/(.-)/(.-)/?$')
- if not substitution
- or not message.reply
- then
- return
- elseif message.reply.from.id == self.info.id
- then
+function sed:on_message(message, _, language)
+ if not message.reply then
+ return false
+ elseif message.reply.from.id == self.info.id then
return mattata.send_reply(
message,
language['sed']['4'],
'html'
)
end
- matches = matches:gsub('%%fwd%_slash%%', '/')
- substitution = substitution:gsub('\\n', '\n'):gsub('\\/', '/'):gsub('\\(%d)', '%%%1')
- local success, output = pcall(
- function()
- return message.reply.text:gsub(matches, substitution)
+ local input = message.reply.text
+ local text = message.text:match('^/?(.*)$')
+ if not text then
+ return false
+ end
+ local pattern, replace, flags, matches, probability = sed.compiled:match(text)
+ if not pattern then
+ return false
+ end
+ matches = matches and tonumber(matches) or matches
+ probability = probability and tonumber(probability) or probability
+ if probability then
+ if not matches then
+ matches = function()
+ return math.random() * 100 < probability
+ end
+ else
+ local remaining = matches
+ matches = function()
+ local temp
+ if remaining > 0 then
+ temp = nil
+ else
+ temp = 0
+ end
+ remaining = remaining - 1
+ return math.random() * 100 < probability, temp
+ end
end
- )
- if not success then
+ end
+ local success, result, matched = pcall(function ()
+ return regex.gsub(input, pattern, replace, matches, flags)
+ end)
+ if success == false then
return mattata.send_reply(
message,
string.format(
- language['sed']['5'],
- mattata.escape_html(matches)
+ '%s is invalid PCRE regex syntax!',
+ mattata.escape_html(text)
),
'html'
)
+ elseif matched == 0 then
+ return
end
- output = mattata.trim(output)
- if not output or output == '' then
+ result = mattata.trim(result)
+ if not result or result == '' then
return false
end
return mattata.send_message(
message.chat.id,
string.format(
language['sed']['6'],
mattata.escape_html(message.reply.from.first_name),
- mattata.escape_html(output)
+ mattata.escape_html(result)
),
'html',
true,
false,
message.reply.message_id,
mattata.inline_keyboard():row(
mattata.row()
:callback_data_button(
language['sed']['7'],
'sed:yes'
)
:callback_data_button(
language['sed']['8'],
'sed:no'
)
:callback_data_button(
language['sed']['9'],
'sed:maybe'
)
)
)
end
return sed
\ No newline at end of file
diff --git a/plugins/slap.lua b/plugins/slap.lua
index d822bf8..05b8959 100644
--- a/plugins/slap.lua
+++ b/plugins/slap.lua
@@ -1,51 +1,52 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local slap = {}
local mattata = require('mattata')
local redis = require('libs.redis')
function slap:init()
slap.commands = mattata.commands(self.info.username):command('slap').table
slap.help = '/slap [target] - Slaps someone, or something. Can be used in reply to someone.'
end
function slap:on_message(message, configuration)
local input = mattata.input(message)
local victor = ''
local victim = ''
local slaps = configuration.slaps
if message.chat.type ~= 'private' then
local more = redis:smembers('slaps:' .. message.chat.id)
if #more > 0 then
for _, v in pairs(more) do
table.insert(slaps, v)
end
end
end
if not input then
if message.reply then
victor = message.from.first_name:gsub('%%', '%%%%')
victim = message.reply.from.first_name:gsub('%%', '%%%%')
else
victor = self.info.first_name:gsub('%%', '%%%%')
victim = message.from.first_name:gsub('%%', '%%%%')
end
else
victor = message.from.first_name:gsub('%%', '%%%%')
victim = input:gsub('%%', '%%%%')
local success = mattata.get_user(input)
if success and success.result and success.result.type == 'private' then
victim = success.result.first_name
victim = victim:gsub('%%', '%%%%')
end
end
local output = slaps[math.random(#slaps)]
output = output:gsub('{THEM}', victim):gsub('{ME}', victor)
return mattata.send_message(message.chat.id, output)
end
return slap
\ No newline at end of file
diff --git a/plugins/spamwatch.lua b/plugins/spamwatch.lua
index 0b23b8d..221cc08 100644
--- a/plugins/spamwatch.lua
+++ b/plugins/spamwatch.lua
@@ -1,51 +1,51 @@
--[[
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local spamwatch = {}
local mattata = require('mattata')
function spamwatch:init()
spamwatch.commands = mattata.commands(self.info.username):command('spamwatch'):command('sw').table
spamwatch.help = '/spamwatch [user] - Returns SpamWatch information for the given user, either specified or replied-to. Alias: /sw.'
end
function spamwatch:on_new_message(message, configuration, language)
if message.chat.type == 'private' then
return false
elseif not mattata.get_setting(message.chat.id, 'ban spamwatch users') then
return false
- elseif self.is_spamwatch_blacklisted then
+ elseif self.is_spamwatch_blocklisted then
mattata.ban_chat_member(message.chat.id, message.from.id)
end
return false
end
function spamwatch:on_message(message, configuration, language)
local input = message.reply and message.reply.from.id or mattata.input(message.text)
if not input then
return mattata.send_reply(message, spamwatch.help)
end
local user = mattata.get_user(input)
if not user then
if not input:match('^%d+$') then
return mattata.send_reply(message, 'I couldn\'t get any information about that user. To teach me who they are, forward a message from them. This will only work if they don\'t have forward privacy enabled!')
end
user = { ['result'] = { ['id'] = input:match('^(%d+)$') } }
end
user = user.result.id
- local res, jdat = mattata.is_spamwatch_blacklisted(user)
+ local res, jdat = mattata.is_spamwatch_blocklisted(user)
if not res then
return mattata.send_reply(message, 'That user isn\'t in the SpamWatch database!')
end
local output = {
'<b>ID:</b> ' .. jdat.id,
'<b>Reason:</b> ' .. mattata.escape_html(jdat.reason),
'<b>Date banned:</b> ' .. os.date('%x', jdat.date)
}
output = table.concat(output, '\n')
return mattata.send_reply(message, output, 'html')
end
return spamwatch
\ No newline at end of file
diff --git a/plugins/wikipedia.lua b/plugins/wikipedia.lua
index a6739fe..44a8779 100644
--- a/plugins/wikipedia.lua
+++ b/plugins/wikipedia.lua
@@ -1,107 +1,108 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See ./LICENSE for details.
]]
local wikipedia = {}
local mattata = require('mattata')
local https = require('ssl.https')
local url = require('socket.url')
local json = require('dkjson')
function wikipedia:init()
wikipedia.commands = mattata.commands(self.info.username)
:command('wikipedia')
:command('wiki')
:command('w').table
wikipedia.help = '/wikipedia <query> - Searches Wikipedia for the given search query and returns the most relevant article. Aliases: /wiki, /w.'
end
function wikipedia:on_message(message, configuration, language)
local input = mattata.input(message.text)
if not input
then
return mattata.send_reply(
message,
wikipedia.help
)
end
local jstr, res = https.request('https://en.wikipedia.org/w/api.php?action=query&list=search&format=json&srsearch=' .. url.escape(input))
if res ~= 200
then
return mattata.send_reply(
message,
language['errors']['connection']
)
end
local jdat = json.decode(jstr)
if jdat.query.searchinfo.totalhits == 0
then
return mattata.send_reply(
message,
language['errors']['results']
)
end
local title
for _, v in ipairs(jdat.query.search)
do
if not v.snippet:match('may refer to:')
then
title = v.title
break
end
end
if not title
then
return mattata.send_reply(
message,
language['errors']['results']
)
end
local res_jstr, res_code = https.request('https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&exchars=4000&explaintext=&titles=' .. url.escape(title))
if res_code ~= 200
then
return mattata.send_reply(
message,
language['errors']['connection']
)
end
local _, text = next(json.decode(res_jstr).query.pages)
if not text
then
return mattata.send_reply(
message,
language['errors']['results']
)
end
text = text.extract
local l = text:find('\n')
if l
then
text = text:sub(1, l - 1)
end
local final_url = 'https://en.wikipedia.org/wiki/' .. url.escape(title)
title = mattata.escape_html(title)
local short_title = title:gsub('%(.+%)', '')
local combined_text, count = text:gsub('^' .. short_title, '<b>' .. short_title .. '</b>')
local output
if count == 1
then
output = combined_text
else
output = '<b>' .. title .. '</b>\n' .. text
end
return mattata.send_message(
message.chat.id,
string.format(
'%s\n<a href="%s">%s</a>',
output,
mattata.escape_html(final_url),
language['wikipedia']['1']
),
'html'
)
end
return wikipedia
\ No newline at end of file
diff --git a/plugins/xkcd.lua b/plugins/xkcd.lua
index 6a69f05..d70b7f6 100644
--- a/plugins/xkcd.lua
+++ b/plugins/xkcd.lua
@@ -1,94 +1,95 @@
--[[
- Based on a plugin by topkecleon.
+ Based on a plugin by topkecleon. Licensed under GNU AGPLv3
+ https://github.com/topkecleon/otouto/blob/master/LICENSE.
Copyright 2020 Matthew Hesketh <matthew@matthewhesketh.com>
This code is licensed under the MIT. See LICENSE for details.
]]
local xkcd = {}
local mattata = require('mattata')
local https = require('ssl.https')
local url = require('socket.url')
local json = require('dkjson')
function xkcd:init()
xkcd.commands = mattata.commands(
self.info.username
):command('xkcd').table
xkcd.help = [[/xkcd [query] - Returns the latest xkcd strip and its alt text. If a number is given, returns that number strip. If 'r' is passed in place of a number, returns a random strip. Any other text passed as the command argument will search Google for a relevant strip and, if applicable, return it.]]
local jstr = https.request('https://xkcd.com/info.0.json')
if jstr
then
local jdat = json.decode(jstr)
if jdat
then
xkcd.latest = jdat.num
end
end
xkcd.latest = xkcd.latest
end
function xkcd:on_message(message, configuration, language)
local input = mattata.input(message.text)
if not input
then
input = xkcd.latest
end
if input == 'r'
then
input = math.random(xkcd.latest)
elseif tonumber(input) ~= nil
then
input = tonumber(input)
else
input = 'inurl:xkcd.com ' .. input
local search, res = https.request('https://relevantxkcd.appspot.com/process?action=xkcd&query=' .. url.escape(input))
if res ~= 200
then
return mattata.send_reply(
message,
language['errors']['results']
)
end
input = tonumber(
search:match('^.-\n.-\n(%d*) %/')
)
end
local url = string.format(
'https://xkcd.com/%s/info.0.json',
tostring(input)
)
local jstr, res = https.request(url)
if res == 404
then
return mattata.send_message(
message.chat.id,
'[<a href="https://xkcd.com/404">404</a>] <b>404 Not Found</b>, 1/4/2008',
'html'
)
elseif res ~= 200
then
return mattata.send_reply(
message,
language['errors']['connection']
)
end
local jdat = json.decode(jstr)
return mattata.send_message(
message.chat.id,
string.format(
'[<a href="%s">%s</a>] <b>%s</b>, %s/%s/%s\n<i>%s</i>',
jdat.img,
jdat.num,
mattata.escape_html(jdat.safe_title),
jdat.day,
jdat.month,
jdat.year,
mattata.escape_html(jdat.alt)
),
'html',
false
)
end
return xkcd
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Sat, May 16, 1:18 PM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
63445
Default Alt Text
(675 KB)

Event Timeline