refactor(notifications): unify email sending via _send_email; standardize crawler notifications\n\n- Extract _send_email and have send_email/send_custom_email share it\n- BaseCrawler: centralize _send_notifications and add _build_email hook\n- BarronsCrawler: override _build_email to keep original subject/body\n- OpenInsiderCrawler: remove custom _send_notifications, add _build_email\n- /notify_test: use crawler _build_email + send_custom_email for emails
This commit is contained in:
@@ -21,28 +21,7 @@ def format_email_body(new_picks: List[Dict]) -> str:
|
||||
return body
|
||||
|
||||
|
||||
def send_email(new_picks: List[Dict], cfg: EmailConfig) -> None:
|
||||
msg = MIMEMultipart()
|
||||
msg['From'] = cfg.from_email
|
||||
msg['To'] = cfg.to_email
|
||||
msg['Subject'] = f"📈 Barron's 新股票推薦 ({len(new_picks)}條)"
|
||||
msg.attach(MIMEText(format_email_body(new_picks), 'plain', 'utf-8'))
|
||||
|
||||
if cfg.smtp_security == 'ssl':
|
||||
server = smtplib.SMTP_SSL(cfg.smtp_server, cfg.smtp_port)
|
||||
else:
|
||||
server = smtplib.SMTP(cfg.smtp_server, cfg.smtp_port)
|
||||
server.ehlo()
|
||||
if cfg.smtp_security == 'starttls':
|
||||
server.starttls()
|
||||
server.ehlo()
|
||||
|
||||
server.login(cfg.username, cfg.password)
|
||||
server.send_message(msg)
|
||||
server.quit()
|
||||
|
||||
|
||||
def send_custom_email(subject: str, body: str, cfg: EmailConfig) -> None:
|
||||
def _send_email(subject: str, body: str, cfg: EmailConfig) -> None:
|
||||
msg = MIMEMultipart()
|
||||
msg['From'] = cfg.from_email
|
||||
msg['To'] = cfg.to_email
|
||||
@@ -63,6 +42,16 @@ def send_custom_email(subject: str, body: str, cfg: EmailConfig) -> None:
|
||||
server.quit()
|
||||
|
||||
|
||||
def send_email(new_picks: List[Dict], cfg: EmailConfig) -> None:
|
||||
subject = f"📈 Barron's 新股票推薦 ({len(new_picks)}條)"
|
||||
body = format_email_body(new_picks)
|
||||
_send_email(subject, body, cfg)
|
||||
|
||||
|
||||
def send_custom_email(subject: str, body: str, cfg: EmailConfig) -> None:
|
||||
_send_email(subject, body, cfg)
|
||||
|
||||
|
||||
def send_webhook(new_picks: List[Dict], url: str) -> None:
|
||||
message = f"🚨 發現 {len(new_picks)} 條新的 Barron's 股票推薦!\n\n"
|
||||
for pick in new_picks[:5]:
|
||||
|
Reference in New Issue
Block a user