スマホにPush通知する

やりたいこと

カメラが人や車両を検知したらスマホに Push 通知。
録画データの ts から mp4 へのエンコードが完了したらスマホに Push 通知。
Zabbix からのメールに連動してスマホに Push 通知。
毎朝、その日の天気予報をスマホに Push 通知。

もうね、なんでもあり。
NanoPi NEO の CPU 温度が50度を超えたらPush通知。とかでもいい。

とにかく手軽に情報をスマホに集めたかった。

用意したもの

Raspberry Pi 4B だけ。スマホはお手元のものを…

使うのはNtfy(ノーティファイ)というセルフホスト型のサーバソフトウェア

ダウンロードとインストール

以下のリリースページからダウンロード。
これを書いている時点(2025/03/31)で V2.21.0 が最新。
そして、ラズパイに導入するので、ARM系のパッケージかつ64ビット版。
Docker版もあるっぽいけど、個人的には管理しやすい tar.gz を入手。

Releases · binwiederhier/ntfy
Send push notifications to your phone or desktop using PUT/POST - binwiederhier/ntfy

ダウンロードと解凍は以下の通り。

$ wget https://github.com/binwiederhier/ntfy/releases/download/v2.21.0/ntfy_2.21.0_linux_arm64.tar.gz
$ tar zxfv ntfy_2.21.0_linux_arm64.tar.gz
$ mv ntfy_2.21.0_linux_arm64 ntfy
$ cd ntfy

これだけでOK

サーバ設定

あとはチョチョイと設定すればすぐ動く。
設定ファイルは server 等ディレクトリ内の server.yml というファイルで行う。

$ cd server
$ vi server.yml

変更箇所は以下。
それぞれ、先頭の # を削除して、値を書いていく。

base-url: "http://yourdomain"
listen-http: ":80"
cache-file: "/var/lib/ntfy/cache.db"
auth-file: "/var/lib/ntfy/user.db"
attachment-cache-dir: "/var/cache/ntfy/attachments"
upstream-base-url: "https://ntfy.sh"

とりあえず、こんなもんで動くようにはなる。

「base-url: “http://yourdomain”」 ローカルで運用するだけならローカルIPで http://192.168.10.251 とかでも良い。
「listen-http: “:80″」は多分変えないとダメよね?Nginx か Apache が既に使っちゃってること多いと思うので。
「upstream-base-url: “https://ntfy.sh”」は iPhone に Push しなければ不要だけど、入れておいてもいいでしょう。

で、2つくらいファイル関連の設定も入れてあるけど、/var/lib/ntfy というディレクトリが存在しないので作っておく。

$ sudo mkdir /var/lib/ntfy

これで ./ntfy に戻って、下記のようにすると動き出す…

$ sudo ./ntfy -c ./server/server.yml

特にエラーは出ないはずだけど、エラーが出たら server.yml に間違いがないか確認。
無事に起動した場合は以下のように表示される。

2026/04/01 00:03:19 INFO Listening on :80[http], ntfy 2.21.0, log level is INFO (tag=startup)
2026/04/01 00:04:19 INFO Server stats (emails_received=0, emails_received_failure=0, emails_received_success=0, emails_sent=0, emails_sent_failure=0, emails_sent_success=0, messages_cached=0, messages_published=0, subscribers=0, tag=manager, topics_active=0, users=1, visitors=0)

起動出来たら、ブラウザで base-url に記載した URL にアクセスしてみる。
以下のような(色合いは端末によって変わる)UI が表示されればOK

通知のための設定:Topicの購読

左ペインの「+ トピックを購読する」をクリックして、新たに開かれたウィンドウ内にある「トピック名」に適当に名前を登録する。
「free_topic」とか「talk_to_oneself」とか、なんでもいい。
で、「購読する」をクリックすればOK

…なんか、Chrome は英語を日本語に自動で翻訳しちゃうので、新たに始まったTopic「talk_to_oneself」が「独り言を言う」に訳されちゃってるけど…まぁ、気にしない。

試しに通知を出してみる。
左ペインの「購読トピック」の「talk_to_oneself」(ブラウザ上の表示は「独り言を言う」)をクリックし、ブラウザ内左上に表示されている内容も「独り言を言う」になったら「通知を公開する」をクリック。

すると、新たなウィンドウが開かれるので、「タイトル」と「メッセージ」に適当に文章を書いて「送信」

で、ちゃんと通知が飛んだ。

PC上のブラウザで履歴が見れたので、基本的な動作はこれでOKということに。

では、次、目的の「スマホにPush通知」に移ろう。

スマホでは「ntfy」アプリを使う

iPhone でも Android でも、同じ名称のアプリがあるので、検索してインストール。

アプリを立ち上げたら、画面下にある「Settings」をタップして、その中の「Default server」を server.yml 内 base-url に設定したURLを書いておくと、あとが楽。

尚、舌では USERS に何かユーザーが入っちゃってるけど、通知の送受信に認証が必要になったら登録すればよいので、動作確認の段階では空欄のままでOK(ブラウザで通知送信確認した時も、特にユーザーの登録はしていないので問題ない)

で、お次は画面下にある「Notifications」へ移動。
購読したいトピックの登録をするので、画面右上の「+」をタップ。

「Topic name, e.g. phil_alerts」となっているところに、さっきブラウザで登録したトピックの「talk_to_onself」を入力。
「Use another server」は上の「Settings」の「Default server」に間違いなければそのままで良い。
入力が終わったら「Subscribe」

これで一通り設定完了。

さっきブラウザで通知を送ったけど、もう一度メッセージを変えて送ってみる。
また、今度はブラウザ下部にある「ここにメッセージを入力してください」に入力して試してみる…

数秒後…

うん、OKだね。

いろいろな通知方法

ここまではブラウザで試していたけど、これは目的の使い方じゃない。

ラズパイのGPIOにスイッチが繋がっててそれが押されたら、とか、何らかのアクションがあって、それに連動して通知を飛ばしたいわけなので、ブラウザでってのはまずない。

python で送信

じゃぁ、何が使われるかって言ったら、やっぱり python が多いのかな?と。

てことで、簡単なコードは以下の通り。

import requests

def send_ntfy(msg, title="アラート", priority="high"):
    # トピックのURL
    url = "http://yourdomain/talk_to_oneself" 
    
    headers = {
        "Title": title.encode('utf-8'),
        "Priority": priority,
        "Tags": "warning,computer"
    }
    
    # メッセージ送信
    response = requests.post(url, data=msg.encode('utf-8'), headers=headers)
    
    if response.status_code == 200:
        print("送信完了")
    else:
        print(f"なんかエラー出た: {response.status_code}")

# 実行
send_ntfy("こうすれば通知を送信できるはず", title="Pythonから")
curl で送信

これは超簡単。

$ curl -d "curlで送ってみる" http://yourdomain/talk_to_oneself

単純なのならこれで送れる。
けど、もう少し工夫すると以下のような感じかな。

$ curl -H "Title: curlから通知送信" -H "Priority: urgent" -H "Tags: warning,rotating_light" -d "curlならやろうと思えば1行でイケる!" http://yourdomain/talk_to_oneself
wget で送信

curl と同じくらいシンプルにイケる。

$ wget --post-data="wgetから送信" http://yourdomain/talk_to_oneself

同様に、ちょっと工夫すればもう少し情報増やせる。ちょっと長いけど…

$ wget --header="Title: curlから通知送信" --header="Priority: urgent" --header="Tags: warning,rotating_light" --post-data="wgetでも1行がちょっと長いけど、イケる!" -qO- http://yourdomain/talk_to_oneself

とりあえず、これだけできれば困らないかな。

この記事にコメントしてみる