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?

C#デスクトップアプリにメール通知を実装しようとしてOAuth2.0の壁に阻まれ、ntfy.shに救われた話

0
Posted at

概要

Windows向けバックアップ支援ツール「Robocopy Scheduler」の開発において、処理完了時の通知機能を実装する際、メール送信(SMTP / OAuth 2.0)の導入コスト回避としてオープンソースの通知基盤 ntfy.sh(ノーティファイ) を採用した経緯と実装例を紹介します。


課題:デスクトップアプリからのメール送信(SMTP)が厳しくなった背景

当初はバックアップ終了時にメール通知を送る機能を検討していました。かつてであれば、System.Net.Mail.SmtpClient などを用いてユーザーにSMTPサーバーのID/パスワードを入力してもらえば実装可能でした。

しかし、主要プロバイダ(GmailやOutlook等)の基本認証(BASIC認証)廃止に伴い、現在は OAuth 2.0 への対応が事実上必須となっています。

デスクトップアプリ(スタンドアロンのクライアントツール)でこれを実装しようとすると、以下のハードルが生じます。

  • OAuth 2.0 (PKCE) の実装: クライアントアプリ内に Client Secret を保持できないため、認可コードフローとPKCE (Proof Key for Code Exchange) のハンドリングが必要
  • クラウドプラットフォーム側の設定・維持: Google Cloud Console や Microsoft Entra ID でのアプリ登録、審査、ドメイン所有確認等
  • ユーザー体験の悪化: アプリ利用者に複雑な認証設定やトークン発行を行ってもらう必要がある

「バッチ処理やバックアップの完了ログを1行通知したいだけ」というユースケースに対して、開発・運用コストおよびユーザー設定のハードルが極めて高いと判断し、メール通知の採用は見送りました。


解決策:Pub/Sub型通知サービス「ntfy.sh」の採用

代替案として採用したのが ntfy.sh です。

ntfy.sh は、HTTP POST リクエストを送るだけでスマホやPCへリアルタイムにプッシュ通知を送信できるオープンソースの Pub/Sub 型通知サービスです。

主な特徴とメリット

  1. ユーザー登録が不要: 任意の「トピック名(ユニークな文字列)」を決めてURLにPOSTするだけで送信可能
  2. オープンソース(OSS): GitHubでコードが公開されており、信頼性が高い(独自サーバーへのセルフホストも可能)
  3. マルチプラットフォーム対応: iOS / Android アプリや Web Push に対応

C# (.NET) での実装例

ntfy.sh への送信は非常にシンプルです。特別なSDKは不要で、標準の HttpClient を用いて指定のトピックURLへメッセージを POST するだけで完了します。

以下は、実アプリの堅牢な設計(URLエンコード処理やタイムアウト指定など)をベースにシンプル化した送信処理の例です。

using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

public class NtfyNotifier
{
    private static readonly HttpClient _httpClient = new()
    {
        Timeout = TimeSpan.FromSeconds(15)
    };

    /// <summary>
    /// ntfy.sh へプッシュ通知を送信します
    /// </summary>
    /// <param name="topic">トピック名</param>
    /// <param name="title">通知タイトル</param>
    /// <param name="message">通知本文</param>
    public static async Task SendNtfyNotificationAsync(string topic, string title, string message)
    {
        // 空白や特殊文字によるURL崩れを防ぐため安全にエンコード
        string encodedTopic = Uri.EscapeDataString(topic.Trim('/', ' '));
        string encodedTitle = Uri.EscapeDataString(title);
        
        string url = $"https://ntfy.sh/{encodedTopic}?title={encodedTitle}";

        using var request = new HttpRequestMessage(HttpMethod.Post, url)
        {
            Content = new StringContent(message, Encoding.UTF8, "text/plain")
        };

        using var response = await _httpClient.SendAsync(request);
        response.EnsureSuccessStatusCode();
    }
}

実際のアプリ組み込み例

自作アプリ『Robocopy Scheduler』の全体設定画面に ntfy.sh のトピック名設定を追加しました。

20261018_090046_001.png
※「ジョブ完了時にntfy.shへ通知する」にチェックを入れ、トピック名を入力するだけで設定完了

バックアップ実行後、終了コード([正常完了 Code: 0] など)や詳細ログを組み込んだメッセージを送信するようにしています。

実際にスマートフォン(Android / iOSアプリ)で受信した画面がこちらです。

Screenshot_20261018-085514.ntfy.png
※実際のスマホ通知。スケジュール実行・手動実行の結果やコピー先パス、終了コードがリアルタイムで届く


まとめ

クライアントサイド・デスクトップアプリにおける通知機能では、OAuth 2.0 の複雑性を回避し、HTTP POST 1本で完了する ntfy.sh などを活用することで、開発・メンテナンスコストを大幅に抑えつつ利便性の高い通知仕組みを構築できました。

今回構築した Robocopy Scheduler は、C# .NET 10 (Native AOT) と Avalonia UI で構築されたポータブルな Windows 用バックアップ支援ツールです。個人利用・非管理デバイスであれば無料の Free Edition で全機能をご利用いただけます。

  • 公式サイト: Robocopy Scheduler | chilili kobo
  • 主な機能: GUIでのRobocopyパラメータ構成、Cron対応スケジュール自動実行、スリープ防止、Slack / ntfy.sh 外部通知
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?