refactor: extract bridge config and loop
This commit is contained in:
@@ -10,6 +10,7 @@ import threading
|
|||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
from dataclasses import dataclass
|
||||||
from weakref import WeakValueDictionary
|
from weakref import WeakValueDictionary
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
@@ -336,6 +337,220 @@ class CodexExecRunner:
|
|||||||
|
|
||||||
# -------------------- Telegram loop --------------------
|
# -------------------- Telegram loop --------------------
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class BridgeConfig:
|
||||||
|
bot: TelegramClient
|
||||||
|
runner: CodexExecRunner
|
||||||
|
chat_id: int
|
||||||
|
pool: ThreadPoolExecutor
|
||||||
|
ignore_backlog: bool
|
||||||
|
progress_edit_every_s: float
|
||||||
|
progress_silent: bool
|
||||||
|
final_notify: bool
|
||||||
|
startup_msg: str
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_bridge_config(
|
||||||
|
*,
|
||||||
|
progress_edit_every_s: float,
|
||||||
|
progress_silent: bool,
|
||||||
|
final_notify: bool,
|
||||||
|
ignore_backlog: bool,
|
||||||
|
cd: str | None,
|
||||||
|
model: str | None,
|
||||||
|
) -> BridgeConfig:
|
||||||
|
config = load_telegram_config()
|
||||||
|
token = config["bot_token"]
|
||||||
|
chat_id = int(config["chat_id"])
|
||||||
|
|
||||||
|
startup_pwd = os.getcwd()
|
||||||
|
startup_msg = f"codex exec bridge has started\npwd: {startup_pwd}"
|
||||||
|
|
||||||
|
codex_cmd = shutil.which("codex")
|
||||||
|
if not codex_cmd:
|
||||||
|
raise RuntimeError("codex not found on PATH")
|
||||||
|
|
||||||
|
workspace = cd if cd is not None else config.get("cd")
|
||||||
|
raw_exec_args = config.get("codex_exec_args", "")
|
||||||
|
if isinstance(raw_exec_args, list):
|
||||||
|
extra_args = [str(v) for v in raw_exec_args]
|
||||||
|
else:
|
||||||
|
extra_args = shlex.split(str(raw_exec_args)) # e.g. "--full-auto --search"
|
||||||
|
|
||||||
|
if model:
|
||||||
|
extra_args.extend(["--model", model])
|
||||||
|
|
||||||
|
def _has_notify_override(args: list[str]) -> bool:
|
||||||
|
for i, arg in enumerate(args):
|
||||||
|
if arg in ("-c", "--config"):
|
||||||
|
key = args[i + 1].split("=", 1)[0].strip()
|
||||||
|
if key == "notify" or key.endswith(".notify"):
|
||||||
|
return True
|
||||||
|
elif arg.startswith(("--config=", "-c=")):
|
||||||
|
key = arg.split("=", 1)[1].split("=", 1)[0].strip()
|
||||||
|
if key == "notify" or key.endswith(".notify"):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not _has_notify_override(extra_args):
|
||||||
|
extra_args.extend(["-c", "notify=[]"])
|
||||||
|
|
||||||
|
bot = TelegramClient(token)
|
||||||
|
runner = CodexExecRunner(codex_cmd=codex_cmd, workspace=workspace, extra_args=extra_args)
|
||||||
|
pool = ThreadPoolExecutor(max_workers=16)
|
||||||
|
|
||||||
|
return BridgeConfig(
|
||||||
|
bot=bot,
|
||||||
|
runner=runner,
|
||||||
|
chat_id=chat_id,
|
||||||
|
pool=pool,
|
||||||
|
ignore_backlog=bool(ignore_backlog),
|
||||||
|
progress_edit_every_s=progress_edit_every_s,
|
||||||
|
progress_silent=progress_silent,
|
||||||
|
final_notify=final_notify,
|
||||||
|
startup_msg=startup_msg,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _send_startup(cfg: BridgeConfig) -> None:
|
||||||
|
try:
|
||||||
|
cfg.bot.send_message(chat_id=cfg.chat_id, text=cfg.startup_msg)
|
||||||
|
logger.info("[startup] sent startup message to chat_id=%s", cfg.chat_id)
|
||||||
|
except Exception as e:
|
||||||
|
logger.info("[startup] failed to send startup message to chat_id=%s: %s", cfg.chat_id, e)
|
||||||
|
|
||||||
|
|
||||||
|
def _drain_backlog(cfg: BridgeConfig, offset: int | None) -> int | None:
|
||||||
|
if not cfg.ignore_backlog:
|
||||||
|
return offset
|
||||||
|
try:
|
||||||
|
updates = cfg.bot.get_updates(offset=offset, timeout_s=0, allowed_updates=["message"])
|
||||||
|
except Exception as e:
|
||||||
|
logger.info("[startup] backlog drain failed: %s", e)
|
||||||
|
return offset
|
||||||
|
if updates:
|
||||||
|
offset = updates[-1]["update_id"] + 1
|
||||||
|
logger.info("[startup] drained %s pending update(s)", len(updates))
|
||||||
|
return offset
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_message(
|
||||||
|
cfg: BridgeConfig,
|
||||||
|
*,
|
||||||
|
chat_id: int,
|
||||||
|
user_msg_id: int,
|
||||||
|
text: str,
|
||||||
|
resume_session: str | None,
|
||||||
|
) -> None:
|
||||||
|
started_at = time.monotonic()
|
||||||
|
progress_renderer = ExecProgressRenderer(max_actions=5)
|
||||||
|
|
||||||
|
progress_id: int | None = None
|
||||||
|
progress: ProgressEditor | None = None
|
||||||
|
try:
|
||||||
|
initial_text = progress_renderer.render_progress(0.0)
|
||||||
|
initial_rendered, initial_entities = render_markdown(initial_text)
|
||||||
|
progress_msg = cfg.bot.send_message(
|
||||||
|
chat_id=chat_id,
|
||||||
|
text=initial_rendered,
|
||||||
|
entities=initial_entities or None,
|
||||||
|
reply_to_message_id=user_msg_id,
|
||||||
|
disable_notification=cfg.progress_silent,
|
||||||
|
)
|
||||||
|
progress_id = int(progress_msg["message_id"])
|
||||||
|
logger.debug("[progress] sent chat_id=%s message_id=%s", chat_id, progress_id)
|
||||||
|
except Exception as e:
|
||||||
|
logger.info("[handle] failed to send progress message chat_id=%s: %s", chat_id, e)
|
||||||
|
|
||||||
|
if progress_id is not None:
|
||||||
|
progress = ProgressEditor(
|
||||||
|
cfg.bot,
|
||||||
|
chat_id,
|
||||||
|
progress_id,
|
||||||
|
cfg.progress_edit_every_s,
|
||||||
|
initial_text=initial_rendered,
|
||||||
|
initial_entities=initial_entities or None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def on_event(evt: dict[str, Any]) -> None:
|
||||||
|
if progress_renderer.note_event(evt) and progress is not None:
|
||||||
|
elapsed = time.monotonic() - started_at
|
||||||
|
progress.set_markdown(progress_renderer.render_progress(elapsed))
|
||||||
|
|
||||||
|
def _stop_background() -> None:
|
||||||
|
if progress is not None:
|
||||||
|
progress.stop()
|
||||||
|
|
||||||
|
try:
|
||||||
|
session_id, answer, saw_agent_message = cfg.runner.run_serialized(
|
||||||
|
text,
|
||||||
|
resume_session,
|
||||||
|
on_event=on_event,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
_stop_background()
|
||||||
|
err = _clamp_tg_text(f"Error:\n{e}")
|
||||||
|
if progress_id is not None and len(err) <= TELEGRAM_TEXT_LIMIT:
|
||||||
|
cfg.bot.edit_message_text(chat_id=chat_id, message_id=progress_id, text=err)
|
||||||
|
return
|
||||||
|
_send_markdown(cfg.bot, chat_id=chat_id, text=err, reply_to_message_id=user_msg_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
_stop_background()
|
||||||
|
|
||||||
|
answer = answer or "(No agent_message captured from JSON stream.)"
|
||||||
|
elapsed = time.monotonic() - started_at
|
||||||
|
status = "done" if saw_agent_message else "error"
|
||||||
|
final_md = progress_renderer.render_final(elapsed, answer, status=status) + f"\n\nresume: `{session_id}`"
|
||||||
|
final_text, final_entities = render_markdown(final_md)
|
||||||
|
can_edit_final = progress_id is not None and len(final_text) <= TELEGRAM_TEXT_LIMIT
|
||||||
|
|
||||||
|
if cfg.final_notify or not can_edit_final:
|
||||||
|
_send_markdown(cfg.bot, chat_id=chat_id, text=final_md, reply_to_message_id=user_msg_id)
|
||||||
|
if progress_id is not None:
|
||||||
|
cfg.bot.delete_message(chat_id=chat_id, message_id=progress_id)
|
||||||
|
else:
|
||||||
|
cfg.bot.edit_message_text(
|
||||||
|
chat_id=chat_id,
|
||||||
|
message_id=progress_id,
|
||||||
|
text=final_text,
|
||||||
|
entities=final_entities or None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _run_main_loop(cfg: BridgeConfig) -> None:
|
||||||
|
offset: int | None = None
|
||||||
|
offset = _drain_backlog(cfg, offset)
|
||||||
|
_send_startup(cfg)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
updates = cfg.bot.get_updates(offset=offset, timeout_s=50, allowed_updates=["message"])
|
||||||
|
for upd in updates:
|
||||||
|
offset = upd["update_id"] + 1
|
||||||
|
msg = upd.get("message") or {}
|
||||||
|
msg_chat_id = msg.get("chat", {}).get("id")
|
||||||
|
if "text" not in msg:
|
||||||
|
continue
|
||||||
|
if int(msg_chat_id) != cfg.chat_id:
|
||||||
|
continue
|
||||||
|
if msg.get("from", {}).get("is_bot"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
text = msg["text"]
|
||||||
|
user_msg_id = msg["message_id"]
|
||||||
|
resume_session = extract_session_id(text)
|
||||||
|
r = msg.get("reply_to_message") or {}
|
||||||
|
resume_session = resume_session or extract_session_id(r.get("text"))
|
||||||
|
|
||||||
|
cfg.pool.submit(
|
||||||
|
_handle_message,
|
||||||
|
cfg,
|
||||||
|
chat_id=msg_chat_id,
|
||||||
|
user_msg_id=user_msg_id,
|
||||||
|
text=text,
|
||||||
|
resume_session=resume_session,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def run(
|
def run(
|
||||||
progress_edit_every_s: float = typer.Option(
|
progress_edit_every_s: float = typer.Option(
|
||||||
@@ -376,292 +591,15 @@ def run(
|
|||||||
),
|
),
|
||||||
) -> None:
|
) -> None:
|
||||||
setup_logging(log_file if log_file else None)
|
setup_logging(log_file if log_file else None)
|
||||||
config = load_telegram_config()
|
cfg = _parse_bridge_config(
|
||||||
token = config["bot_token"]
|
progress_edit_every_s=progress_edit_every_s,
|
||||||
config_chat_id = int(config["chat_id"])
|
progress_silent=progress_silent,
|
||||||
|
final_notify=final_notify,
|
||||||
startup_pwd = os.getcwd()
|
ignore_backlog=ignore_backlog,
|
||||||
startup_msg = f"codex exec bridge has started\npwd: {startup_pwd}"
|
cd=cd,
|
||||||
|
model=model,
|
||||||
codex_cmd = shutil.which("codex")
|
|
||||||
if not codex_cmd:
|
|
||||||
raise RuntimeError("codex not found on PATH")
|
|
||||||
workspace = cd if cd is not None else config.get("cd")
|
|
||||||
raw_exec_args = config.get("codex_exec_args", "")
|
|
||||||
if isinstance(raw_exec_args, list):
|
|
||||||
extra_args = [str(v) for v in raw_exec_args]
|
|
||||||
else:
|
|
||||||
extra_args = shlex.split(str(raw_exec_args)) # e.g. "--full-auto --search"
|
|
||||||
|
|
||||||
if model:
|
|
||||||
extra_args.extend(["--model", model])
|
|
||||||
|
|
||||||
def _has_notify_override(args: list[str]) -> bool:
|
|
||||||
for i, arg in enumerate(args):
|
|
||||||
if arg in ("-c", "--config"):
|
|
||||||
if i + 1 >= len(args):
|
|
||||||
continue
|
|
||||||
key = args[i + 1].split("=", 1)[0].strip()
|
|
||||||
if key == "notify" or key.endswith(".notify"):
|
|
||||||
return True
|
|
||||||
elif arg.startswith(("--config=", "-c=")):
|
|
||||||
key = arg.split("=", 1)[1].split("=", 1)[0].strip()
|
|
||||||
if key == "notify" or key.endswith(".notify"):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Default: disable notify hook for exec-bridge runs to avoid duplicate messages.
|
|
||||||
if not _has_notify_override(extra_args):
|
|
||||||
extra_args.extend(["-c", "notify=[]"])
|
|
||||||
|
|
||||||
bot = TelegramClient(token)
|
|
||||||
runner = CodexExecRunner(
|
|
||||||
codex_cmd=codex_cmd, workspace=workspace, extra_args=extra_args
|
|
||||||
)
|
)
|
||||||
|
_run_main_loop(cfg)
|
||||||
pool = ThreadPoolExecutor(max_workers=16)
|
|
||||||
offset: int | None = None
|
|
||||||
ignore_backlog = bool(ignore_backlog)
|
|
||||||
|
|
||||||
if ignore_backlog:
|
|
||||||
try:
|
|
||||||
updates = bot.get_updates(
|
|
||||||
offset=offset, timeout_s=0, allowed_updates=["message"]
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
logger.info("[startup] backlog drain failed: %s", e)
|
|
||||||
updates = []
|
|
||||||
if updates:
|
|
||||||
offset = updates[-1]["update_id"] + 1
|
|
||||||
logger.info("[startup] drained %s pending update(s)", len(updates))
|
|
||||||
|
|
||||||
logger.info("[startup] pwd=%s", startup_pwd)
|
|
||||||
logger.info("Option1 bridge running (codex exec). Long-polling Telegram...")
|
|
||||||
try:
|
|
||||||
bot.send_message(chat_id=config_chat_id, text=startup_msg)
|
|
||||||
logger.info("[startup] sent startup message to chat_id=%s", config_chat_id)
|
|
||||||
except Exception as e:
|
|
||||||
logger.info("[startup] failed to send startup message to chat_id=%s: %s", config_chat_id, e)
|
|
||||||
|
|
||||||
def handle(
|
|
||||||
chat_id: int, user_msg_id: int, text: str, resume_session: str | None
|
|
||||||
) -> None:
|
|
||||||
logger.info(
|
|
||||||
"[handle] start chat_id=%s user_msg_id=%s resume_session=%r",
|
|
||||||
chat_id,
|
|
||||||
user_msg_id,
|
|
||||||
resume_session,
|
|
||||||
)
|
|
||||||
logger.debug(
|
|
||||||
"[handle] thread name=%s ident=%s",
|
|
||||||
threading.current_thread().name,
|
|
||||||
threading.get_ident(),
|
|
||||||
)
|
|
||||||
edit_every_s = progress_edit_every_s
|
|
||||||
silent_progress = progress_silent
|
|
||||||
loud_final = final_notify
|
|
||||||
|
|
||||||
started_at = time.monotonic()
|
|
||||||
session_box: dict[str, str | None] = {"id": resume_session}
|
|
||||||
progress_renderer = ExecProgressRenderer(max_actions=5)
|
|
||||||
|
|
||||||
progress_id: int | None = None
|
|
||||||
progress: ProgressEditor | None = None
|
|
||||||
try:
|
|
||||||
initial_text = progress_renderer.render_progress(0.0)
|
|
||||||
initial_rendered, initial_entities = render_markdown(initial_text)
|
|
||||||
progress_msg = bot.send_message(
|
|
||||||
chat_id=chat_id,
|
|
||||||
text=initial_rendered,
|
|
||||||
entities=initial_entities or None,
|
|
||||||
reply_to_message_id=user_msg_id,
|
|
||||||
disable_notification=silent_progress,
|
|
||||||
)
|
|
||||||
progress_id = int(progress_msg["message_id"])
|
|
||||||
logger.debug(
|
|
||||||
"[progress] sent chat_id=%s message_id=%s", chat_id, progress_id
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
logger.info(
|
|
||||||
"[handle] failed to send progress message chat_id=%s: %s", chat_id, e
|
|
||||||
)
|
|
||||||
|
|
||||||
if progress_id is not None:
|
|
||||||
progress = ProgressEditor(
|
|
||||||
bot,
|
|
||||||
chat_id,
|
|
||||||
progress_id,
|
|
||||||
edit_every_s,
|
|
||||||
initial_text=initial_rendered,
|
|
||||||
initial_entities=initial_entities or None,
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_event(evt: dict[str, Any]) -> None:
|
|
||||||
event_type = evt.get("type")
|
|
||||||
item = evt.get("item") or {}
|
|
||||||
logger.debug(
|
|
||||||
"[codex] event type=%s item_id=%s item_type=%s status=%s",
|
|
||||||
event_type,
|
|
||||||
item.get("id"),
|
|
||||||
item.get("type"),
|
|
||||||
item.get("status"),
|
|
||||||
)
|
|
||||||
if event_type == "thread.started":
|
|
||||||
thread_id = evt.get("thread_id")
|
|
||||||
if isinstance(thread_id, str) and thread_id:
|
|
||||||
session_box["id"] = thread_id
|
|
||||||
if progress_renderer.note_event(evt) and progress is not None:
|
|
||||||
elapsed = time.monotonic() - started_at
|
|
||||||
msg = progress_renderer.render_progress(elapsed)
|
|
||||||
progress.set_markdown(msg)
|
|
||||||
|
|
||||||
def _stop_background() -> None:
|
|
||||||
if progress is not None:
|
|
||||||
progress.stop()
|
|
||||||
logger.debug("[progress] thread stopped")
|
|
||||||
|
|
||||||
try:
|
|
||||||
session_id, answer, saw_agent_message = runner.run_serialized(
|
|
||||||
text,
|
|
||||||
resume_session,
|
|
||||||
on_event=on_event,
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
_stop_background()
|
|
||||||
err = _clamp_tg_text(f"Error:\n{e}")
|
|
||||||
if progress_id is not None and len(err) <= TELEGRAM_TEXT_LIMIT:
|
|
||||||
try:
|
|
||||||
bot.edit_message_text(
|
|
||||||
chat_id=chat_id, message_id=progress_id, text=err
|
|
||||||
)
|
|
||||||
logger.info(
|
|
||||||
"[handle] error chat_id=%s user_msg_id=%s resume_session=%r err=%s",
|
|
||||||
chat_id,
|
|
||||||
user_msg_id,
|
|
||||||
resume_session,
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
except Exception as ee:
|
|
||||||
logger.info("[handle] failed to edit progress into error: %s", ee)
|
|
||||||
|
|
||||||
_send_markdown(
|
|
||||||
bot, chat_id=chat_id, text=err, reply_to_message_id=user_msg_id
|
|
||||||
)
|
|
||||||
logger.info(
|
|
||||||
"[handle] error chat_id=%s user_msg_id=%s resume_session=%r err=%s",
|
|
||||||
chat_id,
|
|
||||||
user_msg_id,
|
|
||||||
resume_session,
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_stop_background()
|
|
||||||
|
|
||||||
answer = answer or "(No agent_message captured from JSON stream.)"
|
|
||||||
elapsed = time.monotonic() - started_at
|
|
||||||
status = "done" if saw_agent_message else "error"
|
|
||||||
final_md = progress_renderer.render_final(elapsed, answer, status=status)
|
|
||||||
final_md = final_md + f"\n\nresume: `{session_id}`"
|
|
||||||
final_text, final_entities = render_markdown(final_md)
|
|
||||||
can_edit_final = (
|
|
||||||
progress_id is not None and len(final_text) <= TELEGRAM_TEXT_LIMIT
|
|
||||||
)
|
|
||||||
|
|
||||||
if loud_final or not can_edit_final:
|
|
||||||
_send_markdown(
|
|
||||||
bot, chat_id=chat_id, text=final_md, reply_to_message_id=user_msg_id
|
|
||||||
)
|
|
||||||
if progress_id is not None:
|
|
||||||
try:
|
|
||||||
bot.delete_message(chat_id=chat_id, message_id=progress_id)
|
|
||||||
except Exception as e:
|
|
||||||
logger.info(
|
|
||||||
"[handle] delete progress failed chat_id=%s message_id=%s: %s",
|
|
||||||
chat_id,
|
|
||||||
progress_id,
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
bot.edit_message_text(
|
|
||||||
chat_id=chat_id,
|
|
||||||
message_id=progress_id,
|
|
||||||
text=final_text,
|
|
||||||
entities=final_entities or None,
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info(
|
|
||||||
"[handle] done chat_id=%s user_msg_id=%s session_id=%r",
|
|
||||||
chat_id,
|
|
||||||
user_msg_id,
|
|
||||||
session_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
updates = bot.get_updates(
|
|
||||||
offset=offset, timeout_s=50, allowed_updates=["message"]
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
logger.info("[telegram] get_updates error: %s", e)
|
|
||||||
time.sleep(2.0)
|
|
||||||
continue
|
|
||||||
|
|
||||||
for upd in updates:
|
|
||||||
offset = upd["update_id"] + 1
|
|
||||||
msg = upd.get("message") or {}
|
|
||||||
chat_id = msg.get("chat", {}).get("id")
|
|
||||||
from_bot = msg.get("from", {}).get("is_bot")
|
|
||||||
msg_text = msg.get("text")
|
|
||||||
reply_to = (msg.get("reply_to_message") or {}).get("message_id")
|
|
||||||
logger.info(
|
|
||||||
"[telegram] received update_id=%s chat_id=%s from_bot=%s has_text=%s reply_to=%s text=%s",
|
|
||||||
upd.get("update_id"),
|
|
||||||
chat_id,
|
|
||||||
from_bot,
|
|
||||||
msg_text is not None,
|
|
||||||
reply_to,
|
|
||||||
repr(msg_text),
|
|
||||||
)
|
|
||||||
if "text" not in msg:
|
|
||||||
logger.info(
|
|
||||||
"[telegram] ignoring non-text message chat_id=%s update_id=%s",
|
|
||||||
chat_id,
|
|
||||||
upd.get("update_id"),
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if int(chat_id) != config_chat_id:
|
|
||||||
logger.info(
|
|
||||||
"[telegram] rejected by ACL chat_id=%s allowed=%s",
|
|
||||||
chat_id,
|
|
||||||
config_chat_id,
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if msg.get("from", {}).get("is_bot"):
|
|
||||||
logger.info(
|
|
||||||
"[telegram] ignoring bot message chat_id=%s update_id=%s",
|
|
||||||
chat_id,
|
|
||||||
upd.get("update_id"),
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
text = msg["text"]
|
|
||||||
user_msg_id = msg["message_id"]
|
|
||||||
logger.info(
|
|
||||||
"[telegram] accepted message chat_id=%s user_msg_id=%s text=%s",
|
|
||||||
chat_id,
|
|
||||||
user_msg_id,
|
|
||||||
repr(text),
|
|
||||||
)
|
|
||||||
|
|
||||||
resume_session = extract_session_id(text)
|
|
||||||
r = msg.get("reply_to_message") or {}
|
|
||||||
resume_session = resume_session or extract_session_id(r.get("text"))
|
|
||||||
|
|
||||||
pool.submit(handle, chat_id, user_msg_id, text, resume_session)
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user