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:
@@ -8,7 +8,6 @@ import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from app.crawlers.base import BaseCrawler
|
||||
from app.services import notifications as notif
|
||||
|
||||
|
||||
class OpenInsiderCrawler(BaseCrawler):
|
||||
@@ -128,35 +127,15 @@ class OpenInsiderCrawler(BaseCrawler):
|
||||
self.logger.info(f"OpenInsider:解析完成,擷取 {len(items)} 筆交易")
|
||||
return items
|
||||
|
||||
def _send_notifications(self, items: List[Dict]) -> None:
|
||||
# Use BaseCrawler._send_notifications for unified flow
|
||||
|
||||
def _build_email(self, items: List[Dict]):
|
||||
subject = f"OpenInsider 內部人交易異動 - {self.symbol} ({len(items)}筆)"
|
||||
lines = []
|
||||
for it in items[:10]:
|
||||
lines.append(f"• {it['title']}")
|
||||
lines.append(f"• {it.get('title','')}")
|
||||
body = (
|
||||
f"發現 {len(items)} 筆新的內部人交易異動(OpenInsider):\n\n" + "\n".join(lines) + "\n\n"
|
||||
f"抓取時間:{datetime.now().isoformat()}\n來源:{self.url}"
|
||||
)
|
||||
|
||||
sent = False
|
||||
if self.config.email:
|
||||
try:
|
||||
notif.send_custom_email(subject, body, self.config.email)
|
||||
sent = True
|
||||
except Exception as e:
|
||||
self.logger.error(f"電子郵件通知失敗: {e}")
|
||||
if self.config.webhook_url:
|
||||
try:
|
||||
notif.send_text_webhook(subject + "\n\n" + body, self.config.webhook_url)
|
||||
sent = True
|
||||
except Exception as e:
|
||||
self.logger.error(f"Webhook 通知失敗: {e}")
|
||||
if self.config.discord_webhook:
|
||||
try:
|
||||
notif.send_text_discord(title=subject, description=f"{self.symbol} 內部人交易更新(OpenInsider)", lines=lines[:10], webhook=self.config.discord_webhook)
|
||||
sent = True
|
||||
except Exception as e:
|
||||
self.logger.error(f"Discord 通知失敗: {e}")
|
||||
if sent:
|
||||
self.stats['last_notification'] = datetime.now().isoformat()
|
||||
|
||||
return subject, body
|
||||
|
Reference in New Issue
Block a user