Amazonの「発送」「配達中」「お届け済み」メールって、気づくのが遅れて受け取れなかったりしますよね。
そこで筆者の自宅環境では、
Raspberry Pi が Amazonメールを検知 → Discord に自動通知
する仕組みを構築しました。
この記事では、
Gmail API × Python × Discord Webhook × systemd
を使い、再現性の高い手順で構築方法をまとめています。
また、運用する上で重要な
・重複通知防止ロジック
・systemdの正しい監視方法
・権限設定
もすべて改善済みの「実運用バージョン」です。
🎯 ゴール(完成イメージ)
Discord にこんな通知が届くようになります:
📦 Amazon関連メールを検出:
[発送済み] ご注文の商品がAmazonより発送されました
さらに、何かの理由でスクリプトが失敗した場合は:
❌ amazon_mail_notifier.service が停止しました(failed)
という通知も自動で飛んでくるようになります。
🧩 全体アーキテクチャ
Amazon → Gmail → Gmail API → Python → Discord Webhook
↑
systemd service(oneshot)
↑
systemd timer(5分)
↑
is-failed で監視
📌 1. ディレクトリ構成
Raspberry Pi の任意ディレクトリに以下の構成で作成します。
/home/<ユーザー名>/projects/
└─ discord-bots/
└─ amazon-mail-notifier/
├─ amazon_mail_notifier.py
├─ config.json
├─ state.json ← 自動生成
├─ credentials.json ← Google OAuth
├─ token.json ← 初回認証で自動生成
└─ .venv/
※ <ユーザー名> は自身のユーザーに変更。
📌 2. Gmail API の準備
Google Cloud Console で以下を行います。
① プロジェクト作成
② Gmail API を有効化
③ OAuth クライアントID(デスクトップアプリ)を作成
④ credentials.json を保存してプロジェクトに配置
⑤ テストユーザーに自分の Gmail を追加
(Publishing status が Testing の場合は必須)
⚠ 初心者が最もつまずくポイントは⑤。必ず最新メールアドレスを追加すること。
📌 3. Python仮想環境(venv)
cd /home/<ユーザー名>/projects/discord-bots/amazon-mail-notifier
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib requests
📌 4. config.json(通知設定)
{
"discord_webhook_url": "https://discord.com/api/webhooks/xxxx",
"keywords": ["発送", "配達", "お届け", "到着", "出荷"]
}
📌 5. メインスクリプト(重複通知対策済み・最新版)
✔ 最新のIDを一度だけ保存するロジックに修正済み(重要)
✔ rootで実行しないためにsystemd側でUser指定(重要)
amazon_mail_notifier.py:
#!/usr/bin/env python3
import os
import json
import requests
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
# ===== Load base path =====
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# ===== Load config =====
with open(os.path.join(BASE_DIR, "config.json"), encoding="utf-8") as f:
CONFIG = json.load(f)
WEBHOOK_URL = CONFIG["discord_webhook_url"]
KEYWORDS = CONFIG["keywords"]
STATE_FILE = os.path.join(BASE_DIR, "state.json")
# ===== Load last message ID =====
def load_last_message_id():
if not os.path.exists(STATE_FILE):
return None
with open(STATE_FILE, "r") as f:
data = json.load(f)
return data.get("last_message_id")
# ===== Save message ID =====
def save_last_message_id(msg_id):
with open(STATE_FILE, "w") as f:
json.dump({"last_message_id": msg_id}, f)
===== Discord notification =====
def send_discord(text):
payload = {"content": text}
requests.post(WEBHOOK_URL, json=payload)
===== Main process =====
def main():
last_id = load_last_message_id()
creds = Credentials.from_authorized_user_file(
os.path.join(BASE_DIR, "token.json"),
["https://www.googleapis.com/auth/gmail.readonly"]
)
service = build("gmail", "v1", credentials=creds)
# 最新5件を取得(新しい順)
results = service.users().messages().list(
userId="me", maxResults=5
).execute()
messages = results.get("messages", [])
if not messages:
return
# ★ 最新IDを保存するために控えておく(これが正しいやり方)
newest_id = messages[0]["id"]
# メールを新しい順に処理
for msg in messages:
msg_id = msg["id"]
# 以前処理したIDに到達したら終了(差分処理)
if msg_id == last_id:
break
detail = service.users().messages().get(
userId="me", id=msg_id
).execute()
snippet = detail.get("snippet", "")
# キーワード判定
if any(kw in snippet for kw in KEYWORDS):
send_discord(f"📦 Amazon関連メールを検出:\n```\n{snippet}\n```")
# ★ すべての処理後に最新IDを一度だけ保存
save_last_message_id(newest_id)
if __name__ == "__main__":
main()
📌 6. systemd登録(User指定を追加)
/etc/systemd/system/amazon_mail_notifier.service
[Unit]
Description=Amazon Mail Notifier (Gmail → Discord)
[Service]
Type=oneshot
User=<ユーザー名>
ExecStart=/home/<ユーザー名>/projects/discord-bots/amazon-mail-notifier/.venv/bin/python \
/home/<ユーザー名>/projects/discord-bots/amazon-mail-notifier/amazon_mail_notifier.py
/etc/systemd/system/amazon_mail_notifier.timer
[Unit]
Description=Run amazon_mail_notifier every 5 minutes
[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
有効化:
sudo systemctl daemon-reload
sudo systemctl enable --now amazon_mail_notifier.timer
📌 7. 監視スクリプトの改善(誤報防止)
oneshotサービスは 実行していない時間は inactive になるため is-active で監視すると誤報になります。
👉 正解は is-failed を使うこと。
/home/<ユーザー名>/projects/monitoring/check_amazon_mail_notifier.sh
#!/bin/bash
SERVICE="amazon_mail_notifier.service"
WEBHOOK="https://discord.com/api/webhooks/xxxx"
# failed の場合のみ通知(oneshot監視の正しい方法)
if systemctl is-failed --quiet $SERVICE; then
curl -X POST -H "Content-Type: application/json" \
-d "{\"content\":\"❌ $SERVICE が失敗状態(failed)です\"}" \
$WEBHOOK
fi
systemd 登録
/etc/systemd/system/check_amazon_mail_notifier.service
[Unit]
Description=Monitor Amazon Mail Notifier
[Service]
Type=oneshot
User=<ユーザー名>
ExecStart=/home/<ユーザー>/projects/monitoring/check_amazon_mail_notifier.sh
/etc/systemd/system/check_amazon_mail_notifier.timer
[Unit]
Description=Monitor amazon_mail_notifier every 5 minutes
[Timer]
OnBootSec=30sec
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
📌 8. セキュリティ注意点
credentials.json と token.json は 絶対にGitHubに公開しない
.gitignore に以下を入れておくこと:
credentials.json
token.json
state.json
Discord Webhook URL も第三者に漏れると悪用されるので注意
📌 9. まとめ
この記事で構築したシステムは:
Gmail API で最新メールを取得
Pythonでキーワード判定(重複通知防止ロジック込み)
Discord Webhook に送信
systemd timer で 5分ごと実行
oneshotサービスを is-failed で監視
User 指定で root 実行を回避
という 完全に実運用できる Amazon 配送通知システムです。
宅配の見落としがゼロになり、
受け取りの心理コストが本当に減るのでおすすめです。