0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gmail着信通知

Last updated at Posted at 2025-11-11

Gmail着信通知

絶対に見逃したくないメールを待っているあなたへ

プロジェクト構成

ファイル 役割
gmail_notifier.py Gmail API 連携、ポーリング、通知音再生を担うメインスクリプト
requirements.txt 依存ライブラリ(OAuth, google-api-python-client, playsound)の一覧
maintheme.mp3 デフォルト通知音(任意の MP3 に差し替え可能)

セットアップ手順

  1. 依存関係のインストール
    requirements.txt
    google-auth-oauthlib==1.2.0
    google-auth-httplib2==0.2.0
    google-api-python-client==2.118.0
    playsound==1.3.0
    
    pip install -r requirements.txt
    
  2. Gmail API を有効化し認証情報を取得
    • Google Cloud Console で新規プロジェクトを作成し、ナビゲーションの「API とサービス → ライブラリ」から Gmail API を有効化
    • 「認証情報を作成 → OAuth クライアント ID」を選択し、同意画面はユーザータイプ「外部」、テストユーザーに自分の Gmail アドレスを追加
    • アプリケーションの種類に「デスクトップアプリ」を指定して生成した JSON を credentials.json としてプロジェクト直下に配置
  3. アプリ設定
    • gmail_notifier.pyTARGET_EMAIL に監視したい送信元アドレスを記入(複数ある場合は Gmail 検索クエリを工夫)
    • NOTIFICATION_SOUND に再生したい MP3 ファイルのパスを設定(maintheme.mp3 を別音源に差し替えてもOK)
  4. 初回実行と認可
    • python gmail_notifier.py を実行するとブラウザが開き、Google アカウントの OAuth 認可を要求
    • 「このアプリは確認されていません」と表示された場合は「詳細」→「(プロジェクト名)に移動」を選択して許可
    • 認可完了後に token.pickle が生成され、以降はサイレントに再利用される

動作フロー

  1. 資格情報のロード: token.pickle があれば読み込む。期限切れなら自動更新、無ければブラウザで認可を要求。
  2. Gmail API サービス生成: googleapiclient.discovery.build('gmail', 'v1', ...) でクライアントを構築。
  3. ポーリング: 10 秒ごとに users().messages().listfrom:{TARGET_EMAIL} を検索し、最新 1 通を取得。
  4. 差分判定: 取得した Date ヘッダーを前回記録 (last_date) と比較。初回は記録のみ、差分があれば新着と判断。
  5. 爆音通知: playsound で MP3 を再生し、ターミナルに件名と日時を出力。
  6. ループ継続: Ctrl+C で明示的に止めるまで常駐。

フルコード

下記が gmail_notifier.py の全文です。メールアドレスやサウンドファイル名はプレースホルダーになっているので、自分の環境に合わせて編集してください。

gmail_notifier.py
import os
import pickle
import time
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from playsound import playsound

# Gmail API で使用するスコープは読み取り専用に限定
SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"]

# 監視対象の送信者メールアドレス(自分の用途に置き換え)
TARGET_EMAIL = "your-alert@example.com"

# 再生したい MP3 ファイルのパス
NOTIFICATION_SOUND = "maintheme.mp3"


def get_gmail_service():
    """Gmail API サービスを初期化して返す。token.pickle を使い再認証を最小化。"""
    creds = None
    if os.path.exists("token.pickle"):
        with open("token.pickle", "rb") as token_file:
            creds = pickle.load(token_file)

    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
            creds = flow.run_local_server(port=0)
        with open("token.pickle", "wb") as token_file:
            pickle.dump(creds, token_file)

    return build("gmail", "v1", credentials=creds)


def check_new_emails(service):
    """最新メールを取得し、既存記録と日時が変われば爆音通知を鳴らす。"""
    try:
        results = service.users().messages().list(
            userId="me", maxResults=1, q=f"from:{TARGET_EMAIL}"
        ).execute()
        messages = results.get("messages", [])

        if not messages:
            return

        msg = service.users().messages().get(userId="me", id=messages[0]["id"]).execute()
        headers = msg["payload"]["headers"]
        date = next(h["value"] for h in headers if h["name"] == "Date")
        subject = next((h["value"] for h in headers if h["name"] == "Subject"), "(No Subject)")

        if not hasattr(check_new_emails, "last_date"):
            check_new_emails.last_date = date
            print(f"初期化: 最新メール {subject} ({date}) を記録しました。")
            return

        if check_new_emails.last_date != date:
            check_new_emails.last_date = date
            print(f"新着メール検知: {subject} ({date})")
            playsound(NOTIFICATION_SOUND)
    except Exception as err:
        print(f"エラーが発生しました: {err}")


def main():
    """10 秒ピッチで Gmail を監視し続ける常駐ループ。"""
    print("Gmail 爆音通知システムを起動します。")
    print(f"監視対象: {TARGET_EMAIL}")
    service = get_gmail_service()

    try:
        while True:
            check_new_emails(service)
            time.sleep(10)
    except KeyboardInterrupt:
        print("停止コマンドを受信しました。終了します。")


if __name__ == "__main__":
    main()

このコードでは gmail.readonly スコープを使い、削除や送信など破壊的な権限を要求していません。playsound は OS を問わず MP3 を再生できるため、Windows/macOS/Linux で同じ実装を共有できます。

使用方法まとめ

  1. 依存関係を入れる: 任意の Python 環境で pip install -r requirements.txt。Poetry や venv を使う場合も requirements をそのまま読み込めば OK。
  2. Google Cloud Console で OAuth 設定: 新規プロジェクト → Gmail API を有効化 → OAuth クライアント ID(デスクトップ)を作成 → ダウンロードした JSON を credentials.json として保存。
  3. コードを書き換える: TARGET_EMAILNOTIFICATION_SOUND を自分の用途に合わせて編集し、必要なら監視クエリ(q=f"from:{TARGET_EMAIL}" 部分)を Gmail 検索構文で拡張。
  4. 初回実行で認可: python gmail_notifier.py を実行し、ブラウザで Google アカウントの許可を与える。完了すると token.pickle が生成される。
  5. 常駐させる: ターミナルを開いたまま放置するだけで 10 秒ごとに監視。終了するときは Ctrl+C
  6. モバイル/Mac 通知も整備: 本文の「デバイス別通知設定」を参考にショートカットや Mail ルールを作れば、同じ送信者に対するマルチチャネル通知体制を構築できる。

トラブルシューティング

  • 音が鳴らない: ファイルパス、拡張子 (MP3)、OS の音量、Focus/おやすみモードを確認。
  • iPhone で鳴らない: ショートカット自動化が「有効」か、通知の許可と音量、低電力モードを確認。
  • Mac で鳴らない: システム設定の通知許可と Mail ルールを再確認し、フォーカスモードが無効かをチェック。
  • 認証エラー: token.pickle を削除し再実行。credentials.json が最新か確認。
  • API 制限: Cloud Console の「API とサービス → ダッシュボード」で呼び出し状況を確認し、必要ならクォータ引き上げを申請。
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?