├── .gitignore ├── Dockerfile ├── README.md ├── audio ├── billy.mp3 ├── depression-dharwish.mp3 ├── elixir.mpeg └── wow.mp3 ├── data.toml ├── docker-compose.yml ├── main.py ├── requirements.txt └── stickers ├── frand.webp ├── gkr.webp └── levi.webp /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .deta/ 3 | Pipfile 4 | *.lock 5 | venv/ -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Python runtime as a parent image 2 | FROM python:3.10-slim 3 | 4 | # Set environment variables to ensure Python output is set straight to the terminal 5 | # and disable buffering for easier debugging 6 | ENV PYTHONUNBUFFERED=1 7 | 8 | # Create and set the working directory inside the container 9 | WORKDIR /app 10 | 11 | # Copy the requirements.txt into the container at /app 12 | COPY requirements.txt /app/ 13 | 14 | # Install dependencies from requirements.txt 15 | RUN pip install --no-cache-dir -r requirements.txt 16 | 17 | # Copy the current directory contents into the container at /app 18 | COPY . /app/ 19 | 20 | # Expose the port that FastAPI will run on 21 | EXPOSE 8000 22 | 23 | # Command to run the FastAPI app using uvicorn, and set the host to 0.0.0.0 24 | # to make the app accessible from outside the container 25 | CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SPAM Bot 2 | 3 | This is a telegram bot built for handling SPAM. Made with Python and :sparkles: 4 | 5 | ## Setting it Up 6 | 7 | - Python 8 | - Pip 9 | - To install the deps, run `pip install -r requirements.txt` 10 | - The Bot relies on Deta.sh for the DB and Hosting side and Telegram Webhooks for the Command Receiving side. 11 | 12 | > You can totally omit the deta side if you don't want to work on the DB 13 | 14 | -------------------------------------------------------------------------------- /audio/billy.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/athul/spam-bot/438ed3e1ec2982537a2a09d2c95d033069b3fcd7/audio/billy.mp3 -------------------------------------------------------------------------------- /audio/depression-dharwish.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/athul/spam-bot/438ed3e1ec2982537a2a09d2c95d033069b3fcd7/audio/depression-dharwish.mp3 -------------------------------------------------------------------------------- /audio/elixir.mpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/athul/spam-bot/438ed3e1ec2982537a2a09d2c95d033069b3fcd7/audio/elixir.mpeg -------------------------------------------------------------------------------- /audio/wow.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/athul/spam-bot/438ed3e1ec2982537a2a09d2c95d033069b3fcd7/audio/wow.mp3 -------------------------------------------------------------------------------- /data.toml: -------------------------------------------------------------------------------- 1 | [messages] 2 | [messages.one_liners] 3 | # Add those cheeky or shitty one liners here. 4 | # Command name = Oneliner enna format 5 | pai = "Hai Friends 👋" 6 | kween = "അലവലാതി" 7 | abru = "ഞാൻ നന്നായി guis" 8 | githuboli = "എന്നാ ഉണ്" 9 | subin = "എന്താടാ മൈരേ" 10 | ayin = "Ayin poyi oomfanam mister" 11 | pewer = "⚡️" 12 | s = "Athu Sarcasm aarunnu ketto" 13 | pp = "Hehe" 14 | beepathu = "phaa kelava" 15 | 16 | 17 | [messages.reply_only_one_liners] 18 | # Same but for replies and Subin calling everyone else a myren 19 | qt = "**Condom** related കാര്യങ്ങൾക്കു SPAthan എന്ന സ്വയംപ്രഖ്യാപിത \n **Condom Boi (@thetronjohnson)** ne vilikkuka" 20 | tq = "നന്ദി ഉണ്ട് മൈരേ...😍 You're Awesome ❤️" 21 | lol = "എടാ mwonuse അത് കിടു വിറ്റാരുന്നു കേട്ടോ. കില്ലാടി തന്നെ\npoli...\nkidu...\nമ്യാരകം തന്നെ" 22 | 23 | [messages.stickers] 24 | # Parayendallo, stickers varanamenkil enik sticker ayachthannam 25 | gawd = "stickers/levi.webp" 26 | 27 | [messages.messages_with_stickers] 28 | # The OG GKR stuff with that wonderful chiri 29 | gkr = ["എല്ലാവിധ Premium Accountukalkum GKR'ne സമീപിക്കുക", "stickers/gkr.webp"] 30 | 31 | [messages.audio] 32 | # Audio Files inte path 33 | wow = "audio/wow.mp3" 34 | dharwish = "audio/dharwish.mp3" 35 | billy = "audio/billy-mon.mp3" 36 | elixir = "audio/elixir.mpeg" 37 | 38 | [constant] 39 | help = """ 40 | Ammavan is here to help my pillers. Commands chuvade kodukkunnu 41 | 42 | - /re - for re vilikkaling. Aareya re vilikkunnath enn koodi parayanam ketto 43 | - /pai - for invoking Pai's signature message 44 | - /kween - for replying to a message in kween's own language 45 | - /abru - He's a good boi now 46 | - /githuboli - IDK who put this shit here 47 | - /gkr - Premium uyir bakkiyellam mayir. GKR inte sticker free aane 48 | - /qt - You have called upon the catastrophic don, Kadayadi Baby err Quantum Kiran 49 | - /gawd - I see no other gawd other than me memefied 50 | - /wow - Eda kunje adipoli 51 | - /hbd - cliche bday wishes aan ente main 52 | - /tq - nanni maathram ❤️😘 53 | - /pewer - Pewer varatte 54 | - /ayn - Ayin nammal ippo entha cheyya 55 | - /s - Ath oru vittarunnu ketto 56 | - /subin - Kunnamkulam king ningale avisambodhana cheyyunath aayirikkum 57 | - /pp - The way MG Sreekumar Laughs 58 | - /lol - Kidu vittaanallo mwonuse 59 | - /dharwish - Depression veno ninakk? 60 | - /billy - Eternal Laughter of the Billymon Mind 61 | - /elixir - Nee Ethavanaada...? 62 | - Hai paranjal siddhu varum 🙈 63 | 64 | Chilath okke reply il work cheyyunnath aan, ethaanenn enik ormayilla""" 65 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | fastapi-app: 5 | build: . 6 | container_name: fastapi-container 7 | ports: 8 | - "8000:8000" # Expose FastAPI app on port 8000 9 | environment: 10 | - TOKEN=${TOKEN} # Example of a database URL (could be for local DB or other) 11 | - SPAM=${SPAM} # Sensitive secret key for FastAPI 12 | volumes: 13 | - .:/app # Mount current directory to /app inside the container (useful for dev) 14 | env_file: 15 | - .env # Load environment variables from the .env file into the container 16 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI, Request 2 | from telegram.ext import Dispatcher, CommandHandler, CallbackContext, MessageHandler 3 | from telegram import Update, Bot 4 | from deta import Deta 5 | import os 6 | import toml 7 | from functools import partial as __ 8 | 9 | from telegram.ext.filters import Filters 10 | 11 | 12 | TOKEN: str = os.getenv("TOKEN") 13 | SPAM: str = os.getenv("SPAM") 14 | 15 | 16 | def clean_res(message, re: bool = True) -> str: 17 | if "@" in message: 18 | username = message.split()[1].replace("@", "") 19 | if username != "spam_re_mon_bot": 20 | return ( 21 | f"@{username} kutta, aa post Re aarunnu ketto".replace( 22 | "_", "\_") 23 | if re 24 | else username.replace("_", "\_") 25 | ) 26 | else: 27 | return "ഉവ്വ, നീ എനിക്കിട്ട് തന്നെ അടി " 28 | else: 29 | return "Username thaado" 30 | 31 | 32 | def handle_re(bot: Update, _: CallbackContext): 33 | message = bot.message.text 34 | res = clean_res(message) 35 | bot.message.reply_markdown_v2(res) 36 | 37 | 38 | def handle_one_liner(upd: Update, _: CallbackContext, message: str): 39 | """ 40 | Handles One Liners 41 | 42 | Params 43 | ----- 44 | message: str 45 | Takes in the message string from the TOML file specified within one_liners 46 | """ 47 | try: 48 | upd.message.reply_text( 49 | message.replace(".", "\."), 50 | reply_to_message_id=upd.message.reply_to_message.message_id, 51 | ) 52 | print(f"Onliner Sent for {message}") 53 | return 54 | except: 55 | upd.message.reply_text(message) 56 | 57 | 58 | def handle_sticker_only_messages(upd: Update, _: CallbackContext, sticker: str): 59 | """ 60 | Handles sticker only messages. 61 | 62 | Params 63 | ----- 64 | sticker: str 65 | Takes in the path to where the sticker is stored. The path will be specified in the TOML file 66 | """ 67 | try: 68 | upd.message.reply_sticker( 69 | open(sticker, "rb").read(), 70 | reply_to_message_id=upd.message.reply_to_message.message_id, 71 | ) 72 | print(f"Sticker Sent for {sticker}") 73 | except: 74 | upd.message.reply_sticker(open(sticker, "rb").read()) 75 | 76 | 77 | def handle_reply_only_onliner(upd: Update, _: CallbackContext, message: str): 78 | """ 79 | Handles reply only commands 80 | 81 | Params 82 | ----- 83 | message: str 84 | Takes in the Message string from TOML file 85 | """ 86 | try: 87 | upd.message.reply_markdown_v2( 88 | message.replace(".", "\.").replace("(", "\(").replace(")", "\)"), 89 | reply_to_message_id=upd.message.reply_to_message.message_id, 90 | ) 91 | print(f"Reply Sent with {message}") 92 | except Exception as e: 93 | print(e) 94 | 95 | 96 | def handle_messages_with_stickers( 97 | upd: Update, _: CallbackContext, message: str, sticker: str 98 | ): 99 | """ 100 | Handles commands which sends stickers and messages. 101 | 102 | Params 103 | ----- 104 | message: str 105 | Takes in the Message string from TOML file 106 | sticker: str 107 | Takes in the path to sticker from TOML file 108 | """ 109 | try: 110 | upd.message.reply_text(message) 111 | upd.message.reply_sticker(open(sticker, "rb").read()) 112 | print(f"Message and Sticker Sent for {message} and {sticker}") 113 | except Exception as e: 114 | print(e) 115 | 116 | 117 | def handle_audio(upd: Update, _: CallbackContext, audio: str): 118 | """ 119 | Handles Audio Commands 120 | 121 | Params 122 | ------ 123 | audio: str 124 | The Path to the audio file 125 | """ 126 | upd.message.reply_audio( 127 | open(audio, "rb").read(), 128 | reply_to_message_id=upd.message.reply_to_message.message_id, 129 | ) 130 | 131 | def handle_hbd(upd: Update, _: CallbackContext): 132 | uname = clean_res(upd.message.text, False) 133 | if "Uvva" in uname: 134 | message = uname 135 | elif "User" in uname: 136 | message = uname 137 | else: 138 | message = f"@{uname} in സ്പാം കുടുംബത്തിന്റെ എല്ലാവിധ ജന്മദിനാശംസകൾ... അടിച്ചു പോളിയ്ക്ക്" 139 | 140 | upd.message.reply_text(message) 141 | if uname != message: 142 | upd.message.reply_animation(open("stickers/hbd.gif", "rb").read()) 143 | 144 | 145 | def toss_idu(upd: Update, _: CallbackContext): 146 | upd.message.reply_dice() 147 | 148 | 149 | def respond_with_frande(upd: Update, _: CallbackContext): 150 | """ 151 | Checks for the specified strings in the `words` list 152 | If present sends a sticker 153 | """ 154 | txt: str = (upd.message.text).lower().split() 155 | is_bot: bool = upd.message.from_user.is_bot 156 | words = ["hi", "hello", "hai", "halo", "hella", "hallo"] 157 | if not is_bot and any(x in txt for x in words): 158 | try: 159 | upd.message.reply_sticker( 160 | open("stickers/frand.webp", "rb").read(), 161 | reply_to_message_id=upd.message.reply_to_message.message_id, 162 | ) 163 | except: 164 | upd.message.reply_sticker(open("stickers/frand.webp", "rb").read()) 165 | 166 | 167 | def handle_help(upd: Update, _: CallbackContext, message: str): 168 | """ 169 | Handles the Help text 170 | 171 | Params 172 | ------ 173 | message:str 174 | Takes in the help text defined in the TOML file. 175 | """ 176 | upd.message.reply_markdown_v2( 177 | message.replace("-", "\-").replace("/", "\/").replace(".", "\.") 178 | ) 179 | 180 | 181 | data = toml.load("data.toml") 182 | 183 | 184 | def get_dispatcher(): 185 | bot = Bot(TOKEN) 186 | dp = Dispatcher(bot=bot, update_queue=None, use_context=True) 187 | for key, value in data["messages"]["one_liners"].items(): 188 | dp.add_handler(CommandHandler( 189 | key, __(handle_one_liner, message=value))) 190 | 191 | for key, value in data["messages"]["reply_only_one_liners"].items(): 192 | dp.add_handler( 193 | CommandHandler(key, __(handle_reply_only_onliner, message=value)) 194 | ) 195 | 196 | for key, value in data["messages"]["stickers"].items(): 197 | dp.add_handler( 198 | CommandHandler( 199 | key, __(handle_sticker_only_messages, sticker=value)) 200 | ) 201 | 202 | for key, value in data["messages"]["messages_with_stickers"].items(): 203 | dp.add_handler( 204 | CommandHandler( 205 | key, 206 | __(handle_messages_with_stickers, 207 | message=value[0], sticker=value[1]), 208 | ) 209 | ) 210 | for key, value in data["messages"]["audio"].items(): 211 | dp.add_handler( 212 | CommandHandler( 213 | key, 214 | __(handle_audio,audio=value), 215 | ) 216 | ) 217 | dp.add_handler(CommandHandler("re", handle_re)) 218 | dp.add_handler(CommandHandler("hbd", handle_hbd)) 219 | dp.add_handler(CommandHandler("dice", toss_idu)) 220 | dp.add_handler( 221 | CommandHandler("help", __( 222 | handle_help, message=data["constant"]["help"])) 223 | ) 224 | dp.add_handler(MessageHandler(Filters.text, respond_with_frande)) 225 | return dp 226 | 227 | 228 | disp = get_dispatcher() 229 | 230 | app = FastAPI() 231 | 232 | 233 | @app.get("/") 234 | async def hello(): 235 | return "Hallo Frande" 236 | 237 | 238 | @app.post("/webhook") 239 | async def handle_webhook(req: Request): 240 | data = await req.json() 241 | # update = Update.de_json(data, disp.bot) 242 | # disp.process_update(update) 243 | try: 244 | if "SPAM" in data["message"]["chat"]["title"]: 245 | update = Update.de_json(data, disp.bot) 246 | disp.process_update(update) 247 | except: 248 | return "" 249 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | apscheduler==3.6.3 2 | certifi==2020.12.5 3 | click==7.1.2 4 | deta==0.7 5 | fastapi==0.65.1 6 | h11==0.12.0 7 | pydantic==1.8.2 8 | python-telegram-bot==13.5 9 | pytz==2021.1 10 | six==1.16.0 11 | starlette==0.14.2 12 | toml==0.10.2 13 | tornado==6.1 14 | typing-extensions==3.10.0.0 15 | tzlocal==2.1 16 | uvicorn==0.13.4 17 | -------------------------------------------------------------------------------- /stickers/frand.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/athul/spam-bot/438ed3e1ec2982537a2a09d2c95d033069b3fcd7/stickers/frand.webp -------------------------------------------------------------------------------- /stickers/gkr.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/athul/spam-bot/438ed3e1ec2982537a2a09d2c95d033069b3fcd7/stickers/gkr.webp -------------------------------------------------------------------------------- /stickers/levi.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/athul/spam-bot/438ed3e1ec2982537a2a09d2c95d033069b3fcd7/stickers/levi.webp --------------------------------------------------------------------------------