fix: telegram push Graph API proxy support, client_id SELECT, and frontend null checks

- Fix _fetch_new_emails_graph to use get_access_token_graph (not get_access_token)
- Add client_id to get_telegram_push_accounts() SELECT
- JOIN groups table to get proxy_url per account
- Pass proxy_url to get_access_token_graph() and requests.get()
- Add null checks for Telegram DOM elements in loadSettings/saveSettings
- Add job start/end logging to run_telegram_push_job
- Add scheduler registration log message

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
胡绍康andCopilot committed 2026-03-05 16:16:49 +08:00
1 parent 2326410067
commit 4adb255e87
4 files changed
+37 -13

No files matched your search

+7 -4
View File
@@ -408,9 +408,12 @@ def get_telegram_push_accounts() -> List[Dict]:
"""返回所有 telegram_push_enabled=1 且非 disabled 状态的账号。"""
db = get_db()
rows = db.execute(
"""SELECT id, email, provider, refresh_token, imap_host, imap_port,
imap_password, telegram_last_checked_at
FROM accounts
WHERE telegram_push_enabled = 1 AND status != 'disabled'"""
"""SELECT a.id, a.email, a.provider, a.client_id, a.refresh_token,
a.imap_host, a.imap_port, a.imap_password,
a.telegram_last_checked_at, a.group_id,
g.proxy_url
FROM accounts a
LEFT JOIN groups g ON a.group_id = g.id
WHERE a.telegram_push_enabled = 1 AND a.status != 'disabled'"""
).fetchall()
return [dict(r) for r in rows]
+1
View File
@@ -92,6 +92,7 @@ def _configure_telegram_push_job(scheduler, app) -> None:
coalesce=True,
misfire_grace_time=interval,
)
print(f"✓ Telegram 推送 Job 已配置(轮询间隔:{interval} 秒)")
def configure_scheduler_jobs(scheduler, app, test_refresh_token) -> None:
+16 -3
View File
@@ -205,12 +205,14 @@ def _fetch_new_emails_imap(account: dict, since: str) -> List[dict]:
def _fetch_new_emails_graph(account: dict, since: str) -> List[dict]:
"""通过 Microsoft Graph API 获取 received_at > since 的邮件,最多返回 50 封。"""
from outlook_web.security.crypto import decrypt_data
from outlook_web.services.graph import get_access_token
from outlook_web.services.graph import build_proxies, get_access_token_graph
client_id = account.get("client_id", "")
refresh_token_raw = account.get("refresh_token", "")
refresh_token = decrypt_data(refresh_token_raw) if refresh_token_raw else ""
proxy_url = account.get("proxy_url", "") or ""
access_token = get_access_token(refresh_token)
access_token = get_access_token_graph(client_id, refresh_token, proxy_url)
if not access_token:
return []
@@ -223,10 +225,11 @@ def _fetch_new_emails_graph(account: dict, since: str) -> List[dict]:
"$orderby": "receivedDateTime asc",
}
headers = {"Authorization": f"Bearer {access_token}"}
proxies = build_proxies(proxy_url)
results: List[dict] = []
try:
resp = requests.get(url, headers=headers, params=params, timeout=15)
resp = requests.get(url, headers=headers, params=params, timeout=15, proxies=proxies)
if not resp.ok:
return []
data = resp.json()
@@ -258,6 +261,11 @@ def _fetch_new_emails_graph(account: dict, since: str) -> List[dict]:
def run_telegram_push_job(app) -> None:
"""主入口:轮询 → 推送 → 更新游标。由调度器调用。"""
import time
t0 = time.monotonic()
logger.info("[telegram_push] job started")
with app.app_context():
from outlook_web.repositories.accounts import (
get_telegram_push_accounts,
@@ -271,10 +279,12 @@ def run_telegram_push_job(app) -> None:
chat_id = get_setting("telegram_chat_id", "")
if not bot_token or not chat_id:
logger.info("[telegram_push] job skipped: no bot_token or chat_id")
return
accounts = get_telegram_push_accounts()
if not accounts:
logger.info("[telegram_push] job skipped: no push-enabled accounts")
return
job_start_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S")
@@ -309,3 +319,6 @@ def run_telegram_push_job(app) -> None:
finally:
update_telegram_cursor(account["id"], job_start_time)
elapsed = time.monotonic() - t0
logger.info("[telegram_push] job finished: sent=%d elapsed=%.1fs", sent_count, elapsed)
+13 -6
View File
@@ -989,11 +989,15 @@ ${details}
document.getElementById('pollingCount').value = data.settings.polling_count || '5';
// 加载 Telegram 推送设置
document.getElementById('telegramBotToken').value = data.telegram_bot_token || '';
document.getElementById('telegramChatId').value = data.telegram_chat_id || '';
document.getElementById('telegramPollInterval').value = data.telegram_poll_interval || '600';
const tgToken = document.getElementById('telegramBotToken');
const tgChat = document.getElementById('telegramChatId');
const tgPoll = document.getElementById('telegramPollInterval');
if (tgToken) tgToken.value = data.telegram_bot_token || '';
if (tgChat) tgChat.value = data.telegram_chat_id || '';
if (tgPoll) tgPoll.value = data.telegram_poll_interval || '600';
}
} catch (error) {
console.error('loadSettings error:', error);
showToast('加载设置失败', 'error');
}
}
@@ -1126,9 +1130,12 @@ ${details}
settings.polling_count = pCount;
// Telegram 推送配置
const tgBotToken = document.getElementById('telegramBotToken').value.trim();
const tgChatId = document.getElementById('telegramChatId').value.trim();
const tgPollInterval = parseInt(document.getElementById('telegramPollInterval').value);
const tgBotTokenEl = document.getElementById('telegramBotToken');
const tgChatIdEl = document.getElementById('telegramChatId');
const tgPollIntervalEl = document.getElementById('telegramPollInterval');
const tgBotToken = tgBotTokenEl ? tgBotTokenEl.value.trim() : '';
const tgChatId = tgChatIdEl ? tgChatIdEl.value.trim() : '';
const tgPollInterval = tgPollIntervalEl ? parseInt(tgPollIntervalEl.value) : NaN;
if (tgBotToken) {
settings.telegram_bot_token = tgBotToken;