본문 바로가기
실습/파이썬을 활용한 업무 자동화

메일 발송

by 이민우 2021. 11. 18.
728x90
반응형

프로그램을 구현하다 보면 때론 특정 상황 발생 시 관리자 혹은 사용자에게 메일을 보내야 하는 요구사항들이 있다.

 

Python은 이러한 기능을 smtplib, email 기능을 통해 제공해주고 있다.

 

오늘의 실습은 Python을 활용하여 자동으로 메일을 보내는 기능이다.

 

물론 바로 사용은 안되고, 사전 설정이 필요한데 이번 실습은 구글의 지메일을 사용할 것이기 때문에 지메일 내에서 다음 설정이 필요하다.

 

또한 원래 사용하던 비밀번호를 통한 접속이 안되기 때문에 Gmail APP 계정 설정을 통해 생성된 비밀번호 입력이 필요하다.

 

구글 계정 > 보안 > Google에 로그인 > 2단계 인증 설정 > 앱 비밀번호

 

 

이제 사전 준비가 끝났으니, 코딩을 시작하자.

가장 먼저 필요한 라이브러리들을 import한다.

import smtplib #SMTP 프로토콜
import email #메일 관련 기능 제공 (자동 발송 등)
import os
import openpyxl #엑셀 파일을 읽기 위한 명령어
import sys
from io import StringIO
import time
import random

from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText #메일 내용 작성
from email.mime.image import MIMEImage
from email import encoders
from email.mime.base import MIMEBase

 

그 후에는 메일을 보낼 계정과 비밀번호를 입력한다.

구글 지메일을 사용할 것이기 때문에, 아래의 gid에 자신의 구글 아이디와 비밀번호를 입력하면 된다.

#구글 계정 입력
gid = ""
gpw = "" #발급받은 앱 비밀번호

#구글 메일 설정
smtp_1 = smtplib.SMTP_SSL('smtp.gmail.com',465)
smtp_1.ehlo( )
smtp_1.login(gid,gpw)

 

다음으로는 메일에 첨부할 파일들을 지정한다.

기본적으로 텍스트, pdf 등의 문서와, 이미지 파일 등을 첨부하여 전송할 수 있다.

csv_file = "/content/eco.csv"
img_file = "/content/alice.jpg"

 

그 후에는 메일을 수신할 대상들을 불러온다.

현재 상황에서는 사용자들의 메일 데이터가 다음과 같이 엑셀 파일로 저장되어 있다고 가정한다.

해당 엑셀 파일은 엑셀 파일을 읽어주는 라이브러리인 openpyxl을 사용하여 읽어온다.

wb = openpyxl.load_workbook("/content/emails.xlsx")
sheet = wb["Sheet1"]

member = { }
for i in range(2, sheet.max_row) :
    name = sheet.cell(row=i,column=2).value
    email = sheet.cell(row=i,column=3).value
    member[name]=email

 

그 후에는 불러온 member에 대하여 모두 같은 형식의 이메일을 보낸다.

코드는 아래와 같다.

for name, email in member.items( ):
    #보낼 메일 객체
    msg = MIMEMultipart()

    #제목
    msg["Subject"] = Header(s="%s 님께 알려 드립니다."%name , charset="utf-8")

    #내용
    msg_txt = MIMEText("안녕하세요. 테스트 이메일입니다.")
    msg.attach(msg_txt)

    #첨부파일 등록
    for file in files :
      filename = file
      part = MIMEBase('application', "octet-stream")
      part.set_payload(open(filename, "rb").read())
      encoders.encode_base64(part)
      part.add_header('Content-Disposition', "attachment; filename= %s" % os.path.basename(filename))
      msg.attach(part)

    #메일의 정상 발송 여부 확인
    sendmailStatus=smtp_1.sendmail('seojinsu@gmail.com',email,msg.as_string())
    time.sleep(random.randrange(2,6))
    
    if sendmailStatus != {}:
        print("%s 주소 발송 오류: %s" %(email,sendemailStatus))

 

그 후에는 열어놓은 SMTP를 닫아준다.

#SMTP 종료
smtp_1.quit( )

 

 

이에 대한 모든 코드는 아래와 같다.

# 파이썬을 활용하여 자동으로 이메일 보내기

import smtplib #SMTP 프로토콜
import email #메일 관련 기능 제공 (자동 발송 등)
import os
import openpyxl #엑셀 파일을 읽기 위한 명령어
import sys
from io import StringIO
import time
import random

from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText #메일 내용 작성
from email.mime.image import MIMEImage
from email import encoders
from email.mime.base import MIMEBase
#import email.mime.application

#구글 계정 입력
gid = ""
gpw = ""

#구글 메일 설정
smtp_1 = smtplib.SMTP_SSL('smtp.gmail.com',465)
smtp_1.ehlo( )
smtp_1.login(gid,gpw)

#전송 시간
s_time = time.time( )

files = {"/content/eco.csv", "/content/alice.jpg"}

# 엑셀 파일에서 목록 불러와서 자동으로 메일 보내기
# 엑셀은 name - email 로 구성
wb = openpyxl.load_workbook("/content/emails.xlsx")
sheet = wb["Sheet1"]

member = { }
for i in range(2, sheet.max_row) :
    name = sheet.cell(row=i,column=2).value
    email = sheet.cell(row=i,column=3).value
    member[name]=email


for name, email in member.items( ):
    #보낼 메일 객체
    msg = MIMEMultipart()

    #제목
    msg["Subject"] = Header(s="%s 님께 알려 드립니다."%name , charset="utf-8")

    #내용
    msg_txt = MIMEText("안녕하세요. 테스트 이메일입니다.")
    msg.attach(msg_txt)

    #첨부파일 등록
    for file in files :
      filename = file
      part = MIMEBase('application', "octet-stream")
      part.set_payload(open(filename, "rb").read())
      encoders.encode_base64(part)
      part.add_header('Content-Disposition', "attachment; filename= %s" % os.path.basename(filename))
      msg.attach(part)

    #메일의 정상 발송 여부 확인
    sendmailStatus=smtp_1.sendmail('seojinsu@gmail.com',email,msg.as_string())
    time.sleep(random.randrange(2,6))
    
    if sendmailStatus != {}:
        print("%s 주소 발송 오류: %s" %(email,sendemailStatus))
       

#SMTP 종료
smtp_1.quit( )

 

 

이렇게 한 후 실행을 시켜보면 아래와 같이 정상적으로 이메일이 발송되었음을 확인할 수 있다.

728x90
반응형