내가 한 노력들

[ python ] 자동 이메일 프로젝트 본문

IT 공부/python

[ python ] 자동 이메일 프로젝트

JONGI-N CHOI 2020. 12. 26. 16:12

프로젝트 개요

Project) 나도 코딩에서 구독자 분들을 대상으로 파이썬 특강을 진행
참여 신청은 이메일을 통해서 가능하며 메일 수신 시간 기준으로 선착순 3명이 선정된다.
아래 조건에 해당하는 메일을 자동으로 조회하여 선정되신 분들께는 선정 안내 메일을, 
아쉽게 선정되지 못한 분들께는 대기 번호 안내 메일을 자동으로 발신하고,
선정된 3명의 명단을 엑셀 파일로 저장하는 자동화 프로그램을 작성하시오.

[신청 메일 양식]
제목 : 파이썬 특강 신청입니다.
본문 : 닉네임/전화번호 뒤 4자리(Random)
 (예) 나도코딩/1234

[선정 안내 메일]
제목 : 파이썬 특강 안내 [선정]
본문 : xx님 축하드립니다. 특강 대상자로 선정되셨습ㄴ디ㅏ. ( 선정순정 1번)

[탈락 안내 메일]
제목 : 파이썬 특강 안내 [탈락]
본문 : xx님 아쉽게도 탈락입니다. 취소 인원이 발생하는 경우 연락드리겠습니다. (대기순번 1번)

[선정 명단 엑셀]
순번 닉네임 전화번호
1    유재석    8230
2    박명수    2384


@@@@@@@@실제 메일 생겨질 모습@@@@@@@@@
파이썬 특강 안내[탈락]
파이썬 특강 안내[탈락]
파이썬 특강 안내[선정]
파이썬 특강 안내[선정]
파이썬 특강 안내[선정]
파이썬 특강 신청합니다.
파이썬 특강 신청합니다.
파이썬 특강 신청합니다.
파이썬 특강 신청합니다.
파이썬 특강 신청합니다.

1. 특강 신청하는 메일 보내기 

import smtplib
from account import *
from email.message import EmailMessage

메일을 보내기 위해서 필요한 라이브러리 및 모듈을 사용한다. 

import random

전화번호를 적을 때, 랜덤으로 하라는 조건이 있기 때문에 random 모듈도 사용한다. 

 

names = ["유재석", "박명수", "정형돈", "노홍철", "길"]

메일 보낼 사람들을 list로 만들고 for문을 돌려주면 된다. 

 

with smtplib.SMTP("smtp.gmail.com", 587) as smtp:
    smtp.ehlo()
    smtp.starttls()
    smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD)

메일을 보내기 위한 준비를 맞추고, 이젠 보낼 메세지를 지정해주면 된다. 

 

메세지 지정

for name in names:
        msg = EmailMessage()  # 객체 생성
        msg["Subject"] = "파이썬 특강 신청입니다."  # 제목
        msg["From"] = EMAIL_ADDRESS  # 보내는 사람
        msg["To"] = "chlwhddls1224@gmail.com"  # 받는 사람

        number = str(random.randint(0, 9999))
        msg.set_content("{}/{}".format(name, number.zfill(4)))

 

random.randint()

number = str(random.randint(0, 9999))

  0~9999의 int를 랜덤으로 뽑고, str형으로 type을 변경해준다. -> zfill()을 사용하기 위함

 

zfill()

number.zfill(4)

4자리 미만의 값이 나왔을 경우에는 4자리로 맞춰주기 위해서 zfill(4)을 이용해서 빈자리는 0으로 채워준다. 

 

전송

        smtp.send_message(msg)
        print(name + "님으로부터 메일 받음")

send_message()에 위에서 만든 msg객체를 넣어주게 되면 전송이된다. 

그리고 전송될 때 마다 print()로 지금 현재 진행상태를 알 수 있도록 표기 


2. 신청받은 메일을 필터링해서 받아온다.

from imap_tools import MailBox
from account import *

우선 메일을 받기 위해 필요한 라이브러리와 모듈을 불러온다. 

 

객채생성, 로그인 

with MailBox("imap.gmail.com", 993).login(EMAIL_ADDRESS, EMAIL_PASSWORD, initial_folder="INBOX") as mailbox:

객채생성 및 로그인을 하고 받은 메세지함에 접속을 한다. 

 

조건설정

for msg in mailbox.fetch('(SENTSINCE 25-Dec-2020)'):

mailbox.fetch()를 하게 되면, 받은 메세지함에 있는 모든 메일을 다 가져오는 것인데, 조건을 준다. 

SENTSINCE : 특정 날짜 이후의 메일을 가져와라 

(SENTSINCE 25-Dec-2020)') : 2020년 12월 25일 이후로 온 메일 조회

 

if "파이썬 특강 신청입니다." in msg.subject:

msg.subject는 받은 메일함의 제목을 의미하고, 제목에 "파이썬 특강 신청입니다."가 포함되어 있을 경우에만 동작하도록 조건 설정

유저정보 저장

application_list = [] 

그리고, 나중에 엑셀파일에 인덱스, 이름, 폰번호로 엑셀을 저장하기 위해서는 이 정보들을 저장해둬야한다. 

그 정보들을 list에 넣어주기 위해 초기화를 해줌

 

with MailBox("imap.gmail.com", 993).login(EMAIL_ADDRESS, EMAIL_PASSWORD, initial_folder="INBOX") as mailbox:
    index = 1  # 순번
    for msg in mailbox.fetch('(SENTSINCE 25-Dec-2020)'):  # 2020년 12월 25일 이후로 온 메일 조회
        if "파이썬 특강 신청입니다." in msg.subject:
            name, phone = msg.text.strip().split("/")
            print(index, name, phone)
            application_list.append((msg, index, name, phone))  # 튜플식으로 넣는다.
            index += 1

그리고 index번호를 만들기 위해서 index 변수를 추가 

 

name, phone = msg.text.strip().split("/")

메일 본문에 "박명수/6232" 이런식으로 오니까 "/"을 기준으로 나눠서 이름과 폰번호를 저장한다. 

 

application_list.append((msg, index, name, phone))

msg 객체도 같이 저장하는 이유는, 나중에 다시 메일을 보내기 위해서 메일을 누가 보냈는지 알기 위해서 

msg.from_을 사용하기 위해서 같이 넣어놓는 것이다. 


3.선정 / 탈락 메일 발송

1번과 동일하게 이메일을 보내면된다. 

단, 선정된 사람과 탈락된 사람을 나눠서 내용을 보내야한다. 

with smtplib.SMTP("smtp.gmail.com", 587) as smtp:
    smtp.ehlo()
    smtp.starttls()
    smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD)

이부분까지는 동일하지만, 

for applicant in application_list:
        to_addr = applicant[0].from_  # 수신 메일 주소
        # index = applicant[1]
        # name = applicant[2]
        # phone = applicant[3]
        index, name, phone = applicant[1:]

        title = None
        content = None

필터링을 통해 가져온 정보들 application_list에서 하나씩 꺼내와서 작업을 한다. 

 

to_addr = applicant[0].from_

메일을 보낸사람에게 다시 보내기위해서 누가 보냈는지 msg객체에서 from_을 사용해서 to_addr 변수에 넣고

 

index = applicant[1]
name = applicant[2]
phone = applicant[3]

각각 index, name, phone에 값을 바인딩해주는데 위의 코딩을 한줄로 바꿀 수 있다.

index, name, phone = applicant[1:]

이렇게 해주면, 위의 코딩과 똑같은 작업을하지만, 한줄로 바꿀 수 있음

 

 

if index <= max_val:
            title = "파이썬 특강 안내 [선정]"
            content = "{}님 축하드립니다. 특강 대상자로 선정되셨습다. (선정순정 {}번)".format(
                name, index)

else:
            title = "파이썬 특강 안내 [탈락]"
            content = "{}님 아쉽게도 탈락입니다. 취소 인원이 발생하는 경우 연락드리겠습니다. (대기순번 {}번)".format(
                name, index - max_val)

max_val는 최대 선정될 사람을 의미하고 3명까지 선정하기로 조건에 있었으므로 max_val = 3 이다. 

index 3 까지는 선정되므로 선정된 사람에게 보낼 때의 메일의 제목과 타이틀을 지정, 

그리고 3보다 높을 경우에는 탈락이므로 그에 맞는 메일의 제목과 타이틀을 지정해준다.

 

msg = EmailMessage()
        msg["Subject"] = title
        msg["From"] = EMAIL_ADDRESS
        msg["To"] = to_addr
        msg.set_content(content)
        smtp.send_message(msg)
        print(name, "님에게 메일 발송 완료")

 그리고, 위에서 만든 변수들을 통해서 메일을 전송해주면 된다. 


4. 선정자 명단 excel파일로 저장 

python을 이용해서 excel을 다루기 위해서는 openpyxl 라이브러리를 설치해야한다.

pip install openpyxl

 

빈 엑셀 파일 생성

wb = Workbook()

활성화 된 시트를 새로운 변수에 할당

ws = wb.active

새 행 추가

ws.append(["순번", "이름", "전화번호"])

append()를 이용해서 안에 리스트 형식으로 값을 넣어주게되면 새로운 행이 만들어진다. 

 

for applicant in application_list[:max_val]:  # 0:3 -> 0,1,2
    ws.append(applicant[1:])

필터링을 통해 만들었더 유저들의 정보 application_list()에 있는 값을 excel파일에 넣어주면 된다. 

 

선정된 사람들의 정보만 넣어주면 되기 때문에 슬라이싱을 이용해서 

application_list[:max_val]

[:max_val] 처음 부터 max_val까지 즉 인덱스가 0, 1, 2인 값들만 가져온다는 의미 

ws.append(applicant[1:])

append()를 통해서 새 행을 만들어주는데 여기도 슬라이싱을 이용해서 [1:] index가 1인 것 부터 끝까지의 값을 리스트로 만든 다음에 넣어주게 된다. 

 

파일저장

wb.save("result.xlsx")

위의 작업을 순서대로 하게되면, 특강 신청 메일을 보내게 되고, 신청메일을 선착순으로 받아서 선정 / 탈락 을 조건처리 한다음에 메일을 보낸 사람들에게 다시 결과를 알려주는 메일을 보낸다.

그리고, 선정된 사람들의 정보는 excel파일에 넣어서 저장한다.