From b8431631bcd80e0d9b8653a15010eea4c5757165 Mon Sep 17 00:00:00 2001 From: Kaif <88398455+kaif-00z@users.noreply.github.com> Date: Sat, 3 Sep 2022 11:56:06 +0530 Subject: [PATCH 1/5] Update app.json --- app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app.json b/app.json index 48a85ed..10d2be9 100644 --- a/app.json +++ b/app.json @@ -1,9 +1,9 @@ { - "name": "RedditTgBot", + "name": "TgRedditBot", "description": "A Normal Telegram Bot Which can control reddit from telegram", "logo": "https://telegra.ph/file/2a37745048a2d07323e05.jpg", "keywords": ["Telegram","Python", "Reddit","Stream","Interaction"], - "repository": "https://github.com/kaif-00z/RedditTgBot", + "repository": "https://github.com/kaif-00z/TgRedditBot", "success_url": "https://t.me/BotsBakery", "env": { "API_ID": { From 125fc28b4e5a81a4e55e64d9c37fad55857d32e3 Mon Sep 17 00:00:00 2001 From: Kaif <88398455+kaif-00z@users.noreply.github.com> Date: Sat, 3 Sep 2022 12:03:54 +0530 Subject: [PATCH 2/5] Hmm Support Streaming In Multiple Chats. Inbox Streaming In Progress.. Improve Code Quality ** # Todo ** Need To Complete Inbox Streaming. Need To Back All Strings in a Class in strings.py and will try to add multiple languages support. need to rewrite `incoreply` function. --- bot.py | 173 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 141 insertions(+), 32 deletions(-) diff --git a/bot.py b/bot.py index 14b9446..ca61570 100644 --- a/bot.py +++ b/bot.py @@ -30,12 +30,12 @@ from strings import * from var import Var -file = "tgreddit_bot.log" +file = "TgRedditBot.log" if os.path.exists(file): os.remove(file) basicConfig( - format="%(asctime)s || %(name)s [%(levelname)s] : %(message)s", + format="[%(levelname)s] [%(asctime)s] [%(name)s] : %(message)s", handlers=[FileHandler(file), StreamHandler()], level=INFO, datefmt="%m/%d/%Y, %H:%M:%S", @@ -58,7 +58,8 @@ bot = TelegramClient(None, Var.API_ID, Var.API_HASH).start(bot_token=Var.BOT_TOKEN) LOGS.info("Successfully Connected with Telegram") except Exception as e: - LOGS.critical(str(e)) + LOGS.critical("Something Went Wrong While Connecting To Telegram") + LOGS.error(str(e)) exit() try: @@ -72,7 +73,8 @@ ) LOGS.info("Successfully Connected with Reddit") except Exception as exc: - LOGS.critical(str(exc)) + LOGS.critical("Something Went Wrong While Connecting To Reddit") + LOGS.error(str(exc)) exit() try: @@ -87,11 +89,13 @@ ) LOGS.info("successfully connected to Redis database") except Exception as eo: - LOGS.critical(str(eo)) + LOGS.critical("Something Went Wrong While Connecting To Redis") + LOGS.error(str(eo)) exit() UPTIME = dt.now() FUTURE = {} +# STREAM_INBOX = [] # ================Show Case=============================================== @@ -123,7 +127,7 @@ async def help(event): async def loggs(event): xx = await event.reply(PRO) await event.reply( - file="tgreddit_bot.log", + file=file, force_document=True, thumb="thumb.jpg", ) @@ -169,11 +173,10 @@ async def restart(event): return await event.reply(AD) xx = await event.reply(PRO) try: - """ - await bash("git pull") + if os.path.exists(".git"): + await bash("git pull") if os.path.exists("requirements.txt"): await bash("pip3 install -U -r requirements.txt") - """ await xx.edit("`Restarting...`") dB.set("RESTART", str([xx.chat_id, xx.id])) os.execl(sys.executable, sys.executable, "bot.py") @@ -194,10 +197,19 @@ async def on_start(): "wget https://telegra.ph/file/2a37745048a2d07323e05.jpg -O thumb.jpg" ) xxx = eval(dB.get("WATCH_LIST") or "{}") - for username in xxx.keys(): - future = asyncio.ensure_future(watch(username, xxx[username])) - if username not in FUTURE: - FUTURE.update({username: future}) + if xxx: + for username in xxx.keys(): + vlu = username.split("|") + future = asyncio.ensure_future(watch(vlu[0], vlu[1])) + if username not in FUTURE: + FUTURE.update({username: future}) + LOGS.info("Subreddit(s) Streaming Started...") + """ + if dB.get("INBOX_STREAM"): + _future = asyncio.ensure_future(inbox_stream()) + STREAM_INBOX.append(_future) + LOGS.info("Inbox Streaming Started...") + """ except Exception: await bash( "wget https://telegra.ph/file/2a37745048a2d07323e05.jpg -O thumb.jpg" @@ -441,6 +453,7 @@ async def front_feed(event): link_preview=False, parse_mode="HTML", ) + await asyncio.sleep(1) await xx.delete() except Exception as error: await xx.edit(f"`Error` - {error}") @@ -506,13 +519,13 @@ async def watcher(event): return await xx.edit("`UserName Not Found`") try: w_list = eval(dB.get("WATCH_LIST") or "{}") - future = asyncio.ensure_future(watch(username, event.sender_id)) - if username not in FUTURE: - FUTURE.update({username: future}) - w_list.update({username: event.sender_id}) + future = asyncio.ensure_future(watch(username, event.chat_id)) + if f"{username}|{event.chat_id}" not in FUTURE: + FUTURE.update({f"{username}|{event.chat_id}": future}) + w_list.update({f"{username}|{event.chat_id}": event.chat_id}) dB.set("WATCH_LIST", str(w_list)) return await xx.edit( - f"`Successfully Added This on Watching List, To Unwatch this do` `/unwatch {username}`" + f"`Successfully Added This on This Chat's Watching List, To Unwatch this do` `/unwatch {username}`" ) await xx.edit("`Already on Watching List`") except Exception as error: @@ -529,15 +542,18 @@ async def unwatcher(event): if not username: return await xx.edit("`Username Not Given`") try: - if FUTURE.get(username): + _username = f"{username}|{event.chat_id}" + if FUTURE.get(_username): w_list = eval(dB.get("WATCH_LIST") or "{}") - FUTURE[username].cancel() - del FUTURE[username] - if w_list.get(username): - del w_list[username] + FUTURE[_username].cancel() + del FUTURE[_username] + if w_list.get(_username): + del w_list[_username] dB.set("WATCH_LIST", str(w_list)) - return await xx.edit("`Succesfully Removed it from Watching List`") - await xx.edit("`Username Not Found In Watching List`") + return await xx.edit( + "`Succesfully Removed it from This Chat's Watching List`" + ) + await xx.edit("`Username Not Found In This Chat's Watching List`") except Exception as error: await xx.edit(f"`Error` - {error}") LOGS.error(format_exc()) @@ -547,14 +563,41 @@ async def unwatcher(event): async def watch_list(event): if str(event.sender_id) not in Var.OWNER: return await event.reply(AD) - xx = await event.reply(PRO) + await event.reply( + "`Choose...`", + buttons=[ + [ + Button.inline("All Chats", data="alchwlst"), + Button.inline("This Chat Only", data="tschwlst"), + ] + ], + ), + + +@bot.on(events.callbackquery.CallbackQuery(data=re.compile("alchwlst"))) +async def lst_watch(event): try: - txt = "**Watch List**\n\n" + txt = "**Watch List Of All Chats**\n\n" for u in FUTURE.keys(): - txt += f"[{u}](https://reddit.com/r/{u})\n" - await xx.edit(txt) + vlu = u.split("|") + txt += f"[{vlu[0]}](https://reddit.com/r/{vlu[0]}) - `[{vlu[1]}]`\n" + await event.edit(txt, link_preview=False) except Exception as error: - await xx.edit(f"`Error` - {error}") + await event.edit(f"`Error` - {error}") + LOGS.error(format_exc()) + + +@bot.on(events.callbackquery.CallbackQuery(data=re.compile("tschwlst"))) +async def lst_ch_watch(event): + try: + txt = "**Watch List Of This Chat**\n\n" + for u in FUTURE.keys(): + vlu = u.split("|") + if str(event.chat_id) in vlu: + txt += f"[{vlu[0]}](https://reddit.com/r/{vlu[0]})\n" + await event.edit(txt, link_preview=False) + except Exception as error: + await event.edit(f"`Error` - {error}") LOGS.error(format_exc()) @@ -563,7 +606,7 @@ async def incoreply(event): if not event.reply_to: return if str(event.sender_id) not in Var.OWNER: - return await event.reply(AD) + return reply = await event.get_reply_message() msg = event.text try: @@ -577,7 +620,7 @@ async def incoreply(event): xx = await event.reply(PRO) try: if msg.startswith((".", "/")): - return await xx.edit("`You Can't start the message with'.' and '/'`") + return await xx.edit("`You Can't start the message with '.' and '/'`") submission = await reddit.submission(url=url) await submission.reply(msg) await xx.edit("`Successfully Replied`") @@ -641,6 +684,72 @@ async def subinfo(event): LOGS.error(format_exc()) +""" Todo Stuffs""" + +""" + +@bot.on(events.NewMessage(incoming=True, pattern="^/inbox$")) +async def _inbox_opt(event): + if str(event.sender_id) not in Var.OWNER: + return await event.reply(AD) + btn = [ + [ + Button.inline("Enable it", data="strmin"), + Button.inline("Disable it", data="disstrmin"), + ] + ] + await event.reply("`Stream Inbox:`", buttons=btn) + + +@bot.on(events.callbackquery.CallbackQuery(data=re.compile("strmin"))) +async def _stream_inbox(event): + xx = await event.edit(PRO) + if STREAM_INBOX: + return await xx.edit("`Inbox Is Already Streaming... 😑😑`") + try: + future = asyncio.ensure_future(inbox_stream()) + STREAM_INBOX.append(future) + dB.set("INBOX_STREAM", "True") + await xx.edit("`Successfully Enabled Inbox Streaming...`") + LOGS.info("Successfully Enabled Inbox Streaming...") + except Exception as error: + await xx.edit(f"`Error` - {error}") + LOGS.error(format_exc()) + + +@bot.on(events.callbackquery.CallbackQuery(data=re.compile("disstrmin"))) +async def _stop_stream_inbox(event): + xx = await event.edit(PRO) + if not STREAM_INBOX: + return await xx.edit("`Inbox Streaming Already Disabled... 😑😑`") + try: + STREAM_INBOX[0].cancel() + STREAM_INBOX.clear() + dB.delete("INBOX_STREAM") + await xx.edit("`Successfully Disabled Inbox Streaming...`") + LOGS.info("Successfully Disabled Inbox Streaming...") + except Exception as error: + await xx.edit(f"`Error` - {error}") + LOGS.error(format_exc()) + + +async def inbox_stream(): + ids = [int(id) for id in Var.OWNER_ID.split()] + try: + async for pm in reddit.inbox.stream(skip_existing=True): + for id in ids: + await bot.send_message( + id, + INBOX.format(pm.subject, pm.body, pm.author, pm.was_comment), + buttons=[[Button.url("VIEW", url=f"https://redd.it/{pm.id}")]], + ) + except Exception as error: + for id in ids: + await bot.send_message(id, f"`Error` - {error}") + LOGS.error(format_exc()) +""" + + LOGS.info("Bot has Started...") bot.loop.run_until_complete(on_start()) bot.loop.run_forever() From 8a7623439c5dc9820472a7e6a9ad6296adf38b44 Mon Sep 17 00:00:00 2001 From: AsmSafone <77989182+AsmSafone@users.noreply.github.com> Date: Mon, 10 Oct 2022 21:27:55 +0600 Subject: [PATCH 3/5] fix invalid formation type (#2) * deployment.... * fixed * Import on startup rather than each 'about' call * fix invalid formation type. Co-authored-by: Kaif <88398455+kaif-00z@users.noreply.github.com> --- README.md | 2 +- app.json | 10 +++++----- bot.py | 8 +++----- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d78f658..b54e815 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ All Enviroment Variables can be found in [`env.sample`](https://github.com/kaif-00z/TgRedditBot/blob/main/env.sample) ! ## Deploy to Heroku -[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://dashboard.heroku.com/new?button-url=https%3A%2F%2Fgithub.com%2Fkaif-00z%2FTgRedditBot&template=https%3A%2F%2Fgithub.com%2Fkaif-00z%2FCTgRedditBot) +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://dashboard.heroku.com/new?button-url=https%3A%2F%2Fgithub.com%2Fkaif-00z%2FTgRedditBot&template=https%3A%2F%2Fgithub.com%2Fkaif-00z%2FTgRedditBot) ## Deploying Locally Fill Your Env Variables in .env file ! diff --git a/app.json b/app.json index 10d2be9..bb8dc01 100644 --- a/app.json +++ b/app.json @@ -24,19 +24,19 @@ }, "REDDIT_CLIENT_ID": { "description": "Put your reddit client id.", - "value": "", + "value": "" }, "REDDIT_CLIENT_SECRET": { "description": "Put your reddit client secret.", - "value": "", + "value": "" }, "REDDIT_USERNAME": { "description": "Put your reddit username.", - "value": "", + "value": "" }, "REDDIT_PASSWORD": { "description": "Put your reedit password.", - "value": "", + "value": "" }, "REDIS_URI": { "description": "Redis endpoint URL, from redislabs.com", @@ -48,7 +48,7 @@ } }, "formation": { - "bot": { + "worker": { "quantity": 1, "size": "free" } diff --git a/bot.py b/bot.py index ca61570..b899c75 100644 --- a/bot.py +++ b/bot.py @@ -18,11 +18,14 @@ import sys from datetime import datetime as dt from logging import DEBUG, INFO, FileHandler, StreamHandler, basicConfig, getLogger +from platform import python_version, release, system from traceback import format_exc from asyncpraw import Reddit +from asyncpraw.const import __version__ as praw_version from redis import Redis from telethon import Button, TelegramClient, events +from telethon import __version__ as telethon_version from telethon.tl.types import DocumentAttributeVideo from telethon.utils import get_display_name @@ -135,11 +138,6 @@ async def loggs(event): async def about(event, edit=False): - from platform import python_version, release, system - - from asyncpraw.const import __version__ as praw_version - from telethon import __version__ as telethon_version - x = ABOUT.format( ts(int((dt.now() - UPTIME).seconds) * 1000), f"{python_version()}", From 3534a3c941723cdb4b0681c8b5927a9b0cefea53 Mon Sep 17 00:00:00 2001 From: kaif-00z <88398455+kaif-00z@users.noreply.github.com> Date: Mon, 10 Oct 2022 15:28:18 +0000 Subject: [PATCH 4/5] pyLint: auto-fixes --- bot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index b899c75..313537d 100644 --- a/bot.py +++ b/bot.py @@ -24,8 +24,9 @@ from asyncpraw import Reddit from asyncpraw.const import __version__ as praw_version from redis import Redis -from telethon import Button, TelegramClient, events +from telethon import Button, TelegramClient from telethon import __version__ as telethon_version +from telethon import events from telethon.tl.types import DocumentAttributeVideo from telethon.utils import get_display_name From e4b8c3540938779315fff6b0bcdad6f33a11d682 Mon Sep 17 00:00:00 2001 From: AsmSafone <77989182+AsmSafone@users.noreply.github.com> Date: Mon, 10 Oct 2022 22:31:57 +0600 Subject: [PATCH 5/5] Added docker support (#3) * deployment.... * fixed * Create Dockerfile * Added railway support Co-authored-by: Kaif <88398455+kaif-00z@users.noreply.github.com> --- Dockerfile | 13 +++++++++++++ README.md | 3 +++ 2 files changed, 16 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..13690a3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM debian:latest + +RUN apt update && apt upgrade -y +RUN apt install git python3-pip ffmpeg -y + +RUN mkdir /app +WORKDIR /app +COPY . /app + +RUN pip3 install --upgrade pip +RUN pip3 install -U -r requirements.txt + +CMD python3 bot.py diff --git a/README.md b/README.md index b54e815..29e9fad 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ All Enviroment Variables can be found in [`env.sample`](https://github.com/kaif- ## Deploy to Heroku [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://dashboard.heroku.com/new?button-url=https%3A%2F%2Fgithub.com%2Fkaif-00z%2FTgRedditBot&template=https%3A%2F%2Fgithub.com%2Fkaif-00z%2FTgRedditBot) +## Deploy to Railway +[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/boH0zQ?referralCode=RZv4LZ) + ## Deploying Locally Fill Your Env Variables in .env file ! ```shell