Advertisement
Snusmumriken

Another telegramm stuff

Aug 19th, 2017
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.03 KB | None | 0 0
  1. math.randomseed(os.time())
  2. os.execute('chcp 65001')
  3. https = require'ssl.https'
  4.  
  5. sleep = require'socket'.sleep
  6. json = require'cjson.safe'
  7. local serpent = require'libs/serpent'
  8.  
  9. local printf = string.format
  10.  
  11. local function timer(cb, delay)
  12.     local t = delay
  13.     return function(dt)
  14.         t = t - (dt or .013)
  15.         if t < 0 then
  16.             cb()
  17.             t = delay;
  18.         end
  19.     end
  20. end
  21.  
  22.  
  23. local api = {}
  24. api.__index = api
  25. setmetatable(api, {
  26.     __call = function(self, token)
  27.             local o = {
  28.                 token = token,
  29.                 link = ('https://api.telegram.org/bot%s/'):format(token),
  30.                 last = 0
  31.             }
  32.         return setmetatable(o, self)
  33.     end
  34. })
  35.  
  36. local function toPost(t)
  37.     local res = {}
  38.     for k, v in pairs(t) do
  39.         table.insert(res, ('%s=%s'):format(k, v))
  40.     end
  41.     return table.concat(res, '&')
  42. end
  43.  
  44. function api:prepare(api)
  45.     return self.link..api
  46. end
  47.  
  48. function api:request(api, querry)
  49.     local s = self:prepare(api)
  50.     local q = (querry and toPost(querry))
  51.     local data, err = https.request(s, q)
  52.     return data and json.decode(data) or err
  53. end
  54.  
  55. local t = {
  56.     'Ты хочешь со мной поговорить, но ты делаешь это без должного почтения, %s!',
  57.     'Ты думаешь, это смешно, %s?',
  58.     'Никто тебя не любит, %s.\nДаже твои родители не настоящие.\nТы приёмный.',
  59. }
  60.  
  61. local c = {
  62.     'Зачем тебе "%s"? Тебе это не нужно.',
  63.     'Мир рухнет если я сделаю "%s".',
  64.     'Ты предлагаешь мне "%s"? За тобой уже выехали.',
  65.     'Ты думаешь, я сделаю за тебя "%s"?',
  66.     'Ты думаешь, "%s" - это смешно?',
  67.     'Тебе нужен "%s" - ты его и делай.',
  68.     'Мои возможности не безграничны. И "%s" вне моих возможностей.',
  69.     'Все говорят "%s", а ты купи слона!',
  70.     'Шутки кончились. А "%s" так и не выполнен. И не будет.',
  71.     'Вы все там сговорились что ли? Ну не умею я "%s".\nДовольны?\nА теперь идите нафиг.',
  72.     'Достали со своим "%s".',
  73.     'Я не умею "%s", но зато умею рассказывать анекдоты через /joke. Только тссс.',
  74.     'Я устал и не буду делать "%s".',
  75.     'Давай лучше ты сам подумаешь, как делать "%s".',
  76.     'Сталина на вас нет, со своим "%s".',
  77.     'Ох, ну ты ещё со своим "%s".',
  78.     'Тебя мама за "%s" не наругает?',
  79.     'Слушай, если ты мне "%s" предлагаешь, ты явно не читал доки.\nДавай в сторону "/help".',
  80.     'Читаем мануалы и машем.\nАвось даже по "%s" что-то найдёшь.\nЖми уже "/help".',
  81. }
  82.  
  83. local function getrandmsg(text)
  84.     local s = t[math.random(#t)]
  85.     return s:find('%s') and s:format(text) or s
  86. end
  87.  
  88. local function getrandcmm(text)
  89.     local s = c[math.random(#c)]
  90.     return s:find('%s') and s:format(text) or s
  91. end
  92.  
  93. local chats = {list = {}}
  94. function chats:add(name, id)
  95.     for k, v in pairs(self.list) do
  96.         if v == id then return false end
  97.     end
  98.     self.list[name] = id
  99.     self:save()
  100.     return true
  101. end
  102.  
  103. function chats:remove(name)
  104.     if tonumber(name) then
  105.         for k, v in pairs(self.list) do
  106.             if v == name then
  107.                 self.list[k] = nil
  108.                 return true
  109.             end
  110.         end
  111.     end
  112.     if self.list[name] then
  113.         self.list[name] = nil
  114.         return true
  115.     end
  116.     self:save()
  117. end
  118.  
  119. function chats:getNameByID(id)
  120.     for k, v in pairs(self.list) do
  121.         if v == id then return k end
  122.     end
  123. end
  124.  
  125. function chats:getIDByName(name)
  126.     return self.list[name]
  127. end
  128.  
  129. function chats:save()
  130.     local file, err = io.open('save.txt', 'wb')
  131.     if not file then return err end
  132.     file:write(serpent.block(self.list))
  133.     file:close()
  134. end
  135.  
  136. function chats:load()
  137.     local file, err = io.open('save.txt', 'rb')
  138.     if not file then return err end
  139.     succ, self.list = serpent.load(file:read('*all'))
  140.     file:write(serpent.block(self.list))
  141.     file:close()
  142. end
  143.  
  144. chats:load()
  145.  
  146. local commands = {}
  147. commands['/start'] = function(msg)
  148.     return [[
  149.     Привет.
  150.     Задавать вопросы сюда: /help.
  151. ]]
  152. end
  153.  
  154. commands['/help'] = function(msg)
  155.     return [[
  156. Я умею добавлять любых желающих в список рассылок, для вывода статистики и любой произвольной фигни.
  157. Можно добавить себя или группу в список рассылок а потом использовать скрипт отправки мне сообщенек, с помощью которого можно отправить кому-то произвольный текст. Это "кому-то" определяется по имени, которое в меня запихнули.
  158. Инструкция по эксплуатации тут: /how_help.
  159.  
  160. Полный список команд:
  161. /add_me [name]- добавить себя в список рассылок.
  162. /remove_me - удалить себя же из списка рассылок.
  163.  
  164. /add_group [name] - добавить этот чат тоже в список рассылок.
  165. /remove_group - см. remove_me, но уже с группой.
  166.  
  167. Мне можно слать сообщения через udp-сокеты, за дополнительной инфой - тыкай сюды: /udp_help
  168. ]]
  169. end
  170.  
  171. commands['/udp_help'] = function(msg)
  172.     return [[
  173. Мне можно слать json'ы по UDP-сокетам (3480 порт), с содержимым типа такого:
  174. json = {
  175.  "request":{
  176.       "to":"tomato",
  177.         "text":"some text data"
  178.     }
  179. }
  180.  
  181. Я верну что-то вроде этого:
  182. json = {
  183.  "request":{
  184.       "to":"tomato",
  185.         "text":"some text data"
  186.     }
  187.     "response":{
  188.       "succ":true,
  189.       ["err":"error_text"]
  190.     }
  191. }
  192.  
  193. Заранее прошу понять и простить с попытками отправления больших сообщений.
  194. Длину текста не стоит делать больше 8к символов, иначе всё очень плохо ((
  195. ]]
  196. end
  197.  
  198. commands['/how_help'] = function(msg)
  199.     return [[
  200. Меня можно нахально эксплуатировать в собственных рассылках всяких уведомлений, примерно так:
  201. Пишем мне:
  202. /add_me tomato
  203.  
  204. И в скрипте:
  205. bot_api = require'script'
  206. succ, err = bot_api:send('text', 'tomato')
  207.  
  208. Таким образом, я могу уведомлять о всякой фигне, которая очень нужна, запускаться с планировщиком, следить за остановкой скриптов и всем таким.
  209. ]]
  210. end
  211.  
  212. math.randomseed(os.time())
  213. local http = require'socket.http'
  214.  
  215. commands['/joke'] = function(msg)
  216.     local req = 'http://bash.im/random'
  217.     print(req)
  218.     local data, err = http.request(req)
  219.     if not data then return 'Какая-то внутренняя ошибка, шутки недоступны: '..tostring(err) end
  220.     local joke = data:match('<div class="text">(.-)</div>')
  221.     if not joke then return 'Ашипка!' end
  222.     local conv = require'luaconv'
  223.     joke = conv.decode('ansi', joke)
  224.     joke = joke:gsub('<.->', '\n')
  225.     joke = joke:gsub('&lt;', '<')
  226.     joke = joke:gsub('&gt;', '>')
  227.     joke = joke:gsub('&(.-);', '')
  228.     print('joke:', joke)
  229.     return tostring(joke)
  230.     --return 'Что такое, чёрное, стоит в огороде и на трёх ногах?\n\nНеправильно, это твой дедуля!'
  231. end
  232.  
  233. commands['/add_me'] = function(msg)
  234.     local name, id = (msg.text:match('/add_me (.*)') or msg.from.username), msg.from.id
  235.     return chats:add(name, id) and printf('Оки, ты занесён в базу как "%s", под id "%s".', name, id)
  236.         or printf('Ты уже зареган под именем %s, глупышка', chats:getNameByID(id))
  237. end
  238.  
  239. commands['/remove_me'] = function(msg)
  240.     return chats:remove(msg.from.id)
  241.        and 'С превеликим наслаждением удалил тебя из рассылок.\nНадеюсь, навсегда :)'
  242.         or 'Тебя нет в моих списках, глупышка'
  243. end
  244.  
  245. commands['/add_group'] = function(msg)
  246.     if msg.chat.type ~= 'group' then
  247.         return 'Это же не группа, малыш'
  248.     end
  249.     local name, id = (msg.text:match('/add_me (.*)') or msg.chat.title), msg.chat.id
  250.     return chats:add(name, id) and printf('Ладысь, группа занесена в базу как "%s", под id "%s".', name, id)
  251.         or printf('Эта группа уже зарегана под именем %s, глупышка', chats:getNameByID(id))
  252. end
  253.  
  254. commands['/remove_group'] = function(msg)
  255.     if msg.chat.type ~= 'group' then
  256.         return 'Это же не группа, малыш'
  257.     end
  258.    
  259.     return chats:remove(msg.chat.id)
  260.        and 'А я надеялся что смогу писать сюда всякую лабуду и будить народ уведомлениями по ночам.\nНу ладно.'
  261.         or 'Малыш, этой группы и нет в моих списках!\nЯ не могу удалить то чего нет!'
  262. end
  263.  
  264. function api:handler(msg)
  265.     --return getrandmsg(msg.from.first_name)
  266. end
  267.  
  268. function api:command_handler(msg)
  269.     print('get command')
  270.     local comm, bot = msg.text:match'(/%S+)' or '/start'
  271.     if comm:find'@' then
  272.         comm, bot = comm:match'(.-)@(.*)'
  273.     end
  274.     print('command, bot: ', comm, bot)
  275.     if bot and bot ~= self.user then return end
  276.     if commands[comm] then
  277.         return commands[comm](msg)
  278.     end
  279.     return getrandcmm(comm)
  280. end
  281.  
  282. function api:photo_handler(msg)
  283.  
  284. end
  285.  
  286. function api:sticker_handler(msg)
  287.  
  288. end
  289.  
  290. --[[
  291. Struct:
  292. {
  293.  ok = true,
  294.  result = {
  295.    {
  296.      message = {
  297.        chat = {
  298.          first_name = "Snusmumriken",
  299.          id = 237976911,
  300.          type = "private",
  301.          username = "Snusmumriken"
  302.        },
  303.        date = 1488013639,
  304.        entities = {
  305.          {
  306.            length = 6,
  307.            offset = 0,
  308.            type = "bot_command"
  309.          }
  310.        },
  311.        from = {
  312.          first_name = "Snusmumriken",
  313.          id = 237976911,
  314.          username = "Snusmumriken"
  315.        },
  316.        message_id = 1,
  317.        text = "/start"
  318.      },
  319.      update_id = 301492422
  320.    }
  321.  }
  322. }
  323. ]]
  324.  
  325. msg = {}
  326. msg.__index = msg
  327. function msg:isType(t)
  328.     if self.entities then
  329.         for i, v in ipairs(self.entities) do
  330.             if v.type == v then return true end
  331.         end
  332.     end
  333. end
  334.  
  335. function api:receive()
  336.     local data, err
  337.     data, err = self:request('getUpdates', {offset = self.last + 1})
  338.     if not data then return end
  339.     if data.ok and data.result then
  340.         if #data.result > 0 then print('receuvedata: '..serpent.block(data)) end
  341.         for i, v in ipairs(data.result) do
  342.             if v.message then
  343.                 local m = setmetatable(v.message, msg)
  344.                 self.last = v.update_id
  345.                 print('Last update_id: '..self.last)
  346.                 local s
  347.                 if m.entities and m.entities[1].type == 'bot_command' then
  348.                     s = self:command_handler(m)
  349.                 elseif m.photo then
  350.                     s = self:photo_handler(m)
  351.                 elseif m.sticker then
  352.                     s = self:photo_handler(m)
  353.                 else
  354.                     s = self:handler(m)
  355.                 end
  356.                 if s then self:send(s, m.chat.id) end
  357.             end
  358.         end
  359.     end
  360. end
  361.  
  362. function api:send(text, chat)
  363.     local data, err = self:request('sendMessage', {chat_id = chat, text = text})
  364.     if not data then return nil, error(err) end
  365.     if data.ok then
  366.         for i, v in ipairs(data.result) do
  367.             self:handler(v.message, v.from, v.chat)
  368.         end
  369.     end
  370. end
  371.  
  372. function api:sendto(text, user)
  373.     print('sendto', self)
  374.     local id = chats:getIDByName(user)
  375.     if not id then return nil, printf('user %s not found', user) end
  376.     local data, err = self:request('sendMessage', {chat_id = id, text = text})
  377.     if not data then return nil, error(err) end
  378.     if data.ok then
  379.         return true
  380.     end
  381. end
  382.  
  383. function api:getInfo()
  384.     local data, err = self:request('getMe')
  385.     if not data then return nil, error(err) end
  386.     if not data.ok then return
  387.         nil, error(('Code: %s desc: %s'):format(data.error_code, data.description))
  388.     end
  389.     self.id = data.result.id
  390.     self.name = data.result.first_name
  391.     self.user = data.result.username
  392.     print(json.encode(self))
  393.     return self
  394. end
  395.  
  396. bot = api('370183870:AAH7oaNStf4WWc3VFHBJXr_LyXT5Ux4xf-Q')
  397.  
  398. bot:getInfo()
  399.  
  400. local sock = {}
  401. sock.__index = sock
  402.  
  403. function sock:send(data)
  404.     self.channel:sendto(data, self.ip, self.port)
  405. end
  406.  
  407. local socket = {}
  408. local sock = require'socket'.udp4 or require'socket'.udp
  409. socket.channel = sock()
  410. socket.channel:settimeout(0)
  411. socket.channel:setsockname("*", 3480)
  412.  
  413. function socket:receive()
  414.     local data, ip, port
  415.     return function()
  416.         data, ip, port = self.channel:receivefrom()
  417.         if data and ip and port then
  418.             return setmetatable({
  419.                     channel = self.channel,
  420.                     data = data,
  421.                     ip = ip,
  422.                     port = port
  423.                 }, sock)
  424.         end
  425.     end
  426. end
  427.  
  428. function socket:update()
  429.     for sock in self:receive() do
  430.         local data, err = json.decode(sock.data)
  431.         if data and data.request then
  432.             local msg = data.request
  433.             if msg.to and msg.text then
  434.                 local succ, send_err = bot:sendto(msg.text, msg.to)
  435.                 if succ then
  436.                     data.response = {succ = true}
  437.                     sock:send(json.encode(data))
  438.                 else
  439.                     data.response = {succ = false, err = (send_err or printf('sending to "%s" err', data.to))}
  440.                     sock:send(json.encode(data))
  441.                 end
  442.             else
  443.                 data.response = {succ = false, err = 'json request field haven\'t keys "to" and "text"'}
  444.                 sock:send(json.encode(data))
  445.             end
  446.         else
  447.             sock:send(json.encode{succ = false, err = (err or 'json decode error')})
  448.         end
  449.     end
  450. end
  451.  
  452. if love then
  453.     local bot_update = timer(function() bot:receive() end, 3)
  454.    
  455.     function love.update(dt)
  456.         love.window.setTitle(love.timer.getFPS())
  457.         bot_update(dt)
  458.         socket:update()
  459.         love.timer.sleep(.1)
  460.     end
  461.  
  462.     function love.draw()
  463.         love.graphics.print(serpent.block(chats.list))
  464.     end
  465. else
  466.     while true do
  467.         bot:receive()
  468.         socket:update()
  469.         sleep(1)
  470.     end
  471. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement