old/unused plugins
This commit is contained in:
parent
f228fea149
commit
77fadb1806
52
plugins/pluginsold/btc.lua
Normal file
52
plugins/pluginsold/btc.lua
Normal file
@ -0,0 +1,52 @@
|
||||
-- See https://bitcoinaverage.com/api
|
||||
local function getBTCX(amount,currency)
|
||||
local base_url = 'https://api.bitcoinaverage.com/ticker/global/'
|
||||
-- Do request on bitcoinaverage, the final / is critical!
|
||||
local res,code = https.request(base_url..currency.."/")
|
||||
|
||||
if code ~= 200 then return nil end
|
||||
local data = json:decode(res)
|
||||
|
||||
-- Easy, it's right there
|
||||
text = "BTC/"..currency..'\n'..'Buy: '..data.ask..'\n'..'Sell: '..data.bid
|
||||
|
||||
-- If we have a number as second parameter, calculate the bitcoin amount
|
||||
if amount~=nil then
|
||||
btc = tonumber(amount) / tonumber(data.ask)
|
||||
text = text.."\n "..currency .." "..amount.." = BTC "..btc
|
||||
end
|
||||
return text
|
||||
end
|
||||
|
||||
local function run(msg, matches)
|
||||
local cur = 'EUR'
|
||||
local amt = nil
|
||||
|
||||
-- Get the global match out of the way
|
||||
if matches[1] == "!btc" then
|
||||
return getBTCX(amt,cur)
|
||||
end
|
||||
|
||||
if matches[2] ~= nil then
|
||||
-- There is a second match
|
||||
amt = matches[2]
|
||||
cur = string.upper(matches[1])
|
||||
else
|
||||
-- Just a EUR or USD param
|
||||
cur = string.upper(matches[1])
|
||||
end
|
||||
return getBTCX(amt,cur)
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Bitcoin global average market value (in EUR or USD)",
|
||||
usage = "!btc [EUR|USD] [amount]",
|
||||
patterns = {
|
||||
"^!btc$",
|
||||
"^!btc ([Ee][Uu][Rr])$",
|
||||
"^!btc ([Uu][Ss][Dd])$",
|
||||
"^!btc (EUR) (%d+[%d%.]*)$",
|
||||
"^!btc (USD) (%d+[%d%.]*)$"
|
||||
},
|
||||
run = run
|
||||
}
|
105
plugins/pluginsold/bugzilla.lua
Normal file
105
plugins/pluginsold/bugzilla.lua
Normal file
@ -0,0 +1,105 @@
|
||||
do
|
||||
|
||||
local BASE_URL = "https://bugzilla.mozilla.org/rest/"
|
||||
|
||||
local function bugzilla_login()
|
||||
local url = BASE_URL.."login?login=" .. _config.bugzilla.username .. "&password=" .. _config.bugzilla.password
|
||||
print("accessing " .. url)
|
||||
local res,code = https.request( url )
|
||||
local data = json:decode(res)
|
||||
return data
|
||||
end
|
||||
|
||||
local function bugzilla_check(id)
|
||||
-- data = bugzilla_login()
|
||||
local url = BASE_URL.."bug/" .. id .. "?api_key=" .. _config.bugzilla.apikey
|
||||
-- print(url)
|
||||
local res,code = https.request( url )
|
||||
local data = json:decode(res)
|
||||
return data
|
||||
end
|
||||
|
||||
local function bugzilla_listopened(email)
|
||||
local url = BASE_URL.."bug?include_fields=id,summary,status,whiteboard,resolution&email1=" .. email .. "&email2=" .. email .. "&emailassigned_to2=1&emailreporter1=1&emailtype1=substring&emailtype2=substring&f1=bug_status&f2=bug_status&n1=1&n2=1&o1=equals&o2=equals&resolution=---&v1=closed&v2=resolved&api_key=" .. _config.bugzilla.apikey
|
||||
local res,code = https.request( url )
|
||||
print(res)
|
||||
local data = json:decode(res)
|
||||
return data
|
||||
end
|
||||
|
||||
local function run(msg, matches)
|
||||
|
||||
local response = ""
|
||||
|
||||
if matches[1] == "status" then
|
||||
local data = bugzilla_check(matches[2])
|
||||
vardump(data)
|
||||
if data.error == true then
|
||||
return "Sorry, API failed with message: " .. data.message
|
||||
else
|
||||
response = "Bug #"..matches[1]..":\nReporter: "..data.bugs[1].creator
|
||||
response = response .. "\n Last update: "..data.bugs[1].last_change_time
|
||||
response = response .. "\n Status: "..data.bugs[1].status.." "..data.bugs[1].resolution
|
||||
response = response .. "\n Whiteboard: "..data.bugs[1].whiteboard
|
||||
response = response .. "\n Access: https://bugzilla.mozilla.org/show_bug.cgi?id=" .. matches[1]
|
||||
print(response)
|
||||
end
|
||||
elseif matches[1] == "list" then
|
||||
local data = bugzilla_listopened(matches[2])
|
||||
|
||||
vardump(data)
|
||||
if data.error == true then
|
||||
return "Sorry, API failed with message: " .. data.message
|
||||
else
|
||||
|
||||
-- response = "Bug #"..matches[1]..":\nReporter: "..data.bugs[1].creator
|
||||
-- response = response .. "\n Last update: "..data.bugs[1].last_change_time
|
||||
-- response = response .. "\n Status: "..data.bugs[1].status.." "..data.bugs[1].resolution
|
||||
-- response = response .. "\n Whiteboard: "..data.bugs[1].whiteboard
|
||||
-- response = response .. "\n Access: https://bugzilla.mozilla.org/show_bug.cgi?id=" .. matches[1]
|
||||
local total = table.map_length(data.bugs)
|
||||
|
||||
print("total bugs: " .. total)
|
||||
local response = "There are " .. total .. " number of bug(s) assigned/reported by " .. matches[2]
|
||||
|
||||
if total > 0 then
|
||||
response = response .. ": "
|
||||
|
||||
for tableKey, bug in pairs(data.bugs) do
|
||||
response = response .. "\n #" .. bug.id
|
||||
response = response .. "\n Status: " .. bug.status .. " " .. bug.resolution
|
||||
response = response .. "\n Whiteboard: " .. bug.whiteboard
|
||||
response = response .. "\n Summary: " .. bug.summary
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
return response
|
||||
end
|
||||
|
||||
-- (table)
|
||||
-- [bugs] = (table)
|
||||
-- [1] = (table)
|
||||
-- [status] = (string) ASSIGNED
|
||||
-- [id] = (number) 927704
|
||||
-- [whiteboard] = (string) [approved][full processed]
|
||||
-- [summary] = (string) Budget Request - Arief Bayu Purwanto - https://reps.mozilla.org/e/mozilla-summit-2013/
|
||||
-- [2] = (table)
|
||||
-- [status] = (string) ASSIGNED
|
||||
-- [id] = (number) 1049337
|
||||
-- [whiteboard] = (string) [approved][full processed][waiting receipts][waiting report and photos]
|
||||
-- [summary] = (string) Budget Request - Arief Bayu Purwanto - https://reps.mozilla.org/e/workshop-firefox-os-pada-workshop-media-sosial-untuk-perubahan-1/
|
||||
-- total bugs: 2
|
||||
|
||||
return {
|
||||
description = "Lookup bugzilla status update",
|
||||
usage = "/bot bugzilla [bug number]",
|
||||
patterns = {
|
||||
"^/bugzilla (status) (.*)$",
|
||||
"^/bugzilla (list) (.*)$"
|
||||
},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
38
plugins/pluginsold/eur.lua
Normal file
38
plugins/pluginsold/eur.lua
Normal file
@ -0,0 +1,38 @@
|
||||
do
|
||||
-- TODO: More currencies
|
||||
|
||||
-- See http://webrates.truefx.com/rates/connect.html
|
||||
local function getEURUSD(usd)
|
||||
local url = 'http://webrates.truefx.com/rates/connect.html?c=EUR/USD&f=csv&s=n'
|
||||
local res,code = http.request(url)
|
||||
local rates = res:split(", ")
|
||||
local symbol = rates[1]
|
||||
local timestamp = rates[2]
|
||||
local sell = rates[3]..rates[4]
|
||||
local buy = rates[5]..rates[6]
|
||||
local text = symbol..'\n'..'Buy: '..buy..'\n'..'Sell: '..sell
|
||||
if usd then
|
||||
local eur = tonumber(usd) / tonumber(buy)
|
||||
text = text.."\n "..usd.."USD = "..eur.."EUR"
|
||||
end
|
||||
return text
|
||||
end
|
||||
|
||||
local function run(msg, matches)
|
||||
if matches[1] == "!eur" then
|
||||
return getEURUSD(nil)
|
||||
end
|
||||
return getEURUSD(matches[1])
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Real-time EURUSD market price",
|
||||
usage = "!eur [USD]",
|
||||
patterns = {
|
||||
"^!eur$",
|
||||
"^!eur (%d+[%d%.]*)$",
|
||||
},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
26
plugins/pluginsold/expand.lua
Normal file
26
plugins/pluginsold/expand.lua
Normal file
@ -0,0 +1,26 @@
|
||||
local function run(msg, patterns)
|
||||
local response_body = {}
|
||||
local request_constructor = {
|
||||
url = patterns[1],
|
||||
method = "HEAD",
|
||||
sink = ltn12.sink.table(response_body),
|
||||
headers = {},
|
||||
redirect = false
|
||||
}
|
||||
|
||||
local ok, response_code, response_headers, response_status_line = http.request(request_constructor)
|
||||
if ok and response_headers.location then
|
||||
return " 👍 " .. response_headers.location
|
||||
else
|
||||
return "Can't expand the url."
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Expand a shortened URL to the original one.",
|
||||
usage = "!expand [url]: Return the original URL",
|
||||
patterns = {
|
||||
"^!expand (https?://[%w-_%.%?%.:/%+=&]+)$"
|
||||
},
|
||||
run = run
|
||||
}
|
24
plugins/pluginsold/fortunes_uc3m.lua
Normal file
24
plugins/pluginsold/fortunes_uc3m.lua
Normal file
@ -0,0 +1,24 @@
|
||||
do
|
||||
|
||||
local function get_fortunes_uc3m()
|
||||
local i = math.random(0,178) -- max 178
|
||||
local web = "http://www.gul.es/fortunes/f"..i
|
||||
local b, c, h = http.request(web)
|
||||
return b
|
||||
end
|
||||
|
||||
|
||||
local function run(msg, matches)
|
||||
return get_fortunes_uc3m()
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Fortunes from Universidad Carlos III",
|
||||
usage = "!uc3m",
|
||||
patterns = {
|
||||
"^!uc3m$"
|
||||
},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
28
plugins/pluginsold/gps.lua
Normal file
28
plugins/pluginsold/gps.lua
Normal file
@ -0,0 +1,28 @@
|
||||
do
|
||||
|
||||
function run(msg, matches)
|
||||
local lat = matches[1]
|
||||
local lon = matches[2]
|
||||
local receiver = get_receiver(msg)
|
||||
|
||||
local zooms = {16, 18}
|
||||
local urls = {}
|
||||
for i = 1, #zooms do
|
||||
local zoom = zooms[i]
|
||||
local url = "http://maps.googleapis.com/maps/api/staticmap?zoom=" .. zoom .. "&size=600x300&maptype=roadmap¢er=" .. lat .. "," .. lon .. "&markers=color:blue%7Clabel:X%7C" .. lat .. "," .. lon
|
||||
table.insert(urls, url)
|
||||
end
|
||||
|
||||
send_photos_from_url(receiver, urls)
|
||||
|
||||
return "www.google.es/maps/place/@" .. lat .. "," .. lon
|
||||
end
|
||||
|
||||
return {
|
||||
description = "generates a map showing the given GPS coordinates",
|
||||
usage = "!gps latitude,longitude: generates a map showing the given GPS coordinates",
|
||||
patterns = {"^!gps ([^,]*)[,%s]([^,]*)$"},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
24
plugins/pluginsold/hackernews.lua
Normal file
24
plugins/pluginsold/hackernews.lua
Normal file
@ -0,0 +1,24 @@
|
||||
do
|
||||
|
||||
function run(msg, matches)
|
||||
local result = 'Hacker News Top5:\n'
|
||||
local top_stories_json, code = https.request('https://hacker-news.firebaseio.com/v0/topstories.json')
|
||||
if code ~=200 then return nil end
|
||||
local top_stories = json:decode(top_stories_json)
|
||||
for i = 1, 5 do
|
||||
local story_json, code = https.request('https://hacker-news.firebaseio.com/v0/item/'..top_stories[i]..'.json')
|
||||
if code ~=200 then return nil end
|
||||
local story = json:decode(story_json)
|
||||
result = result .. i .. '. ' .. story.title .. ' - ' .. story.url .. '\n'
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Show top 5 hacker news (ycombinator.com)",
|
||||
usage = "!hackernews",
|
||||
patterns = {"^!hackernews$"},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
17
plugins/pluginsold/hello.lua
Normal file
17
plugins/pluginsold/hello.lua
Normal file
@ -0,0 +1,17 @@
|
||||
do
|
||||
|
||||
function run(msg, matches)
|
||||
return "Hello, " .. matches[1]
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Says hello to someone",
|
||||
usage = "say hello to [name]",
|
||||
patterns = {
|
||||
"^say hello to (.*)$",
|
||||
"^Say hello to (.*)$"
|
||||
},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
34
plugins/pluginsold/imdb.lua
Normal file
34
plugins/pluginsold/imdb.lua
Normal file
@ -0,0 +1,34 @@
|
||||
do
|
||||
|
||||
local function imdb(movie)
|
||||
local http = require("socket.http")
|
||||
local movie = movie:gsub(' ', '+')
|
||||
local url = "http://www.imdbapi.com/?t=" .. movie
|
||||
local response, code, headers = http.request(url)
|
||||
|
||||
if code ~= 200 then
|
||||
return "Error: " .. code
|
||||
end
|
||||
|
||||
if #response > 0 then
|
||||
local r = json:decode(response)
|
||||
r['Url'] = "http://imdb.com/title/" .. r.imdbID
|
||||
local t = ""
|
||||
for k, v in pairs(r) do t = t .. k .. ": " .. v .. ", " end
|
||||
return t:sub(1, -3)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function run(msg, matches)
|
||||
return imdb(matches[1])
|
||||
end
|
||||
|
||||
return {
|
||||
description = "IMDB plugin for telegram",
|
||||
usage = "!imdb [movie]",
|
||||
patterns = {"^!imdb (.+)"},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
48
plugins/pluginsold/invite.lua
Normal file
48
plugins/pluginsold/invite.lua
Normal file
@ -0,0 +1,48 @@
|
||||
-- Invite other user to the chat group.
|
||||
-- Use !invite name User_name or !invite id id_number
|
||||
-- The User_name is the print_name (there are no spaces but _)
|
||||
|
||||
do
|
||||
|
||||
local function callback(extra, success, result)
|
||||
vardump(success)
|
||||
vardump(result)
|
||||
end
|
||||
|
||||
local function run(msg, matches)
|
||||
local user = matches[2]
|
||||
|
||||
-- User submitted a user name
|
||||
if matches[1] == "name" then
|
||||
user = string.gsub(user," ","_")
|
||||
end
|
||||
|
||||
-- User submitted an id
|
||||
if matches[1] == "id" then
|
||||
user = 'user#id'..user
|
||||
end
|
||||
|
||||
-- The message must come from a chat group
|
||||
if msg.to.type == 'chat' then
|
||||
local chat = 'chat#id'..msg.to.id
|
||||
chat_add_user(chat, user, callback, false)
|
||||
return "Add: "..user.." to "..chat
|
||||
else
|
||||
return 'This isnt a chat group!'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Invite other user to the chat group",
|
||||
usage = {
|
||||
"!invite name [user_name]",
|
||||
"!invite id [user_id]" },
|
||||
patterns = {
|
||||
"^!invite (name) (.*)$",
|
||||
"^!invite (id) (%d+)$"
|
||||
},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
61
plugins/pluginsold/location.lua
Normal file
61
plugins/pluginsold/location.lua
Normal file
@ -0,0 +1,61 @@
|
||||
-- Implement a command !loc [area] which uses
|
||||
-- the static map API to get a location image
|
||||
|
||||
-- Not sure if this is the proper way
|
||||
-- Intent: get_latlong is in time.lua, we need it here
|
||||
-- loadfile "time.lua"
|
||||
|
||||
-- Globals
|
||||
-- If you have a google api key for the geocoding/timezone api
|
||||
do
|
||||
|
||||
local api_key = nil
|
||||
|
||||
local base_api = "https://maps.googleapis.com/maps/api"
|
||||
|
||||
function get_staticmap(area)
|
||||
local api = base_api .. "/staticmap?"
|
||||
|
||||
-- Get a sense of scale
|
||||
local lat,lng,acc,types = get_latlong(area)
|
||||
|
||||
local scale = types[1]
|
||||
if scale=="locality" then zoom=8
|
||||
elseif scale=="country" then zoom=4
|
||||
else zoom = 13 end
|
||||
|
||||
local parameters =
|
||||
"size=600x300" ..
|
||||
"&zoom=" .. zoom ..
|
||||
"¢er=" .. URL.escape(area) ..
|
||||
"&markers=color:red"..URL.escape("|"..area)
|
||||
|
||||
if api_key ~=nil and api_key ~= "" then
|
||||
parameters = parameters .. "&key="..api_key
|
||||
end
|
||||
return lat, lng, api..parameters
|
||||
end
|
||||
|
||||
|
||||
function run(msg, matches)
|
||||
local receiver = get_receiver(msg)
|
||||
local lat,lng,url = get_staticmap(matches[1])
|
||||
|
||||
-- Send the actual location, is a google maps link
|
||||
send_location(receiver, lat, lng, ok_cb, false)
|
||||
|
||||
-- Send a picture of the map, which takes scale into account
|
||||
send_photo_from_url(receiver, url)
|
||||
|
||||
-- Return a link to the google maps stuff is now not needed anymore
|
||||
return nil
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Gets information about a location, maplink and overview",
|
||||
usage = "!loc (location): Gets information about a location, maplink and overview",
|
||||
patterns = {"^!loc (.*)$"},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
22
plugins/pluginsold/magic8ball.lua
Normal file
22
plugins/pluginsold/magic8ball.lua
Normal file
@ -0,0 +1,22 @@
|
||||
do
|
||||
|
||||
function run(msg, matches)
|
||||
local answers = {'It is certain','It is decidedly so','Without a doubt',
|
||||
'Yes definitely','You may rely on it','As I see it, yes',
|
||||
'Most likely','Outlook good','Yes','Signs point to yes',
|
||||
'Reply hazy try again','Ask again later',
|
||||
'Better not tell you now','Cannot predict now',
|
||||
'Concentrate and ask again','Don\'t count on it',
|
||||
'My reply is no','My sources say no','Outlook not so good',
|
||||
'Very doubtful'}
|
||||
return answers[math.random(#answers)]
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Magic 8Ball",
|
||||
usage = "!magic8ball",
|
||||
patterns = {"^!magic8ball"},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
11
plugins/pluginsold/nau.lua
Normal file
11
plugins/pluginsold/nau.lua
Normal file
@ -0,0 +1,11 @@
|
||||
function run(msg, matches)
|
||||
send_photo(get_receiver(msg), "pictures/nau.jpg", ok_cb, false)
|
||||
end
|
||||
|
||||
return {
|
||||
description = "RTL Nau",
|
||||
usage = {"/nau","/now"},
|
||||
patterns = {"^/nau$","^/now$"},
|
||||
run = run
|
||||
}
|
||||
--by Akamaru [https://ponywave.de]
|
11
plugins/pluginsold/neorame.lua
Normal file
11
plugins/pluginsold/neorame.lua
Normal file
@ -0,0 +1,11 @@
|
||||
function run(msg, matches)
|
||||
send_photo(get_receiver(msg), "pictures/neorame.jpg", ok_cb, false)
|
||||
end
|
||||
|
||||
return {
|
||||
description = "NeoRame is best pony!",
|
||||
usage = {"/neorame"},
|
||||
patterns = {"^/neorame"},
|
||||
run = run
|
||||
}
|
||||
--by Akamaru [https://ponywave.de]
|
11
plugins/pluginsold/niissan.lua
Normal file
11
plugins/pluginsold/niissan.lua
Normal file
@ -0,0 +1,11 @@
|
||||
function run(msg, matches)
|
||||
send_photo(get_receiver(msg), "pictures/Nii-san.jpg", ok_cb, false)
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Nii-san <3",
|
||||
usage = {"nii-san","Nii-san","nissan","Nissan"},
|
||||
patterns = {"^nii-san$","^Nii-san$","^nissan$","^Nissan$"},
|
||||
run = run
|
||||
}
|
||||
--by Akamaru [https://ponywave.de]
|
12
plugins/pluginsold/nope.avi.lua
Normal file
12
plugins/pluginsold/nope.avi.lua
Normal file
@ -0,0 +1,12 @@
|
||||
function run(msg, matches)
|
||||
send_video(get_receiver(msg), "videos/nope.avi", ok_cb, false)
|
||||
return 'Video wird gesendet...'
|
||||
end
|
||||
|
||||
return {
|
||||
description = 'Sendet ein Video namens "nope.avi"',
|
||||
usage = {"nope.avi"},
|
||||
patterns = {"^nope.avi"},
|
||||
run = run
|
||||
}
|
||||
--by Akamaru [https://ponywave.de]
|
11
plugins/pluginsold/nyu.lua
Normal file
11
plugins/pluginsold/nyu.lua
Normal file
@ -0,0 +1,11 @@
|
||||
function run(msg, matches)
|
||||
send_photo(get_receiver(msg), "pictures/nyu.jpg", ok_cb, false)
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Nyu?",
|
||||
usage = {"nyu"},
|
||||
patterns = {"^[N|n][Y|y][U|u]$"},
|
||||
run = run
|
||||
}
|
||||
--by Akamaru [https://ponywave.de]
|
11
plugins/pluginsold/old.lua
Normal file
11
plugins/pluginsold/old.lua
Normal file
@ -0,0 +1,11 @@
|
||||
function run(msg, matches)
|
||||
return 'Deine Mudda is old!'
|
||||
end
|
||||
|
||||
return {
|
||||
description = "",
|
||||
usage = {"#old"},
|
||||
patterns = {"^#old$","^.#old$"},
|
||||
run = run
|
||||
}
|
||||
--by Akamaru [https://ponywave.de]
|
32
plugins/pluginsold/pili.lua
Normal file
32
plugins/pluginsold/pili.lua
Normal file
@ -0,0 +1,32 @@
|
||||
local helpers = require "OAuth.helpers"
|
||||
|
||||
local url = "http://pili.la/api.php"
|
||||
|
||||
local function run(msg, matches)
|
||||
local url_req = matches[1]
|
||||
|
||||
local request = {
|
||||
url = url_req
|
||||
}
|
||||
|
||||
local url = url .. "?" .. helpers.url_encode_arguments(request)
|
||||
|
||||
local res, code = http.request(url)
|
||||
if code ~= 200 then
|
||||
return "Sorry, can't connect"
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
return {
|
||||
description = "Shorten an URL with the awesome http://pili.la",
|
||||
usage = {
|
||||
"!pili [url]: Shorten the URL"
|
||||
},
|
||||
patterns = {
|
||||
"^!pili (https?://[%w-_%.%?%.:/%+=&]+)$"
|
||||
},
|
||||
run = run
|
||||
}
|
65
plugins/pluginsold/rae.lua
Normal file
65
plugins/pluginsold/rae.lua
Normal file
@ -0,0 +1,65 @@
|
||||
do
|
||||
|
||||
function getDulcinea( text )
|
||||
-- Powered by https://github.com/javierhonduco/dulcinea
|
||||
|
||||
local api = "http://dulcinea.herokuapp.com/api/?query="
|
||||
local query_url = api..text
|
||||
|
||||
local b, code = http.request(query_url)
|
||||
|
||||
if code ~= 200 then
|
||||
return "Error: HTTP Connection"
|
||||
end
|
||||
|
||||
dulcinea = json:decode(b)
|
||||
|
||||
if dulcinea.status == "error" then
|
||||
return "Error: " .. dulcinea.message
|
||||
end
|
||||
|
||||
while dulcinea.type == "multiple" do
|
||||
text = dulcinea.response[1].id
|
||||
b = http.request(api..text)
|
||||
dulcinea = json:decode(b)
|
||||
end
|
||||
|
||||
local text = ""
|
||||
|
||||
local responses = #dulcinea.response
|
||||
|
||||
if responses == 0 then
|
||||
return "Error: 404 word not found"
|
||||
end
|
||||
|
||||
if (responses > 5) then
|
||||
responses = 5
|
||||
end
|
||||
|
||||
for i = 1, responses, 1 do
|
||||
text = text .. dulcinea.response[i].word .. "\n"
|
||||
local meanings = #dulcinea.response[i].meanings
|
||||
if (meanings > 5) then
|
||||
meanings = 5
|
||||
end
|
||||
for j = 1, meanings, 1 do
|
||||
local meaning = dulcinea.response[i].meanings[j].meaning
|
||||
text = text .. meaning .. "\n\n"
|
||||
end
|
||||
end
|
||||
|
||||
return text
|
||||
end
|
||||
|
||||
function run(msg, matches)
|
||||
return getDulcinea(matches[1])
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Spanish dictionary",
|
||||
usage = "!rae [word]: Search that word in Spanish dictionary.",
|
||||
patterns = {"^!rae (.*)$"},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
11
plugins/pluginsold/rich_bitch.lua
Normal file
11
plugins/pluginsold/rich_bitch.lua
Normal file
@ -0,0 +1,11 @@
|
||||
function run(msg, matches)
|
||||
return 'Akamaru ist nicht reich!'
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Sagt euch dass Akamaru nicht reich ist",
|
||||
usage = {"Rich Bitch","rich bitch","rich Bitch","Rich bitch","RICH BITCH"},
|
||||
patterns = {"^Rich Bitch$","^rich bitch$","^rich Bitch$","^Rich bitch$","^RICH BITCH$"},
|
||||
run = run
|
||||
}
|
||||
--by Akamaru [https://ponywave.de]
|
44
plugins/pluginsold/roll.lua
Normal file
44
plugins/pluginsold/roll.lua
Normal file
@ -0,0 +1,44 @@
|
||||
do
|
||||
|
||||
local ROLL_USAGE = "!roll d<sides>|<count> d<sides>"
|
||||
local DEFAULT_SIDES = 100
|
||||
local DEFAULT_NUMBER_OF_DICE = 1
|
||||
local MAX_NUMBER_OF_DICE = 100
|
||||
|
||||
function run(msg, matches)
|
||||
local str = matches[1]
|
||||
local sides = DEFAULT_SIDES
|
||||
local number_of_dice = DEFAULT_NUMBER_OF_DICE
|
||||
|
||||
if str:find("!roll%s+d%d+%s*$") then
|
||||
sides = tonumber(str:match("[^d]%d+%s*$"))
|
||||
elseif str:find("!roll%s+%d+d%d+%s*$") then
|
||||
number_of_dice = tonumber(str:match("%s+%d+"))
|
||||
sides = tonumber(str:match("%d+%s*$"))
|
||||
end
|
||||
|
||||
if number_of_dice > MAX_NUMBER_OF_DICE then
|
||||
number_of_dice = MAX_NUMBER_OF_DICE
|
||||
end
|
||||
|
||||
local padding = #string.format("%d", sides)
|
||||
local results = ""
|
||||
|
||||
local fmt = "%s %0"..padding.."d"
|
||||
for i=1,number_of_dice do
|
||||
results = string.format(fmt, results, math.random(sides))
|
||||
end
|
||||
|
||||
return string.format("Rolling %dd%d:\n%s", number_of_dice, sides, results)
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Roll some dice!",
|
||||
usage = ROLL_USAGE,
|
||||
patterns = {
|
||||
"^!roll%s*.*"
|
||||
},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
68
plugins/pluginsold/service_entergroup.lua
Normal file
68
plugins/pluginsold/service_entergroup.lua
Normal file
@ -0,0 +1,68 @@
|
||||
local add_user_cfg = load_from_file('data/add_user_cfg.lua')
|
||||
|
||||
local function template_add_user(base, to_username, from_username, chat_name, chat_id)
|
||||
base = base or ''
|
||||
to_username = '@' .. (to_username or '')
|
||||
from_username = '@' .. (from_username or '')
|
||||
chat_name = chat_name or ''
|
||||
chat_id = "chat#id" .. (chat_id or '')
|
||||
if to_username == "@" then
|
||||
to_username = ''
|
||||
end
|
||||
if from_username == "@" then
|
||||
from_username = ''
|
||||
end
|
||||
base = string.gsub(base, "{to_username}", to_username)
|
||||
base = string.gsub(base, "{from_username}", from_username)
|
||||
base = string.gsub(base, "{chat_name}", chat_name)
|
||||
base = string.gsub(base, "{chat_id}", chat_id)
|
||||
return base
|
||||
end
|
||||
|
||||
function chat_new_user_link(msg)
|
||||
local pattern = add_user_cfg.initial_chat_msg
|
||||
local to_username = msg.from.username
|
||||
local from_username = '[link](@' .. (msg.action.link_issuer.username or '') .. ')'
|
||||
local chat_name = msg.to.print_name
|
||||
local chat_id = msg.to.id
|
||||
pattern = template_add_user(pattern, to_username, from_username, chat_name, chat_id)
|
||||
if pattern ~= '' then
|
||||
local receiver = get_receiver(msg)
|
||||
send_msg(receiver, pattern, ok_cb, false)
|
||||
end
|
||||
end
|
||||
|
||||
function chat_new_user(msg)
|
||||
local pattern = add_user_cfg.initial_chat_msg
|
||||
local to_username = msg.action.user.username
|
||||
local from_username = msg.from.username
|
||||
local chat_name = msg.to.print_name
|
||||
local chat_id = msg.to.id
|
||||
pattern = template_add_user(pattern, to_username, from_username, chat_name, chat_id)
|
||||
if pattern ~= '' then
|
||||
local receiver = get_receiver(msg)
|
||||
send_msg(receiver, pattern, ok_cb, false)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function run(msg, matches)
|
||||
if not msg.service then
|
||||
return "Are you trying to troll me?"
|
||||
end
|
||||
if matches[1] == "chat_add_user" then
|
||||
chat_new_user(msg)
|
||||
elseif matches[1] == "chat_add_user_link" then
|
||||
chat_new_user_link(msg)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Service plugin that sends a custom message when an user enters a chat.",
|
||||
usage = "",
|
||||
patterns = {
|
||||
"^!!tgservice (chat_add_user)$",
|
||||
"^!!tgservice (chat_add_user_link)$"
|
||||
},
|
||||
run = run
|
||||
}
|
18
plugins/pluginsold/service_template.lua
Normal file
18
plugins/pluginsold/service_template.lua
Normal file
@ -0,0 +1,18 @@
|
||||
local function run(msg, matches)
|
||||
-- avoid this plugins to process user messages
|
||||
if not msg.service then
|
||||
-- return "Are you trying to troll me?"
|
||||
return nil
|
||||
end
|
||||
print("Service message received: " .. matches[1])
|
||||
end
|
||||
|
||||
|
||||
return {
|
||||
description = "Template for service plugins",
|
||||
usage = "",
|
||||
patterns = {
|
||||
"^!!tgservice (.*)$" -- Do not use the (.*) match in your service plugin
|
||||
},
|
||||
run = run
|
||||
}
|
100
plugins/pluginsold/time.lua
Normal file
100
plugins/pluginsold/time.lua
Normal file
@ -0,0 +1,100 @@
|
||||
-- Implement a command !time [area] which uses
|
||||
-- 2 Google APIs to get the desired result:
|
||||
-- 1. Geocoding to get from area to a lat/long pair
|
||||
-- 2. Timezone to get the local time in that lat/long location
|
||||
|
||||
-- Globals
|
||||
-- If you have a google api key for the geocoding/timezone api
|
||||
api_key = nil
|
||||
|
||||
base_api = "https://maps.googleapis.com/maps/api"
|
||||
dateFormat = "%A %d %B - %H:%M:%S"
|
||||
|
||||
-- Need the utc time for the google api
|
||||
function utctime()
|
||||
return os.time(os.date("!*t"))
|
||||
end
|
||||
|
||||
-- Use the geocoding api to get the lattitude and longitude with accuracy specifier
|
||||
-- CHECKME: this seems to work without a key??
|
||||
function get_latlong(area)
|
||||
local api = base_api .. "/geocode/json?"
|
||||
local parameters = "address=".. (URL.escape(area) or "")
|
||||
if api_key ~= nil then
|
||||
parameters = parameters .. "&key="..api_key
|
||||
end
|
||||
|
||||
-- Do the request
|
||||
local res, code = https.request(api..parameters)
|
||||
if code ~=200 then return nil end
|
||||
local data = json:decode(res)
|
||||
|
||||
if (data.status == "ZERO_RESULTS") then
|
||||
return nil
|
||||
end
|
||||
if (data.status == "OK") then
|
||||
-- Get the data
|
||||
lat = data.results[1].geometry.location.lat
|
||||
lng = data.results[1].geometry.location.lng
|
||||
acc = data.results[1].geometry.location_type
|
||||
types= data.results[1].types
|
||||
return lat,lng,acc,types
|
||||
end
|
||||
end
|
||||
|
||||
-- Use timezone api to get the time in the lat,
|
||||
-- Note: this needs an API key
|
||||
function get_time(lat,lng)
|
||||
local api = base_api .. "/timezone/json?"
|
||||
|
||||
-- Get a timestamp (server time is relevant here)
|
||||
local timestamp = utctime()
|
||||
local parameters = "location=" ..
|
||||
URL.escape(lat) .. "," ..
|
||||
URL.escape(lng) ..
|
||||
"×tamp="..URL.escape(timestamp)
|
||||
if api_key ~=nil then
|
||||
parameters = parameters .. "&key="..api_key
|
||||
end
|
||||
|
||||
local res,code = https.request(api..parameters)
|
||||
if code ~= 200 then return nil end
|
||||
local data = json:decode(res)
|
||||
|
||||
if (data.status == "ZERO_RESULTS") then
|
||||
return nil
|
||||
end
|
||||
if (data.status == "OK") then
|
||||
-- Construct what we want
|
||||
-- The local time in the location is:
|
||||
-- timestamp + rawOffset + dstOffset
|
||||
local localTime = timestamp + data.rawOffset + data.dstOffset
|
||||
return localTime, data.timeZoneId
|
||||
end
|
||||
return localTime
|
||||
end
|
||||
|
||||
function getformattedLocalTime(area)
|
||||
if area == nil then
|
||||
return "The time in nowhere is never"
|
||||
end
|
||||
|
||||
lat,lng,acc = get_latlong(area)
|
||||
if lat == nil and lng == nil then
|
||||
return 'It seems that in "'..area..'" they do not have a concept of time.'
|
||||
end
|
||||
local localTime, timeZoneId = get_time(lat,lng)
|
||||
|
||||
return "The local time in "..timeZoneId.." is: ".. os.date(dateFormat,localTime)
|
||||
end
|
||||
|
||||
function run(msg, matches)
|
||||
return getformattedLocalTime(matches[1])
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Displays the local time in an area",
|
||||
usage = "!time [area]: Displays the local time in that area",
|
||||
patterns = {"^!time (.*)$"},
|
||||
run = run
|
||||
}
|
238
plugins/pluginsold/trivia.lua
Normal file
238
plugins/pluginsold/trivia.lua
Normal file
@ -0,0 +1,238 @@
|
||||
do
|
||||
-- Trivia plugin developed by Guy Spronck
|
||||
|
||||
-- Returns the chat hash for storing information
|
||||
local function get_hash(msg)
|
||||
local hash = nil
|
||||
if msg.to.type == 'chat' then
|
||||
hash = 'chat:'..msg.to.id..':trivia'
|
||||
end
|
||||
if msg.to.type == 'user' then
|
||||
hash = 'user:'..msg.from.id..':trivia'
|
||||
end
|
||||
return hash
|
||||
end
|
||||
|
||||
-- Sets the question variables
|
||||
local function set_question(msg, question, answer)
|
||||
local hash =get_hash(msg)
|
||||
if hash then
|
||||
redis:hset(hash, "question", question)
|
||||
redis:hset(hash, "answer", answer)
|
||||
redis:hset(hash, "time", os.time())
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns the current question
|
||||
local function get_question( msg )
|
||||
local hash = get_hash(msg)
|
||||
if hash then
|
||||
local question = redis:hget(hash, 'question')
|
||||
if question ~= "NA" then
|
||||
return question
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Returns the answer of the last question
|
||||
local function get_answer(msg)
|
||||
local hash = get_hash(msg)
|
||||
if hash then
|
||||
return redis:hget(hash, 'answer')
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns the time of the last question
|
||||
local function get_time(msg)
|
||||
local hash = get_hash(msg)
|
||||
if hash then
|
||||
return redis:hget(hash, 'time')
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- This function generates a new question if available
|
||||
local function get_newquestion(msg)
|
||||
local timediff = 601
|
||||
if(get_time(msg)) then
|
||||
timediff = os.time() - get_time(msg)
|
||||
end
|
||||
if(timediff > 600 or get_question(msg) == nil)then
|
||||
-- Let's show the answer if no-body guessed it right.
|
||||
if(get_question(msg)) then
|
||||
send_large_msg(get_receiver(msg), "The question '" .. get_question(msg) .."' has not been answered. \nThe answer was '" .. get_answer(msg) .."'")
|
||||
end
|
||||
|
||||
local url = "http://jservice.io/api/random/"
|
||||
local b,c = http.request(url)
|
||||
local query = json:decode(b)
|
||||
|
||||
if query then
|
||||
local stringQuestion = ""
|
||||
if(query[1].category)then
|
||||
stringQuestion = "Category: " .. query[1].category.title .. "\n"
|
||||
end
|
||||
if query[1].question then
|
||||
stringQuestion = stringQuestion .. "Question: " .. query[1].question
|
||||
set_question(msg, query[1].question, query[1].answer:lower())
|
||||
return stringQuestion
|
||||
end
|
||||
end
|
||||
return 'Something went wrong, please try again.'
|
||||
else
|
||||
return 'Please wait ' .. 600 - timediff .. ' seconds before requesting a new question. \nUse !triviaquestion to see the current question.'
|
||||
end
|
||||
end
|
||||
|
||||
-- This function generates a new question when forced
|
||||
local function force_newquestion(msg)
|
||||
-- Let's show the answer if no-body guessed it right.
|
||||
if(get_question(msg)) then
|
||||
send_large_msg(get_receiver(msg), "The question '" .. get_question(msg) .."' has not been answered. \nThe answer was '" .. get_answer(msg) .."'")
|
||||
end
|
||||
|
||||
local url = "http://jservice.io/api/random/"
|
||||
local b,c = http.request(url)
|
||||
local query = json:decode(b)
|
||||
|
||||
if query then
|
||||
local stringQuestion = ""
|
||||
if(query[1].category)then
|
||||
stringQuestion = "Category: " .. query[1].category.title .. "\n"
|
||||
end
|
||||
if query[1].question then
|
||||
stringQuestion = stringQuestion .. "Question: " .. query[1].question
|
||||
set_question(msg, query[1].question, query[1].answer:lower())
|
||||
return stringQuestion
|
||||
end
|
||||
end
|
||||
return 'Something went wrong, please try again.'
|
||||
end
|
||||
|
||||
-- This function adds a point to the player
|
||||
local function give_point(msg)
|
||||
local hash = get_hash(msg)
|
||||
if hash then
|
||||
local score = tonumber(redis:hget(hash, msg.from.id) or 0)
|
||||
redis:hset(hash, msg.from.id, score+1)
|
||||
end
|
||||
end
|
||||
|
||||
-- This function checks for a correct answer
|
||||
local function check_answer(msg, answer)
|
||||
if(get_answer(msg)) then -- Safety for first time use
|
||||
if(get_answer(msg) == "NA")then
|
||||
-- Question has not been set, give a new one
|
||||
--get_newquestion(msg)
|
||||
return "No question set, please use !trivia first."
|
||||
elseif (get_answer(msg) == answer:lower()) then -- Question is set, lets check the answer
|
||||
set_question(msg, "NA", "NA") -- Correct, clear the answer
|
||||
give_point(msg) -- gives out point to player for correct answer
|
||||
return msg.from.print_name .. " has answered correctly! \nUse !trivia to get a new question."
|
||||
else
|
||||
return "Sorry " .. msg.from.print_name .. ", but '" .. answer .. "' is not the correct answer!"
|
||||
end
|
||||
else
|
||||
return "No question set, please use !trivia first."
|
||||
end
|
||||
end
|
||||
|
||||
local function user_print_name(user)
|
||||
if user.print_name then
|
||||
return user.print_name
|
||||
end
|
||||
|
||||
local text = ''
|
||||
if user.first_name then
|
||||
text = user.last_name..' '
|
||||
end
|
||||
if user.lastname then
|
||||
text = text..user.last_name
|
||||
end
|
||||
|
||||
return text
|
||||
end
|
||||
|
||||
|
||||
local function get_user_score(msg, user_id, chat_id)
|
||||
local user_info = {}
|
||||
local uhash = 'user:'..user_id
|
||||
local user = redis:hgetall(uhash)
|
||||
local hash = 'chat:'..msg.to.id..':trivia'
|
||||
user_info.score = tonumber(redis:hget(hash, user_id) or 0)
|
||||
user_info.name = user_print_name(user)..' ('..user_id..')'
|
||||
return user_info
|
||||
end
|
||||
|
||||
-- Function to print score
|
||||
local function trivia_scores(msg)
|
||||
if msg.to.type == 'chat' then
|
||||
-- Users on chat
|
||||
local hash = 'chat:'..msg.to.id..':users'
|
||||
local users = redis:smembers(hash)
|
||||
local users_info = {}
|
||||
|
||||
-- Get user info
|
||||
for i = 1, #users do
|
||||
local user_id = users[i]
|
||||
local user_info = get_user_score(msg, user_id, msg.to.id)
|
||||
table.insert(users_info, user_info)
|
||||
end
|
||||
|
||||
table.sort(users_info, function(a, b)
|
||||
if a.score and b.score then
|
||||
return a.score > b.score
|
||||
end
|
||||
end)
|
||||
|
||||
local text = ''
|
||||
for k,user in pairs(users_info) do
|
||||
text = text..user.name..' => '..user.score..'\n'
|
||||
end
|
||||
|
||||
return text
|
||||
else
|
||||
return "This function is only available in group chats."
|
||||
end
|
||||
end
|
||||
|
||||
local function run(msg, matches)
|
||||
if(matches[1] == "!triviascore" or matches[1] == "!triviascores") then
|
||||
-- Output all scores
|
||||
return trivia_scores(msg)
|
||||
elseif(matches[1] == "!triviaquestion")then
|
||||
return "Question: " .. get_question(msg)
|
||||
elseif(matches[1] == "!triviaskip") then
|
||||
if is_sudo(msg) then
|
||||
return force_newquestion(msg)
|
||||
end
|
||||
elseif(matches[1] ~= "!trivia") then
|
||||
return check_answer(msg, matches[1])
|
||||
end
|
||||
|
||||
return get_newquestion(msg)
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Trivia plugin for Telegram",
|
||||
usage = {
|
||||
"!trivia to obtain a new question.",
|
||||
"!trivia [answer] to answer the question.",
|
||||
"!triviaquestion to show the current question.",
|
||||
"!triviascore to get a scoretable of all players.",
|
||||
"!triviaskip to skip a question (requires sudo)"
|
||||
},
|
||||
patterns = {"^!trivia (.*)$",
|
||||
"^!trivia$",
|
||||
"^!triviaquestion$",
|
||||
"^!triviascore$",
|
||||
"^!triviascores$",
|
||||
"^!triviaskip$"},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
88
plugins/pluginsold/vote.lua
Normal file
88
plugins/pluginsold/vote.lua
Normal file
@ -0,0 +1,88 @@
|
||||
do
|
||||
|
||||
local _file_votes = './data/votes.lua'
|
||||
|
||||
function read_file_votes ()
|
||||
local f = io.open(_file_votes, "r+")
|
||||
if f == nil then
|
||||
print ('Created voting file '.._file_votes)
|
||||
serialize_to_file({}, _file_votes)
|
||||
else
|
||||
print ('Values loaded: '.._file_votes)
|
||||
f:close()
|
||||
end
|
||||
return loadfile (_file_votes)()
|
||||
end
|
||||
|
||||
function clear_votes (chat)
|
||||
local _votes = read_file_votes ()
|
||||
_votes [chat] = {}
|
||||
serialize_to_file(_votes, _file_votes)
|
||||
end
|
||||
|
||||
function votes_result (chat)
|
||||
local _votes = read_file_votes ()
|
||||
local results = {}
|
||||
local result_string = ""
|
||||
if _votes [chat] == nil then
|
||||
_votes[chat] = {}
|
||||
end
|
||||
for user,vote in pairs (_votes[chat]) do
|
||||
if (results [vote] == nil) then
|
||||
results [vote] = user
|
||||
else
|
||||
results [vote] = results [vote] .. ", " .. user
|
||||
end
|
||||
end
|
||||
for vote,users in pairs (results) do
|
||||
result_string = result_string .. vote .. " : " .. users .. "\n"
|
||||
end
|
||||
return result_string
|
||||
end
|
||||
|
||||
|
||||
function save_vote(chat, user, vote)
|
||||
local _votes = read_file_votes ()
|
||||
if _votes[chat] == nil then
|
||||
_votes[chat] = {}
|
||||
end
|
||||
_votes[chat][user] = vote
|
||||
|
||||
serialize_to_file(_votes, _file_votes)
|
||||
|
||||
end
|
||||
|
||||
function run(msg, matches)
|
||||
if (matches[1] == "ing") then
|
||||
if (matches [2] == "reset") then
|
||||
clear_votes (tostring(msg.to.id))
|
||||
return "Voting statistics reset.."
|
||||
elseif (matches [2] == "stats") then
|
||||
local votes_result = votes_result (tostring(msg.to.id))
|
||||
if (votes_result == "") then
|
||||
votes_result = "[No votes registered]\n"
|
||||
end
|
||||
return "Voting statistics :\n" .. votes_result
|
||||
end
|
||||
else
|
||||
save_vote(tostring(msg.to.id), msg.from.print_name, tostring(tonumber(matches[2])))
|
||||
return "Vote registered : " .. msg.from.print_name .. " " .. tostring(tonumber(matches [2]))
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
description = "Plugin for voting in groups.",
|
||||
usage = {
|
||||
"!voting reset: Reset all the votes.",
|
||||
"!vote [number]: Cast the vote.",
|
||||
"!voting stats: Shows the statistics of voting."
|
||||
},
|
||||
patterns = {
|
||||
"^!vot(ing) (reset)",
|
||||
"^!vot(ing) (stats)",
|
||||
"^!vot(e) ([0-9]+)$"
|
||||
},
|
||||
run = run
|
||||
}
|
||||
|
||||
end
|
Reference in New Issue
Block a user