# Mailing Service App & AWS SES ## 撰寫想法 我們目前只有在使用者忘記密碼時,要輸入註冊 Email 重置密碼才需要寄信的功能。在寄送信件方面,Django 也有相對應支援的 API: `from django.core.mail import send_mail` 相關文件: https://docs.djangoproject.com/en/1.11/topics/email/#module-django.core.mail 所以在實作這個功能不算太困難。不過一般來說,實作寄信的功能都是用 SMTP,並且有一個 mailing server。在這裡我們使用的是 [AWS SES](https://aws.amazon.com/tw/ses/)(Simple Email Service) 的服務。Django 的寄信服務預設都是支援 SMTP,但是這對 EC2 跟 SES 溝通來說就必須走外部的網路,因此會有額外的 Latency 耗損。所以,我在這裡使用 [`django-ses`](https://github.com/django-ses/django-ses) 他實作的方式可以讓 EC2 利用 AWS 內部網路的方式來觸發 SES。 **SES 的使用** 使用 AWS SES 的服務其實滿簡單的,不過首先得要有一個 domain 才行。因為使用 SES 的時候,必須要到域名管理商設置域名的 DNS。至於,設置的方式 AWS 上面都說明的很清楚所以就不贅述。 唯一需要注意的是:當你設定好 SES 的時候,並不表示它可以馬上對外寄信。你必須要做額外的申請才可以對外寄信。這動作叫做:[Move out of the SES sandbox](http://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html) 申請不算太困難。在填寫申請原因的時候,我是直接跟 AWS 的客服說我要用來實作尋找密碼的功能,然後選項勾選如果不是使用者請求過,不會主動寄信即可等候審核。 ## 檔案結構 為了兼容性,我們在創立 mailing service 的時候,是以創建 app 的形式來產生這個資料夾。因此,會包含 models.py, admin.py, views.py 等檔案。 但是針對我們的 mailing service,實際上實作的檔案只有: - utils.py ## 實作功能 1. 寄發信件 當初在設計這部分的時候,是想到我們未來要寄信的情境可能不只一種。所以在 `utils.py` 實作一個 `SESMessage` 的 class 來專門處理寄信的實作。 這個 Class 的操作方式是先判別今天要處理的寄信事件是什麼?然後選定信件的 Template,將 Template 填好內容之後,在送出。 **SESMessage Class** Class Attribute: - service_provider: 用來標明我們寄信的來源。使用的網域必須與 SES 相對應。 - reset_password_template: 這是用來重置密碼的 Template。 不過,以上兩個 attribute 其實都可以向外提出,成為單獨一個 Class 的 Attribute。目前為了簡便我們就將它跟 SESMessage 包裝在一起。 Object Attribute: - subject: 該篇信件標題 - template: 該篇信件所使用的 template - filled_message: 該篇信件基於 template 填上內容後的結果,將視實際要寄出的訊息。 Object Method: - set_subject - set_template - fill_content - send_email: 這是我們實際寄信的方法。 **SES in settings.py** 在 Django 設定檔的部分,因為我們使用 `django-ses` 這個 package,所以就必須做額外的設定。 設定大致如下: ``` with open("shareclass/aws_credentials.json") as f: aws_credentials = json.loads(f.read()) EMAIL_BACKEND = 'django_ses.SESBackend' AWS_SES_ACCESS_KEY_ID = aws_credentials['ses_key_id'] AWS_SES_SECRET_ACCESS_KEY = aws_credentials['ses_secret_key'] AWS_SES_REGION_NAME = 'us-west-2' AWS_SES_REGION_ENDPOINT = 'email.us-west-2.amazonaws.com' ``` 我們實際上要設定的部分是後面四個 - AWS_SES_ACCESS_KEY_ID, AWS_SES_SECRET_ACCESS_KEY: 通常會開一個 IAM user 專管 SES Service。對於 django-ses 來說,如果沒有設定這兩個,它會去讀取根目錄下的 `~/.aws/credentials` 看看是不是符合權限。 - AWS_SES_REGION_NAME = 'us-west-2' - AWS_SES_REGION_ENDPOINT = 'email.us-west-2.amazonaws.com' aws_credentials.json 的內容像是這樣: ``` { "ses_key_id":"key_id", "ses_secret_key":"secret_key" } ``` 目前就只有將 SES 的憑證獨立區分。其它 AWS 服務(S3)則是利用 ~/.aws/credentials 以及 ~/.aws/config 的設定。 ## TODO List 1. 寄信內容可以支援 HTML 格式。 2. 將這個 Class 的邏輯重新設計。