2022-04-09 17:45:02 +00:00
import telebot
2022-04-10 17:54:48 +00:00
import std / [ asyncdispatch , logging , options , strutils , random , with , os , tables , times , sequtils ]
2022-04-09 17:45:02 +00:00
import norm / [ model , sqlite ]
2022-04-07 17:41:36 +00:00
2022-04-11 04:14:57 +00:00
var L = newConsoleLogger ( fmtStr = " $levelname , [ $time ] " )
addHandler ( L )
2022-04-07 17:41:36 +00:00
type
2022-04-09 15:18:41 +00:00
CensoredData * = ref object of Model
2022-04-07 17:41:36 +00:00
ftype * : string
2022-04-09 14:30:05 +00:00
fhash * : string
2022-04-07 17:41:36 +00:00
fileid * : string
2022-04-11 04:06:04 +00:00
time * : float
2022-04-07 17:41:36 +00:00
caption * : string
2022-04-09 17:45:02 +00:00
type
BannedUsers * = ref object of Model
2022-04-10 17:54:48 +00:00
userid * : int64
bantime * : float
bantype * : string
var RateLimiter = initTable [ int64 , seq [ float ] ] ( )
2022-04-11 02:46:47 +00:00
var GroupMedia = initTable [ int , string ] ( )
2022-04-10 17:54:48 +00:00
let AdminID = getEnv ( " ADMIN_ID " ) . split ( " , " )
2022-04-09 17:45:02 +00:00
2022-04-11 04:14:57 +00:00
let dbConn * = getDb ( )
2022-04-09 15:18:41 +00:00
func NewCensoredData * ( ftype = " " ; fhash = " " ; fileid = " " ; caption = " " ) :
CensoredData = CensoredData ( ftype : ftype , fhash : fhash , fileid : fileid , caption : caption )
2022-04-07 17:41:36 +00:00
2022-04-10 17:54:48 +00:00
func NewBannedUsers * ( userid = int64 ( 0 ) , bantime = 0 .0 , bantype = " " ) :
BannedUsers = BannedUsers ( userid : userid , bantime : bantime , bantype : bantype )
2022-04-09 17:45:02 +00:00
2022-04-11 04:14:57 +00:00
dbConn . createTables ( NewCensoredData ( ) )
dbConn . createTables ( NewBannedUsers ( ) )
2022-04-07 17:41:36 +00:00
2022-04-10 17:54:48 +00:00
proc ManageRateLimit ( ) : void =
for i in RateLimiter . keys ( ) . toSeq ( ) :
if RateLimiter [ i ] [ ^ 1 ] - RateLimiter [ i ] [ 0 ] > = 60 :
RateLimiter . del ( i )
elif len ( RateLimiter [ i ] ) > = 20 :
var BannedUser = NewBannedUsers ( i , epochTime ( ) , " auto " )
RateLimiter . del ( i )
with dbConn :
insert BannedUser
if dbConn . exists ( BannedUsers , " bantype = ? and ? - bantime >= 1800 " , " auto " , epochTime ( ) ) :
var TempData = @ [ NewBannedUsers ( ) ]
dbConn . select ( TempData , " bantype = ? and ? - bantime >= 1800 " , " auto " , epochTime ( ) )
for i in TempData :
var e = i
dbConn . delete ( e )
2022-04-11 04:14:57 +00:00
proc OldDataCleanup ( ) : void =
if dbConn . exists ( CensoredData , " ? - time >= 15780000 " , epochTime ( ) ) :
var TempData = @ [ NewCensoredData ( ) ]
dbConn . select ( TempData , " ? - time >= 15780000 " , epochTime ( ) )
for i in TempData :
var e = i
dbConn . delete ( e )
2022-04-07 10:51:02 +00:00
2022-04-07 11:45:56 +00:00
proc generate_hash ( ) : string =
result = newString ( 7 )
const charset = { ' a ' .. ' z ' , ' A ' .. ' Z ' , ' 0 ' .. ' 9 ' }
for i in 0 .. 6 :
result [ i ] = sample ( charset )
return result
2022-04-09 14:26:17 +00:00
proc updateHandler ( b : Telebot , u : Update ) : Future [ bool ] {. async , gcsafe . } =
2022-04-09 15:41:01 +00:00
let response = u . message . get
2022-04-10 17:54:48 +00:00
ManageRateLimit ( )
2022-04-09 17:45:02 +00:00
if not dbConn . exists ( BannedUsers , " userid = ? " , response . chat . id ) :
2022-04-10 17:54:48 +00:00
if RateLimiter . contains ( response . chat . id ) :
RateLimiter [ response . chat . id ] . insert ( epochTime ( ) )
else :
RateLimiter [ response . chat . id ] = @ [ epochTime ( ) ]
2022-04-09 17:45:02 +00:00
if response . text . isSome :
let message = response . text . get
if message = = " /start " :
discard await b . sendMessage ( response . chat . id , " Hey, To create a censored post, you can share any album, video, photo, gif, sticker, etc. The messages could then be forwarded to any chat for them to view " )
elif message . contains ( " /ban " ) :
2022-04-10 18:00:15 +00:00
if $ response . chat . id in AdminID :
let user = message . split ( " " )
var BannedUser = NewBannedUsers ( int64 ( parseInt ( user [ 1 ] ) ) , epochTime ( ) , " permanent " )
with dbConn :
insert BannedUser
discard await b . sendMessage ( response . chat . id , " Banned! " )
2022-04-09 17:45:02 +00:00
elif message . contains ( " /start " ) :
let deeplink = message . split ( " " )
2022-04-09 17:48:48 +00:00
if not dbConn . exists ( CensoredData , " fhash = ? " , deeplink [ 1 ] ) :
discard await b . sendMessage ( response . chat . id , " Media does not exist on database, ask the sender to censor this again! " )
else :
var TempData = @ [ NewCensoredData ( ) ]
dbConn . select ( TempData , " fhash = ? " , deeplink [ 1 ] )
2022-04-11 02:46:47 +00:00
if len ( TempData ) > 1 :
var inputmedia = newSeq [ InputMediaPhoto ] ( )
for i in TempData :
if i . caption ! = " " :
inputmedia . insert ( InputMediaPhoto ( kind : i . ftype , media : i . fileid , caption : some ( i . caption ) ) )
else :
inputmedia . insert ( InputMediaPhoto ( kind : i . ftype , media : i . fileid ) )
discard await b . sendMediaGroup ( $ response . chat . id , media = inputmedia )
else :
if TempData [ 0 ] . ftype = = " photo " :
discard await b . sendPhoto ( response . chat . id , TempData [ 0 ] . fileid , TempData [ 0 ] . caption )
elif TempData [ 0 ] . ftype = = " document " :
discard await b . sendDocument ( response . chat . id , TempData [ 0 ] . fileid , TempData [ 0 ] . caption )
elif TempData [ 0 ] . ftype = = " video " :
discard await b . sendVideo ( response . chat . id , TempData [ 0 ] . fileid , caption = TempData [ 0 ] . caption )
elif TempData [ 0 ] . ftype = = " videoNote " :
discard await b . sendVideoNote ( response . chat . id , TempData [ 0 ] . fileid )
elif TempData [ 0 ] . ftype = = " animation " :
discard await b . sendAnimation ( response . chat . id , TempData [ 0 ] . fileid , caption = TempData [ 0 ] . caption )
elif TempData [ 0 ] . ftype = = " sticker " :
discard await b . sendSticker ( response . chat . id , TempData [ 0 ] . fileid )
2022-04-09 17:45:02 +00:00
else :
var fileid = " "
var ftype = " "
var fcaption = " "
if response . caption . isSome :
fcaption = response . caption . get
if response . document . isSome :
fileid = response . document . get . fileId
ftype = " document "
elif response . video . isSome :
fileid = response . video . get . fileId
ftype = " video "
elif response . videoNote . isSome :
fileid = response . videoNote . get . fileId
2022-04-11 02:46:47 +00:00
ftype = " videoNote "
2022-04-09 17:45:02 +00:00
elif response . animation . isSome :
fileid = response . animation . get . fileId
ftype = " animation "
elif response . photo . isSome :
fileid = response . photo . get [ 0 ] . fileId
ftype = " photo "
elif response . sticker . isSome :
fileid = response . sticker . get . fileId
ftype = " sticker "
2022-04-11 02:46:47 +00:00
if response . mediaGroupId . isSome :
if parseInt ( response . mediaGroupId . get ) notin GroupMedia . keys ( ) . toSeq ( ) :
let filehash = generate_hash ( )
GroupMedia [ parseInt ( response . mediaGroupId . get ) ] = filehash
var CensoredRow = NewCensoredData ( ftype , filehash , fileid , fcaption )
with dbConn :
insert CensoredRow
discard await b . sendMessage ( response . chat . id , " Censored --> " & " tg://resolve?domain=botbotbotnotabot&start= " & filehash )
else :
let filehash = GroupMedia [ parseInt ( response . mediaGroupId . get ) ]
var CensoredRow = NewCensoredData ( ftype , filehash , fileid , fcaption )
with dbConn :
insert CensoredRow
else :
let filehash = generate_hash ( )
var CensoredRow = NewCensoredData ( ftype , filehash , fileid , fcaption )
with dbConn :
insert CensoredRow
discard await b . sendMessage ( response . chat . id , " Censored --> " & " tg://resolve?domain=botbotbotnotabot&start= " & filehash )
2022-04-11 04:14:57 +00:00
OldDataCleanup ( )
2022-04-07 10:51:02 +00:00
2022-04-10 17:54:48 +00:00
let bot = newTeleBot ( getEnv ( " TELEGRAM_TOKEN " ) )
2022-04-07 10:51:02 +00:00
bot . onUpdate ( updateHandler )
bot . poll ( timeout = 300 )