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?

🚚 Amazonの配送メールを自動でDiscord通知する仕組みを Raspberry Pi で構築してみた(Gmail API × Python × systemd)

Posted at

Amazonの「発送」「配達中」「お届け済み」メールって、気づくのが遅れて受け取れなかったりしますよね。

そこで筆者の自宅環境では、
Raspberry Pi が Amazonメールを検知 → Discord に自動通知
する仕組みを構築しました。

この記事では、
Gmail API × Python × Discord Webhook × systemd
を使い、再現性の高い手順で構築方法をまとめています。

また、運用する上で重要な

・重複通知防止ロジック
・systemdの正しい監視方法
・権限設定
もすべて改善済みの「実運用バージョン」です。

🎯 ゴール(完成イメージ)

Discord にこんな通知が届くようになります:

less

📦 Amazon関連メールを検出:
[発送済み] ご注文の商品がAmazonより発送されました

さらに、何かの理由でスクリプトが失敗した場合は:

less

❌ amazon_mail_notifier.service が停止しました(failed)

という通知も自動で飛んでくるようになります。

csharp

🧩 全体アーキテクチャ
Amazon → Gmail → Gmail API → Python → Discord Webhook
                       ↑
                 systemd service(oneshot)
                       ↑
                 systemd timer(5分)
                       ↑
                 is-failed で監視

📌 1. ディレクトリ構成

Raspberry Pi の任意ディレクトリに以下の構成で作成します。

pgsql

/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)

bash

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(通知設定)

json

{
  "discord_webhook_url": "https://discord.com/api/webhooks/xxxx",
  "keywords": ["発送", "配達", "お届け", "到着", "出荷"]
}

📌 5. メインスクリプト(重複通知対策済み・最新版)

✔ 最新のIDを一度だけ保存するロジックに修正済み(重要)
✔ rootで実行しないためにsystemd側でUser指定(重要)

amazon_mail_notifier.py:

python

#!/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

ini
[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

ini
[Unit]
Description=Run amazon_mail_notifier every 5 minutes

[Timer]
OnBootSec=1min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target

有効化:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now amazon_mail_notifier.timer

📌 7. 監視スクリプトの改善(誤報防止)

oneshotサービスは 実行していない時間は inactive になるため is-active で監視すると誤報になります。

👉 正解は is-failed を使うこと。

bash
/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

ini
[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

ini
[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 に以下を入れておくこと:

pgsql
credentials.json
token.json
state.json

Discord Webhook URL も第三者に漏れると悪用されるので注意

📌 9. まとめ

この記事で構築したシステムは:

Gmail API で最新メールを取得

Pythonでキーワード判定(重複通知防止ロジック込み)

Discord Webhook に送信

systemd timer で 5分ごと実行

oneshotサービスを is-failed で監視

User 指定で root 実行を回避

という 完全に実運用できる Amazon 配送通知システムです。

宅配の見落としがゼロになり、
受け取りの心理コストが本当に減るのでおすすめです。

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?