11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-09-01

背景

以前、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 :宛先です。カンマ区切りにすることで複数設定可能です。
11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?