feat(email): 配置 foxmail SMTP 发信 + 发件人显示名品牌化 + bump 0.23.2
- .env 填入 smtp.qq.com:25/STARTTLS/授权码,send_email tool 与定时任务 notify 兜底投递生效(.env 不入库) - send_email.py 发件人显示名由硬编码 zcbot 改读 SMTP_FROM_NAME,默认 「总院科研辅助智能体」,对外不暴露内部代号 - RUN.md 补 SMTP_FROM_NAME 说明;PROGRESS 记一条 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
340786a42f
commit
320f428dd3
|
|
@ -21,6 +21,11 @@
|
||||||
|
|
||||||
## 已完成关键能力
|
## 已完成关键能力
|
||||||
|
|
||||||
|
### 2026-06-24 / 配置 QQ/foxmail SMTP 发信 + 发件人显示名品牌化(bump 0.23.2)
|
||||||
|
|
||||||
|
- `.env` 填入 foxmail SMTP(smtp.qq.com:25 / STARTTLS / 授权码),`send_email` tool 与定时任务 notify 兜底投递就此生效;自检发信链路通过。
|
||||||
|
- `tools/send_email.py` 发件人显示名从硬编码 `zcbot` 改为读 `SMTP_FROM_NAME`,默认「总院科研辅助智能体」—— 对外不暴露内部代号。RUN.md env 段补 `SMTP_FROM_NAME`。
|
||||||
|
|
||||||
### 2026-06-24 / 微信任务徽章改品牌绿 + 微信 logo + 整行绿边(bump 0.23.1)
|
### 2026-06-24 / 微信任务徽章改品牌绿 + 微信 logo + 整行绿边(bump 0.23.1)
|
||||||
|
|
||||||
- 上一版徽章复用 `.badge.active`(蓝灰),与旁边「进行中」状态徽章撞色、不显眼。
|
- 上一版徽章复用 `.badge.active`(蓝灰),与旁边「进行中」状态徽章撞色、不显眼。
|
||||||
|
|
|
||||||
1
RUN.md
1
RUN.md
|
|
@ -51,6 +51,7 @@
|
||||||
# SMTP_USER=you@qq.com
|
# SMTP_USER=you@qq.com
|
||||||
# SMTP_PASSWORD=<授权码/应用专用密码,非登录密码>
|
# SMTP_PASSWORD=<授权码/应用专用密码,非登录密码>
|
||||||
# SMTP_FROM=you@qq.com # 可选,默认取 SMTP_USER
|
# SMTP_FROM=you@qq.com # 可选,默认取 SMTP_USER
|
||||||
|
# SMTP_FROM_NAME=总院科研辅助智能体 # 可选,发件人显示名,默"总院科研辅助智能体"(不暴露内部代号)
|
||||||
# 定时任务守护循环(DESIGN §8.5,随 web 进程起,plain-asyncio 仿 _disk_scanner):
|
# 定时任务守护循环(DESIGN §8.5,随 web 进程起,plain-asyncio 仿 _disk_scanner):
|
||||||
# ZCBOT_DISABLE_SCHEDULER=1 # 可选,整体关掉调度(对照 Claude Code CLAUDE_CODE_DISABLE_CRON)
|
# ZCBOT_DISABLE_SCHEDULER=1 # 可选,整体关掉调度(对照 Claude Code CLAUDE_CODE_DISABLE_CRON)
|
||||||
# ZCBOT_SCHEDULER_TICK_SECONDS=10 # 可选,扫描间隔,默 10s(只决定最坏延迟≤1tick,不影响会否漏)
|
# ZCBOT_SCHEDULER_TICK_SECONDS=10 # 可选,扫描间隔,默 10s(只决定最坏延迟≤1tick,不影响会否漏)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
||||||
# 改版本只动这一行。
|
# 改版本只动这一行。
|
||||||
__version__ = "0.23.1"
|
__version__ = "0.23.2"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@
|
||||||
|
|
||||||
密钥只在 host 进程读,绝不进沙箱 / run_python。env:
|
密钥只在 host 进程读,绝不进沙箱 / run_python。env:
|
||||||
SMTP_HOST SMTP_PORT(默 465) SMTP_USER SMTP_PASSWORD
|
SMTP_HOST SMTP_PORT(默 465) SMTP_USER SMTP_PASSWORD
|
||||||
SMTP_FROM(默 SMTP_USER) SMTP_TLS(ssl|starttls|none;默按端口:465→ssl 否则 starttls)
|
SMTP_FROM(默 SMTP_USER) SMTP_FROM_NAME(发件人显示名,默"总院科研辅助智能体")
|
||||||
|
SMTP_TLS(ssl|starttls|none;默按端口:465→ssl 否则 starttls)
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
@ -62,6 +63,7 @@ def send_email_smtp(
|
||||||
user = os.getenv("SMTP_USER", "").strip()
|
user = os.getenv("SMTP_USER", "").strip()
|
||||||
password = os.getenv("SMTP_PASSWORD", "").strip()
|
password = os.getenv("SMTP_PASSWORD", "").strip()
|
||||||
sender = os.getenv("SMTP_FROM", "").strip() or user
|
sender = os.getenv("SMTP_FROM", "").strip() or user
|
||||||
|
from_name = os.getenv("SMTP_FROM_NAME", "").strip() or "总院科研辅助智能体"
|
||||||
|
|
||||||
if isinstance(to, str):
|
if isinstance(to, str):
|
||||||
to_list = [to]
|
to_list = [to]
|
||||||
|
|
@ -74,7 +76,7 @@ def send_email_smtp(
|
||||||
raise ValueError(f"收件人过多(上限 {_MAX_RECIPIENTS})")
|
raise ValueError(f"收件人过多(上限 {_MAX_RECIPIENTS})")
|
||||||
|
|
||||||
msg = EmailMessage()
|
msg = EmailMessage()
|
||||||
msg["From"] = formataddr(("zcbot", sender))
|
msg["From"] = formataddr((from_name, sender))
|
||||||
msg["To"] = ", ".join(to_list)
|
msg["To"] = ", ".join(to_list)
|
||||||
msg["Subject"] = subject or "(无主题)"
|
msg["Subject"] = subject or "(无主题)"
|
||||||
msg.set_content(body or "")
|
msg.set_content(body or "")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue