Edited at

SMTPの設定無しで、pythonで特定のメールアドレスにメールを送付する

More than 3 years have passed since last update.


背景

以前、Ubuntu上でブラウザを自動実行し、WEB上の値を定点観測するという記事を書きました。

監視している値に目立つ動きがあった場合、メールでアラートを送るということを検討したのですが、SMTPサーバーを1から設定するのは面倒でした。

調べてみるとGmail APIを使えばSMTPを用意しなくてもメールの送信ができるということでプログラムを組んでみました。


環境

OS : Ubuntu16.04

python : version3.5


Step1) Gmai APIを使うための準備


(1)python用Gmail APIパッケージをインストール

pip3 install --upgrade google-api-python-client


(2)GmailのページでAPIを利用する認証を行う

認証はこちらのページのStep1に従って作業すれば大丈夫でしょう。


Step2) Gmailを送信するプログラムコードを書く

実際のプログラムコードは以下のサイトからほとんど真似をして書きました。

→ Python3 + google-api-python-clientで、Gmail APIを使ってメールを送信する



とても分かりやすく書かれています。

以下にプログラムコードを示します。

コード内の4つの定数(CLIENT_SECRET_FILE,APPLICATION_NAME,MAIL_FROM,MAIL_TO)を変えるだけで、ご自身の環境でお使い頂けると思います。

from __future__ import print_function

import httplib2
import os

import apiclient
from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools

import base64
from email.mime.text import MIMEText
from email.utils import formatdate
import traceback

try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/gmail-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/gmail.send'
CLIENT_SECRET_FILE = '<path_to_credintial>.json'
APPLICATION_NAME = '<application_name>'

MAIL_FROM = "<sender email-address>"
MAIL_TO = "<receiver email-address>"

def get_credentials():

home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'gmail-send-api.json')

store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials

def create_message(receiver,subject,mail_str):
message = MIMEText(mail_str)
message["from"] = MAIL_FROM
message["to"] = receiver
message["subject"] = subject
message["Date"] = formatdate(localtime=True)

byte_msg = message.as_string().encode(encoding="UTF-8")
byte_msg_b64encoded = base64.urlsafe_b64encode(byte_msg)
str_msg_b64encoded = byte_msg_b64encoded.decode(encoding="UTF-8")

return {"raw": str_msg_b64encoded}

def send_mail(receiver,subject,mail_str):

credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)

try:
result = service.users().messages().send(
userId = MAIL_FROM,
body=create_message(receiver,subject,mail_str)
).execute()

print("Message Id: {}" .format(result["id"]))

except apiclient.errors.HttpError:
print("-----start trace-----")
traceback.print_exc()
print("-----end trace-----")

if __name__ == '__main__':
send_mail("gano_test\ngano_test2")

補足ですが、4つの定数はそれぞれ以下を入力します。


  • CLIENT_SECRET_FILE :STEP1でGMAILサイトからダウンロードした認証用jsonファイルのパス

  • APPLICATION_NAME :任意につけたアプリケーション名。なんでもよいです。

  • MAIL_FROM :送信者名。Step1でログインしたアカウントのアドレスです。

  • MAIL_TO :宛先です。カンマ区切りにすることで複数設定可能です。