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:
2025-11-06 21:58:03 +02:00
parent 1e20334b3d
commit 7e8dadcbdc
3 changed files with 88 additions and 2 deletions

View File

@@ -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`.
## Coding Guidelines
**NO EMOJIS**: Do not use emojis in user-facing messages (Telegram, email, notifications). Use plain text only.
## Running the Scraper
```powershell

View File

@@ -45,6 +45,13 @@ class EmailNotifier:
logging.error("Email configuration incomplete")
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
msg = MIMEMultipart()
msg['From'] = self.config.EMAIL_FROM
@@ -138,6 +145,64 @@ class EmailNotifier:
logging.error(f"Failed to send email with ZIP: {e}")
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:
"""Create HTML email body"""
file_list = '<br>'.join([f'{Path(f).name}' for f in files])

View File

@@ -15,6 +15,8 @@ from datetime import datetime
import glob
import requests
from dotenv import load_dotenv
from config import Config
from notifications import EmailNotifier
# Load environment
load_dotenv()
@@ -238,7 +240,7 @@ class TelegramTriggerBot:
return
# 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"Dimensiune: {zip_size:.2f} MB\n"
caption += f"Fișiere: {len(files_to_zip)}\n\n"
@@ -256,7 +258,7 @@ class TelegramTriggerBot:
caption += f"Conturi: {len(transaction_files)}"
# 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"
with open(zip_path, 'rb') as f:
@@ -277,6 +279,21 @@ class TelegramTriggerBot:
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)
# 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
zip_path.unlink()