Files
talia_bot/talia_bot/modules/mailer.py
google-labs-jules[bot] 6ebe452c05 feat: implement JSON-driven conversational flow engine (final)
This commit delivers the complete and final implementation of the new conversational flow engine, addressing all feedback from previous code reviews.

- **Adds Critical Data Files:** Creates `talia_bot/data/flows.json` and `talia_bot/data/services.json`, resolving the critical blocking issue and making the bot fully functional.
- **Corrects Vikunja Flow:** The `admin_project_management` flow in `flows.json` now correctly includes a step to select a task after selecting a project. The resolution logic in `main.py` is updated to use the correct `task_id`.
- **Implements All Resolutions:** The `handle_flow_resolution` function in `main.py` is now complete, with functional logic for all resolution types, including robust date/time parsing for calendar events and branching logic for idea capture.
- **Fixes and Cleanup:** Corrects the OpenAI API call in the `transcription.py` module and removes all legacy `ConversationHandler` code from `vikunja.py` and `main.py`.
- **Configuration and Docs:** The project configuration (`config.py`, `.env.example`) and documentation (`README.md`) are fully updated to reflect the final state of the new architecture.
2025-12-21 01:28:24 +00:00

65 lines
2.0 KiB
Python

# talia_bot/modules/mailer.py
import smtplib
import ssl
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import logging
import asyncio
from talia_bot.config import (
SMTP_SERVER, SMTP_PORT, SMTP_USER, SMTP_PASSWORD,
IMAP_USER, PRINTER_EMAIL
)
logger = logging.getLogger(__name__)
async def send_email_with_attachment(file_content: bytes, filename: str, subject: str):
"""
Sends an email with an attachment using SMTP.
Adapts connection method based on SMTP_PORT.
"""
if not all([SMTP_SERVER, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, PRINTER_EMAIL]):
logger.error("SMTP settings are not fully configured.")
return False
message = MIMEMultipart()
message["From"] = IMAP_USER
message["To"] = PRINTER_EMAIL
message["Subject"] = subject
part = MIMEBase("application", "octet-stream")
part.set_payload(file_content)
encoders.encode_base64(part)
part.add_header(
"Content-Disposition",
f"attachment; filename= {filename}",
)
message.attach(part)
text = message.as_string()
try:
context = ssl.create_default_context()
def _send_mail():
if SMTP_PORT == 465:
# Use SMTP_SSL for port 465
with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT, context=context) as server:
server.login(SMTP_USER, SMTP_PASSWORD)
server.sendmail(IMAP_USER, PRINTER_EMAIL, text)
else:
# Use STARTTLS for other ports like 587
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
server.starttls(context=context)
server.login(SMTP_USER, SMTP_PASSWORD)
server.sendmail(IMAP_USER, PRINTER_EMAIL, text)
logger.info(f"Email sent to {PRINTER_EMAIL} for printing.")
await asyncio.to_thread(_send_mail)
return True
except Exception as e:
logger.error(f"Failed to send email: {e}")
return False