Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 44 additions & 22 deletions agent/bot_telethon.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,54 @@
api_hash = config.app_api_hash
bot_token = config.token

thonbot = TelegramClient(
session_handler, app_id, api_hash).start(bot_token=bot_token)
# Do not connect at import time: MTProto is blocked in some environments
# (Cloud Agent, filtered networks) while Bot API HTTPS still works.
thonbot = TelegramClient(session_handler, app_id, api_hash)
thonbot_uploader: TelegramClient | None = None
thobot_session_handler = ""
telethon_available = False

if os.path.exists(uploader_session):
with open(uploader_session, 'r') as f:
string_session = StringSession(f.readline())
else:
string_session = StringSession()
logger = Logger(file="sender")

thonbot_uploader = TelegramClient(string_session, app_id, api_hash).start(bot_token=bot_token)
thobot_session_handler = thonbot_uploader.session.save()

logger = Logger(file="sender")
def try_start_telethon() -> bool:
"""Connect Telethon clients. Returns False when MTProto is unavailable."""
global thonbot_uploader, thobot_session_handler, telethon_available

if telethon_available:
return True

if os.environ.get('TELEGRAM_FORCE_BOTAPI', '').lower() in ('1', 'true', 'yes'):
logger.log("TELEGRAM_FORCE_BOTAPI is set, skipping MTProto")
return False

with open(uploader_session, 'w+') as f:
f.write(thobot_session_handler)
if not bot_token or not app_id or not api_hash:
logger.log("Telethon credentials missing, skipping MTProto")
return False

try:
thonbot.start(bot_token=bot_token)

if os.path.exists(uploader_session):
with open(uploader_session, 'r') as f:
string_session = StringSession(f.readline())
else:
string_session = StringSession()

uploader = TelegramClient(string_session, app_id, api_hash).start(
bot_token=bot_token)
session_string = uploader.session.save()
with open(uploader_session, 'w+') as f:
f.write(session_string)

thonbot_uploader = uploader
thobot_session_handler = session_string
telethon_available = True
logger.log("Telethon MTProto connected")
return True
except Exception as e:
logger.err("Telethon MTProto connect failed:", e)
return False


async def __uploader(local_thonbot, fname, callback=None):
Expand Down Expand Up @@ -131,13 +163,3 @@ def get_next_ep_button(argv):

else:
return None

# def get_or_create_event_loop():
# try:
# loop = asyncio.get_event_loop()
# except RuntimeError:
# loop = asyncio.new_event_loop()
# asyncio.set_event_loop(loop)
# print("LOOOOP IS ", loop, flush=True)
# return loop

7 changes: 5 additions & 2 deletions app/controller/general/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ def notify(
disable_web_page_preview: bool = True
):
if call is not None:
bot.answer_callback_query(
callback_query_id=call.id, show_alert=alert, text=text)
try:
bot.answer_callback_query(
callback_query_id=call.id, show_alert=alert, text=text)
except Exception:
pass
return

if message is not None:
Expand Down
33 changes: 26 additions & 7 deletions app/core/balancers/recordSender.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from telethon import TelegramClient
from telethon.sessions import StringSession

from agent.bot_telethon import thobot_session_handler
from agent import bot_telethon
from app.controller.builders import recsModule
from app.jobs import podcastsUpdater
from config import app_api_id, app_api_hash, token, threads_config
Expand Down Expand Up @@ -155,12 +155,9 @@ def run(self):

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop = asyncio.get_event_loop()

thonbot = TelegramClient(
StringSession(thobot_session_handler), app_api_id, app_api_hash, loop=loop
).start(bot_token=token)
thonbot.disconnect()
thonbot = None
logger.log(f"{self.thread_num} waiting for send jobs")

while True:
try:
Expand All @@ -171,14 +168,36 @@ def run(self):

try:
logger.log(f"Sending in thread #{self.thread_num}")
self.process_input(input_data, thonbot)
if thonbot is None:
thonbot = self._connect_telethon(loop)
if thonbot is None:
logger.warn(
f"{self.thread_num} Telethon unavailable, "
f"cannot {input_data.get('action')}")
else:
self.process_input(input_data, thonbot)
except Exception as e:
logger.err(f"{self.thread_num} failed sending, continuing:", e)
finally:
self.thread_queue.task_done()
if self.thread_queue.empty():
self.pause()

def _connect_telethon(self, loop):
if not bot_telethon.telethon_available or not bot_telethon.thobot_session_handler:
logger.log(f"{self.thread_num} running without Telethon")
return None
try:
client = TelegramClient(
StringSession(bot_telethon.thobot_session_handler),
app_api_id, app_api_hash, loop=loop
).start(bot_token=token)
client.disconnect()
return client
except Exception as e:
logger.err(f"{self.thread_num} Telethon connect failed:", e)
return None

def process_input(self, input_data, thonbot):

if input_data['action'] == 'rec':
Expand Down
7 changes: 7 additions & 0 deletions app/core/balancers/telebotAnswerer.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ def _serve(self, input_data: HandleInThreadParams):
controller_params, input_data['data']['user'],
start_related_params['is_new_user'], start_related_params['is_by_refer'],
start_related_params['action'])
callback = controller_params.get('callback')
if callback is not None:
try:
from agent.bot_telebot import bot
bot.answer_callback_query(callback.id)
except Exception:
pass

# Inline query
elif 'inline' in input_data['data']:
Expand Down
8 changes: 3 additions & 5 deletions app/core/controller.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import telethon

from app.repository.storage import storage
from app.routes import router_tools
from app.routes.routes import RouteMap
Expand All @@ -10,8 +8,8 @@
from lib.python import dict_tools


def empty_state_input_state_corrector(event: telethon.events.NewMessage.Event):
prev, curr = storage.get_user_prev_curr_states(event.chat_id)
def empty_state_input_state_corrector(chat_id: int):
prev, curr = storage.get_user_prev_curr_states(chat_id)
if prev is None:
return

Expand All @@ -31,7 +29,7 @@ def empty_state_input_state_corrector(event: telethon.events.NewMessage.Event):
(dict_tools.deep_get(RouteMap.ROUTES, prev, 'waits_for_input', default=False)
or someone_have_state_for_input)
and curr == empty):
storage.del_user_curr_state(event.chat_id)
storage.del_user_curr_state(chat_id)


def construct_params(
Expand Down
19 changes: 12 additions & 7 deletions app/jobs/podcastsUpdater.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import app.service.user.language
import lib.markup.cleaner
from agent.bot_telebot import bot
from agent.bot_telethon import thobot_session_handler
from agent import bot_telethon
from app.controller.builders.helpModule import get_promo_messages
from app.controller.general.notify import notify
from app.core.sender.send_record_helper import ChatParamsType, DescriptionModeOptions
Expand Down Expand Up @@ -51,13 +51,18 @@
def main(interval=120):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop = asyncio.get_event_loop()

asyncio.set_event_loop(loop)
thonbot = TelegramClient(
StringSession(thobot_session_handler), app_api_id, app_api_hash, loop=loop
).start(bot_token=token)
thonbot.disconnect()
if bot_telethon.telethon_available and bot_telethon.thobot_session_handler:
try:
thonbot = TelegramClient(
StringSession(bot_telethon.thobot_session_handler),
app_api_id, app_api_hash, loop=loop
).start(bot_token=token)
thonbot.disconnect()
except Exception as e:
logger.err("Telethon unavailable for updater:", e)
else:
logger.log("Updater running without Telethon session warmup")

while True:
if not server:
Expand Down
Loading