본문 바로가기

좋아하는 것_매직IT/99.업무자동화하기

SMTP 공부해서 내마음대로 이메일보내기.(feat. 업무자동화시리즈01)

반응형

블로그 목적

 - "SMTP 공부해서 내맘대로 이메일보내기" 대해서 공부및 정리후 나만의 노하우와 지식을 공유한다.​

블로그 요약

- SMTP에 대해서 정리해본다.
- Python 언어를 활용해서 내마음대로  이메일을 보내는 과정및 방법을 공유해본다.
   - smtplib : 메일 정보를 SMTP 형태로 보내기위한 라이브러리
   - email : 메일 발송을 위해서 필요한 정보를 편리하게 표현하기 위한 라이브러리

블로그 상세 내용

우선, SMTP에 대해서 정리해 볼까요?


SMTP의 약자에 대해서 정리해보면요...
 - Simple Mail Transfer Protocol의 약자입니다.

즉, 인터넷 상에서 상대방에게 이메일을 전송 하기 위해서 사용하는 프로토콜입니다. 
해당 프로토콜에서 사용하는 TCP 포트번호는 25번이고요...
아래와 같이 RFC2821에 읽어보시면 상세하게 정리되어 있습니다. 

출처 : RFC2821



그리고, 해당 프로토콜은 메일 서버간의 송수신뿐만 아니라, 메일 클라이언트에서 메일 서버로 메일을 보낼 때에도 사용되는 경우가 많습니다. 
우리가 아래에서 Python 언어를 통해서 구현해볼 내용이 바로 클라이언트에서 서버로 메일을 전송하는 방법을 알아보려고 하는 것이죠...

아무튼, SMTP에서는 텍스트 기반의 프로토콜로서 Request 와 Response  메시지뿐만 아니라 모든 문자가 7bit ASCII로 되어있어야 한다고 규정되어 있습니다. 
즉, 이 때문에 문자 표현에 8비트 이상의 코드를 사용하는 언어나 첨부파일과 자주 사용되는 각종 바이너리는 마임(MIME)이라고 불리는 방식으로 7비트로 변환되어 전달되고 있습니다. 

참고로, 마임(MIME) 은 Multipurpose Internet Mail Extensions 의 약자로, 이메일을 위한 인터넷 표준 형식을 의미하는 것이고요...
 - 해당 표준에서는 전달하고자 하는 내용에 따라서 "텍스트", "이미지파일" 등등 여러 타입이 정의되어 있습니다. 


SMTP는 메시지를 생성하는 방법을 따로 규정하지 않는데요...
즉, 메시지 생성을 위하여 로컬 편집이나 단순한 전자 우편 응용이 사용되고 있고요...
해당 메시지가 생성되면,  호출된 SMTP가 메시지를 수신하고 해당 메시지를 TCP를 이용하여 다른 호스트의 SMTP에게 전달하게되는 과정을 거칩니다.

SMTP를 통해서 메일을 전송하는 프로그램을 개발하려면, 해당 프로토콜을 완벽하게 이해하고 직접 구현해야하겠지만, 현재 머리좋은 사람들(?)이 해당 프로토콜을 정성스럽게 라이브러리화 시켜놔서 우리는 해당 프로토콜에 대해서 정확히 알지 못하고 메일을 보내려면 SMTP 를 사용해야하구나 하고 이해만 한다면....
바로 자신이 좋아하는 언어를 통해서 메일을 보내기를 자동화 할수 있습니다. 

우선, 저는 언어중에 C++ 을 가장좋아하고 Java 와 Go도 좋아하지만 때론 Python 도 괜찮은 언어중에 하나 이지 않을까? 생각하면서 시간날때마다 공부하고 있습니다. 

오늘도 Python 을 공부하다가,  메일 보내기를 자동화하는 방법은 없을까라는 니즈와 고민을 가지고 찾아보던중...
역시나 Python 에 라이브러리가 있음을 확인할 수 있었습니다. 

해당 라이브러리를 소개하자면 smtplib / email 라이브러리인데요...
 - smtplib 는 메일 정보를 SMTP 형태로 보내기위한 라이브러리입니다. 
 - email 라이브러리는 메일 발송을 위해서 필요한 정보를 편리하게 표현하기 위한 라이브러리입니다. 
참고로, 해당 라이브러리들은 Python 에 기본적으로 포함되어 있는 라이브러리이기때문에 별도로 설치가 필요하지 않습니다. 이점 참고하시면 될것 같고요...즉 구현할 마음만 먹으면 된다? 라고 보시면 됩니다. 

라이브러리에 대해서 살짝쿵(?) 데이터 하듯이 알아보죠... 
우선, smtplib 의 레퍼런스를 찾아보려면, 아래 URI 를 클릭하시면 됩니다. 
 - 한마디로 해당 라이브러리는 SMTP 프로토콜 클라이언트 라이브러리고요...
해당 smtplib모듈은 SMTP 또는 ESMTP 수신기 데몬이 있는 인터넷 시스템에 메일을 보내는 데 사용할 수 있는 SMTP 클라이언트 세션 개체를 정의하는 모듈입니다. 자세한 사항은 아래 URI 로 직접 접속하셔서 확인하시면 됩니다.

출처 : docs.python.org/3/library/smtplib.html


참고로, 아래는 해당 라이브러리 사용한 예시코드입니다.

import smtplib

def prompt(prompt):
    return input(prompt).strip()

fromaddr = prompt("From: ")
toaddrs  = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
       % (fromaddr, ", ".join(toaddrs)))
while True:
    try:
        line = input()
    except EOFError:
        break
    if not line:
        break
    msg = msg + line

print("Message length is", len(msg))

server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

그럼, email 라이브러리에 대해서 알아볼까요?

email 라이브러리는 An email and MIME handling package, 즉 이메일및 마임을 다루는 패키지입니다. 

자세한 사항은 아래 URI 로 접속하셔서 확인해보시면 좋을 것 같습니다. 

아무튼, 여기까지 지식이 머리에 정리가 되셨으면, 간단하게 Python 으로 구현이 가능한데요...그럼 본격적으로 알아보겠습니다.

그럼,간단하게 Python을 사용해서 샘플프로그램을 구현해보겠습니다.

위에서 알아본 smtplib 와 email  라이브러리를 사용해서 앞으로 우리가 구현할 프로그램을 간단하게 설명드리자면...
구현할 SMTP 클라이언트 프로그램은 naver 메일서버를 통해서 nate 메일서버로 샘플메시지를 SMTP 로 전송하는 정말 간단한 프로그램입니다. 
우선 해당 프로그램을 사용하기 위해서 사전 작업이 필요한데요...
송신자로 네이버에 로그인한 후 아래와 같이 설정을 세팅해야합니다. 

위와 같이 POP3/SMTP 사용을 "사용함"으로 세팅하시고요...
메일 프로그램 환경설정안내를 꼭 확인하셔야합니다. 

우선 변경을 안하고 프로그램을 실행하면...아래와 같은 인증 에러가 나옵니다. 

그럼, 샘플코드를 소개하자면 아래와 같습니다.

우선 파일구조는 아래와 같습니다.

파일에 대해서 설명드리자면..
 - idpw.py 은 말그대로 패쓰워드가 있는 파일이고요..
   - 그런데, 말입니다. 이렇게 따로 소스파일을 만든이유는요?  (제 패쓰워드는 소중하니깐요..ㅎㅎ)
 - smtp_cc_send.py 는 실제 SMTP로 메일을 전송할 수 있는 클라이언트 소스입니다. 
그리고 코드는 아래와 같습니다. 

from idpw import PASSWORD
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

import smtplib

SMTP_SERVER = 'smtp.naver.com'
SMTP_PORT = 465
SMTP_USER = 'djlee118'
SMTP_PASSWORD = PASSWORD

attachment = 'C:\data\Helm.pdf'

msg = MIMEMultipart('alternative')

if attachment:
    msg = MIMEMultipart('mixed')

msg['From'] = SMTP_USER + '@naver.com'
msg['To']   = 'djlee118@nate.com'
msg['Subject'] = '쿠버네티스관련 Helm 공부 자료 파일을 전송합니다.'

contents = '안녕하세요. 해당 자료가 부디 도움이 되셨으면 좋겠습니다. '
mimetext = MIMEText(contents, _charset='utf-8')

msg.attach(mimetext)

if attachment:
    from email.mime.base import MIMEBase
    from email import encoders

    file_data = MIMEBase('application', 'octect-stream')
    file_data.set_payload(open(attachment, 'rb').read())
    encoders.encode_base64(file_data)

    import os
    filename = os.path.basename(attachment)
    file_data.add_header('Content-Disposition', 'attachment; filename="' + filename + '"')
    msg.attach(file_data)

# print(msg.as_string())

smtp = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT)
smtp.login(SMTP_USER, SMTP_PASSWORD)
smtp.sendmail(SMTP_USER + '@naver.com', 'djlee118@nate.com', msg.as_string())
smtp.close()

이 소스를 보다 보시면 궁금한 점이 몇개가 있으실텐데요...
 - 우선, MIMEMultipart 의 "alternative" 의 의미를 알고 싶으실건데요...
 - 참고로, alternative 의 의미는 만약 메일에 text/plain 이라는 타입과 text/html 이라는 타입의 내용을 추가했다고 가정한다면, 메일을 수신한 프로그램은 둘 중에 더 보기 좋은 내용을 선택해서 내용을 출력하게되는데요...
즉, 해당 alternative 의 의미는 메일을 수신한 프로그램이 여러 내용 중에 선택하여 출력할 수 있도록 하는 타입을 말합니다. 

그런데 말입니다. 해당 프로그램은 attachment 즉, 파일이 있을경우, alternative 대신 mixed 로 바꾸고 있는데요...
즉,  해당 메일이 그냥 텍스트메일이 아니고, 첨부파일이 포함된 메일일 경우에는 SMTP 서버에 첨부파일이 존재하는 메일이라고 알려줘야하는데요... 바로 이때는 MIMEMultipart 의 "alternative"  대신 "mixed" 키워드로 클래스 변수를 생성해야 합니다.

워낙 샘플 프로그램이 간단해서, 그외에는 무난히 해당 소스를 이해하실수 있을것입니다.

아무튼 해당 프로그램을 실행하면 아래와 같이 메일이 잘 전송되었음을 확인할 수 있습니다.

결론

이제까지, "SMTP 공부해서 내맘대로 이메일보내기" 에 대해서 소개및 설명을 드렸는데요...

어떻게 도움이 되셨는지 모르겠습니다..최대한 쉽게 설명드리려고 노력했으나....^^; 블로그를 작성하면 할 수록 어떻게 하면, 보다 쉽게 정보들을 전달할 수 있을것인가.. 고민을 더욱 해보겠습니다.

아무튼, 앞으로도 더욱 열심히 노력하는 제가 되도록 노력하겠습니다.

오늘도 마지막까지 제 글을 끝까지 읽어주셔서 진심으로 감사드리고, 제 글이 조금이라도 여러분의 각자의 삶을 살아가시는데 도움이 되셨길 기원합니다.

앞으로도 더욱 좋은 블로그를 남기는 제가 되도록 노력하겠습니다.

 




728x90
300x250