【完全ガイド】Pythonでメール自動送信

ソニック

Outlook/Gmail両対応・コピペで使えるコード付き

「毎月10名以上の顧客にレポートをメール送信」「定型メールの送信に毎日30分かけている」

そんな悩み、Pythonで一気に解決できます。

私自身、データサイエンス業務で顧客にレポートを納品する際、メール送信業務を半自動化しています。月10件以上のレポート送信が、ボタン1つで完了するようになりました。

この記事では、Pythonでメールを自動送信する方法を、Gmail・Outlook両対応で、コピペで使えるコード付きで完全解説します。

第1章|なぜメール自動化が業務時間を変えるのか

目次

こんな業務、ありませんか?

  • 毎月の請求書を顧客にメール送信
  • 週次レポートを部署メンバーに一斉配信
  • 定型の連絡メール(顧客への案内、社内通知)
  • 売上アラート(一定額を超えたら自動通知)
  • 週末のサマリーレポートを上司に送信

これらは「送信先・件名・本文」が決まったパターンの繰り返しです。Pythonなら、データを差し替えるだけで自動送信できます。

メール自動化のメリット

観点手作業Python自動化
10名分送信30〜60分10秒
送信ミス(誤送信)起こりやすい起こりにくい
定期実行人が忘れる確実に送信
レポート添付手動で1件ずつ自動で各顧客のレポート添付

第2章|環境準備(uv環境前提)

この記事は、uv環境でPythonを使う前提で進めます。まだuvをインストールしていない方は、別記事「【完全版】uv入門」をご覧ください。

必要なライブラリ

実は、Pythonの標準ライブラリだけでメール送信ができます。追加インストールは基本不要です。

# smtplib(メール送信)と email(メール作成)は標準搭載
# 追加インストールが必要なのは、Excel連携する場合のみ
uv add pandas openpyxl

第3章|基本|SMTPでメールを送る

メール送信の仕組みを理解するため、まずは最もシンプルなメール送信から始めます。

メール送信の3ステップ

  1. メールの内容を組み立てる(宛先・件名・本文)
  2. SMTPサーバーに接続してログイン
  3. メールを送信して、接続を切断

最小のメール送信コード

# メール送信に必要な標準ライブラリを読み込み
import smtplib
from email.mime.text import MIMEText

# === 設定 ===
# 送信元(自分のメールアドレス)
SMTP_SERVER = "smtp.gmail.com"  # Gmailの場合
SMTP_PORT = 587
SENDER_EMAIL = "your-email@gmail.com"
SENDER_PASSWORD = "your-app-password"  # 第4章で取得方法を解説

# 送信先
RECIPIENT_EMAIL = "recipient@example.com"

# === メールを組み立てる ===
# MIMETextでメール本文を作成(日本語のため utf-8 を指定)
msg = MIMEText("これはPythonから送信したテストメールです。", "plain", "utf-8")
msg["Subject"] = "Pythonからのテストメール"
msg["From"] = SENDER_EMAIL
msg["To"] = RECIPIENT_EMAIL

# === メールを送信 ===
# SMTPサーバーに接続
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
    # TLSで通信を暗号化(セキュリティのため必須)
    server.starttls()
    # ログイン
    server.login(SENDER_EMAIL, SENDER_PASSWORD)
    # メール送信
    server.send_message(msg)

print("メールを送信しました")

コードの各行の意味

  • smtplib:メール送信のためのライブラリ
  • MIMEText:メール本文(テキスト形式)を作るクラス
  • SMTP_SERVER:使用するメールサーバーの住所
  • SMTP_PORT:587は「TLS暗号化通信用」のポート番号
  • starttls():通信を暗号化(盗聴防止)
  • login():メールアカウントにログイン
  • send_message():実際にメールを送信

第4章|Gmailでの送信設定(アプリパスワード)

Gmailから送信する場合、通常のパスワードではログインできません。「アプリパスワード」という専用パスワードを生成する必要があります。

アプリパスワードの取得手順

  • Googleアカウント設定画面を開く(myaccount.google.com)
  • 「セキュリティ」を選択
  • 「2段階認証プロセス」を有効にする(必須・未設定の場合)
  • 「2段階認証プロセス」の中の「アプリパスワード」を開く
  • アプリ名を入力(例:Python自動送信)
  • 生成された16桁のパスワードをコピー

Gmail用の接続設定

# Gmailの場合
SMTP_SERVER = "smtp.gmail.com"
SMTP_PORT = 587
SENDER_EMAIL = "your-email@gmail.com"
SENDER_PASSWORD = "xxxxxxxxxxxxxxxx"  # 16桁のアプリパスワード

アプリパスワードは絶対にGitHub等にアップロードしないでください。漏洩するとアカウント乗っ取りのリスクがあります。

第5章|Outlookでの送信設定

Outlook(@outlook.com、@hotmail.com)の場合も基本的な仕組みは同じです。ただし、SMTPサーバーの設定が異なります。

Outlook用の接続設定

# Outlook(個人アカウント)の場合
SMTP_SERVER = "smtp-mail.outlook.com"
SMTP_PORT = 587
SENDER_EMAIL = "your-email@outlook.com"
SENDER_PASSWORD = "your-password"  # 通常のパスワード

# 法人版Outlook(Microsoft 365)の場合
SMTP_SERVER = "smtp.office365.com"
SMTP_PORT = 587

法人版Outlook(Microsoft 365)では、SMTP AUTHの有効化が必要な場合があります。会社のIT管理者に確認してください。

主要メールサービスの設定一覧

サービスSMTPサーバーポート
Gmailsmtp.gmail.com587
Outlook(個人)smtp-mail.outlook.com587
Outlook(法人)smtp.office365.com587
Yahoo!メールsmtp.mail.yahoo.co.jp587

第6章|応用|添付ファイル付きメール

実務でよくあるのが「Excelの請求書を添付してメール送信」。ここまで自動化できれば、業務の半分は楽になります。

添付ファイル付きメールのコード

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

# === 設定 ===
SMTP_SERVER = "smtp.gmail.com"
SMTP_PORT = 587
SENDER_EMAIL = "your-email@gmail.com"
SENDER_PASSWORD = "your-app-password"
RECIPIENT_EMAIL = "recipient@example.com"
ATTACHMENT_PATH = "請求書_202604.xlsx"  # 添付するファイルのパス

# === メールを組み立てる ===
# MIMEMultipartで「本文+添付ファイル」を含むメールを作成
msg = MIMEMultipart()
msg["Subject"] = "【2026年4月分】請求書のご送付"
msg["From"] = SENDER_EMAIL
msg["To"] = RECIPIENT_EMAIL

# === 本文を追加 ===
body = """
お世話になっております。

2026年4月分の請求書を添付ファイルにてお送りいたします。
ご確認のほど、よろしくお願いいたします。

ソニック
"""
msg.attach(MIMEText(body, "plain", "utf-8"))

# === 添付ファイルを追加 ===
# バイナリモードでファイルを開く
with open(ATTACHMENT_PATH, "rb") as f:
    # MIMEBaseで添付ファイルのオブジェクトを作成
    part = MIMEBase("application", "octet-stream")
    part.set_payload(f.read())

# Base64でエンコード(メール添付の標準形式)
encoders.encode_base64(part)

# ファイル名を指定して添付
part.add_header(
    "Content-Disposition",
    f"attachment; filename={ATTACHMENT_PATH}"
)
msg.attach(part)

# === メールを送信 ===
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
    server.starttls()
    server.login(SENDER_EMAIL, SENDER_PASSWORD)
    server.send_message(msg)

print(f"{RECIPIENT_EMAIL}宛にメールを送信しました")

コードのポイント

  • MIMEMultipart:「本文+添付」を含むメール形式
  • MIMEBase:添付ファイル用のオブジェクト
  • encode_base64:添付ファイルをメール送信用にエンコード
  • Content-Disposition:受信側でファイル名を正しく表示するためのヘッダー

第7章|実務スクリプト|月次レポート自動配信

ここまでの内容を統合した、実務で使える完成スクリプトです。複数の顧客に、それぞれのレポートを自動配信できます。

シナリオ

CSVファイル「顧客リスト.csv」に、顧客名・メールアドレス・添付ファイル名が記載されているとします。

# 顧客リスト.csv の中身
顧客名,メール,添付ファイル
株式会社A,a@example.com,請求書_株式会社A.xlsx
株式会社B,b@example.com,請求書_株式会社B.xlsx
株式会社C,c@example.com,請求書_株式会社C.xlsx

完成スクリプト

import smtplib
import pandas as pd
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from datetime import datetime
import time

# === 設定 ===
# 送信元情報
SMTP_SERVER = "smtp.gmail.com"
SMTP_PORT = 587
SENDER_EMAIL = "your-email@gmail.com"
SENDER_PASSWORD = "your-app-password"

# 送信先リストのCSVファイル
CUSTOMER_LIST = "顧客リスト.csv"

# 添付ファイルがあるフォルダ
ATTACHMENT_FOLDER = "請求書/"

# 当月
CURRENT_MONTH = datetime.now().strftime("%Y年%m月")


def create_message(customer_name, recipient_email, attachment_path):
    """
    1件分のメールを作成する関数
    """
    # メールの基本情報
    msg = MIMEMultipart()
    msg["Subject"] = f"【{CURRENT_MONTH}分】請求書のご送付"
    msg["From"] = SENDER_EMAIL
    msg["To"] = recipient_email
    
    # 本文(顧客名を動的に挿入)
    body = f"""
{customer_name} ご担当者様

いつもお世話になっております。

{CURRENT_MONTH}分の請求書を添付ファイルにてお送りいたします。
ご確認のほど、よろしくお願いいたします。

何かご不明な点がございましたら、お気軽にお問い合わせください。

--
ソニック
"""
    msg.attach(MIMEText(body, "plain", "utf-8"))
    
    # 添付ファイルを追加
    with open(attachment_path, "rb") as f:
        part = MIMEBase("application", "octet-stream")
        part.set_payload(f.read())
    
    encoders.encode_base64(part)
    part.add_header(
        "Content-Disposition",
        f"attachment; filename={attachment_path.split('/')[-1]}"
    )
    msg.attach(part)
    
    return msg


# === メイン処理 ===
# 顧客リストを読み込む
df = pd.read_csv(CUSTOMER_LIST)
print(f"{len(df)}件の顧客にメール送信を開始します")

# SMTPサーバーに接続(一度だけログインして、複数送信)
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
    server.starttls()
    server.login(SENDER_EMAIL, SENDER_PASSWORD)
    
    # 各顧客にメールを送信
    for index, row in df.iterrows():
        customer_name = row["顧客名"]
        recipient_email = row["メール"]
        attachment_file = row["添付ファイル"]
        attachment_path = f"{ATTACHMENT_FOLDER}{attachment_file}"
        
        try:
            # メールを作成
            msg = create_message(customer_name, recipient_email, attachment_path)
            # 送信
            server.send_message(msg)
            print(f"  ✓ {customer_name}({recipient_email})")
            # スパム判定を避けるため、各送信間に2秒待機
            time.sleep(2)
        except Exception as e:
            print(f"  ✗ {customer_name}:エラー({e})")

print("\n完了しました")

このスクリプトでできること

  • CSVから複数顧客のリストを読み込み
  • 各顧客に個別のレポートを添付して送信
  • 件名・本文に当月を自動挿入
  • エラーが発生しても他の送信は続行
  • スパム判定を避けるため、送信間隔を設ける

毎月のレポート作成にはmatplotlibやplotlyを組み合わせると効果的です。データ分析の自動化記事も今後公開予定です。

第8章|つまずき対処&まとめ

よくあるトラブル

トラブル1:「認証エラー」が出る(Gmail)

原因:

通常のパスワードを使っている。Gmailではアプリパスワードが必須。

対処:

2段階認証を有効化→アプリパスワードを生成→そのパスワードを使う(第4章参照)。

トラブル2:日本語が文字化けする

原因:

MIMETextでencoding(utf-8)を指定し忘れている。

対処:

# 第3引数に "utf-8" を必ず指定
msg = MIMEText("本文", "plain", "utf-8")

トラブル3:「スパムフォルダ」に入る

原因:

一気に大量送信、件名や本文が「スパムっぽい」、送信元が信頼されていない、など。

対処:

  • 送信間隔を設ける(time.sleep(2)など)
  • 件名・本文を業務的なものにする
  • 一度に大量送信しない(1日100件未満が安全)
  • 送信元アドレスを業務で使い慣れたものに

トラブル4:添付ファイルが文字化けする

原因:

日本語ファイル名のエンコーディング問題。

対処:

from email.header import Header

# 日本語ファイル名はHeaderでエンコード
filename = "請求書.xlsx"
part.add_header(
    "Content-Disposition",
    "attachment",
    filename=("utf-8", "", filename)
)

トラブル5:法人版Outlookで送信できない

原因:

Microsoft 365では、デフォルトでSMTP AUTHが無効になっている場合がある。

対処:

会社のIT管理者にSMTP AUTHの有効化を依頼するか、別の方法(Microsoft Graph API等)を検討します。

セキュリティの注意

  1. パスワードをコードに直接書かない(環境変数に逃がす)
  2. GitHubに公開しない(.gitignoreで除外)
  3. 不要になったアプリパスワードは即削除
  4. 一度に大量送信しない(迷惑メール認定リスク)

環境変数でパスワードを管理する方法

import os

# 環境変数からパスワードを取得
# 事前に「export EMAIL_PASSWORD=xxxx」のように設定する
SENDER_PASSWORD = os.environ.get("EMAIL_PASSWORD")

この記事のまとめ

  1. Pythonの標準ライブラリだけでメール自動送信が可能
  2. Gmailはアプリパスワード必須、Outlookは設定が比較的容易
  3. 添付ファイル付きメールも数十行で実装できる
  4. 月次レポート配信などの実務に直結
  5. セキュリティに最大限の注意を払う

FAQ

Q1. 一日に何件まで送信できますか?

Gmailは1日500件、Outlookは1日300件が目安です。ただし大量送信はスパム判定リスクがあるため、業務利用なら1日100件未満に抑えるのが安全です。それ以上は専用メール送信サービス(SendGrid等)の利用を推奨します。

Q2. HTML形式のリッチなメールを送りたい

可能です。MIMEText(“本文”, “html”, “utf-8”) のように第2引数を「html」にすると、HTMLタグを含むメールが送信できます。

Q3. メールの送信履歴を残したい

送信した内容をログファイルに記録するコードを追加します。logging モジュールを使うと、エラーも含めた送信履歴を体系的に管理できます。

Q4. 毎月1日に自動で送りたい

Windowsのタスクスケジューラ、Macのcronで定期実行できます。「毎月1日の午前9時に自動実行」のような運用が可能です。

Q5. 自分の会社のSMTPサーバーが不明です

会社のIT管理者またはメールクライアントの設定画面(Outlookの「アカウント設定」など)で確認できます。

メール自動化で、業務が変わる

「毎月のメール送信に半日かかっていた業務が、5秒で終わる」――この変化を体験すると、Pythonの本当の威力を実感できます。

openpyxlで作った請求書をメール自動送信、matplotlibで作ったレポートを定期配信、データ分析の結果を経営層に毎週配信。組み合わせ次第で、業務自動化の世界は無限に広がります。

最新の解説記事は、新着記事から順次公開しています。X(旧Twitter)でも更新情報を発信していますので、ぜひフォローしてください。

この記事を書いた人

ソニック|バックオフィス出身の業務効率化ブロガー。データサイエンス業務でクライアントへのレポート送信業務を自動化中。リアルな実体験をもとにしたノウハウを発信中。

→ 詳しいプロフィールはこちら→ はじめての方へ

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次