インターネット接続にプロキシサーバ必須な環境にて、PythonのSMTPクライアントでGmailからメールを送る方法


#本記事の内容
- インターネット接続にプロキシサーバ利用が必須な環境において、Gmailからメールを送れるPythonアプリを実装します。メールプロトコルはSMTPです。

Gmailのsmtpサーバを用いて、Pythonからメールを送りたかったのですが、
インターネット接続のためにプロキシサーバを経由させる必要がでたので、対応方法を調査してまとめました。

例えば、企業内の内部ネットワークやクラウドにおける内部ネットワークからのメール送信等、インターネット接続にプロキシサーバ利用が必要となるプライベートなネットワーク環境でPythonアプリを動かすことを想定しています。
きっと状況としては、よくあるはず。何かの役に立てば幸いです。

#実施環境
- Windows 10
- Visual Studio Code
- Python 3.8

#手順の流れ
1. Googleアカウントでのアプリ認証用のパスワード発行
2. SMTPでプロキシ設定できるPythonライブラリのインストール
3. Pythonプログラムの作成と実行

## 1. Googleアカウントでのアプリ認証用のパスワード発行

Googleアカウント管理画面に移動します。(Googleアカウントを未発行でしたら発行してください。）

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/25f01371-fbda-d730-c15f-c59bdb3bbfbf.png)

左のメニューから`セキュリティ`をクリックする。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/9fe589d5-ab9a-18d1-1f79-111561a377eb.png)

下の方へスクロールし、`アプリパスワード`をクリックする。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/e1069a7b-08f7-3309-9ad1-d30f1f78346e.png)

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/721398cf-2686-ec2c-57b8-091c8032042f.png)

Googleアカウントのパスワードを入力し、`次へ`をクリックする。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/91077954-e3b4-cdb2-2e2b-0d311de97245.png)

`アプリを選択`をクリックする。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/d41328bf-8ee5-1e26-7a98-44e202f8022e.png)

`その他(名前を入力)`をクリックする。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/3354f20a-c912-511a-8de5-e9e2fb5930ac.png)

デバイス名を入力し、`生成`をクリックする。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/054ce47e-4ac2-876b-8581-a0f19494b5d1.png)
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/54ef6006-ea4d-9b3e-4ec8-be37190cb5d4.png)

生成されたアプリパスワードをメモする。これは後ほどPythonアプリ内で使います。

## 2.SMTPでプロキシ設定できるPythonライブラリのインストール

私の場合Visual Studio Codeで開発していたので、Visual Studio Codeのターミナルを起動して、以下のコマンドでPySocksライブラリーをインストールしました。

	pip install PySocks

## 3. Pythonプログラムの作成と実行

以下にサンプルプログラムを載せます。

```python:smtp_send.py
from email import message
import smtplib
import ssl
import socks

SMTP_HOSTS = 'smtp.gmail.com'
SMTP_PORT = 465

FROM_EMAIL_ADDRESS = 'XXXXXXXX@gmail.com' #自身のgmailアドレスを記載する
PASSWORD = 'XXXXXXXXXX' #手順１で生成したアプリパスワードを記載する

PROXY_HOST = 'YYYYYYYYYYYYYYYYY' #Proxyサーバのドメイン abc.def.comの様な形式
PROXY_PORT = ZZZZZZZ #Proxyサーバのポート番号

TO_EMAIL_ADDRESS = 'AAAAA@BBBB' #送信先のメールアドレス
MAIL_SUBJECT = 'Test E-Mail' #メールタイトルを記載する
BODY_MESSAGE = 'Hello! This is Test Message.' #メール本文を記載する


def make_message(mail_subject, from_address, to_address, body_message):
   msg = message.EmailMessage()
   msg.set_content(body_message)
   msg['Subject'] = mail_subject
   msg['From'] = from_address
   msg['To'] = to_address
   return msg


def set_smtp_client_with_proxy(proxy_host, proxy_port, smtp_host, smtp_port):
   socks.setdefaultproxy(socks.HTTP, proxy_host, proxy_port)
   socks.wrapmodule(smtplib)
   context = ssl.create_default_context()
   smtp_client = smtplib.SMTP_SSL(smtp_host, smtp_port, timeout=10, context=context)
   return smtp_client


if __name__ == '__main__':
   msg = make_message(MAIL_SUBJECT, FROM_EMAIL_ADDRESS, TO_EMAIL_ADDRESS, BODY_MESSAGE)
   smtp = set_smtp_client_with_proxy(PROXY_HOST, PROXY_PORT, SMTP_HOSTS, SMTP_PORT)
   print('smtp login attempt')
   smtp.login(FROM_EMAIL_ADDRESS, PASSWORD)
   print('smtp login success')
   print('smtp message send attempt')
   smtp.send_message(msg)
   print('smtp message send success')
   smtp.quit()

```

Visual Studio Codeのターミナルで以下の様に実施する。

	PS D:\01_Python> python .\smtp_send.py
	smtp login attempt
	smtp login success
	smtp message send attempt
	smtp message send success
	PS D:\01_Python>

以下がメールが届いた様子です。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/b9e5a9f9-ac94-17bc-80ef-0affae7ea212.png)


今回のテストでは自身のメールアドレスから、自身宛てにテストメールを送るコードで実行しています。


手順は以上。

# 参考文献
本記事の作成に当たり、以下の情報を参考にさせて頂きました。
- [【2020年度版】PythonでGmailの自動送信を実装する方法を詳しく解説](https://marsquai.com/745ca65e-e38b-4a8e-8d59-55421be50f7e/05f253f8-c11b-4c91-8091-989eb2600a7b/04328017-ac2d-4a22-90a1-657848ec1520/)
- [Proxy経由でSMTPアクセス](https://www.lunaplus.net/posts/2021/06/proxy-for-smtp/)