본문 바로가기

etc

스레드를 사용한 이메일 비동기 전송(django email)

@마크다운


이메일을 발송하기 위해 기본적으로 세팅해야할 것들이 있다.

본 글에서는 gmail을 기준으로 설명함


SMTP설정을 위해 사용하려는 gmail계정에 다음과 같은 설정을 먼저 해주자

1.[IMAP설정](https://support.google.com/mail/answer/7126229?hl=ko&rd=3&visit_id=1-636281811566888160-3239280507#ts=1665018)

2.[보안 수준이 낮은 앱 허용](https://support.google.com/accounts/answer/6010255)

3.[캡챠 잠금해제](https://accounts.google.com/displayunlockcaptcha)


그 후 django settings.py에서 다음과 같이 설정을 한다

### 

587포트는 gmail권장사항이라고 한다. (시키는대로 따라하자)

```

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_USE_TLS =True

EMAIL_HOST = 'smtp.gmail.com'

EMAIL_HOST_USER = '사용하려는 이메일'

EMAIL_HOST_PASSWORD = '패스워드'

EMAIL_PORT = 587

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

```

셸에서 테스트

```

django.core.mail import EmailMessage

email = EmailMessage('제목', '내용', to=['받는사람의 이메일']

email.send()

```

1이 뜬다면 성공이다.

실패한다면 위의 1,2,3중 하나가 제대로 설정되지 않은것이니 다시 해보도록하자.

받는 이메일을 자신의 이메일로하여 도착했는지 확인을 해보면된다.


#

이렇게 만든 코드를 만약 회원가입을 할때 적용한다고 생각해보면

회원가입 -> 이메일 발송 -> 리다이렉트

위와 같은 순서가 될텐데 비동기 스레드를 사용하지 않는다면 이메일이 발송될때 까지 페이지는 동작하지 않을것이고 발송이 다 된 후에 리다이렉트가 될것이다.

그래서 흔히 사용하는 방법이 샐러리를 이용한 비동기나 python자체의 스레드를 사용하여 작업을 비동기로 처리하곤 한다.


여기서는 샐러리가 아닌 python thread를 사용했다.

[코드]( https://github.com/ui/django_asynchronous_send_mail)

여기 아주 좋은 코드가 있다.

만약 스레드를 잘 다룰 자신이 없다면 위의코드를 그대로 사용하여 쓰는것이 정신건강에 이로울듯 싶다.


```

class EmailThread(threading.Thread):

    def __init__(self, subject, body, from_email, recipient_list, fail_silently, html):

        self.subject = subject

        self.body = body

        self.recipient_list = recipient_list

        self.from_email = from_email

        self.fail_silently = fail_silently

        self.html = html

        threading.Thread.__init__(self)


    def run(self):

        msg = EmailMultiAlternatives(self.subject, self.body, self.from_email, self.recipient_list)


        if self.html:

            msg.attach_alternative(self.html, 'text/html')

        msg.send(self.fail_silently)



def send_email(subject, body, from_email, recipient_list, fail_silently=False, html=None, *args, **kwargs):

    EmailThread(subject, body, from_email, recipient_list, fail_silently, html).start()

```


이제 이 send_email을 원하는 타이밍에 import하여 사용하면 끝이난다.


> AWS와 같은 클라우드 서비스를 사용할때 이메일이 발송이 안되는 경우 3.을 다시 설정하고 메일을 발송해보기 바란다.