Adaugă trimitere ZIP pe email și elimină emoji-uri din mesaje
- /scrape_zip trimite ZIP pe ambele canale (Telegram + email) - /zip trimite ZIP și pe email, nu doar pe Telegram - Elimină emoji-uri din mesajele Telegram user-facing - Adaugă ghid "NO EMOJIS" în CLAUDE.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,10 @@ BTGO Scraper - Playwright automation for extracting account balances and transac
|
|||||||
|
|
||||||
**⚠️ CRITICAL**: Docker/headless mode is **BLOCKED by WAF**. ONLY works locally with `HEADLESS=false`.
|
**⚠️ CRITICAL**: Docker/headless mode is **BLOCKED by WAF**. ONLY works locally with `HEADLESS=false`.
|
||||||
|
|
||||||
|
## Coding Guidelines
|
||||||
|
|
||||||
|
**NO EMOJIS**: Do not use emojis in user-facing messages (Telegram, email, notifications). Use plain text only.
|
||||||
|
|
||||||
## Running the Scraper
|
## Running the Scraper
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
|
|||||||
@@ -45,6 +45,13 @@ class EmailNotifier:
|
|||||||
logging.error("Email configuration incomplete")
|
logging.error("Email configuration incomplete")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Check if SEND_AS_ZIP flag is set (from Telegram bot /scrape_zip command)
|
||||||
|
send_as_zip = os.getenv('SEND_AS_ZIP', 'false').lower() == 'true'
|
||||||
|
|
||||||
|
if send_as_zip:
|
||||||
|
logging.info("SEND_AS_ZIP flag detected - sending email with ZIP archive")
|
||||||
|
return self._send_with_zip(files, accounts)
|
||||||
|
|
||||||
# Create message
|
# Create message
|
||||||
msg = MIMEMultipart()
|
msg = MIMEMultipart()
|
||||||
msg['From'] = self.config.EMAIL_FROM
|
msg['From'] = self.config.EMAIL_FROM
|
||||||
@@ -138,6 +145,64 @@ class EmailNotifier:
|
|||||||
logging.error(f"Failed to send email with ZIP: {e}")
|
logging.error(f"Failed to send email with ZIP: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def send_existing_zip(self, zip_path: Path, accounts: list) -> bool:
|
||||||
|
"""
|
||||||
|
Send email with existing ZIP file
|
||||||
|
|
||||||
|
Args:
|
||||||
|
zip_path: Path to existing ZIP file
|
||||||
|
accounts: List of account data with balances
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if successful, False otherwise
|
||||||
|
"""
|
||||||
|
if not self.enabled:
|
||||||
|
logging.info("Email notifications disabled")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Validate config
|
||||||
|
if not all([self.config.SMTP_SERVER, self.config.EMAIL_FROM, self.config.EMAIL_TO]):
|
||||||
|
logging.error("Email configuration incomplete")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not zip_path.exists():
|
||||||
|
logging.error(f"ZIP file not found: {zip_path}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Create message
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
msg['From'] = self.config.EMAIL_FROM
|
||||||
|
msg['To'] = self.config.EMAIL_TO
|
||||||
|
msg['Subject'] = f'BTGO Export (ZIP) - {datetime.now().strftime("%Y-%m-%d %H:%M")}'
|
||||||
|
|
||||||
|
# Email body
|
||||||
|
body = self._create_email_body([str(zip_path)], accounts, is_zip=True)
|
||||||
|
msg.attach(MIMEText(body, 'html'))
|
||||||
|
|
||||||
|
# Attach ZIP file
|
||||||
|
with open(zip_path, 'rb') as f:
|
||||||
|
part = MIMEBase('application', 'zip')
|
||||||
|
part.set_payload(f.read())
|
||||||
|
encoders.encode_base64(part)
|
||||||
|
part.add_header('Content-Disposition', f'attachment; filename={zip_path.name}')
|
||||||
|
msg.attach(part)
|
||||||
|
|
||||||
|
# Send email
|
||||||
|
logging.info(f"Sending email with existing ZIP to {self.config.EMAIL_TO}...")
|
||||||
|
with smtplib.SMTP(self.config.SMTP_SERVER, self.config.SMTP_PORT) as server:
|
||||||
|
server.starttls()
|
||||||
|
if self.config.SMTP_USERNAME and self.config.SMTP_PASSWORD:
|
||||||
|
server.login(self.config.SMTP_USERNAME, self.config.SMTP_PASSWORD)
|
||||||
|
server.send_message(msg)
|
||||||
|
|
||||||
|
logging.info(f"✓ Email with ZIP sent successfully to {self.config.EMAIL_TO}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Failed to send email with existing ZIP: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def _create_email_body(self, files: List[str], accounts: list, is_zip: bool = False) -> str:
|
def _create_email_body(self, files: List[str], accounts: list, is_zip: bool = False) -> str:
|
||||||
"""Create HTML email body"""
|
"""Create HTML email body"""
|
||||||
file_list = '<br>'.join([f'• {Path(f).name}' for f in files])
|
file_list = '<br>'.join([f'• {Path(f).name}' for f in files])
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ from datetime import datetime
|
|||||||
import glob
|
import glob
|
||||||
import requests
|
import requests
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
from config import Config
|
||||||
|
from notifications import EmailNotifier
|
||||||
|
|
||||||
# Load environment
|
# Load environment
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
@@ -238,7 +240,7 @@ class TelegramTriggerBot:
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Construiește mesaj cu solduri
|
# Construiește mesaj cu solduri
|
||||||
caption = f"📦 *BTGO Export (ZIP)*\n\n"
|
caption = f"*BTGO Export (ZIP)*\n\n"
|
||||||
caption += f"Timp: {datetime.fromtimestamp(solduri_time).strftime('%Y-%m-%d %H:%M:%S')}\n"
|
caption += f"Timp: {datetime.fromtimestamp(solduri_time).strftime('%Y-%m-%d %H:%M:%S')}\n"
|
||||||
caption += f"Dimensiune: {zip_size:.2f} MB\n"
|
caption += f"Dimensiune: {zip_size:.2f} MB\n"
|
||||||
caption += f"Fișiere: {len(files_to_zip)}\n\n"
|
caption += f"Fișiere: {len(files_to_zip)}\n\n"
|
||||||
@@ -256,7 +258,7 @@ class TelegramTriggerBot:
|
|||||||
caption += f"Conturi: {len(transaction_files)}"
|
caption += f"Conturi: {len(transaction_files)}"
|
||||||
|
|
||||||
# Trimite ZIP-ul
|
# Trimite ZIP-ul
|
||||||
self.send_message(chat_id, "📦 *Creare arhivă ZIP...*", reply_to_message_id)
|
self.send_message(chat_id, "*Creare arhivă ZIP...*", reply_to_message_id)
|
||||||
|
|
||||||
url = f"{self.base_url}/sendDocument"
|
url = f"{self.base_url}/sendDocument"
|
||||||
with open(zip_path, 'rb') as f:
|
with open(zip_path, 'rb') as f:
|
||||||
@@ -277,6 +279,21 @@ class TelegramTriggerBot:
|
|||||||
logging.error(f"Eroare trimitere ZIP: {response.text}")
|
logging.error(f"Eroare trimitere ZIP: {response.text}")
|
||||||
self.send_message(chat_id, f"*EROARE*\n\nNu s-a putut trimite arhiva.", reply_to_message_id)
|
self.send_message(chat_id, f"*EROARE*\n\nNu s-a putut trimite arhiva.", reply_to_message_id)
|
||||||
|
|
||||||
|
# Trimite și pe email dacă este configurat
|
||||||
|
try:
|
||||||
|
config = Config()
|
||||||
|
if config.EMAIL_ENABLED:
|
||||||
|
email_notifier = EmailNotifier(config)
|
||||||
|
logging.info("Trimitere ZIP pe email...")
|
||||||
|
if email_notifier.send_existing_zip(zip_path, accounts_data):
|
||||||
|
logging.info("✓ ZIP trimis cu succes pe email")
|
||||||
|
else:
|
||||||
|
logging.warning("Nu s-a putut trimite ZIP-ul pe email")
|
||||||
|
else:
|
||||||
|
logging.info("Email notifications disabled - skipping email")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Eroare trimitere ZIP pe email: {e}")
|
||||||
|
|
||||||
# Șterge fișierul ZIP temporar
|
# Șterge fișierul ZIP temporar
|
||||||
zip_path.unlink()
|
zip_path.unlink()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user