- Inline keyboard: view original / back to summary toggle per message - SMTP config per account for sending replies - Reply button: click, type message, auto-send via SMTP - AI Reply button: generates 3 suggestions via DeepSeek - Simple replies (OK, Got it) send immediately on tap - Substantive replies require confirm before send - Hides AI Reply button when AI determines reply unnecessary - Telegram long polling integrated into main loop for real-time interaction
56 lines
1.3 KiB
Python
56 lines
1.3 KiB
Python
import logging
|
||
import signal
|
||
import sys
|
||
import time
|
||
from src.config import load_config
|
||
from src.summarizer import process_all
|
||
from src.tg_bot import poll_telegram
|
||
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
||
datefmt="%Y-%m-%d %H:%M:%S",
|
||
)
|
||
logger = logging.getLogger("main")
|
||
|
||
_running = True
|
||
|
||
|
||
def _signal_handler(signum, frame):
|
||
global _running
|
||
logger.info("收到退出信号,正在停止...")
|
||
_running = False
|
||
|
||
|
||
def main():
|
||
global _running
|
||
signal.signal(signal.SIGINT, _signal_handler)
|
||
signal.signal(signal.SIGTERM, _signal_handler)
|
||
|
||
cfg_path = sys.argv[1] if len(sys.argv) > 1 else "config.yaml"
|
||
cfg = load_config(cfg_path)
|
||
logger.info(f"AI邮件摘要机器人已启动,轮询间隔: {cfg.polling.interval_seconds}s")
|
||
|
||
last_check = 0.0
|
||
last_update_id = 0
|
||
|
||
while _running:
|
||
try:
|
||
now = time.time()
|
||
if now - last_check >= cfg.polling.interval_seconds:
|
||
process_all(cfg)
|
||
last_check = now
|
||
|
||
last_update_id = poll_telegram(cfg.telegram, cfg, last_update_id)
|
||
except Exception as e:
|
||
logger.error(f"主循环出错: {e}", exc_info=True)
|
||
|
||
if _running:
|
||
time.sleep(1)
|
||
|
||
logger.info("机器人已停止")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|