# send_mail.py import os, smtplib, sys, mimetypes from datetime import datetime, timezone, timedelta from email.message import EmailMessage # 讀環境變數(請在 crontab 或 GitHub Actions secrets 設定) # 如果未設定,則跳過郵件發送功能 GMAIL_USER = os.environ.get("GMAIL_USERNAME") # 例如:yourname@gmail.com GMAIL_PASS = os.environ.get("GMAIL_APP_PASSWORD") # 16碼 App Password(非一般登入密碼) TO = os.environ.get("MAIL_TO", "kaeruzak@gmail.com") # 檢查是否啟用郵件功能 ENABLE_MAIL = GMAIL_USER and GMAIL_PASS # 參數:CSV 路徑(預設 ./hbr_articles.csv) csv_path = sys.argv[1] if len(sys.argv) > 1 else "hbr_articles.csv" if not os.path.exists(csv_path): print(f"[WARN] CSV not found: {csv_path}") sys.exit(0) # 如果未啟用郵件功能,僅顯示資訊並退出 if not ENABLE_MAIL: print("[INFO] Gmail SMTP 未設定,跳過郵件發送功能") print(f"[INFO] CSV 檔案已產生: {csv_path}") print("[INFO] 如需啟用郵件功能,請設定以下環境變數:") print(" - GMAIL_USERNAME") print(" - GMAIL_APP_PASSWORD") print(" - MAIL_TO (可選,預設: kaeruzak@gmail.com)") sys.exit(0) # 產生台北時間日期字串 tz = timezone(timedelta(hours=8)) date_str = datetime.now(tz).strftime("%Y-%m-%d %H:%M") # 組信 msg = EmailMessage() msg["Subject"] = f"[HBRTW 每週爬取] 文章清單 CSV - {date_str}" msg["From"] = GMAIL_USER msg["To"] = TO msg.set_content(f"""您好, 附件為本週 HBR Taiwan 最新/熱門文章彙整(CSV)。 產生時間:{date_str}(Asia/Taipei) 若您需要改排程或加上上傳雲端,回覆此信即可。 """) # 夾帶 CSV ctype, encoding = mimetypes.guess_type(csv_path) if ctype is None or encoding is not None: ctype = "application/octet-stream" maintype, subtype = ctype.split("/", 1) with open(csv_path, "rb") as f: msg.add_attachment(f.read(), maintype=maintype, subtype=subtype, filename=os.path.basename(csv_path)) # 寄送郵件 try: with smtplib.SMTP_SSL("smtp.gmail.com", 465) as smtp: smtp.login(GMAIL_USER, GMAIL_PASS) smtp.send_message(msg) print(f"[OK] Mail sent to {TO}") except smtplib.SMTPAuthenticationError as e: print(f"[ERROR] Gmail 認證失敗: {e}") print("請確認:") print(" 1. GMAIL_USERNAME 是否正確") print(" 2. GMAIL_APP_PASSWORD 是否為有效的 App Password(16碼)") print(" 3. 是否已啟用 Gmail 的兩步驟驗證") sys.exit(1) except Exception as e: print(f"[ERROR] 郵件發送失敗: {e}") sys.exit(1)