Skip to content

Commit

Permalink
Merge pull request #478 from MobCode100/main
Browse files Browse the repository at this point in the history
[Plugin] Sender
  • Loading branch information
aahnik authored Dec 6, 2023
2 parents 1f65cb3 + 1559220 commit c7a108c
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 19 deletions.
28 changes: 14 additions & 14 deletions tgcf/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
import os
import sys
from typing import Dict, List, Optional, Union
from typing import Dict, List, Optional, Union, Any

from dotenv import load_dotenv
from pydantic import BaseModel, validator # pylint: disable=no-name-in-module
Expand Down Expand Up @@ -207,19 +207,6 @@ async def load_admins(client: TelegramClient):
return ADMINS


def get_SESSION():
if CONFIG.login.SESSION_STRING and CONFIG.login.user_type == 1:
logging.info("using session string")
SESSION = StringSession(CONFIG.login.SESSION_STRING)
elif CONFIG.login.BOT_TOKEN and CONFIG.login.user_type == 0:
logging.info("using bot account")
SESSION = "tgcf_bot"
else:
logging.warning("Login information not set!")
sys.exit()
return SESSION


def setup_mongo(client):

mydb = client[MONGO_DB_NAME]
Expand Down Expand Up @@ -257,3 +244,16 @@ def read_db():
from_to = {}
is_bot: Optional[bool] = None
logging.info("config.py got executed")


def get_SESSION(section: Any = CONFIG.login, default: str = 'tgcf_bot'):
if section.SESSION_STRING and section.user_type == 1:
logging.info("using session string")
SESSION = StringSession(section.SESSION_STRING)
elif section.BOT_TOKEN and section.user_type == 0:
logging.info("using bot account")
SESSION = default
else:
logging.warning("Login information not set!")
sys.exit()
return SESSION
5 changes: 4 additions & 1 deletion tgcf/live.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from tgcf import storage as st
from tgcf.bot import get_events
from tgcf.config import CONFIG, get_SESSION
from tgcf.plugins import apply_plugins
from tgcf.plugins import apply_plugins, load_async_plugins
from tgcf.utils import clean_session_files, send_message


Expand Down Expand Up @@ -119,6 +119,9 @@ async def start_sync() -> None:
# clear past session files
clean_session_files()

# load async plugins defined in plugin_models
await load_async_plugins()

SESSION = get_SESSION()
client = TelegramClient(
SESSION,
Expand Down
6 changes: 5 additions & 1 deletion tgcf/past.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@
from tgcf import config
from tgcf import storage as st
from tgcf.config import CONFIG, get_SESSION, write_config
from tgcf.plugins import apply_plugins
from tgcf.plugins import apply_plugins, load_async_plugins
from tgcf.utils import clean_session_files, send_message


async def forward_job() -> None:
"""Forward all existing messages in the concerned chats."""
clean_session_files()

# load async plugins defined in plugin_models
await load_async_plugins()

if CONFIG.login.user_type != 1:
logging.warning(
"You cannot use bot account for tgcf past mode. Telegram does not allow bots to access chat history."
Expand Down
10 changes: 10 additions & 0 deletions tgcf/plugin_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ class Caption(BaseModel):
header: str = ""
footer: str = ""

class Sender(BaseModel):
check: bool = False
user_type: int = 0 # 0:bot, 1:user
BOT_TOKEN: str = ""
SESSION_STRING: str = ""

class PluginConfig(BaseModel):
filter: Filters = Filters()
Expand All @@ -89,3 +94,8 @@ class PluginConfig(BaseModel):
ocr: OcrConfig = OcrConfig()
replace: Replace = Replace()
caption: Caption = Caption()
sender: Sender = Sender()


# List of plugins that need to load asynchronously
ASYNC_PLUGIN_IDS = ['sender']
17 changes: 15 additions & 2 deletions tgcf/plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from telethon.tl.custom.message import Message

from tgcf.config import CONFIG
from tgcf.plugin_models import FileType
from tgcf.plugin_models import FileType, ASYNC_PLUGIN_IDS
from tgcf.utils import cleanup, stamp

PLUGINS = CONFIG.plugins
Expand All @@ -29,6 +29,7 @@ def __init__(self, message: Message) -> None:
self.new_file = None
self.cleanup = False
self.reply_to = None
self.client = self.message.client

async def get_file(self) -> str:
"""Downloads the file in the message and returns the path where its saved."""
Expand Down Expand Up @@ -57,6 +58,9 @@ class TgcfPlugin:
def __init__(self, data: Dict[str, Any]) -> None: # TODO data type has changed
self.data = data

async def __ainit__(self) -> None:
"""Asynchronous initialization here."""

def modify(self, tm: TgcfMessage) -> TgcfMessage:
"""Modify the message here."""
return tm
Expand Down Expand Up @@ -93,13 +97,22 @@ def load_plugins() -> Dict[str, TgcfPlugin]:
logging.error(f"Plugin id for {plugin_id} does not match expected id.")
continue
except AttributeError:
logging.error(f"Found plugin {plugin_id}, but plguin class not found.")
logging.error(f"Found plugin {plugin_id}, but plugin class not found.")
else:
logging.info(f"Loaded plugin {plugin_id}")
_plugins.update({plugin.id_: plugin})
return _plugins


async def load_async_plugins() -> None:
"""Load async plugins specified plugin_models."""
if plugins:
for id in ASYNC_PLUGIN_IDS:
if id in plugins:
await plugins[id].__ainit__()
logging.info(f"Plugin {id} asynchronously loaded")


async def apply_plugins(message: Message) -> TgcfMessage:
"""Apply all loaded plugins to a message."""
tm = TgcfMessage(message)
Expand Down
31 changes: 31 additions & 0 deletions tgcf/plugins/sender.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import logging
import sys

from tgcf.plugins import TgcfMessage, TgcfPlugin
from tgcf.config import CONFIG, get_SESSION
from telethon import TelegramClient

class TgcfSender(TgcfPlugin):
id_ = "sender"

async def __ainit__(self) -> None:
sender = TelegramClient(
get_SESSION(CONFIG.plugins.sender, 'tgcf_sender'),
CONFIG.login.API_ID,
CONFIG.login.API_HASH,
)
if self.data.user_type == 0:
if self.data.BOT_TOKEN == "":
logging.warning("[Sender] Bot token not found, but login type is set to bot.")
sys.exit()
await sender.start(bot_token=self.data.BOT_TOKEN)
else:
await sender.start()
self.sender = sender

async def modify(self, tm: TgcfMessage) -> TgcfMessage:
tm.client = self.sender
if tm.file_type != "nofile":
tm.new_file = await tm.get_file()
tm.cleanup = True
return tm
2 changes: 1 addition & 1 deletion tgcf/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def platform_info():

async def send_message(recipient: EntityLike, tm: "TgcfMessage") -> Message:
"""Forward or send a copy, depending on config."""
client: TelegramClient = tm.message.client
client: TelegramClient = tm.client
if CONFIG.show_forwarded_from:
return await client.forward_messages(recipient, tm.message)
if tm.new_file:
Expand Down
43 changes: 43 additions & 0 deletions tgcf/web_ui/pages/4_🔌_Plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,48 @@
"You can have blank lines inside header and footer, to make space between the orignal message and captions."
)

with st.expander("Sender"):
st.write("Modify the sender of forwarded messages other than the current user/bot")
st.warning("Show 'Forwarded from' option must be disabled or else messages will not be sent",icon="⚠️")
CONFIG.plugins.sender.check = st.checkbox(
"Set sender to:", value=CONFIG.plugins.sender.check
)
leftpad,content,rightpad = st.columns([0.05,0.9,0.05])
with content:
user_type = st.radio("Account Type", ["Bot", "User"], index=CONFIG.plugins.sender.user_type,horizontal=True)
if user_type == "Bot":
CONFIG.plugins.sender.user_type = 0
CONFIG.plugins.sender.BOT_TOKEN = st.text_input(
"Bot Token", value=CONFIG.plugins.sender.BOT_TOKEN, type="password"
)
else:
CONFIG.plugins.sender.user_type = 1
CONFIG.plugins.sender.SESSION_STRING = st.text_input(
"Session String", CONFIG.plugins.sender.SESSION_STRING, type="password"
)
st.markdown(
"""
###### How to get session string?
Link to repl: https://replit.com/@aahnik/tg-login?v=1
<p style="line-height:0px;margin-bottom:2em">
<i>Click on the above link and enter api id, api hash, and phone no to generate session string.</i>
</p>
> <small>**Note from developer:**<small>
>
> <small>Due some issues logging in with a user account using a phone no is not supported in this web interface.</small>
>
> <small>I have built a command-line program named tg-login (https://github.com/aahnik/tg-login) that can generate the session string for you.</small>
>
> <small>You can run tg-login on your computer, or securely in this repl. tg-login is open source, and you can also inspect the bash script running in the repl.</small>
>
> <small>What is a session string?</small>
> <small>https://docs.telethon.dev/en/stable/concepts/sessions.html#string-sessions</small>
"""
,unsafe_allow_html=True)

if st.button("Save"):
write_config(CONFIG)

0 comments on commit c7a108c

Please sign in to comment.