File size: 3,879 Bytes
9f6c9c1
 
 
 
 
cda2fea
1a3c66f
9f6c9c1
 
 
 
1a3c66f
9f6c9c1
 
 
 
 
1a3c66f
cda2fea
7bb2e35
b6db6e3
1a3c66f
 
 
 
 
 
 
 
 
9f6c9c1
1a3c66f
9f6c9c1
 
 
 
 
1a3c66f
9f6c9c1
1a3c66f
 
 
 
b6db6e3
1a3c66f
9f6c9c1
1a3c66f
 
 
 
9f6c9c1
1a3c66f
 
 
 
 
 
 
9f6c9c1
 
1a3c66f
 
9f6c9c1
b6db6e3
 
1a3c66f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import os
import ssl
import time

class EmailHandler:
    def __init__(self):
        self.smtp_server = "smtp.gmail.com"
        self.smtp_port = 587  # Using TLS port instead of SSL
        self.sender_email = os.getenv('GMAIL_USER')
        self.sender_password = os.getenv('GMAIL_APP_PASSWORD')

        # Verify credentials
        if not self.sender_email or not self.sender_password:
            raise ValueError("Email credentials not properly configured. Please check GMAIL_USER and GMAIL_APP_PASSWORD environment variables.")
       
    def send_invoice(self, recipient_email, workflow_state_dict, invoice_path):
        """Send invoice email with retry mechanism"""
        max_retries = 3
        retry_delay = 2
        
        for attempt in range(max_retries):
            try:
                msg = MIMEMultipart()
                msg['From'] = self.sender_email
                msg['To'] = recipient_email
                msg['Subject'] = f"Invoice #{workflow_state_dict['invoice']['transaction_id']} - Payment Due"

                body = f"""Dear {workflow_state_dict['customer']['cust_fname']},
Your payment of {workflow_state_dict['invoice']['currency']} {workflow_state_dict['invoice']['billed_amount']} is due by {workflow_state_dict['invoice']['payment_due_date']}.
Please do the payment at the earliest.
Best regards,
Your Company Name"""

                msg.attach(MIMEText(body, 'plain'))

                # Attach PDF
                with open(invoice_path, "rb") as f:
                    pdf = MIMEApplication(f.read(), _subtype="pdf")
                    pdf.add_header('Content-Disposition', 'attachment', 
                                 filename=os.path.basename(invoice_path))
                    msg.attach(pdf)

                print(f"Attempt {attempt + 1}: Connecting to Gmail SMTP server...")
                
                # Using SMTP with TLS
                with smtplib.SMTP(self.smtp_server, self.smtp_port, timeout=30) as server:
                    print("Connected to SMTP server")
                    server.ehlo()  # Identify ourselves to the server
                    print("Starting TLS encryption...")
                    server.starttls(context=ssl.create_default_context())
                    server.ehlo()  # Re-identify ourselves over TLS connection
                    print("TLS encryption established")
                    
                    print("Attempting login...")
                    server.login(self.sender_email, self.sender_password)
                    print("Login successful")
                    
                    print("Sending email...")
                    server.send_message(msg)
                    print("Email sent successfully")
                    return True

            except smtplib.SMTPAuthenticationError as e:
                print(f"Authentication failed. Please check your Gmail credentials and ensure you're using an App Password.")
                print(f"Error details: {str(e)}")
                return False
                
            except smtplib.SMTPException as e:
                print(f"SMTP error on attempt {attempt + 1}: {str(e)}")
                if attempt < max_retries - 1:
                    print(f"Retrying in {retry_delay} seconds...")
                    time.sleep(retry_delay)
                continue
                
            except Exception as e:
                print(f"Unexpected error on attempt {attempt + 1}: {str(e)}")
                print(f"Error type: {type(e)}")
                if attempt < max_retries - 1:
                    print(f"Retrying in {retry_delay} seconds...")
                    time.sleep(retry_delay)
                continue
        
        return False