Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- math.randomseed(os.time())
- os.execute('chcp 65001')
- https = require'ssl.https'
- sleep = require'socket'.sleep
- json = require'cjson.safe'
- local serpent = require'libs/serpent'
- local printf = string.format
- local function timer(cb, delay)
- local t = delay
- return function(dt)
- t = t - (dt or .013)
- if t < 0 then
- cb()
- t = delay;
- end
- end
- end
- local api = {}
- api.__index = api
- setmetatable(api, {
- __call = function(self, token)
- local o = {
- token = token,
- link = ('https://api.telegram.org/bot%s/'):format(token),
- last = 0
- }
- return setmetatable(o, self)
- end
- })
- local function toPost(t)
- local res = {}
- for k, v in pairs(t) do
- table.insert(res, ('%s=%s'):format(k, v))
- end
- return table.concat(res, '&')
- end
- function api:prepare(api)
- return self.link..api
- end
- function api:request(api, querry)
- local s = self:prepare(api)
- local q = (querry and toPost(querry))
- local data, err = https.request(s, q)
- return data and json.decode(data) or err
- end
- local t = {
- 'Ты хочешь со мной поговорить, но ты делаешь это без должного почтения, %s!',
- 'Ты думаешь, это смешно, %s?',
- 'Никто тебя не любит, %s.\nДаже твои родители не настоящие.\nТы приёмный.',
- }
- local c = {
- 'Зачем тебе "%s"? Тебе это не нужно.',
- 'Мир рухнет если я сделаю "%s".',
- 'Ты предлагаешь мне "%s"? За тобой уже выехали.',
- 'Ты думаешь, я сделаю за тебя "%s"?',
- 'Ты думаешь, "%s" - это смешно?',
- 'Тебе нужен "%s" - ты его и делай.',
- 'Мои возможности не безграничны. И "%s" вне моих возможностей.',
- 'Все говорят "%s", а ты купи слона!',
- 'Шутки кончились. А "%s" так и не выполнен. И не будет.',
- 'Вы все там сговорились что ли? Ну не умею я "%s".\nДовольны?\nА теперь идите нафиг.',
- 'Достали со своим "%s".',
- 'Я не умею "%s", но зато умею рассказывать анекдоты через /joke. Только тссс.',
- 'Я устал и не буду делать "%s".',
- 'Давай лучше ты сам подумаешь, как делать "%s".',
- 'Сталина на вас нет, со своим "%s".',
- 'Ох, ну ты ещё со своим "%s".',
- 'Тебя мама за "%s" не наругает?',
- 'Слушай, если ты мне "%s" предлагаешь, ты явно не читал доки.\nДавай в сторону "/help".',
- 'Читаем мануалы и машем.\nАвось даже по "%s" что-то найдёшь.\nЖми уже "/help".',
- }
- local function getrandmsg(text)
- local s = t[math.random(#t)]
- return s:find('%s') and s:format(text) or s
- end
- local function getrandcmm(text)
- local s = c[math.random(#c)]
- return s:find('%s') and s:format(text) or s
- end
- local chats = {list = {}}
- function chats:add(name, id)
- for k, v in pairs(self.list) do
- if v == id then return false end
- end
- self.list[name] = id
- self:save()
- return true
- end
- function chats:remove(name)
- if tonumber(name) then
- for k, v in pairs(self.list) do
- if v == name then
- self.list[k] = nil
- return true
- end
- end
- end
- if self.list[name] then
- self.list[name] = nil
- return true
- end
- self:save()
- end
- function chats:getNameByID(id)
- for k, v in pairs(self.list) do
- if v == id then return k end
- end
- end
- function chats:getIDByName(name)
- return self.list[name]
- end
- function chats:save()
- local file, err = io.open('save.txt', 'wb')
- if not file then return err end
- file:write(serpent.block(self.list))
- file:close()
- end
- function chats:load()
- local file, err = io.open('save.txt', 'rb')
- if not file then return err end
- succ, self.list = serpent.load(file:read('*all'))
- file:write(serpent.block(self.list))
- file:close()
- end
- chats:load()
- local commands = {}
- commands['/start'] = function(msg)
- return [[
- Привет.
- Задавать вопросы сюда: /help.
- ]]
- end
- commands['/help'] = function(msg)
- return [[
- Я умею добавлять любых желающих в список рассылок, для вывода статистики и любой произвольной фигни.
- Можно добавить себя или группу в список рассылок а потом использовать скрипт отправки мне сообщенек, с помощью которого можно отправить кому-то произвольный текст. Это "кому-то" определяется по имени, которое в меня запихнули.
- Инструкция по эксплуатации тут: /how_help.
- Полный список команд:
- /add_me [name]- добавить себя в список рассылок.
- /remove_me - удалить себя же из списка рассылок.
- /add_group [name] - добавить этот чат тоже в список рассылок.
- /remove_group - см. remove_me, но уже с группой.
- Мне можно слать сообщения через udp-сокеты, за дополнительной инфой - тыкай сюды: /udp_help
- ]]
- end
- commands['/udp_help'] = function(msg)
- return [[
- Мне можно слать json'ы по UDP-сокетам (3480 порт), с содержимым типа такого:
- json = {
- "request":{
- "to":"tomato",
- "text":"some text data"
- }
- }
- Я верну что-то вроде этого:
- json = {
- "request":{
- "to":"tomato",
- "text":"some text data"
- }
- "response":{
- "succ":true,
- ["err":"error_text"]
- }
- }
- Заранее прошу понять и простить с попытками отправления больших сообщений.
- Длину текста не стоит делать больше 8к символов, иначе всё очень плохо ((
- ]]
- end
- commands['/how_help'] = function(msg)
- return [[
- Меня можно нахально эксплуатировать в собственных рассылках всяких уведомлений, примерно так:
- Пишем мне:
- /add_me tomato
- И в скрипте:
- bot_api = require'script'
- succ, err = bot_api:send('text', 'tomato')
- Таким образом, я могу уведомлять о всякой фигне, которая очень нужна, запускаться с планировщиком, следить за остановкой скриптов и всем таким.
- ]]
- end
- math.randomseed(os.time())
- local http = require'socket.http'
- commands['/joke'] = function(msg)
- local req = 'http://bash.im/random'
- print(req)
- local data, err = http.request(req)
- if not data then return 'Какая-то внутренняя ошибка, шутки недоступны: '..tostring(err) end
- local joke = data:match('<div class="text">(.-)</div>')
- if not joke then return 'Ашипка!' end
- local conv = require'luaconv'
- joke = conv.decode('ansi', joke)
- joke = joke:gsub('<.->', '\n')
- joke = joke:gsub('<', '<')
- joke = joke:gsub('>', '>')
- joke = joke:gsub('&(.-);', '')
- print('joke:', joke)
- return tostring(joke)
- --return 'Что такое, чёрное, стоит в огороде и на трёх ногах?\n\nНеправильно, это твой дедуля!'
- end
- commands['/add_me'] = function(msg)
- local name, id = (msg.text:match('/add_me (.*)') or msg.from.username), msg.from.id
- return chats:add(name, id) and printf('Оки, ты занесён в базу как "%s", под id "%s".', name, id)
- or printf('Ты уже зареган под именем %s, глупышка', chats:getNameByID(id))
- end
- commands['/remove_me'] = function(msg)
- return chats:remove(msg.from.id)
- and 'С превеликим наслаждением удалил тебя из рассылок.\nНадеюсь, навсегда :)'
- or 'Тебя нет в моих списках, глупышка'
- end
- commands['/add_group'] = function(msg)
- if msg.chat.type ~= 'group' then
- return 'Это же не группа, малыш'
- end
- local name, id = (msg.text:match('/add_me (.*)') or msg.chat.title), msg.chat.id
- return chats:add(name, id) and printf('Ладысь, группа занесена в базу как "%s", под id "%s".', name, id)
- or printf('Эта группа уже зарегана под именем %s, глупышка', chats:getNameByID(id))
- end
- commands['/remove_group'] = function(msg)
- if msg.chat.type ~= 'group' then
- return 'Это же не группа, малыш'
- end
- return chats:remove(msg.chat.id)
- and 'А я надеялся что смогу писать сюда всякую лабуду и будить народ уведомлениями по ночам.\nНу ладно.'
- or 'Малыш, этой группы и нет в моих списках!\nЯ не могу удалить то чего нет!'
- end
- function api:handler(msg)
- --return getrandmsg(msg.from.first_name)
- end
- function api:command_handler(msg)
- print('get command')
- local comm, bot = msg.text:match'(/%S+)' or '/start'
- if comm:find'@' then
- comm, bot = comm:match'(.-)@(.*)'
- end
- print('command, bot: ', comm, bot)
- if bot and bot ~= self.user then return end
- if commands[comm] then
- return commands[comm](msg)
- end
- return getrandcmm(comm)
- end
- function api:photo_handler(msg)
- end
- function api:sticker_handler(msg)
- end
- --[[
- Struct:
- {
- ok = true,
- result = {
- {
- message = {
- chat = {
- first_name = "Snusmumriken",
- id = 237976911,
- type = "private",
- username = "Snusmumriken"
- },
- date = 1488013639,
- entities = {
- {
- length = 6,
- offset = 0,
- type = "bot_command"
- }
- },
- from = {
- first_name = "Snusmumriken",
- id = 237976911,
- username = "Snusmumriken"
- },
- message_id = 1,
- text = "/start"
- },
- update_id = 301492422
- }
- }
- }
- ]]
- msg = {}
- msg.__index = msg
- function msg:isType(t)
- if self.entities then
- for i, v in ipairs(self.entities) do
- if v.type == v then return true end
- end
- end
- end
- function api:receive()
- local data, err
- data, err = self:request('getUpdates', {offset = self.last + 1})
- if not data then return end
- if data.ok and data.result then
- if #data.result > 0 then print('receuvedata: '..serpent.block(data)) end
- for i, v in ipairs(data.result) do
- if v.message then
- local m = setmetatable(v.message, msg)
- self.last = v.update_id
- print('Last update_id: '..self.last)
- local s
- if m.entities and m.entities[1].type == 'bot_command' then
- s = self:command_handler(m)
- elseif m.photo then
- s = self:photo_handler(m)
- elseif m.sticker then
- s = self:photo_handler(m)
- else
- s = self:handler(m)
- end
- if s then self:send(s, m.chat.id) end
- end
- end
- end
- end
- function api:send(text, chat)
- local data, err = self:request('sendMessage', {chat_id = chat, text = text})
- if not data then return nil, error(err) end
- if data.ok then
- for i, v in ipairs(data.result) do
- self:handler(v.message, v.from, v.chat)
- end
- end
- end
- function api:sendto(text, user)
- print('sendto', self)
- local id = chats:getIDByName(user)
- if not id then return nil, printf('user %s not found', user) end
- local data, err = self:request('sendMessage', {chat_id = id, text = text})
- if not data then return nil, error(err) end
- if data.ok then
- return true
- end
- end
- function api:getInfo()
- local data, err = self:request('getMe')
- if not data then return nil, error(err) end
- if not data.ok then return
- nil, error(('Code: %s desc: %s'):format(data.error_code, data.description))
- end
- self.id = data.result.id
- self.name = data.result.first_name
- self.user = data.result.username
- print(json.encode(self))
- return self
- end
- bot = api('370183870:AAH7oaNStf4WWc3VFHBJXr_LyXT5Ux4xf-Q')
- bot:getInfo()
- local sock = {}
- sock.__index = sock
- function sock:send(data)
- self.channel:sendto(data, self.ip, self.port)
- end
- local socket = {}
- local sock = require'socket'.udp4 or require'socket'.udp
- socket.channel = sock()
- socket.channel:settimeout(0)
- socket.channel:setsockname("*", 3480)
- function socket:receive()
- local data, ip, port
- return function()
- data, ip, port = self.channel:receivefrom()
- if data and ip and port then
- return setmetatable({
- channel = self.channel,
- data = data,
- ip = ip,
- port = port
- }, sock)
- end
- end
- end
- function socket:update()
- for sock in self:receive() do
- local data, err = json.decode(sock.data)
- if data and data.request then
- local msg = data.request
- if msg.to and msg.text then
- local succ, send_err = bot:sendto(msg.text, msg.to)
- if succ then
- data.response = {succ = true}
- sock:send(json.encode(data))
- else
- data.response = {succ = false, err = (send_err or printf('sending to "%s" err', data.to))}
- sock:send(json.encode(data))
- end
- else
- data.response = {succ = false, err = 'json request field haven\'t keys "to" and "text"'}
- sock:send(json.encode(data))
- end
- else
- sock:send(json.encode{succ = false, err = (err or 'json decode error')})
- end
- end
- end
- if love then
- local bot_update = timer(function() bot:receive() end, 3)
- function love.update(dt)
- love.window.setTitle(love.timer.getFPS())
- bot_update(dt)
- socket:update()
- love.timer.sleep(.1)
- end
- function love.draw()
- love.graphics.print(serpent.block(chats.list))
- end
- else
- while true do
- bot:receive()
- socket:update()
- sleep(1)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement