ctucx.git: ctucxbot

[nimlang] A telegram bot

commit ed18e82a1eb4f152ac0f01f45cbcdda2974ef0a7
parent c4609ee18216f06a86d662915d3868bf5e0692ae
Author: ctucx <c@ctu.cx>
Date: Mon, 20 Apr 2020 00:48:26 +0200

updated code for new telebot.nim version
17 files changed, 176 insertions(+), 224 deletions(-)
M
ctucxbot.nimble
|
2
+-
A
data/stats/penis/28209912.json
|
2
++
M
src/cmd/animalpics.nim
|
28
+++++++++++++---------------
M
src/cmd/daysuntilcongress.nim
|
14
++++++--------
M
src/cmd/debuginfo.nim
|
10
+++-------
M
src/cmd/help.nim
|
7
++-----
M
src/cmd/httpstatuscode.nim
|
18
++++++++----------
D
src/cmd/invitelinks.nim
|
27
---------------------------
M
src/cmd/sarcasm.nim
|
9
+++++----
M
src/cmd/stats.nim
|
18
++++++++----------
M
src/cmd/unixtime.nim
|
8
++------
M
src/cmd/uptime.nim
|
9
+++------
M
src/cmd/utc.nim
|
13
+++++--------
M
src/cmd/whoami.nim
|
9
+++------
M
src/cmd/yesorno.nim
|
7
++-----
M
src/ctucxbot.nim
|
154
+++++++++++++++++++++++++------------------------------------------------------
A
src/updateHandler.nim
|
65
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/ctucxbot.nimble b/ctucxbot.nimble
@@ -11,4 +11,4 @@ bin           = @["ctucxbot"]
 
 # Dependencies
 requires "nim >= 1.0.4"
-requires "telebot 0.7.0"
+requires "telebot 1.0.1"
diff --git a/data/stats/penis/28209912.json b/data/stats/penis/28209912.json
@@ -0,0 +1 @@
+{"lastReset":"2020-04-20","messagesCount":{"today":1,"total":1},"users":{"28209912":{"username":"petabyteboy","todayMessagesCount":1,"totalMessagesCount":1}}}+
\ No newline at end of file
diff --git a/src/cmd/animalpics.nim b/src/cmd/animalpics.nim
@@ -1,17 +1,19 @@
-import asyncdispatch, telebot, strutils, os, times, httpClient, json
+import asyncdispatch, telebot, os, times, httpClient, json
 
 type
-  AnimalType = enum
+  AnimalType* = enum
     fox, cat, dog, penguin
 
-proc animalCommand(animalType: AnimalType, animated: bool): proc =
-  return proc(bot: Telebot, command: Command) {.async.} =
+proc animalCommand* (animalType: AnimalType, animated: bool): proc =
+  return proc(bot: Telebot, command: Command): Future[bool] {.async.} =
     var httpClient = newAsyncHttpClient()
 
     let ext = if animated: ".gif" else: ".image"
-    var tmpFile = getCurrentDir() & "/data/tmp/" & $(toUnix(getTime())) & ext
+    var tmpFile = getEnv("DATA_PATH") & "/tmp/" & $(toUnix(getTime())) & ext
     var url = ""
 
+    discard existsOrCreateDir(getEnv("DATA_PATH") & "/tmp")
+
     if animalType == fox and not animated:
       url = "https://foxrudor.de"
     elif animalType == penguin and not animated:

@@ -30,19 +32,14 @@ proc animalCommand(animalType: AnimalType, animated: bool): proc =
       let imginfo = parseJson(await httpClient.getContent("https://api.thecatapi.com/v1/images/search?format=json&mime_types=" & filetypes & "&order=RANDOM&limit=1"))
       url = imginfo[0]["url"].getStr()
     else:
-      tmpFile = getCurrentDir() & "/data/pics/unknown_animal.webp"
+      tmpFile = getEnv("ASSETS_PATH") & "/pics/unknown_animal.webp"
 
     if url != "":
       await httpClient.downloadFile(url, tmpFile)
 
-
-    template `sendMessage` (messageExp: untyped): untyped =
-      var message = messageExp
-      message.replyToMessageId = command.message.messageId
-      discard await bot.send(message)
-      removeFile(tmpFile)
-
     if animated:
-      sendMessage(newDocument(command.message.chat.id, "file://" & tmpFile))
+      discard await bot.sendDocument(command.message.chat.id, "file://" & tmpFile, replyToMessageId = command.message.messageId)
     else:
-      sendMessage(newPhoto(command.message.chat.id, "file://" & tmpFile))
+      discard await bot.sendPhoto(command.message.chat.id, "file://" & tmpFile, replyToMessageId = command.message.messageId)
+
+    removeFile(tmpFile)+
\ No newline at end of file
diff --git a/src/cmd/daysuntilcongress.nim b/src/cmd/daysuntilcongress.nim
@@ -1,10 +1,8 @@
 import asyncdispatch, strformat, strutils, times, telebot
 
-proc daysUntilCongressCommand(bot: Telebot, command: Command) {.async.} =
-  let difference                        =   parse("2020-12-26", "yyyy-MM-dd") - now()
-  let days                              =   difference.inDays()
-  let answer                            =   fmt"{days}"
-  var message                           =   newMessage(command.message.chat.id, answer)
-  message.replyToMessageId              =   command.message.messageId
-  message.parseMode                     =   "markdown"
-  discard await bot.send(message)
+proc daysUntilCongressCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
+  let difference = parse("2020-12-26", "yyyy-MM-dd") - now()
+  let days       = difference.inDays()
+  let answer     = fmt"{days}"
+
+  discard await bot.sendMessage(command.message.chat.id, answer, replyToMessageId = command.message.messageId)
diff --git a/src/cmd/debuginfo.nim b/src/cmd/debuginfo.nim
@@ -1,6 +1,6 @@
 import asyncdispatch, telebot, strutils, options, json
 
-proc debuginfoCommand(bot: Telebot, command: Command) {.async.} =
+proc debuginfoCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
   var json = %*{
     "params": command.params,
     "message": {

@@ -23,8 +23,4 @@ proc debuginfoCommand(bot: Telebot, command: Command) {.async.} =
     }
   }
 
-
-  var message = newMessage(command.message.chat.id, "```" & pretty(json) & "```")
-  message.replyToMessageId = command.message.messageId
-  message.parseMode = "markdown"
-  discard await bot.send(message)-
\ No newline at end of file
+  discard await bot.sendMessage(command.message.chat.id, "```" & pretty(json) & "```", replyToMessageId = command.message.messageId, parseMode = "markdown")+
\ No newline at end of file
diff --git a/src/cmd/help.nim b/src/cmd/help.nim
@@ -9,7 +9,7 @@ const COMMANDS = [
   [ "yesorno",            "",           "helps with decisions."                         ],
 ]
 
-proc helpCommand(bot: Telebot, command: Command) {.async.} =
+proc helpCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
   var answer                            =   ""
   if command.params.len() > 0:
     let command                         =   command.params

@@ -34,7 +34,4 @@ proc helpCommand(bot: Telebot, command: Command) {.async.} =
       let description                   =   entry[ 2 ]
       answer                            &=  fmt"{'\n'}/{command} {arguments} – {description}"
 
-  var message                           =   newMessage(command.message.chat.id, answer)
-  message.replyToMessageId              =   command.message.messageId
-  message.parseMode                     =   "markdown"
-  discard await bot.send(message)
+  discard await bot.sendMessage(command.message.chat.id, answer, replyToMessageId = command.message.messageId, parseMode = "markdown")
diff --git a/src/cmd/httpstatuscode.nim b/src/cmd/httpstatuscode.nim
@@ -1,4 +1,4 @@
-import tables
+import asyncdispatch, telebot, httpclient, os, times, tables
 
 const codes = {
   "1xx": ("Informational response", false),

@@ -182,21 +182,19 @@ const codes = {
   "9xx": ("Proprietary Error", false)
 }.toTable
 
-proc httpstatuscodeCommand(bot: Telebot, command: Command) {.async.} =
+proc httpstatuscodeCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
   let code = codes.getOrDefault(command.params, ("I don't know about this status code", false))
   if code[1]: # hazcat
-    var tmpFile = getCurrentDir() & "/data/tmp/" & $(toUnix(getTime())) & ".jpg"
+    discard existsOrCreateDir(getEnv("DATA_PATH") & "/tmp")
+
+    var tmpFile = getEnv("DATA_PATH") & "/tmp/" & $(toUnix(getTime())) & ".jpg"
     var httpClient = newAsyncHttpClient()
     await httpClient.downloadFile("https://http.cat/" & command.params & ".jpg", tmpFile)
 
-    var message = newPhoto(command.message.chat.id, "file://" & tmpFile)
-    message.replyToMessageId = command.message.messageId
-    discard await bot.send(message)
+    discard await bot.sendPhoto(command.message.chat.id, "file://" & tmpFile, replyToMessageId = command.message.messageId)
 
     removeFile(tmpFile)
 
-    discard await bot.send(newMessage(command.message.chat.id, code[0]))
+    discard await bot.sendMessage(command.message.chat.id, code[0])
   else:
-    var message = newMessage(command.message.chat.id, code[0])
-    message.replyToMessageId = command.message.messageId
-    discard await bot.send(message)
+    discard await bot.sendMessage(command.message.chat.id, code[0], replyToMessageId = command.message.messageId)
diff --git a/src/cmd/invitelinks.nim b/src/cmd/invitelinks.nim
@@ -1,26 +0,0 @@
-import asyncdispatch, telebot, strutils, options, os, json
-
-proc invitelinksCommand(bot: Telebot, command: Command) {.async.} =
-  var text = ""
-  var links = ""
-
-  if command.message.chat.kind == "private":
-    let json = parseFile(getCurrentDir() & "/data/invitelinks.json")
-
-    for item in items(json):
-      if not item["allowedUsers"].contains(%command.message.fromUser.get.username.get): continue
-
-      let inviteLink = await bot.exportChatInviteLink(item["chatId"].getStr)
-      links &= item["name"].getStr & ": " & inviteLink & "\n"
-
-    if links != "":
-      text = links
-    else:
-      text = "I have no groups for you, sorry." 
-
-  else:
-    text = "This is not a private chat..."
-
-  var message = newMessage(command.message.chat.id, text)
-  message.replyToMessageId = command.message.messageId
-  discard await bot.send(message)-
\ No newline at end of file
diff --git a/src/cmd/sarcasm.nim b/src/cmd/sarcasm.nim
@@ -1,4 +1,5 @@
-proc sarcasmCommand(bot: Telebot, command: Command) {.async.} =
-  var response = newSticker(command.message.chat.id, "file://" & getCurrentDir() & "/data/pics/sarcasm_sign.webp")
-  response.replyToMessageId = command.message.messageId
-  discard await bot.send(response)
+import asyncdispatch, telebot, os
+
+proc sarcasmCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
+  discard await bot.sendSticker(command.message.chat.id, "file://" & getEnv("ASSETS_PATH") & "/pics/sarcasm_sign.webp", replyToMessageId = command.message.messageId)
+
diff --git a/src/cmd/stats.nim b/src/cmd/stats.nim
@@ -8,12 +8,12 @@ type User = tuple
 proc myCmp(x, y: User): int =
   if x.todayMsgs < y.todayMsgs: -1 else: 1
 
-proc statsCommand(bot: Telebot, command: Command) {.async.} =
-  var filePath = getCurrentDir() & "/data/stats/" & $(command.message.chat.id) & ".json"
+proc statsCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
+  var filePath = getEnv("DATA_PATH") & "/stats/" & $(command.message.chat.id) & ".json"
   var text     = ""
 
   if command.params == "nsfw":
-    filePath = getCurrentDir() & "/data/stats/penis/" & $(command.message.chat.id) & ".json"
+    filePath = getEnv("DATA_PATH") & "/stats/penis/" & $(command.message.chat.id) & ".json"
 
   if not fileExists(filePath):
     text = "No statistics yet."

@@ -43,18 +43,16 @@ proc statsCommand(bot: Telebot, command: Command) {.async.} =
     text &= "total sent: " & $(data["messagesCount"]["total"]) & "\n"
 
 
-  var message = newMessage(command.message.chat.id, text)
-  message.replyToMessageId = command.message.messageId
-  discard await bot.send(message)
+  discard await bot.sendMessage(command.message.chat.id, text, replyToMessageId = command.message.messageId)
 
-proc statsHandler(message: Message, penis: bool) {.async.} =
+proc statsHandler* (message: Message, penis: bool) {.async.} =
   let user     = message.fromUser.get
-  var filePath = getCurrentDir() & "/data/stats/" & $(message.chat.id) & ".json"
+  var filePath = getEnv("DATA_PATH") & "/stats/" & $(message.chat.id) & ".json"
 
   if penis:
-    discard existsOrCreateDir(getCurrentDir() & "/data/stats/penis")
+    discard existsOrCreateDir(getEnv("DATA_PATH") & "/stats/penis")
 
-    filePath = getCurrentDir() & "/data/stats/penis/" & $(message.chat.id) & ".json"
+    filePath = getEnv("DATA_PATH") & "/stats/penis/" & $(message.chat.id) & ".json"
 
   var data = %* {
     "lastReset": getDateStr(now()),
diff --git a/src/cmd/unixtime.nim b/src/cmd/unixtime.nim
@@ -1,7 +1,4 @@
 import asyncdispatch, telebot, strutils, times
 
-proc unixtimeCommand(bot: Telebot, command: Command) {.async.} =
-  var message = newMessage(command.message.chat.id, "```" & $(toUnix(getTime())) & "```")
-  message.replyToMessageId = command.message.messageId
-  message.parseMode = "markdown"
-  discard await bot.send(message)-
\ No newline at end of file
+proc unixtimeCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
+  discard await bot.sendMessage(command.message.chat.id, "```" & $(toUnix(getTime())) & "```", replyToMessageId = command.message.messageId, parseMode = "markdown")
diff --git a/src/cmd/uptime.nim b/src/cmd/uptime.nim
@@ -1,8 +1,5 @@
 import asyncdispatch, telebot, strutils, osproc
 
-proc uptimeCommand(bot: Telebot, command: Command) {.async.} =
+proc uptimeCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
   let uptime = execProcess("uptime", options={poUsePath})
-  var message = newMessage(command.message.chat.id, "```" & uptime & "```")
-  message.replyToMessageId = command.message.messageId
-  message.parseMode = "markdown"
-  discard await bot.send(message)-
\ No newline at end of file
+  discard await bot.sendMessage(command.message.chat.id, "```" & uptime & "```", replyToMessageId = command.message.messageId, parseMode = "markdown")+
\ No newline at end of file
diff --git a/src/cmd/utc.nim b/src/cmd/utc.nim
@@ -1,8 +1,5 @@
 import asyncdispatch, telebot, strutils, times 
-proc utcCommand(bot: Telebot, command: Command) {.async.} =
-  let time = now().utc
-  
-  var message = newMessage(command.message.chat.id, time.format("dd'.'MM'.'yyyy' 'HH':'mm"))
-  message.replyToMessageId = command.message.messageId
-  message.parseMode = "markdown"
-  discard await bot.send(message)-
\ No newline at end of file
+
+proc utcCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
+  let time = now().utc 
+  discard await bot.sendMessage(command.message.chat.id, time.format("dd'.'MM'.'yyyy' 'HH':'mm"), replyToMessageId = command.message.messageId, parseMode = "markdown")+
\ No newline at end of file
diff --git a/src/cmd/whoami.nim b/src/cmd/whoami.nim
@@ -1,6 +1,6 @@
 import asyncdispatch, telebot, strutils, options
 
-proc whoamiCommand(bot: Telebot, command: Command) {.async.} =
+proc whoamiCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
   var text = "who are you?"
 
   let user = command.message.fromUser.get

@@ -8,7 +8,4 @@ proc whoamiCommand(bot: Telebot, command: Command) {.async.} =
   if user.username.isSome():
     text = "you are @" & user.username.get & ", nice to meet you!"
 
-  var message = newMessage(command.message.chat.id, text)
-  message.replyToMessageId = command.message.messageId
-  message.parseMode = "markdown"
-  discard await bot.send(message)-
\ No newline at end of file
+  discard await bot.sendMessage(command.message.chat.id, text, replyToMessageId = command.message.messageId, parseMode = "markdown")+
\ No newline at end of file
diff --git a/src/cmd/yesorno.nim b/src/cmd/yesorno.nim
@@ -1,6 +1,6 @@
 import asyncdispatch, telebot, strutils, random
 
-proc yesornoCommand(bot: Telebot, command: Command) {.async.} =
+proc yesornoCommand* (bot: Telebot, command: Command): Future[bool] {.async.} =
   let random = rand(-8..8)
   let maybe  = ["maybe", "dunno", "perhabs", "…", "idk", "I have no idea", "mrew", "mew", "meow", "use TOR, use Signal"]
 

@@ -15,7 +15,4 @@ proc yesornoCommand(bot: Telebot, command: Command) {.async.} =
 
     answer = maybe[num]
   
-  var message = newMessage(command.message.chat.id, answer)
-  message.replyToMessageId = command.message.messageId
-  message.parseMode = "markdown"
-  discard await bot.send(message)
+  discard await bot.sendMessage(command.message.chat.id, answer, replyToMessageId = command.message.messageId, parseMode = "markdown")
diff --git a/src/ctucxbot.nim b/src/ctucxbot.nim
@@ -1,109 +1,50 @@
-import asyncdispatch, telebot, options, strutils, random, os, re, unicode
-include cmd/[animalpics, daysuntilcongress, debuginfo, help, stats, unixtime, utc, uptime, yesorno, whoami, invitelinks, sarcasm, httpstatuscode]
+import asyncdispatch, telebot, posix, os 
+include updateHandler
+import cmd/[animalpics, daysuntilcongress, debuginfo, help, stats, unixtime, utc, uptime, yesorno, whoami, sarcasm, httpstatuscode]
 
-#init rng
-randomize()
-
-proc ctrlcHandler() {.noconv.} =
+proc CtrlCHook() {.noconv.} =
+  echo "Ctrl+C fired! \nStopping bot now!"
   quit()
 
-proc updateHandler(bot: Telebot, update: Update) {.async.} =
-  if not update.message.isNone:
-    var message = update.message.get
-    discard statsHandler(message, false)
-
-    if message.text.isSome:
-      let text = message.text.get
-
-      let lewdAnswers = [
-        "Höhö! Penis!",
-        "Schwaaaaaanz!",
-        "Gihihihi, Pimmel!",
-        "Höhö, Döödel!",
-        "Glied",
-        "8===D",
-      ]
-
-      let meowAnswers = [
-        "meow USER!",
-        "Meow USER!",
-        "Mew USER!",
-        "mew USER!",
-        "meow USER",
-        "Meow USER",
-        "Mew USER",
-        "mew USER",
-        "mreow USER!",
-        "Mreow USER!",
-        "Mrew USER!",
-        "mrew USER!",
-        "mreow USER",
-        "Mreow USER",
-        "Mrew USER",
-        "mrew USER",
-      ]
-
-      let penisCount = text.normalize.count("penis")
-
-      # if much penis send a pic
-      if penisCount > 4:
-        discard statsHandler(message, true)
-
-        var response = newPhoto(message.chat.id, "file://" & getCurrentDir() & "/data/pics/penis.jpg")
-        response.replyToMessageId = message.messageId
-        discard await bot.send(response)
-
-      #if not so much penis send a random lewd message
-      elif penisCount > 0:
-        discard statsHandler(message, true)
-
-        var response = newMessage(message.chat.id, sample(lewdAnswers))
-        response.replyToMessageId = message.messageId
-        discard await bot.send(response)
-
-      #if sinep send a random dwel string
-      elif text.normalize.contains("sinep"):
-        var response = newMessage(message.chat.id, reversed(sample(lewdAnswers)))
-        response.replyToMessageId = message.messageId
-        discard await bot.send(response)
-
-      #if text is "egg_irl" send a real egg!
-      elif text == "egg_irl":
-        var response = newPhoto(message.chat.id, "file://" & getCurrentDir() & "/data/pics/egg.jpg")
-        response.replyToMessageId = message.messageId
-        discard await bot.send(response)
-
-      #meow back at people with a 20% chance
-      if (rand(100) < 20 or message.chat.kind == "private") and text.contains(re(r"^mr*(a+u+|e*[eo]o*w+)!*$", {reIgnoreCase})):
-        var response = newMessage(message.chat.id, sample(meowAnswers).replace("USER", message.fromUser.get.firstName))
-        response.replyToMessageId = message.messageId
-        discard await bot.send(response)
-
-setControlCHook(ctrlcHandler)
-
-if getEnv("API_KEY") != "":
-  let bot = newTeleBot(getEnv("API_KEY"))
-
-  bot.onUpdate(updateHandler)
-  bot.onCommand("daysuntilcongress", daysUntilCongressCommand)
-  bot.onCommand("fox", animalCommand(fox, false))
-  bot.onCommand("penguin", animalCommand(penguin, false))
-  bot.onCommand("dog", animalCommand(dog, false))
-  bot.onCommand("doggo", animalCommand(dog, false))
-  bot.onCommand("debuginfo", debuginfoCommand)
-  bot.onCommand("cat", animalCommand(cat, false))
-  bot.onCommand("catgif", animalCommand(cat, true))
-  bot.onCommand("help", helpCommand)
-  bot.onCommand("stats", statsCommand)
-  bot.onCommand("unixtime", unixtimeCommand)
-  bot.onCommand("utc", utcCommand)
-  bot.onCommand("uptime", uptimeCommand)
-  bot.onCommand("yesorno", yesornoCommand)
-  bot.onCommand("whoami", whoamiCommand)
-  bot.onCommand("invitelinks", invitelinksCommand)
-  bot.onCommand("s", sarcasmCommand)
-  bot.onCommand("httpstatuscode", httpstatuscodeCommand)
-  bot.poll(timeout=300)
-
-else:
-  echo "No API_KEY given!"
+proc main =  # for gcsafe
+  setControlCHook(CtrlCHook)
+
+  onSignal(SIGTERM):
+    echo "Got SIGTERM! \nStopping bot now!"
+    quit()
+
+  if getEnv("DATA_PATH") == "":
+    echo "DATA_PATH not set."
+    quit()
+
+  if getEnv("ASSETS_PATH") == "":
+    echo "ASSETS_PATH not set."
+    quit()
+
+  if getEnv("API_KEY") != "":
+    let bot = newTeleBot(getEnv("API_KEY"))
+
+    bot.onUpdate(updateHandler)
+    bot.onCommand("daysuntilcongress", daysUntilCongressCommand)
+    bot.onCommand("fox", animalCommand(fox, false))
+    bot.onCommand("penguin", animalCommand(penguin, false))
+    bot.onCommand("dog", animalCommand(dog, false))
+    bot.onCommand("doggo", animalCommand(dog, false))
+    bot.onCommand("debuginfo", debuginfoCommand)
+    bot.onCommand("cat", animalCommand(cat, false))
+    bot.onCommand("catgif", animalCommand(cat, true))
+    bot.onCommand("help", helpCommand)
+    bot.onCommand("stats", statsCommand)
+    bot.onCommand("unixtime", unixtimeCommand)
+    bot.onCommand("utc", utcCommand)
+    bot.onCommand("uptime", uptimeCommand)
+    bot.onCommand("yesorno", yesornoCommand)
+    bot.onCommand("whoami", whoamiCommand)
+    bot.onCommand("s", sarcasmCommand)
+    bot.onCommand("httpstatuscode", httpstatuscodeCommand)
+    bot.poll(timeout=300)
+
+  else:
+    echo "No API_KEY given!"
+
+main()+
\ No newline at end of file
diff --git a/src/updateHandler.nim b/src/updateHandler.nim
@@ -0,0 +1,65 @@
+import asyncdispatch, telebot, options, strutils, random, re, unicode, os 
+import cmd/stats
+
+randomize()
+
+proc updateHandler* (bot: Telebot, update: Update): Future[bool] {.async.} =
+  if not update.message.isNone:
+    var message = update.message.get
+    discard statsHandler(message, false)
+
+    if message.text.isSome:
+      let text = message.text.get
+
+      let lewdAnswers = [
+        "Höhö! Penis!",
+        "Schwaaaaaanz!",
+        "Gihihihi, Pimmel!",
+        "Höhö, Döödel!",
+        "Glied",
+        "8===D",
+      ]
+
+      let meowAnswers = [
+        "meow USER!",
+        "Meow USER!",
+        "Mew USER!",
+        "mew USER!",
+        "meow USER",
+        "Meow USER",
+        "Mew USER",
+        "mew USER",
+        "mreow USER!",
+        "Mreow USER!",
+        "Mrew USER!",
+        "mrew USER!",
+        "mreow USER",
+        "Mreow USER",
+        "Mrew USER",
+        "mrew USER",
+      ]
+
+      let penisCount = text.normalize.count("penis")
+
+      # if much penis send a pic
+      if penisCount > 4:
+        discard statsHandler(message, true)
+        discard await bot.sendPhoto(message.chat.id, "file://" & getEnv("ASSETS_PATH") & "/pics/penis.jpg", replyToMessageId = message.messageId)
+
+      #if not so much penis send a random lewd message
+      elif penisCount > 0:
+        discard statsHandler(message, true)
+        discard await bot.sendMessage(message.chat.id, sample(lewdAnswers), replyToMessageId = message.messageId)
+
+      #if sinep send a random dwel string
+      elif text.normalize.contains("sinep"):
+        discard await bot.sendMessage(message.chat.id, reversed(sample(lewdAnswers)), replyToMessageId = message.messageId)
+
+      #if text is "egg_irl" send a real egg!
+      elif text == "egg_irl":
+        discard await bot.sendPhoto(message.chat.id, "file://" & getEnv("ASSETS_PATH") & "/pics/egg.jpg", replyToMessageId = message.messageId)
+
+      #meow back at people with a 20% chance
+      if (rand(100) < 20 or message.chat.kind == "private") and text.contains(re(r"^mr*(a+u+|e*[eo]o*w+)!*$", {reIgnoreCase})):
+        discard await bot.sendMessage(message.chat.id, sample(meowAnswers).replace("USER", message.fromUser.get.firstName), replyToMessageId = message.messageId)
+