ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 파이썬 SMTP이용하여 email 보내기
    Backend/Python 2024. 1. 15. 11:13

    필자는 프로젝트 중에 각 구역 별로 이상치 & 결측치 발생하는 알림을 이메일 발송하도록 하는 부분이 필요했다.

     

    따라서, SMTP & IMAP 을 이용하였으며, 그 중 파이썬에서 smtplib 라이브러리를 사용하였다.

     

    이 전에 필자는 SMTP와 IMAP에 대한 개념을 잘 몰랐는데, 이번 기회를 통해 정리해보았다. 

     

    SMTP란?

    • email을 보내는 데 있어서 업계 표준 프로토콜이다.

    IMAP란?

    • 인터넷 메시지 액세스 프로토콜(IMAP)이며, 이메일을 받는 서버로부터 이메일 메세지를 관리하고 이메일을 꺼내서 가져오는데 사용되는 프로토콜이다.

     

     

    client A가 SMTP를 이용하여 서버로 메일을 보냄 → 그리고 다시 한번 SMTP를 통해 B가 있는 서버와 메일을 주고 받음 - > 마지막으로 B의 서버가 IMAP을 이용하여 Client B에게 이메일을 발송 하는 과정임을 알 수 있음

     

    이제 본격적으로, 이메일 발송 클래스를 만들어 보려 한다.

     

    <필수적으로 해야 할 것>

    1. smtplib 라이브러리 설치

    2. MIME import 

    3. gmail 정보(보안 부분) 에 들어가서, IMAP 사용하기 체크로 변경 해 줄 것 꼭!

     

    import smtplib
    import traceback
    import pendulum
    
    from datetime import datetime, timedelta
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from common import env
    
    from loguru import logger
    
    
    class BaseMail:
        def __init__(self) -> None:
        	
            # SMTP 서버의 url과 port 번호
            self.host = "smtp.gmail.com"
            self.port = 587
    		
            # Email 정보
            self.caller_id = env.EMAIL_ADDRESS   
            self.caller_pw = env.EMAIL_PASSWORD
            self.receiver_id = env.TO_MAIL_ADDRESS
        
        def gmail_send_success_v2(self, cusmotr_subject: str, cusmotr_message: str):
            
            try:
                
                alert_time = pendulum.now('Asia/Seoul')
                yesterday_time = alert_time.subtract(days=1).format('YYYY-MM-DD')
                
                message = MIMEMultipart("alternative")
                
                # 이메일 제목
                message["Subject"] = cusmotr_subject
                # 이메일 보내는 사람 계정
                message["From"] = self.caller_id
                # 이메일 받는 사람 계정
                message["To"] = self.receiver_id
    
                body = f"""
                <p>안녕하세요. OOO 입니다.</p>
                <p>이상치 및 결측치 결과를 안내드리겠습니다. 전일 기준 / {yesterday_time} </p>
                
                <div> {cusmotr_message} </div>
    
                <p>감사합니다.</p>
                """
    
                message.attach(MIMEText(body, "html"))
                # 이메일 연결
                server = smtplib.SMTP(self.host, self.port)
                server.starttls()
                # 이메일 로그인 
                server.login(self.caller_id, self.caller_pw)
                # 이메일 보내기
                server.sendmail(
                    self.caller_id, message["To"].split(","), message.as_string()
                )
                # 메일 보내면 서버와의 연결 끊기
                server.quit()
    
            except smtplib.SMTPAuthenticationError as e:
                print(f"SMTP Authentication Error: {e}")
                logger.error(f"SMTP Authentication Error: {e}")
            
            except Exception as e:
                logger.error(traceback.print_exc(e))

     

     

    위 클래스(BaseMail)을 바탕으로 실제 적용해보도록 하겠다.

     

    def send_mail():
        
        try:
            data1 = select_region_cnt()
            
            send_data1 = []
    
            for one in data1:
                one['region'] = set_region_area(one['region'])
                contents1 = f"{one['region']} 구역에서 이상치가 {one['total']} 건 발생했습니다." 
                send_data1.append(contents1)
            
            mail = BaseMail()
            
            def create_html_body(mail_content):
                body = "<html><body>"
                
                # ~구역에서 ~ 건 발생하였습니다 를 줄바꿈 하여, 내용에 보여지도록 하는 것 
                for item in mail_content:
                    body += f"<li>{item}</li>"
                
                body += "</body></html>"
                
                return body
                
            mail.gmail_send_success_v2(
            	  # 제목 
                "[ OOOO ] 이상치 건수 및 상세 내역 ",
                
                f" 구역 및 이상치 발생 건수 : {create_html_body(send_data1)}"
                
            )
            
            return send_data1
            
        except Exception as e:
            logger.error(e)
            return None

     

    이렇게 적용한 후, 메일을 발송하면 아래와 같이 잘 발송된 것을 볼 수 있다.

     

     

     

Designed by Tistory.