NotifyHub — Unified Notification MCP Server について
NotifyHubは、JavaおよびSpring Bootアプリケーション向けの統合通知ライブラリです。多様なチャネルを扱う流れるようなAPIに、フォールバック、再試行、予約送信、追跡機能を備えています。
主な機能
- 01記載された23チャネルに対応する統一API
- 02フォールバックチェーンと複数チャネル送信
- 03非同期配信・再試行・予約送信
- 04ロケール解決に対応したMustacheテンプレート
- 05レート制限・重複排除・配信追跡
- 06管理ダッシュボードとデッドレターキュー
活用シーン
- 01優先チャネルで注文通知を送り、失敗時に切り替え
- 02リマインダーを予約し、配信レシートを追跡
- 03デッドレターキューで失敗通知を管理
MCP 対応
AIエージェント向けのMCPサーバーが含まれます。READMEでは連携への言及はありますが、提供するツールは説明されていません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm -e NOTIFY_CHANNELS_EMAIL_HOST -e NOTIFY_CHANNELS_EMAIL_PORT -e NOTIFY_CHANNELS_EMAIL_USERNAME -e NOTIFY_CHANNELS_EMAIL_PASSWORD -e NOTIFY_CHANNELS_EMAIL_FROM -e NOTIFY_CHANNELS_SMS_ACCOUNTSID -e NOTIFY_CHANNELS_SMS_AUTHTOKEN -e NOTIFY_CHANNELS_SMS_FROMNUMBER -e NOTIFY_CHANNELS_SLACK_WEBHOOKURL -e NOTIFY_CHANNELS_TELEGRAM_BOTTOKEN -e NOTIFY_CHANNELS_TELEGRAM_CHATID -e NOTIFY_CHANNELS_DISCORD_WEBHOOKURL -e NOTIFY_CHANNELS_TEAMS_WEBHOOKURL -e NOTIFY_CHANNELS_GOOGLECHAT_WEBHOOKURL -e NOTIFY_CHANNELS_TWITTER_APIKEY -e NOTIFY_CHANNELS_TWITTER_APISECRET -e NOTIFY_CHANNELS_TWITTER_ACCESSTOKEN -e NOTIFY_CHANNELS_TWITTER_ACCESSTOKENSECRET -e NOTIFY_CHANNELS_LINKEDIN_ACCESSTOKEN -e NOTIFY_CHANNELS_LINKEDIN_ORGANIZATIONID -e NOTIFY_CHANNELS_WHATSAPP_ACCOUNTSID -e NOTIFY_CHANNELS_WHATSAPP_AUTHTOKEN -e NOTIFY_CHANNELS_WHATSAPP_FROMNUMBER -e NOTIFY_CHANNELS_PUSH_FIREBASECREDENTIALS -e NOTIFY_CHANNELS_NOTION_APIKEY -e NOTIFY_CHANNELS_NOTION_DATABASEID -e NOTIFY_CHANNELS_TWITCH_CLIENTID -e NOTIFY_CHANNELS_TWITCH_CLIENTSECRET -e NOTIFY_CHANNELS_TWITCH_BROADCASTERID -e NOTIFY_CHANNELS_YOUTUBE_CLIENTID -e NOTIFY_CHANNELS_YOUTUBE_CLIENTSECRET -e NOTIFY_CHANNELS_YOUTUBE_REFRESHTOKEN -e NOTIFY_CHANNELS_YOUTUBE_LIVECHATID -e NOTIFY_CHANNELS_INSTAGRAM_ACCESSTOKEN -e NOTIFY_CHANNELS_INSTAGRAM_USERID -e NOTIFY_CHANNELS_SENDGRID_APIKEY -e NOTIFY_CHANNELS_SENDGRID_FROMEMAIL -e NOTIFY_CHANNELS_TIKTOKSHOP_APPKEY -e NOTIFY_CHANNELS_TIKTOKSHOP_APPSECRET -e NOTIFY_CHANNELS_TIKTOKSHOP_ACCESSTOKEN -e NOTIFY_CHANNELS_TIKTOKSHOP_SHOPID -e NOTIFY_CHANNELS_FACEBOOK_PAGEACCESSTOKEN -e NOTIFY_CHANNELS_FACEBOOK_PAGEID -e NOTIFY_CHANNELS_AWSSNS_ACCESSKEYID -e NOTIFY_CHANNELS_AWSSNS_SECRETACCESSKEY -e NOTIFY_CHANNELS_AWSSNS_REGION -e NOTIFY_CHANNELS_MAILGUN_APIKEY -e NOTIFY_CHANNELS_MAILGUN_DOMAIN -e NOTIFY_CHANNELS_MAILGUN_FROMEMAIL -e NOTIFY_CHANNELS_PAGERDUTY_APIKEY ghcr.io/gabrielbbaldez/notify-hub:1.1.0NOTIFY_CHANNELS_EMAIL_HOSTSMTP server host for email notificationsNOTIFY_CHANNELS_EMAIL_PORTSMTP server portNOTIFY_CHANNELS_EMAIL_USERNAMEシークレットSMTP authentication usernameNOTIFY_CHANNELS_EMAIL_PASSWORDシークレットSMTP authentication passwordNOTIFY_CHANNELS_EMAIL_FROMDefault sender email addressNOTIFY_CHANNELS_SMS_ACCOUNTSIDシークレットTwilio Account SID for SMSNOTIFY_CHANNELS_SMS_AUTHTOKENシークレットTwilio Auth Token for SMSNOTIFY_CHANNELS_SMS_FROMNUMBERTwilio sender phone numberNOTIFY_CHANNELS_SLACK_WEBHOOKURLシークレットSlack incoming webhook URLNOTIFY_CHANNELS_TELEGRAM_BOTTOKENシークレットTelegram Bot API tokenNOTIFY_CHANNELS_TELEGRAM_CHATIDTelegram chat/group IDNOTIFY_CHANNELS_DISCORD_WEBHOOKURLシークレットDiscord webhook URLNOTIFY_CHANNELS_TEAMS_WEBHOOKURLシークレットMicrosoft Teams webhook URLNOTIFY_CHANNELS_GOOGLECHAT_WEBHOOKURLシークレットGoogle Chat webhook URLNOTIFY_CHANNELS_TWITTER_APIKEYシークレットTwitter/X API keyNOTIFY_CHANNELS_TWITTER_APISECRETシークレットTwitter/X API secretNOTIFY_CHANNELS_TWITTER_ACCESSTOKENシークレットTwitter/X access tokenNOTIFY_CHANNELS_TWITTER_ACCESSTOKENSECRETシークレットTwitter/X access token secretNOTIFY_CHANNELS_LINKEDIN_ACCESSTOKENシークレットLinkedIn OAuth2 access tokenNOTIFY_CHANNELS_LINKEDIN_ORGANIZATIONIDLinkedIn organization/company IDNOTIFY_CHANNELS_WHATSAPP_ACCOUNTSIDシークレットTwilio Account SID for WhatsAppNOTIFY_CHANNELS_WHATSAPP_AUTHTOKENシークレットTwilio Auth Token for WhatsAppNOTIFY_CHANNELS_WHATSAPP_FROMNUMBERWhatsApp sender number (with whatsapp: prefix)NOTIFY_CHANNELS_PUSH_FIREBASECREDENTIALSシークレットFirebase Cloud Messaging credentials JSON (base64 or path)NOTIFY_CHANNELS_NOTION_APIKEYシークレットNotion integration API keyNOTIFY_CHANNELS_NOTION_DATABASEIDNotion database IDNOTIFY_CHANNELS_TWITCH_CLIENTIDシークレットTwitch application client IDNOTIFY_CHANNELS_TWITCH_CLIENTSECRETシークレットTwitch application client secretNOTIFY_CHANNELS_TWITCH_BROADCASTERIDTwitch broadcaster/channel IDNOTIFY_CHANNELS_YOUTUBE_CLIENTIDシークレットYouTube/Google OAuth2 client IDNOTIFY_CHANNELS_YOUTUBE_CLIENTSECRETシークレットYouTube/Google OAuth2 client secretNOTIFY_CHANNELS_YOUTUBE_REFRESHTOKENシークレットYouTube/Google OAuth2 refresh tokenNOTIFY_CHANNELS_YOUTUBE_LIVECHATIDYouTube Live Chat IDNOTIFY_CHANNELS_INSTAGRAM_ACCESSTOKENシークレットInstagram Graph API access tokenNOTIFY_CHANNELS_INSTAGRAM_USERIDInstagram Business account user IDNOTIFY_CHANNELS_SENDGRID_APIKEYシークレットSendGrid API key for email delivery with trackingNOTIFY_CHANNELS_SENDGRID_FROMEMAILSendGrid sender email addressNOTIFY_CHANNELS_TIKTOKSHOP_APPKEYシークレットTikTok Shop application keyNOTIFY_CHANNELS_TIKTOKSHOP_APPSECRETシークレットTikTok Shop application secretNOTIFY_CHANNELS_TIKTOKSHOP_ACCESSTOKENシークレットTikTok Shop access tokenNOTIFY_CHANNELS_TIKTOKSHOP_SHOPIDTikTok Shop IDNOTIFY_CHANNELS_FACEBOOK_PAGEACCESSTOKENシークレットFacebook Page access tokenNOTIFY_CHANNELS_FACEBOOK_PAGEIDFacebook Page IDNOTIFY_CHANNELS_AWSSNS_ACCESSKEYIDシークレットAWS access key ID for SNSNOTIFY_CHANNELS_AWSSNS_SECRETACCESSKEYシークレットAWS secret access key for SNSNOTIFY_CHANNELS_AWSSNS_REGIONAWS region for SNS (e.g., us-east-1)NOTIFY_CHANNELS_MAILGUN_APIKEYシークレットMailgun API keyNOTIFY_CHANNELS_MAILGUN_DOMAINMailgun sending domainNOTIFY_CHANNELS_MAILGUN_FROMEMAILMailgun sender email addressNOTIFY_CHANNELS_PAGERDUTY_APIKEYシークレットPagerDuty Events API v2 integration keyローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/gabrielbbaldez/notify-hub:1.1.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
NotifyHub
1つのAPIですべてのチャネルに。
JavaとSpring Boot向けの統合通知ライブラリです。
通知チャネルごとに異なるコードを書くのはやめましょう。NotifyHub を使えば、メール、SMS、WhatsApp、Slack、Telegram、Discord、Microsoft Teams、Firebase Push、Webhook、WebSocket、Google Chat、Twitter/X、LinkedIn、Notion、Twitch、YouTube、Instagram、SendGrid、TikTok Shop、Facebook、AWS SNS、Mailgun、PagerDuty、Kick、または独自に作成したカスタムチャネルを通じて、単一の流れるようなAPIで通知を送信できます。
notify.to(user)
.via(EMAIL)
.fallback(SMS)
.priority(Priority.HIGH)
.subject("Order confirmed")
.template("order-confirmed")
.param("orderId", order.getId())
.attach(invoicePdf)
.send();
NotifyHubを選ぶ理由
| 課題 | NotifyHub を使わない場合 | NotifyHub を使う場合 | |
|---|---|---|---|
| メール | JavaMail の設定、MIME タイプ、Session など | .via(EMAIL) | |
| 📱 | SMS | Twilio SDK、まったく異なる API | .via(SMS) |
| 別途 Twilio を設定し、プレフィックス処理も必要 | .via(WHATSAPP) | ||
| Slack | Webhook の HTTP 通信、JSON ペイロード | .via(SLACK) | |
| Telegram | Bot API、HTTP クライアントの設定 | .via(TELEGRAM) | |
| Discord | Webhook の HTTP 通信、JSON ペイロード | .via(DISCORD) | |
| 👥 | Teams | Incoming Webhook、MessageCard の JSON | .via(TEAMS) |
| プッシュ通知 | Firebase Admin SDK、認証情報など | .via(PUSH) | |
| 🔗 | Webhook | 独自の HTTP 通信、ペイロードのテンプレート | .via(Channel.custom("pagerduty")) |
| WebSocket | Java WebSocket API、再接続処理 | .via(WEBSOCKET) | |
| Google Chat | Webhook の HTTP 通信、JSON ペイロード | .via(GOOGLE_CHAT) | |
| Twitter/X | OAuth 1.0a、API v2 の設定 | .via(TWITTER) | |
| 💼 | OAuth 2.0、REST API の設定 | .via(LINKEDIN) | |
| Notion | インテグレーショントークン、API の設定 | .via(NOTION) | |
| Twitch | OAuth 2.0、Twitch API の設定 | .via(TWITCH) | |
| YouTube | YouTube Data API v3 の設定 | .via(YOUTUBE) | |
| Meta Graph API の設定 | .via(INSTAGRAM) | ||
| 📧 | SendGrid | SendGrid API、Webhook のトラッキング | .via(Channel.custom("sendgrid")) |
| TikTok Shop | HMAC-SHA256、Shop API | .via(TIKTOK_SHOP) | |
| Graph API、ページトークン | .via(FACEBOOK) | ||
| ☁️ | AWS SNS | AWS SDK、認証情報、ARN | .via(Channel.custom("aws-sns")) |
| Mailgun | Mailgun API、ドメインの設定 | .via(Channel.custom("mailgun")) | |
| PagerDuty | Events API v2、ルーティングキー | .via(Channel.custom("pagerduty")) | |
| Kick | 公開 API、OAuth 2.1 | .via(KICK) | |
| 複数のチャネル | チャネルごとにまったく異なるコード | 同じ Fluent API | |
| フォールバック | 手動の try/catch チェーン | .fallback(SMS) | |
| リトライ | 自分で実装 | 組み込みの指数バックオフ | |
| 非同期処理 | スレッドプール、CompletableFuture | .sendAsync() | |
| スケジューリング | ScheduledExecutor、タイマー処理 | .schedule(Duration.ofMinutes(30)) | |
| テンプレート | チャネルごとに異なるエンジン | すべてのチャネルで共通のテンプレート | |
| i18n | ロケールの手動解決 | .locale(Locale.PT_BR) | |
| レート制限 | トークンバケットを一から実装 | 設定に基づくチャネルごとの制御 | |
| トラッキング | 独自の配信ログを構築 | 組み込みの受領記録 + JPA | |
| デッドレター | どこかへ消失 | DLQ に自動保存 | |
| 重複排除 | 送信済みメッセージを自分で追跡 | 組み込みのコンテンツハッシュ/明示的なキー | |
| テンプレートのバージョン | ファイルを手動で管理 | .templateVersion("v2") + A/B テスト | |
| バッチ処理 | ループして祈る | .toAll(users).send() | |
| モニタリング | Micrometer を自分で接続 | カウンターを自動設定 | |
| ヘルスチェック | Actuator のインジケーターを作成 | 自動設定 | |
| 管理 UI | 独自のダッシュボードを構築 | 組み込みの /notify-admin | |
| サーキットブレーカー | チャネルごとに自分で実装 | チャネルごとに組み込みのサーキットブレーカー | |
| オーケストレーション | エスカレーション処理を手動で実装 | .orchestrate().first(EMAIL).ifNoOpen(24h).then(PUSH) | |
| A/B テスト | 外部サービス + 接続コード | 組み込みの .abTest("exp").variant(...).split(50,50) | |
| テスト | すべてをモック化 | TestNotifyHub がすべての送信を記録 | |
| 新しいチャネル | 一から構築 | 1 つのインターフェースを実装 |
目次
- クイックスタート
- 機能
- フォールバックチェーン
- 複数チャネルへの送信
- 非同期送信
- バックオフ付き再試行
- テンプレート(Mustache)
- i18n(国際化)
- 添付ファイル
- 優先度レベル
- レート制限
- デッドレターキュー(DLQ)
- 一括送信
- 配信追跡
- 通知のスケジュール設定
- 通知ルーティング
- Notifiable インターフェース
- メッセージの重複排除
- テンプレートのバージョン管理
- カスタムチャネル
- イベントリスナー+Spring イベント
- 名前付き受信者
- メッセージキュー(RabbitMQ / Kafka)
- サーキットブレーカー
- バルクヘッド(同時実行の分離)
- 複数チャネルのオーケストレーション
- A/B テスト
- Cron スケジュール設定
- 通知停止時間
- テストユーティリティ
- サポート対象のチャネル
- 管理ダッシュボード
- Spring Boot との統合
- 設定リファレンス
- Spring Boot を使用しない場合
- MCP サーバー(AI エージェント)
- デモの実行
- アーキテクチャ
- Maven Central
- ロードマップ
- ライセンス
クイックスタート
1. 依存関係を追加する
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
チャネルを追加する必要がありますか? オプションのモジュールを追加してください:
<dependency> <groupId>io.github.gabrielbbaldez</groupId> <artifactId>notify-sms</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>io.github.gabrielbbaldez</groupId> <artifactId>notify-slack</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>io.github.gabrielbbaldez</groupId> <artifactId>notify-websocket</artifactId> <version>1.0.0</version> </dependency>
2. application.yml で設定する
notify:
channels:
email:
host: smtp.gmail.com
port: 587
username: ${GMAIL_USER}
password: ${GMAIL_PASS}
from: [email protected]
from-name: MyApp
tls: true
retry:
max-attempts: 3
strategy: exponential
tracking:
enabled: true
3. インジェクトして使用する
@Service
public class OrderService {
private final NotifyHub notify;
public OrderService(NotifyHub notify) {
this.notify = notify;
}
public void confirmOrder(Order order) {
notify.to(order.getCustomer())
.via(Channel.EMAIL)
.subject("Order confirmed!")
.template("order-confirmed")
.param("customerName", order.getCustomer().getName())
.param("orderId", order.getId())
.param("total", order.getTotal())
.send();
}
}
これで完了です。3 つのステップだけです。
機能
フォールバックチェーン
プライマリチャネルで失敗した場合、次のチャネルを自動的に試します:
notify.to(user)
.via(Channel.WHATSAPP)
.fallback(Channel.SMS)
.fallback(Channel.EMAIL)
.template("payment-reminder")
.param("amount", "R$ 150,00")
.send();
// Tries WhatsApp -> SMS -> Email
複数チャネルへの送信
すべてのチャネルを通じて同時に送信します:
notify.to(user)
.via(Channel.EMAIL)
.via(Channel.SLACK)
.via(Channel.TEAMS)
.subject("Security Alert")
.content("Login from a new device detected")
.sendAll();
非同期送信
処理をブロックせずに通知を送信します:
// Fire and forget
notify.to(user)
.via(Channel.EMAIL)
.template("welcome")
.sendAsync();
// Or wait for result
CompletableFuture<Void> future = notify.to(user)
.via(Channel.EMAIL)
.via(Channel.SLACK)
.content("Deploy complete!")
.sendAllAsync();
future.thenRun(() -> log.info("All notifications sent!"));
バックオフ付き再試行
指数バックオフまたは固定バックオフで自動的に再試行します:
# application.yml (global)
notify:
retry:
max-attempts: 3
strategy: exponential # waits 1s, 2s, 4s...
// Or per-notification
notify.to(user)
.via(Channel.EMAIL)
.retry(3)
.template("invoice")
.send();
テンプレート(Mustache)
src/main/resources/templates/notify/ にテンプレートを作成します:
order-confirmed.html(メールで自動的に使用):
<h1>Hello, {{customerName}}!</h1>
<p>Your order <strong>#{{orderId}}</strong> has been confirmed.</p>
<p>Total: <strong>{{total}}</strong></p>
order-confirmed.txt(SMS/WhatsApp/Slack/Telegram/Discord/Teams で自動的に使用):
Hello {{customerName}}, your order #{{orderId}} is confirmed. Total: {{total}}
ライブラリは、メールには .html を、その他のチャネルには .txt を自動的に選択します。
i18n(国際化)
テンプレートはロケールに基づく解決に対応し、自動的にフォールバックします:
// User with locale
notify.to(user)
.via(Channel.EMAIL)
.locale(Locale.forLanguageTag("pt-BR"))
.template("welcome")
.param("name", user.getName())
.send();
テンプレートの解決順序:welcome_pt_BR.html -> welcome_pt.html -> welcome.html
Notifiable からロケールを返すこともできます:
public class User implements Notifiable {
@Override
public Locale getLocale() {
return Locale.forLanguageTag("pt-BR");
}
}
添付ファイル
メール通知にファイルを添付します:
notify.to(user)
.via(Channel.EMAIL)
.subject("Your Invoice")
.template("invoice")
.attach("invoice.pdf", pdfBytes, "application/pdf")
.attach(new File("/reports/monthly.xlsx"))
.attach(Attachment.fromFile(contractFile))
.send();
優先度レベル
通知の優先度を設定します。URGENT 通知はレート制限を回避します:
notify.to(user)
.via(Channel.EMAIL)
.priority(Priority.URGENT)
.subject("SERVER DOWN!")
.content("Production server is unresponsive")
.send();
使用可能な優先度:URGENT(レート制限を回避)、HIGH、NORMAL(デフォルト)、LOW。
レート制限
チャネルごとの通知スループットを制御します:
notify:
rate-limit:
enabled: true
max-requests: 100
window: 1m
channels:
email:
max-requests: 50
window: 1m
sms:
max-requests: 10
window: 1m
レート制限にはトークンバケットアルゴリズムが使用されます。優先度が URGENT の通知は、常にレート制限を回避します。
デッドレターキュー(DLQ)
すべての再試行に失敗した通知は、DLQ に自動的に保存されます。
notify:
tracking:
enabled: true
dlq-enabled: true
/notify-admin/dlq の管理ダッシュボードからデッドレターを確認・管理するか、プログラムから操作できます。
DeadLetterQueue dlq = hub.getDeadLetterQueue();
List<DeadLetter> failed = dlq.findAll();
dlq.remove(deadLetterId); // after manual reprocessing
一括送信
複数の宛先に通知を一度に送信します。
// By email addresses
notify.toAll(List.of("[email protected]", "[email protected]", "[email protected]"))
.via(Channel.EMAIL)
.subject("System Maintenance")
.template("maintenance-notice")
.param("date", "2025-03-01")
.send();
// By Notifiable entities
notify.toAllNotifiable(users)
.via(Channel.EMAIL)
.template("newsletter")
.send();
// Async batch
notify.toAll(recipients)
.via(Channel.EMAIL)
.template("promo")
.sendAsync();
配信追跡
配信レシートを使用して、すべての通知を追跡します。
notify:
tracking:
enabled: true
type: memory # or "jpa" for database persistence
// Send and get a receipt
DeliveryReceipt receipt = notify.to(user)
.via(Channel.EMAIL)
.content("Hello!")
.sendTracked();
System.out.println(receipt.getStatus()); // SENT
System.out.println(receipt.getId()); // uuid
System.out.println(receipt.getTimestamp()); // 2025-01-15T10:30:00Z
データベースに永続化するには、JPA トラッカーモジュールを追加します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-tracker-jpa</artifactId>
<version>1.0.0</version>
</dependency>
notify:
tracking:
enabled: true
type: jpa
通知のスケジュール設定
将来の配信に向けて通知をスケジュールします。
ScheduledNotification scheduled = notify.to(user)
.via(Channel.EMAIL)
.subject("Reminder")
.content("Don't forget your appointment tomorrow!")
.schedule(Duration.ofHours(24));
// Check status
scheduled.getStatus(); // SCHEDULED, SENT, FAILED, CANCELLED
scheduled.getRemainingDelay(); // PT23H59M...
// Cancel if needed
scheduled.cancel();
通知のルーティング
ユーザーの設定に基づいて、通知を自動的にルーティングします。
public class User implements Notifiable {
@Override
public List<Channel> getPreferredChannels() {
return List.of(Channel.WHATSAPP, Channel.SMS, Channel.EMAIL);
}
}
// Auto-routes: WhatsApp (primary) -> SMS (fallback) -> Email (fallback)
notify.notify(user)
.template("order-update")
.param("orderId", "12345")
.send();
ルールを使った条件付きルーティング:
NotificationRouter router = NotificationRouter.builder()
.rule(RoutingRule.timeBasedRule(
LocalTime.of(9, 0), LocalTime.of(18, 0),
Channel.SLACK, Channel.EMAIL)) // Slack during business hours, email after
.build();
Notifiable インターフェース
User エンティティを通知の宛先にします。
@Entity
public class User implements Notifiable {
private String name;
private String email;
private String phone;
@Override
public String getNotifyEmail() { return email; }
@Override
public String getNotifyPhone() { return phone; }
@Override
public String getNotifyName() { return name; }
@Override
public Locale getLocale() { return Locale.forLanguageTag("pt-BR"); }
@Override
public List<Channel> getPreferredChannels() {
return List.of(Channel.EMAIL, Channel.SMS);
}
}
あとは、ユーザーオブジェクトを渡すだけです。
notify.to(user) // resolves email/phone automatically
.via(Channel.EMAIL)
.template("welcome")
.send();
または、アドレスを直接指定します。
notify.to("[email protected]").via(Channel.EMAIL).content("Hello!").send();
notify.toPhone("+5511999999999").via(Channel.SMS).content("Code: 1234").send();
メッセージの重複排除
コンテンツハッシュまたは明示的なキーを使って、通知の重複を自動的に防止します。
notify:
deduplication:
enabled: true
ttl: 24h
strategy: content-hash # content-hash | explicit-key | both
// Auto-dedup by content hash (same recipient + channel + content = skipped)
notify.to(user).via(EMAIL).content("Order confirmed").send();
notify.to(user).via(EMAIL).content("Order confirmed").send(); // skipped!
// Dedup by explicit key
notify.to(user).via(EMAIL)
.deduplicationKey("order-" + orderId)
.template("order-confirmed")
.send();
方式:
content-hash— 宛先、チャネル、件名、コンテンツの SHA-256 ハッシュexplicit-key—.deduplicationKey("...")で指定したキーを使用しますboth— 明示的なキーが指定されていればそれを使用し、指定されていなければコンテンツハッシュにフォールバックします
Spring Boot を使用しない場合:
NotifyHub notify = NotifyHub.builder()
.deduplicationStore(new InMemoryDeduplicationStore(Duration.ofHours(12)))
.channel(emailChannel)
.build();
テンプレートのバージョン管理
A/B テストや段階的なロールアウトのために、複数のテンプレートバージョンを管理します。
templates/notify/
├── order-confirmed.html ← default version
├── [email protected] ← version v1
├── [email protected] ← version v2
├── [email protected] ← v2 with i18n
└── order-confirmed.txt ← text default
// Use a specific version
notify.to(user).via(EMAIL)
.template("order-confirmed")
.templateVersion("v2")
.param("orderId", "123")
.send();
// No version = default template (backward compatible)
notify.to(user).via(EMAIL)
.template("order-confirmed")
.send();
// A/B testing
String version = abTestService.getVariant(user, "email-template");
notify.to(user).via(EMAIL)
.template("welcome")
.templateVersion(version) // "v1" or "v2"
.send();
解決順序:{name}@{version}_{locale}.{variant} → {name}@{version}.{variant} → {name}_{locale}.{variant} → {name}.{variant}
カスタムチャネル
1 つのインターフェースを実装して、独自のチャネルを作成します。
@Component
public class PushChannel implements NotificationChannel {
@Override
public String getName() { return "push"; }
@Override
public void send(Notification notification) {
firebaseClient.send(notification.getRecipient(), notification.getRenderedContent());
}
@Override
public boolean isAvailable() { return true; }
}
次のように使用します。
notify.to(user)
.via(Channel.custom("push"))
.template("new-message")
.send();
Spring Boot は NotificationChannel Bean を自動検出します。追加の設定は不要です。
イベントリスナーと Spring イベント
リスナーインターフェースを使用して、通知の結果を監視します。
@Component
public class NotifyMonitor implements NotificationListener {
@Override
public void onSuccess(String channel, String template) {
metrics.increment("notifications.sent." + channel);
}
@Override
public void onFailure(String channel, String template, Exception error) {
log.error("Failed on {}: {}", channel, error.getMessage());
alertService.warn("Channel " + channel + " is failing");
}
@Override
public void onScheduled(String channel, String recipient, Duration delay) {
log.info("Scheduled for {} in {}", recipient, delay);
}
}
または、Spring Application Events(自動設定済み)を使用します。
@Component
public class NotificationEventHandler {
@EventListener
public void onSent(NotificationSentEvent event) {
log.info("Sent via {} to {}", event.getChannel(), event.getRecipient());
}
@EventListener
public void onFailed(NotificationFailedEvent event) {
log.error("Failed: {}", event.getError().getMessage());
}
}
名前付き宛先
名前付きエイリアスを使用して、チャネルごとに複数の宛先へ通知を送信します。ハードコードされた Webhook URL やチャット ID を 1 つだけ使うのではなく、必要な数だけ設定できます。
application.yml で設定:
notify:
channels:
discord:
webhook-url: ${DISCORD_DEFAULT} # default destination
username: NotifyHub
avatar-url: https://example.com/logo.png
recipients:
alerts: https://discord.com/api/webhooks/111/aaa
devops: https://discord.com/api/webhooks/222/bbb
general: https://discord.com/api/webhooks/333/ccc
slack:
webhook-url: ${SLACK_DEFAULT}
recipients:
engineering: https://hooks.slack.com/services/XXX/YYY/ZZZ
marketing: https://hooks.slack.com/services/AAA/BBB/CCC
telegram:
bot-token: ${TELEGRAM_BOT_TOKEN}
chat-id: ${TELEGRAM_DEFAULT_CHAT}
recipients:
alerts: "-1001234567890"
devops: "-1009876543210"
Java API で使用:
// Send to a named alias
notify.to("alerts").via(DISCORD).content("Server is down!").send();
notify.to("engineering").via(SLACK).content("Deploy complete").send();
notify.to("devops").via(TELEGRAM).content("CPU at 95%").send();
// Send to default (no alias)
notify.to("user").via(DISCORD).content("Hello!").send();
// Pass a raw URL directly (no alias needed)
notify.to("https://discord.com/api/webhooks/444/ddd").via(DISCORD).content("Direct!").send();
MCP サーバー(AI エージェント)で使用:
send_discord(recipient="alerts", body="Server is down!")
send_slack(recipient="engineering", body="Deploy complete")
send_telegram(recipient="devops", body="CPU at 95%")
MCP/Docker 用の環境変数:
# Default webhook
NOTIFY_CHANNELS_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/111/aaa
# Named recipients (RECIPIENTS_<NAME>)
NOTIFY_CHANNELS_DISCORD_RECIPIENTS_ALERTS=https://discord.com/api/webhooks/222/bbb
NOTIFY_CHANNELS_DISCORD_RECIPIENTS_DEVOPS=https://discord.com/api/webhooks/333/ccc
# Same pattern for all channels
NOTIFY_CHANNELS_SLACK_RECIPIENTS_ENGINEERING=https://hooks.slack.com/services/XXX
NOTIFY_CHANNELS_TELEGRAM_RECIPIENTS_ALERTS=-1001234567890
NOTIFY_CHANNELS_TEAMS_RECIPIENTS_GENERAL=https://outlook.office.com/webhook/XXX
NOTIFY_CHANNELS_GOOGLE_CHAT_RECIPIENTS_TEAM=https://chat.googleapis.com/v1/spaces/XXX
解決順序: recipients マップ内のエイリアスとの一致 > URL/値をそのまま使用 > 設定のデフォルト値。
対応チャネル:Discord、Slack、Telegram、Teams、Google Chat。
メッセージキュー(RabbitMQ / Kafka)
非同期メッセージキューを使用して、通知送信を分離します。NotifyHub は 2 つのモジュールを提供します。
RabbitMQ
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-queue-rabbitmq</artifactId>
<version>1.0.0</version>
</dependency>
spring.rabbitmq.host: localhost
spring.rabbitmq.port: 5672
notify.queue.rabbitmq:
enabled: true
queue-name: notifyhub-notifications
exchange-name: notifyhub-exchange
routing-key: notification
consumer:
enabled: true
concurrency: 1
max-concurrency: 5
@Autowired RabbitNotificationProducer producer;
// Enqueue for async delivery
producer.enqueue(QueuedNotification.builder()
.recipient("[email protected]")
.channelName("email")
.subject("Welcome!")
.templateName("welcome")
.params(Map.of("name", "Gabriel"))
.build());
// Consumer picks it up and sends via NotifyHub automatically
Apache Kafka
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-queue-kafka</artifactId>
<version>1.0.0</version>
</dependency>
spring.kafka.bootstrap-servers: localhost:9092
notify.queue.kafka:
enabled: true
topic: notifyhub-notifications
consumer:
enabled: true
group-id: notifyhub-group
concurrency: 1
@Autowired KafkaNotificationProducer producer;
// Same API as RabbitMQ — just different transport
producer.enqueue(QueuedNotification.builder()
.recipient("+5548999999999")
.channelName("sms")
.rawContent("Your code is 1234")
.priority("URGENT")
.build());
どちらのモジュールも、テンプレート、優先度、重複排除キー、配信追跡、SMS/WhatsApp 用の電話番号ルーティングに対応しています。
サーキットブレーカー
チャネルごとのサーキットブレーカーにより、障害の連鎖を防止します。チャネルで障害が繰り返し発生すると、回路が開き、それ以降の試行を遮断します。
// Without Spring Boot
NotifyHub notify = NotifyHub.builder()
.channel(emailChannel)
.circuitBreaker(CircuitBreakerConfig.defaults()) // 5 failures → open for 30s
.build();
// Custom thresholds
NotifyHub notify = NotifyHub.builder()
.channel(emailChannel)
.circuitBreaker(CircuitBreakerConfig.custom()
.failureThreshold(3)
.openDuration(Duration.ofMinutes(1))
.windowSize(Duration.ofSeconds(30))
.build())
.build();
# Spring Boot
notify:
circuit-breaker:
enabled: true
failure-threshold: 5
open-duration: 30s
window-size: 60s
状態:CLOSED(通常)→ OPEN(拒否中)→ HALF_OPEN(復旧をテスト中)。ヘルスエンドポイントには、チャネルごとのサーキットブレーカーの状態が含まれます。
バルクヘッド(同時実行の分離)
リソースの枯渇を防ぐため、チャネルごとの同時送信数を制限します。
NotifyHub notify = NotifyHub.builder()
.channel(emailChannel)
.bulkhead(BulkheadConfig.defaults()) // 10 concurrent per channel
.bulkhead(BulkheadConfig.perChannel(5)) // or custom limit
.build();
マルチチャネルオーケストレーション
ユーザーが反応しない場合にチャネルを順次切り替える、エスカレーションワークフローを構築します。
notify.to(user)
.orchestrate()
.first(Channel.EMAIL)
.template("order-update")
.ifNoOpen(Duration.ofHours(24))
.then(Channel.PUSH)
.content("You have an unread order update")
.ifNoOpen(Duration.ofHours(48))
.then(Channel.SMS)
.content("Order update waiting — check your email")
.execute();
各ステップでは、指定した時間だけ待機してから次のチャネルにエスカレーションします。
A/B テスト
通知向けの決定論的な A/B テスト機能を組み込みで提供します。バリアントの割り当ては SHA-256 によるハッシュベースのため、同じ宛先には常に同じバリアントが割り当てられます。
notify.to(user)
.via(Channel.EMAIL)
.subject("Welcome!")
.abTest("welcome-experiment")
.variant("control", b -> b.template("welcome-v1"))
.variant("new-design", b -> b.template("welcome-v2"))
.split(50, 50);
重み付けによる分割で、任意の数のバリアントに対応します。決定論的なハッシュにより、送信をまたいでも一貫した体験が実現します。
Cron スケジューリング
cron 式を使って、通知を定期的にスケジュールできます。
ScheduledNotification job = notify.to(user)
.via(Channel.EMAIL)
.template("weekly-digest")
.cron("0 9 * * MON"); // Every Monday at 9 AM
標準の 5 フィールド cron 構文(分、時、日、月、曜日)をサポートしています。範囲、リスト、ステップ、曜日と月の名前を使用できます。
通知を控える時間帯
通知の送信時間に関するユーザーの設定を尊重します。
public class User implements Notifiable {
@Override
public QuietHours getQuietHours() {
return QuietHours.between(
LocalTime.of(22, 0), // 10 PM
LocalTime.of(8, 0), // 8 AM
ZoneId.of("America/Sao_Paulo")
);
}
@Override
public Set<Channel> getOptedOutChannels() {
return Set.of(Channel.SMS); // User opted out of SMS
}
}
通知を控える時間帯に送信された通知は、次に許可される時間帯まで延期されます。オプトアウトされたチャネルは通知なしでスキップされます。
テストユーティリティ
TestNotifyHub は、組み込みのすべてのチャネルタイプに対応したキャプチャチャネルを備えた、テストしやすいラッパーを提供します。
@Test
void shouldSendWelcomeEmail() {
TestNotifyHub test = TestNotifyHub.create();
test.to("[email protected]")
.via(Channel.EMAIL)
.subject("Welcome")
.content("Hello!")
.send();
assertThat(test.sent()).hasSize(1);
assertThat(test.sent("email").get(0).subject()).isEqualTo("Welcome");
}
モックは不要です。TestNotifyHub はすべての通知をメモリ内にキャプチャするため、アサーションで検証できます。テスト間では test.reset() を呼び出してください。
対応チャネル
| チャネル | プロバイダー | モジュール | |
|---|---|---|---|
| メール | SMTP(Gmail、SES、Outlook など) | notify-email | |
| 📱 | SMS | Twilio | notify-sms |
| Twilio | notify-sms | ||
| Slack | Incoming Webhooks | notify-slack | |
| Telegram | Bot API | notify-telegram | |
| Discord | Webhooks | notify-discord | |
| 👥 | Microsoft Teams | Incoming Webhooks | notify-teams |
| プッシュ通知(FCM) | Firebase Cloud Messaging | notify-push-firebase | |
| 🔗 | Webhook | 任意の HTTP エンドポイント | notify-webhook |
| WebSocket | JDK WebSocket(java.net.http) | notify-websocket | |
| Google Chat | Webhooks | notify-google-chat | |
| Twitter/X | API v2(OAuth 1.0a) | notify-twitter | |
| 💼 | REST API(OAuth 2.0) | notify-linkedin | |
| Notion | API(インテグレーショントークン) | notify-notion | |
| Twitch | Helix API(OAuth 2.0 自動更新) | notify-twitch | |
| YouTube | Data API v3(OAuth 自動更新) | notify-youtube | |
| Meta Graph API | notify-instagram | ||
| 📧 | SendGrid | SendGrid API(配信トラッキング) | notify-sendgrid |
| TikTok Shop | TikTok Shop API(HMAC-SHA256) | notify-tiktok-shop | |
| Graph API(ページ+Messenger) | notify-facebook | ||
| WhatsApp Cloud | Meta Cloud API(Twilio 不要の直接接続) | notify-whatsapp | |
| ☁️ | AWS SNS | AWS SDK v2 | notify-aws-sns |
| Mailgun | Mailgun REST API | notify-mailgun | |
| PagerDuty | Events API v2 | notify-pagerduty | |
| Kick | Public API | notify-kick | |
| ➕ | カスタム | 任意 — 1 つのインターフェースを実装 | notify-core |
管理ダッシュボード
NotifyHub には、通知システムを監視するための組み込み管理ダッシュボードが用意されています。
notify:
admin:
enabled: true
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-admin</artifactId>
<version>1.0.0</version>
</dependency>
/notify-admin にアクセスすると、次の項目を確認できます。
- ダッシュボード — メトリクスカード(送信済み/失敗/保留中/DLQ/チャネル/連絡先)、最近のアクティビティフィード、システムステータスグリッド、登録済みチャネル
- 分析 — 送信量、チャネル分布、成功率、時間別ヒートマップを示す Chart.js チャート
- 追跡 — チャネルフィルターとステータスバッジを備えた配信レシート
- デッドレターキュー — エラーの詳細と削除アクションを備えた失敗した通知
- チャネル — ヘルスインジケーターを備えた、登録済み各チャネルのステータス
- 監査ログ — イベントタイプフィルターを備えた、すべての通知イベントの完全な履歴
- オーディエンス — タグベースのフィルタリングによる連絡先とオーディエンスセグメントの管理
- ステータス Webhook — リアルタイム HTTP コールバックの設定と配信履歴
ダーク/ライトテーマの切り替え機能を備えており、localStorage を介してページ間で設定が保持されます。
Spring Boot との統合
Micrometer メトリクス
Micrometer がクラスパスにある場合、自動的に設定されます。
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
統合 EventBus を介してカウンターとゲージを公開します。
notifyhub.notifications.sent(タグ:channel)notifyhub.notifications.failed(タグ:channel)notifyhub.notifications.retried(タグ:channel)notifyhub.notifications.rate_limited(タグ:channel)notifyhub.notifications.deduped(タグ:channel)notifyhub.notifications.circuit_opened(タグ:channel)notifyhub.notifications.circuit_closed(タグ:channel)notifyhub.notifications.send_duration(タイマー、タグ:channel)
Actuator ヘルスチェック
Spring Boot Actuator がクラスパスにある場合、自動的に設定されます。
GET /actuator/health/notifyhub
{
"status": "UP",
"details": {
"email": { "status": "UP", "circuitBreaker": "CLOSED" },
"slack": { "status": "UP", "circuitBreaker": "CLOSED" },
"totalChannels": 2,
"availableChannels": 2
}
}
ステータスは、すべてのチャネルが利用可能な場合は UP、一部が停止している場合は DEGRADED、すべて停止している場合は DOWN です。サーキットブレーカーが設定されている場合、各チャネルのサーキット状態も報告されます。
Actuator Info
GET /actuator/info
{
"notifyhub": {
"version": "1.0.0",
"channels": ["email", "slack", "teams"],
"tracking.enabled": true,
"dlq.enabled": true
}
}
OpenTelemetry トレーシング
Micrometer Observation と OTel ブリッジがクラスパスにある場合、自動的に設定されます。 OTLP 経由で分散トレースをエクスポートするには、次の依存関係を追加します。
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
application.yml で OTLP エンドポイントを設定します。
management:
tracing:
sampling:
probability: 1.0 # 100% sampling (adjust for production)
otlp:
tracing:
endpoint: http://localhost:4318/v1/traces
次のオブザベーション(スパン)が作成されます。
notifyhub.send(タグ:channel、template、outcome)notifyhub.schedule(タグ:channel、outcome)
Jaeger、Zipkin、Grafana Tempo、Datadog、および OTLP 互換の任意のコレクターと互換性があります。
Webhook HMAC 署名
Status Webhook リスナーは、セキュリティのために HMAC-SHA256 リクエスト署名をサポートしています。設定すると、すべての Webhook POST に X-NotifyHub-Signature ヘッダーが含まれ、サーバー側でリクエストが NotifyHub から送信されたことを検証できます。
notify:
status-webhook:
url: https://your-server.com/webhook
signing-secret: ${WEBHOOK_SECRET} # any secret string
各リクエストには次のヘッダーが含まれます。
X-NotifyHub-Signature: sha256=<hex-encoded HMAC-SHA256 of request body>
サーバー側での検証:
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
String expected = "sha256=" + HexFormat.of().formatHex(mac.doFinal(body.getBytes()));
boolean valid = MessageDigest.isEqual(expected.getBytes(), signature.getBytes());
設定リファレンス
すべてのオプションを含む完全な application.yml:
notify:
channels:
email:
host: smtp.gmail.com
port: 587
username: ${GMAIL_USER}
password: ${GMAIL_PASS}
from: [email protected]
from-name: MyApp
tls: true
ssl: false
sms:
account-sid: ${TWILIO_SID}
auth-token: ${TWILIO_TOKEN}
from-number: "+1234567890"
whatsapp:
account-sid: ${TWILIO_SID}
auth-token: ${TWILIO_TOKEN}
from-number: "+14155238886"
slack:
webhook-url: ${SLACK_WEBHOOK}
recipients: # named aliases (optional)
engineering: https://hooks.slack.com/services/XXX
marketing: https://hooks.slack.com/services/YYY
telegram:
bot-token: ${TELEGRAM_BOT_TOKEN}
chat-id: ${TELEGRAM_CHAT_ID}
recipients: # named aliases (optional)
alerts: "-1001234567890"
devops: "-1009876543210"
discord:
webhook-url: ${DISCORD_WEBHOOK}
username: NotifyHub
avatar-url: https://example.com/logo.png
recipients: # named aliases (optional)
alerts: https://discord.com/api/webhooks/111/aaa
devops: https://discord.com/api/webhooks/222/bbb
teams:
webhook-url: ${TEAMS_WEBHOOK}
recipients: # named aliases (optional)
general: https://outlook.office.com/webhook/XXX
push:
credentials-path: ${FIREBASE_CREDENTIALS}
project-id: ${FIREBASE_PROJECT_ID}
webhooks:
- name: pagerduty
url: https://events.pagerduty.com/v2/enqueue
headers:
Authorization: "Token ${PAGERDUTY_TOKEN}"
payload-template: '{"summary":"{{content}}"}'
websocket:
uri: wss://echo.example.com/ws
timeout-ms: 10000
reconnect-enabled: true
reconnect-delay-ms: 5000
max-reconnect-attempts: 3
headers:
Authorization: "Bearer ${WS_TOKEN}"
message-format: '{"type":"notification","content":"{{content}}"}'
google-chat:
webhook-url: ${GOOGLE_CHAT_WEBHOOK}
timeout-ms: 10000
recipients: # named aliases (optional)
team-a: https://chat.googleapis.com/v1/spaces/XXX/messages?key=YYY
team-b: https://chat.googleapis.com/v1/spaces/ZZZ/messages?key=WWW
retry:
max-attempts: 3
strategy: exponential
rate-limit:
enabled: true
max-requests: 100
window: 1m
channels:
email:
max-requests: 50
window: 1m
tracking:
enabled: true
type: memory # memory | jpa
dlq-enabled: true
deduplication:
enabled: true
ttl: 24h
strategy: content-hash # content-hash | explicit-key | both
admin:
enabled: true
Spring Boot を使用しない場合
NotifyHub は Spring なしでも動作します。ビルダーを直接使用してください。
NotifyHub notify = NotifyHub.builder()
.templateEngine(new MustacheTemplateEngine())
.channel(new SmtpEmailChannel(
SmtpConfig.builder()
.host("smtp.gmail.com").port(587)
.username("[email protected]").password("app-password")
.from("[email protected]").tls(true)
.build()
))
.channel(new SlackChannel(
SlackConfig.builder()
.webhookUrl("https://hooks.slack.com/services/XXX/YYY/ZZZ")
.recipients(Map.of("engineering", "https://hooks.slack.com/services/AAA/BBB/CCC"))
.build()
))
.channel(new TeamsChannel(
TeamsConfig.builder()
.webhookUrl("https://outlook.office.com/webhook/XXX/YYY/ZZZ")
.build()
))
.channel(new WebhookChannel(
WebhookConfig.builder()
.name("pagerduty")
.url("https://events.pagerduty.com/v2/enqueue")
.payloadTemplate("{\"summary\":\"{{content}}\"}")
.build()
))
.channel(new WebSocketChannel(
WebSocketConfig.builder()
.uri("wss://echo.example.com/ws")
.messageFormat("{\"text\":\"{{content}}\"}")
.build()
))
.channel(new GoogleChatChannel(
GoogleChatConfig.builder()
.webhookUrl("https://chat.googleapis.com/v1/spaces/XXX/messages?key=YYY")
.build()
))
.deduplicationStore(new InMemoryDeduplicationStore(Duration.ofHours(24)))
.defaultRetryPolicy(RetryPolicy.exponential(3))
.rateLimiter(new TokenBucketRateLimiter(
RateLimitConfig.perMinute(100)))
.deadLetterQueue(new InMemoryDeadLetterQueue())
.tracker(new InMemoryNotificationTracker())
.circuitBreaker(CircuitBreakerConfig.defaults())
.bulkhead(BulkheadConfig.defaults())
.build();
// Sync
notify.to("[email protected]")
.via(Channel.EMAIL)
.subject("Hello!")
.content("Welcome to the app!")
.send();
// Async
notify.to("#general")
.via(Channel.SLACK)
.content("Deploy complete!")
.sendAsync();
// Tracked
DeliveryReceipt receipt = notify.to(user)
.via(Channel.EMAIL)
.content("Invoice attached")
.sendTracked();
// Scheduled
notify.to(user)
.via(Channel.EMAIL)
.content("Reminder!")
.schedule(Duration.ofMinutes(30));
// Batch
notify.toAll(List.of("[email protected]", "[email protected]"))
.via(Channel.EMAIL)
.template("announcement")
.send();
必要なのは notify-core とチャネルモジュールのみです。Spring への依存関係はありません。
MCP サーバー(AI エージェント)
NotifyHub には MCP(Model Context Protocol)サーバー が含まれており、すべての通知チャネルを、Claude Desktop、Claude Code、Cursor などの AI エージェントや、MCP 互換クライアント向けのツールとして公開します。
仕組み
notify-mcp モジュールは、JSON-RPC プロトコルを使用して STDIO 経由で通信するスタンドアロンの Java アプリケーションです。AI エージェントは利用可能なツールを検出し、設定済みの任意のチャネルから通知を送信できます。
セットアップ
1. MCP サーバーをビルドします。
mvn clean package -pl notify-mcp -am -DskipTests
2. Claude Desktop で設定します(claude_desktop_config.json)。
{
"mcpServers": {
"notify-hub": {
"command": "java",
"args": ["-jar", "path/to/notify-mcp-1.0.0.jar"],
"env": {
"NOTIFY_CHANNELS_EMAIL_HOST": "smtp.gmail.com",
"NOTIFY_CHANNELS_EMAIL_PORT": "587",
"NOTIFY_CHANNELS_EMAIL_USERNAME": "[email protected]",
"NOTIFY_CHANNELS_EMAIL_PASSWORD": "app-password",
"NOTIFY_CHANNELS_SLACK_WEBHOOK_URL": "https://hooks.slack.com/...",
"NOTIFY_CHANNELS_DISCORD_WEBHOOK_URL": "https://discord.com/api/webhooks/..."
}
}
}
}
Claude Code の場合(プロジェクトルートの .mcp.json):
{
"mcpServers": {
"notify-hub": {
"command": "java",
"args": ["-jar", "path/to/notify-mcp-1.0.0.jar"],
"env": {
"NOTIFY_CHANNELS_DISCORD_WEBHOOK_URL": "https://discord.com/api/webhooks/..."
}
}
}
}
利用可能な MCP ツール
| ツール | 説明 | 必須パラメーター |
|---|---|---|
send_notification | 任意のチャネル経由で送信(汎用) | channel、recipient、body または template |
send_email | メールを送信 | to、body または template |
send_sms | Twilio 経由で SMS を送信 | phone、body または template |
send_slack | Slack チャネルに送信 | recipient、body または template |
send_telegram | Telegram Bot 経由で送信 | recipient、body または template |
send_discord | Discord チャネルに送信 | recipient、body または template |
send_whatsapp | Twilio 経由で WhatsApp を送信 | phone、body または template |
send_teams | Microsoft Teams に送信 | recipient、body または template |
send_google_chat | Google Chat に送信 | recipient、body または template |
send_push | Firebase 経由でプッシュ通知を送信 | push_token、body |
send_twitter | Twitter/X にツイートを投稿 | body または template |
send_linkedin | LinkedIn に投稿を公開 | body または template |
send_notion | Notion にページを作成 | recipient、body または template |
send_twitch | Twitch のチャットメッセージとアンケートを送信 | recipient、body または template |
send_youtube | YouTube のライブチャットメッセージを送信 | recipient、body または template |
send_instagram | Instagram の DM またはフィード投稿を送信 | recipient、body または template |
send_multi_channel | 複数のチャネルに送信 | channels[]、recipient、body または template |
send_batch | 複数の宛先に一度に送信 | recipients[]、channel、body または template |
send_to_audience | 名前付きオーディエンスに送信 | audience、channel、body または template |
list_channels | 設定済みのチャネルを一覧表示 | (なし) |
list_delivery_receipts | 配信履歴を照会 | (なし) |
list_dead_letters | 失敗した通知(DLQ)を表示 | (なし) |
create_contact | タグ付きの連絡先を作成 | name |
list_contacts | 連絡先を一覧表示(タグで絞り込み) | (なし) |
create_audience | タグフィルターを使ってオーディエンスを作成 | name、tags[] |
list_audiences | 連絡先数とともにオーディエンスを一覧表示 | (なし) |
get_analytics | チャネル/ステータス別の配信統計 | (なし) |
send_tiktok_shop | TikTok Shop の通知を送信 | recipient、body または template |
send_facebook | Facebook ページへの投稿または Messenger の DM を送信 | recipient、body または template |
check_email_status | SendGrid のメール配信ステータスを確認 | message_id |
schedule_notification | 通知を予約して後で配信 | channel、recipient、body、send_at |
list_scheduled_notifications | 予約済みの通知をすべて一覧表示 | (なし) |
cancel_scheduled_notification | 保留中の予約通知をキャンセル | notification_id |
すべての送信ツールでは、任意で次のパラメーターも指定できます:subject、template、params、priority。
使用例(AI エージェントから)
設定後は、AI エージェントに次のように依頼するだけです。
「#alerts に、デプロイが完了したと Discord メッセージを送信して」
エージェントは適切なパラメーターを指定して、send_discord ツールを呼び出します。
Docker
Java をインストールせずに MCP サーバーを実行できます。必要なのは Docker だけです。
# Build
docker build -t notifyhub-mcp .
# Run with Discord
docker run -i --rm \
-e NOTIFY_CHANNELS_DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..." \
-e NOTIFY_CHANNELS_DISCORD_USERNAME="NotifyHub" \
gabrielbbal10/notifyhub-mcp
# Run with multiple Discord channels + Email
docker run -i --rm \
-e NOTIFY_CHANNELS_DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..." \
-e NOTIFY_CHANNELS_DISCORD_USERNAME="NotifyHub" \
-e NOTIFY_CHANNELS_DISCORD_RECIPIENTS_ALERTS="https://discord.com/api/webhooks/111/aaa" \
-e NOTIFY_CHANNELS_DISCORD_RECIPIENTS_DEVOPS="https://discord.com/api/webhooks/222/bbb" \
-e NOTIFY_CHANNELS_EMAIL_HOST="smtp.gmail.com" \
-e NOTIFY_CHANNELS_EMAIL_PORT="587" \
-e NOTIFY_CHANNELS_EMAIL_USERNAME="[email protected]" \
-e NOTIFY_CHANNELS_EMAIL_PASSWORD="app-password" \
-e NOTIFY_CHANNELS_EMAIL_FROM="[email protected]" \
gabrielbbal10/notifyhub-mcp
Claude Code で設定する(.mcp.json):
{
"mcpServers": {
"notify-hub": {
"command": "docker",
"args": ["run", "-i", "--rm",
"-e", "NOTIFY_CHANNELS_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...",
"-e", "NOTIFY_CHANNELS_DISCORD_USERNAME=NotifyHub",
"-e", "NOTIFY_CHANNELS_DISCORD_RECIPIENTS_ALERTS=https://discord.com/api/webhooks/111/aaa",
"gabrielbbal10/notifyhub-mcp"
]
}
}
}
Docker REST API
Java は不要で、Docker だけで Swagger UI を備えた完全な REST API を実行できます。
docker run -d -p 8080:8080 \
-e [email protected] \
-e NOTIFY_CHANNELS_EMAIL_PASSWORD=your-app-password \
-e [email protected] \
gabrielbbal10/notifyhub-api:latest
対話型の API ドキュメントを確認するには、http://localhost:8080/swagger-ui.html を開いてください。
環境変数 — MCP イメージと API イメージで共通です。必要なチャネルだけ追加してください。
| チャネル | 変数 | 必須 | 例 |
|---|---|---|---|
| メール | NOTIFY_CHANNELS_EMAIL_HOST | いいえ(デフォルト:smtp.gmail.com) | smtp.gmail.com |
NOTIFY_CHANNELS_EMAIL_PORT | いいえ(デフォルト:587) | 587 | |
NOTIFY_CHANNELS_EMAIL_USERNAME | はい(メールの場合) | [email protected] | |
NOTIFY_CHANNELS_EMAIL_PASSWORD | はい(メールの場合) | abcd efgh ijkl mnop (アプリ パスワード) | |
NOTIFY_CHANNELS_EMAIL_FROM | はい(メールの場合) | [email protected] | |
| Discord | NOTIFY_CHANNELS_DISCORD_WEBHOOK_URL | はい(Discord の場合) | https://discord.com/api/webhooks/... |
NOTIFY_CHANNELS_DISCORD_USERNAME | いいえ | NotifyHub | |
NOTIFY_CHANNELS_DISCORD_AVATAR_URL | いいえ | https://example.com/avatar.png | |
NOTIFY_CHANNELS_DISCORD_RECIPIENTS_<NAME> | いいえ | 名前付きエイリアスの Webhook URL | |
| Slack | NOTIFY_CHANNELS_SLACK_WEBHOOK_URL | はい(Slack の場合) | https://hooks.slack.com/services/... |
NOTIFY_CHANNELS_SLACK_RECIPIENTS_<NAME> | いいえ | 名前付きエイリアスの Webhook URL | |
| Telegram | NOTIFY_CHANNELS_TELEGRAM_BOT_TOKEN | はい(Telegram の場合) | 123456:ABC-DEF... |
NOTIFY_CHANNELS_TELEGRAM_CHAT_ID | はい(Telegram の場合) | 123456789 | |
NOTIFY_CHANNELS_TELEGRAM_RECIPIENTS_<NAME> | いいえ | 名前付きエイリアスのチャット ID | |
| Google Chat | NOTIFY_CHANNELS_GOOGLE_CHAT_WEBHOOK_URL | はい(gchat の場合) | https://chat.googleapis.com/v1/spaces/... |
NOTIFY_CHANNELS_GOOGLE_CHAT_RECIPIENTS_<NAME> | いいえ | 名前付きエイリアスの Webhook URL | |
| Teams | NOTIFY_CHANNELS_TEAMS_WEBHOOK_URL | はい(Teams の場合) | https://outlook.office.com/webhook/... |
NOTIFY_CHANNELS_TEAMS_RECIPIENTS_<NAME> | いいえ | 名前付きエイリアスの Webhook URL | |
| SMS | NOTIFY_CHANNELS_SMS_ACCOUNT_SID | はい(SMS の場合) | Twilio アカウント SID |
NOTIFY_CHANNELS_SMS_AUTH_TOKEN | はい(SMS の場合) | Twilio 認証トークン | |
NOTIFY_CHANNELS_SMS_FROM_NUMBER | はい(SMS の場合) | +12025551234 | |
NOTIFY_CHANNELS_WHATSAPP_ACCOUNT_SID | はい(WhatsApp の場合) | Twilio アカウント SID | |
NOTIFY_CHANNELS_WHATSAPP_AUTH_TOKEN | はい(WhatsApp の場合) | Twilio 認証トークン | |
NOTIFY_CHANNELS_WHATSAPP_FROM_NUMBER | はい(WhatsApp の場合) | +14155238886 |
複数のチャネルを使用する例:
docker run -d -p 8080:8080 \
-e [email protected] \
-e NOTIFY_CHANNELS_EMAIL_PASSWORD=your-app-password \
-e [email protected] \
-e NOTIFY_CHANNELS_DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..." \
-e NOTIFY_CHANNELS_DISCORD_USERNAME="NotifyHub" \
-e NOTIFY_CHANNELS_TELEGRAM_BOT_TOKEN="123456:ABC-DEF..." \
-e NOTIFY_CHANNELS_TELEGRAM_CHAT_ID="123456789" \
-e NOTIFY_CHANNELS_GOOGLE_CHAT_WEBHOOK_URL="https://chat.googleapis.com/v1/spaces/..." \
gabrielbbal10/notifyhub-api:latest
任意の言語からの使用方法:
# Send email
curl -X POST "http://localhost:8080/send/[email protected]&subject=Hello&body=Hi!"
# Send Discord
curl -X POST "http://localhost:8080/send/discord?message=Deploy done!"
# Send Telegram
curl -X POST "http://localhost:8080/send/telegram?chatId=123456789&message=Alert!"
# Send Google Chat
curl -X POST "http://localhost:8080/send/google-chat?message=Build passed!"
Docker Hub: gabrielbbal10/notifyhub-api
デモの実行
デモアプリでは、SMTP サーバーが組み込まれており、外部設定が一切不要で、すべての機能を試せます。
git clone https://github.com/GabrielBBaldez/notify-hub.git
cd notify-hub
mvn clean install -DskipTests
# Run the demo
mvn -pl notify-demo spring-boot:run
次に、以下を開いてください。
- http://localhost:8080 — API エンドポイント
- http://localhost:8080/notify-admin — 管理ダッシュボード
デモ用エンドポイント
| メソッド | エンドポイント | 説明 |
|---|---|---|
GET | / | ホーム — すべてのエンドポイントを一覧表示 |
POST | /send/email | シンプルなメールを送信 |
POST | /send/template | Mustache テンプレートを使ってメールを送信 |
POST | /send/notifiable | Notifiable エンティティに送信 |
POST | /send/sms | SMS を送信(Twilio が必要) |
POST | /send/whatsapp | WhatsApp を送信(Twilio が必要) |
POST | /send/telegram | Bot 経由で Telegram に送信 |
POST | /send/discord | Webhook 経由で Discord に送信 |
POST | /send/slack | Slack チャンネルに送信 |
POST | /send/teams | Webhook 経由で Microsoft Teams に送信 |
POST | /send/google-chat | Webhook 経由で Google Chat に送信 |
POST | /send/push | Firebase 経由でプッシュ通知を送信 |
POST | /send/websocket | WebSocket 経由でメッセージを送信 |
POST | /send/multi | メールと Slack に同時に送信 |
POST | /send/fallback | フォールバックをテスト(メールの送信に失敗した場合 -> Slack) |
POST | /send/tracked | 配信追跡付きで送信 |
POST | /send/scheduled | 通知を後の日時に予約 |
GET | /tracking | 配信追跡履歴 |
GET | /notify-admin | 管理者ダッシュボード |
GET | /inbox | 受信したメールを表示 |
DELETE | /inbox | すべての受信トレイを消去 |
アーキテクチャ
notify-hub/
├── notify-core/ # Zero Spring dependency
│ ├── NotifyHub # Thin facade — delegates to executor/scheduler/eventbus
│ ├── NotificationExecutor # Channel resolution, send logic, fallback chains
│ ├── NotificationScheduler # Scheduling with delay/cancel/list
│ ├── NotificationBuilder # Fluent builder (send/async/tracked/scheduled)
│ ├── BatchNotificationBuilder # Batch send to multiple recipients
│ ├── Notification # Immutable notification object
│ ├── Channel / ChannelRef # Built-in + custom channel refs
│ ├── Priority # URGENT, HIGH, NORMAL, LOW
│ ├── Notifiable # Recipient interface (i18n + routing + quiet hours)
│ ├── NotificationChannel # Channel SPI (implement this!)
│ ├── QuietHours # Per-recipient quiet time windows
│ ├── pipeline/ # Resilience handler chain
│ │ ├── SendPipeline # Assembles: Dedup → RateLimit → CircuitBreaker → Template → Retry
│ │ ├── SendHandler # Handler chain interface
│ │ ├── SendContext # Per-send state (channel, builder, notification)
│ │ ├── DeduplicationHandler # Skip duplicates
│ │ ├── RateLimitHandler # Enforce per-channel limits
│ │ ├── CircuitBreakerHandler # Short-circuit failing channels
│ │ ├── TemplateHandler # Build + render notification
│ │ └── RetrySendHandler # Terminal: retry with backoff → DLQ
│ ├── resilience/ # Resilience primitives
│ │ ├── ChannelCircuitBreaker # Per-channel circuit breaker (sliding window)
│ │ ├── CircuitBreakerConfig # Thresholds + durations
│ │ ├── CircuitState # CLOSED, OPEN, HALF_OPEN
│ │ └── BulkheadConfig # Per-channel concurrency limits
│ ├── event/ # Unified event system
│ │ ├── NotificationEventBus # Publish events to listeners
│ │ ├── NotificationEvent # Immutable event record
│ │ ├── EventType # SENT, FAILED, RETRIED, RATE_LIMITED, DEDUPED, CIRCUIT_*
│ │ ├── NotificationEventListener # Listener interface
│ │ └── LegacyListenerAdapter # Bridge: old NotificationListener → EventBus
│ ├── orchestration/ # Multi-step notification workflows
│ │ ├── OrchestrationBuilder # first(EMAIL).ifNoOpen(24h).then(PUSH)
│ │ └── OrchestrationStep # Individual step record
│ ├── abtest/ # A/B testing
│ │ └── AbTestBuilder # Deterministic SHA-256 variant selection
│ ├── schedule/ # Cron support
│ │ └── CronExpression # Lightweight 5-field cron parser
│ ├── attachment/ # File attachments
│ │ └── Attachment # Email file attachments
│ ├── testing/ # Test utilities
│ │ ├── TestNotifyHub # Test wrapper with capturing channels
│ │ └── SentNotification # Captured notification record
│ ├── RateLimiter / TokenBucket # Rate limiting
│ ├── NotificationRouter / RoutingRule # Conditional routing
│ ├── MustacheTemplateEngine # Template engine (i18n-aware + versioning)
│ ├── DeduplicationStore # Dedup interface (in-memory impl)
│ └── RetryPolicy # Retry + backoff strategies
│
├── notify-channels/
│ ├── notify-email/ # SMTP email (Jakarta Mail + attachments)
│ ├── notify-sms/ # Twilio SMS + WhatsApp
│ ├── notify-slack/ # Slack webhooks (JDK HttpClient)
│ ├── notify-telegram/ # Telegram Bot API (JDK HttpClient)
│ ├── notify-discord/ # Discord webhooks (JDK HttpClient)
│ ├── notify-teams/ # Microsoft Teams webhooks (JDK HttpClient)
│ ├── notify-push-firebase/ # Firebase Cloud Messaging (FCM)
│ ├── notify-webhook/ # Generic webhook (configurable)
│ ├── notify-websocket/ # WebSocket (JDK java.net.http)
│ ├── notify-google-chat/ # Google Chat webhooks (JDK HttpClient)
│ ├── notify-twitch/ # Twitch chat + polls via Helix API (JDK HttpClient)
│ ├── notify-youtube/ # YouTube live chat via Data API v3 (JDK HttpClient)
│ ├── notify-instagram/ # Instagram DM + feed via Meta Graph API (JDK HttpClient)
│ ├── notify-sendgrid/ # SendGrid email with delivery tracking (JDK HttpClient)
│ ├── notify-tiktok-shop/ # TikTok Shop API (HMAC-SHA256, JDK HttpClient)
│ ├── notify-facebook/ # Facebook Graph API (Page + Messenger)
│ ├── notify-whatsapp/ # WhatsApp Cloud API (Meta Graph API, no Twilio)
│ ├── notify-aws-sns/ # AWS SNS (AWS SDK v2)
│ ├── notify-mailgun/ # Mailgun transactional email (JDK HttpClient)
│ ├── notify-pagerduty/ # PagerDuty Events API v2 (JDK HttpClient)
│ └── notify-kick/ # Kick Public API (JDK HttpClient)
│ └── notify-channel-template/ # Template/archetype for creating new channels
│
├── notify-tracker-jpa/ # JPA-backed delivery tracker
├── notify-audit-jpa/ # JPA-backed audit logging
│
├── notify-spring-boot-starter/ # Auto-config for Spring Boot
│ ├── NotifyAutoConfiguration # Auto-discovers all channels + event listeners
│ ├── MetricsEventListener # Micrometer metrics via EventBus
│ ├── TracingNotificationListener # OpenTelemetry tracing (Observation API)
│ ├── NotifyHubHealthIndicator # Actuator health (+ circuit breaker status)
│ ├── NotifyHubInfoContributor # Actuator info endpoint
│ ├── SpringEventNotificationListener # Spring ApplicationEvents
│ └── NotifyProperties # application.yml binding
│
├── notify-admin/ # Admin dashboard (Thymeleaf)
│ └── NotifyAdminController # /notify-admin/*
│
├── notify-mcp/ # MCP Server for AI agents
│ ├── NotifyMcpServer # Spring Boot headless main
│ ├── McpServerRunner # STDIO MCP server bootstrap
│ └── tools/ # 36 MCP tools (send, batch, audiences, DLQ, analytics)
│
├── notify-queue-rabbitmq/ # RabbitMQ integration
├── notify-queue-kafka/ # Kafka integration
│
└── notify-demo/ # Demo app (run it!)
耐障害性パイプライン
すべての通知は、チャネルに到達する前にハンドラーのチェーンを通過します。
Deduplication → Rate Limit → Circuit Breaker → Template Rendering → Retry + Send → DLQ
各ハンドラーは処理を短絡できます(例:重複排除は重複をスキップし、サーキットブレーカーはオープン時に拒否します)。パイプラインは完全にオプションです。依存関係が null の場合、ハンドラーはスキップされます。
設計原則
notify-coreに Spring 依存関係はありません — あらゆる Java プロジェクトで使用できます- チャネルはプラグイン可能です —
NotificationChannelを実装し、Spring Bean として登録します - Slack、Telegram、Discord、Teams、WebSocket、Google Chat は外部 SDK を一切使用しません — JDK の
java.net.http.HttpClientのみを使用します - テンプレートエンジンは置き換え可能です —
TemplateEngineインターフェースを実装します - Spring Boot スターターがすべてを自動設定します — 依存関係を追加するだけです
- 非同期サポート —
CompletableFutureを使ったsendAsync()とsendAllAsync() - 条件付き自動設定 — チャネル Bean は、そのモジュールがクラスパスにある場合にのみ読み込まれます
- 統合イベントシステム —
NotificationEventBusが分散していたリスナー呼び出しを置き換え、LegacyListenerAdapterにより後方互換性を保ちます
Maven Central
NotifyHub は Maven Central で公開されています。追加のリポジトリは不要です。
Maven Central で検索:io.github.gabrielbbaldez
利用可能なモジュール
以下に、すべてのモジュール、その機能、必要となる状況、および追加方法を示します。
notify-spring-boot-starter — メインの依存関係
機能: Spring Boot アプリケーション内で NotifyHub を自動設定します。チャネル Bean の検出、再試行ポリシーの接続、追跡、レート制限、DLQ、Micrometer メトリクス、OpenTelemetry トレース、Actuator ヘルスチェック、Spring イベントを自動的に行います。notify-core と notify-email を推移的に含みます。
使用する状況: Spring Boot アプリを構築しており、自動セットアップを利用したい場合に使用します。ほとんどのプロジェクトで必要な依存関係はこれだけです。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
notify-core — コア API(Spring なし)
機能: 流暢な API 全体(NotifyHub、NotificationBuilder、Channel、Notification、Priority、Attachment、RetryPolicy)に加え、チャネル、テンプレート、追跡、DLQ、レート制限、ルーティングの各インターフェースを含みます。Spring 依存関係は一切なく、SLF4J と Mustache のみを使用します。
使用する状況: Spring Boot を使わない通常の Java プロジェクトで NotifyHub を使用したい場合、または NotifyHub をベースにライブラリ/フレームワークを構築する場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-core</artifactId>
<version>1.0.0</version>
</dependency>
notify-email — SMTP メールチャネル
機能: あらゆる SMTP サーバー(Gmail、Outlook、Amazon SES、Mailtrap など)経由でメールを送信します。HTML とプレーンテキスト、ファイル添付、TLS/SSL、カスタム送信者名に対応しています。内部では Jakarta Mail を使用します。
用途: メール通知を送信する場合に使用します。notify-spring-boot-starter にすでに含まれています。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-email</artifactId>
<version>1.0.0</version>
</dependency>
notify-sms — Twilio SMS + WhatsApp チャネル
機能: Twilio API 経由で SMS と WhatsApp メッセージを送信します。電話番号の形式(E.164)と whatsapp: プレフィックスを自動的に処理します。
用途: SMS または WhatsApp メッセージを送信する場合に使用します。Twilio アカウント、Account SID、Auth Token、電話番号が必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-sms</artifactId>
<version>1.0.0</version>
</dependency>
notify-slack — Slack Webhook チャネル
機能: Incoming Webhooks 経由で Slack チャンネルにメッセージを送信します。JDK の HttpClient を使用するため、外部 SDK は不要です。
用途: Slack に通知を投稿する場合に使用します。Slack Incoming Webhook URL(api.slack.com/apps で作成)が必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-slack</artifactId>
<version>1.0.0</version>
</dependency>
notify-telegram — Telegram Bot チャネル
機能: Bot API 経由で Telegram のチャット、グループ、チャンネルにメッセージを送信します。デフォルトのチャット ID と通知ごとの送信先指定に対応しています。JDK の HttpClient を使用します。
用途: Telegram メッセージを送信する場合に使用します。@BotFather から取得したボットトークンが必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-telegram</artifactId>
<version>1.0.0</version>
</dependency>
notify-discord — Discord Webhook チャネル
機能: Webhook 経由で Discord チャンネルにメッセージを送信します。カスタムのボットユーザー名とアバターに対応しています。JDK の HttpClient を使用します。
用途: Discord に通知を投稿する場合に使用します。Discord webhook URL(チャンネルの Settings > Integrations > Webhooks)が必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-discord</artifactId>
<version>1.0.0</version>
</dependency>
notify-teams — Microsoft Teams チャネル
機能: Incoming Webhooks 経由で Teams チャンネルに MessageCard 通知を送信します。JDK の HttpClient を使用します。
用途: Microsoft Teams に通知を投稿する場合に使用します。Teams Incoming Webhook URL(チャンネル > Connectors > Incoming Webhook)が必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-teams</artifactId>
<version>1.0.0</version>
</dependency>
notify-push-firebase — Firebase Cloud Messaging (FCM)
機能: Firebase Cloud Messaging 経由でモバイルデバイス(Android/iOS)やウェブアプリにプッシュ通知を送信します。サービスアカウントの認証情報を使用して Firebase Admin SDK を利用します。
用途: モバイルアプリにプッシュ通知を送信する場合に使用します。サービスアカウントの JSON 認証情報ファイルがある Firebase プロジェクトが必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-push-firebase</artifactId>
<version>1.0.0</version>
</dependency>
notify-webhook — 汎用 Webhook チャネル
機能: あらゆる HTTP エンドポイント(REST API、PagerDuty、Datadog、カスタムサービスなど)に通知を送信します。{{recipient}}、{{subject}}、{{content}} プレースホルダーを使用した設定可能なペイロードテンプレート、カスタムヘッダー、PUT/POST メソッド、タイムアウトに対応しています。
用途: HTTP API を備えた外部サービスと連携する場合や、カスタム Webhook 連携を作成する場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-webhook</artifactId>
<version>1.0.0</version>
</dependency>
notify-websocket — WebSocket チャネル
機能: JDK の java.net.http.WebSocket API を使用して、WebSocket 接続経由で通知を送信します。{{recipient}}、{{subject}}、{{content}} プレースホルダーを使用した設定可能なメッセージ形式、カスタムヘッダー、バックオフ付きの自動再接続、接続タイムアウトに対応しています。外部依存関係はありません。
用途: サーバー(ライブダッシュボード、チャットシステム、カスタム WebSocket コンシューマーなど)に WebSocket 経由でリアルタイム通知を送信する場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-websocket</artifactId>
<version>1.0.0</version>
</dependency>
notify-google-chat — Google Chat チャネル
機能: Incoming Webhooks 経由で Google Chat のスペースにメッセージを送信します。JDK の HttpClient を使用して JSON ペイロードを投稿するため、外部 SDK は不要です。
用途: Google Chat のスペースに通知を送信する場合に使用します。Google Chat webhook URL(スペースの Settings > Apps & integrations > Webhooks)が必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-google-chat</artifactId>
<version>1.0.0</version>
</dependency>
notify-twitch — Twitch チャネル
機能: Helix API 経由で Twitch チャネルにチャットメッセージや投票を送信します。JDK の HttpClient を使用するため、外部 SDK は不要です。
使用する場面: Twitch のチャットに通知を送信したり、投票を作成したりする場合に使用します。Twitch API の OAuth 2.0 認証情報(Client ID + OAuth トークン)が必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-twitch</artifactId>
<version>1.0.0</version>
</dependency>
notify-youtube — YouTube チャネル
機能: YouTube Data API v3 経由で、YouTube ライブ配信にライブチャットメッセージを送信します。JDK の HttpClient を使用するため、外部 SDK は不要です。
使用する場面: YouTube ライブチャットに通知を送信する場合に使用します。Google API キー、または YouTube Data API v3 を有効にした OAuth 2.0 認証情報が必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-youtube</artifactId>
<version>1.0.0</version>
</dependency>
notify-instagram — Instagram チャネル
機能: Meta Graph API(Instagram Graph API)経由で DM やフィード投稿を送信します。JDK の HttpClient を使用するため、外部 SDK は不要です。
使用する場面: Instagram 経由で通知を送信する場合に使用します。Instagram Graph API へのアクセス権を持つ Facebook Developer アカウントが必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-instagram</artifactId>
<version>1.0.0</version>
</dependency>
notify-sendgrid — SendGrid メールチャネル
機能: SendGrid API 経由でトランザクションメールを送信し、配信イベント(配信済み、開封済み、クリック済み、バウンス)の追跡機能も備えています。JDK の HttpClient を使用するため、外部 SDK は不要です。
使用する場面: 基本的な SMTP を超えるメール配信追跡が必要な場合や、すでにメールプロバイダーとして SendGrid を使用している場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-sendgrid</artifactId>
<version>1.0.0</version>
</dependency>
notify-tiktok-shop — TikTok Shop チャネル
機能: TikTok Shop API 経由で TikTok Shop の販売者にメッセージを送信します。HMAC-SHA256 によるリクエスト署名を自動で処理します。JDK の HttpClient を使用します。
使用する場面: TikTok Shop の販売者に通知(注文の更新、顧客メッセージ)を送信する場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-tiktok-shop</artifactId>
<version>1.0.0</version>
</dependency>
notify-facebook — Facebook チャネル
機能: Graph API 経由で Facebook ページへの投稿や Messenger メッセージを送信します。JDK の HttpClient を使用するため、外部 SDK は不要です。
使用する場面: Facebook ページに投稿したり、Messenger メッセージを送信したりする場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-facebook</artifactId>
<version>1.0.0</version>
</dependency>
notify-whatsapp — WhatsApp Cloud API チャネル
機能: Meta の Cloud API 経由で WhatsApp メッセージを直接送信します(Twilio は不要です)。JDK の HttpClient を使用し、外部依存関係はありません。
使用する場面: Twilio ではなく Meta の公式 Cloud API を使用して WhatsApp メッセージを送信する場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-whatsapp</artifactId>
<version>1.0.0</version>
</dependency>
notify-aws-sns — AWS SNS チャネル
機能: AWS SNS トピックにメッセージを発行するか、AWS Simple Notification Service 経由で SMS を直接送信します。AWS SDK v2 を使用します。
使用する場面: すでに AWS エコシステムを利用しており、通知に SNS を使用したい場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-aws-sns</artifactId>
<version>1.0.0</version>
</dependency>
notify-mailgun — Mailgun チャネル
機能: Mailgun REST API 経由でトランザクションメールを送信します。JDK の HttpClient を使用するため、外部 SDK は不要です。
使用する場面: メールプロバイダーとして Mailgun を使用している場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-mailgun</artifactId>
<version>1.0.0</version>
</dependency>
notify-pagerduty — PagerDuty チャネル
機能: Events API v2 経由で PagerDuty インシデントを作成します。JDK の HttpClient を使用するため、外部 SDK は不要です。
使用する場面: 通知パイプラインから PagerDuty のアラートやインシデントを起動する場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-pagerduty</artifactId>
<version>1.0.0</version>
</dependency>
notify-kick — Kick チャネル
機能: Kick Public API 経由で Kick チャネルにチャットメッセージを送信します。OAuth 2.1 認証とトークン更新に対応し、ボットとユーザーのメッセージタイプをサポートします。
使用する場面: 通知パイプラインから Kick のストリーミングチャネルにチャットメッセージを送信する場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-kick</artifactId>
<version>1.0.0</version>
</dependency>
notify-tracker-jpa — JPA 配信トラッカー
機能: Spring Data JPA を使用して、配信確認情報をリレーショナルデータベース(MySQL、PostgreSQL、H2 など)に永続化します。通知 ID、チャネル、受信者、ステータス、タイムスタンプ、エラーメッセージを保存します。フィルタリングや件数カウントのためのクエリメソッドを提供します。
使用する場面: 配信追跡データを再起動後も保持したい場合(デフォルトのインメモリトラッカーの代わり)に使用します。クラスパスに Spring Data JPA とデータベースが必要です。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-tracker-jpa</artifactId>
<version>1.0.0</version>
</dependency>
notify-admin — 管理者ダッシュボード
概要: /notify-admin に組み込みの Web UI を提供します。4 つのページ(ダッシュボード(概要メトリクス)、トラッキング(配信レシート)、DLQ(失敗した通知)、チャネル(ステータス))で構成されます。Thymeleaf で構築されており、ダークテーマに対応した完全なレスポンシブデザインです。
用途: 一から構築することなく、通知システムを監視するための視覚的な管理パネルが必要な場合に使用します。設定で notify.admin.enabled=true を有効にする必要があります。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-admin</artifactId>
<version>1.0.0</version>
</dependency>
notify-queue-rabbitmq — RabbitMQ メッセージキュー
概要: RabbitMQ を使った非同期通知処理を追加します。プロデューサー(通知をキューに登録)、コンシューマー(キューから通知を読み込み、NotifyHub 経由で送信)、およびエクスチェンジ/キュー/バインディングの設定を含む Spring Boot の自動構成が含まれます。
用途: 通知の送信をメインのアプリケーションフローから切り離す必要がある場合や、あるサービスがキューに登録し、別のサービスが送信するマイクロサービスアーキテクチャを採用している場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-queue-rabbitmq</artifactId>
<version>1.0.0</version>
</dependency>
notify-queue-kafka — Apache Kafka メッセージキュー
概要: RabbitMQ モジュールと同様の機能を提供しますが、メッセージブローカーとして Apache Kafka を使用します。チャネル:宛先をメッセージキーとして Kafka トピックに通知を送信し、パーティション内の順序を維持します。
用途: すでにインフラストラクチャで Kafka を使用している場合や、大規模な高スループットの通知処理が必要な場合に使用します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-queue-kafka</artifactId>
<version>1.0.0</version>
</dependency>
notify-mcp — AI エージェント向け MCP サーバー
概要: すべての NotifyHub チャネルを MCP(Model Context Protocol)ツールとして公開し、AI エージェント(Claude Desktop、Claude Code、Cursor)が自然言語コマンドで通知を送信できるようにします。ヘッドレスの Spring Boot アプリとして動作し、STDIO JSON-RPC 経由で通信します。27 個のツール(任意のチャネル経由での送信、一括送信、オーディエンス管理、DLQ の監視、配信分析)を提供します。
用途: AI エージェントに代わりに通知を送信してもらいたい場合に使用します。MCP クライアントの設定ファイルに JAR のパスを設定すると、エージェントが利用可能なすべてのツールを自動的に検出します。
<dependency>
<groupId>io.github.gabrielbbaldez</groupId>
<artifactId>notify-mcp</artifactId>
<version>1.0.0</version>
</dependency>
何が必要ですか?
| やりたいこと... | 追加する依存関係 |
|---|---|
| Spring Boot からメールを送信する | notify-spring-boot-starter(メール機能が含まれています) |
| SMS または WhatsApp を送信する | notify-spring-boot-starter + notify-sms |
| Slack に送信する | notify-spring-boot-starter + notify-slack |
| Telegram に送信する | notify-spring-boot-starter + notify-telegram |
| Discord に送信する | notify-spring-boot-starter + notify-discord |
| Microsoft Teams に送信する | notify-spring-boot-starter + notify-teams |
| モバイルプッシュ通知(FCM)を送信する | notify-spring-boot-starter + notify-push-firebase |
| 任意の HTTP API に送信する | notify-spring-boot-starter + notify-webhook |
| WebSocket 経由で送信する | notify-spring-boot-starter + notify-websocket |
| Google Chat に送信する | notify-spring-boot-starter + notify-google-chat |
| Twitch チャットに送信する | notify-spring-boot-starter + notify-twitch |
| YouTube ライブチャットに送信する | notify-spring-boot-starter + notify-youtube |
| Instagram に送信する | notify-spring-boot-starter + notify-instagram |
| SendGrid 経由で送信する(トラッキング付き) | notify-spring-boot-starter + notify-sendgrid |
| TikTok Shop に送信する | notify-spring-boot-starter + notify-tiktok-shop |
| Facebook ページ/Messenger に送信する | notify-spring-boot-starter + notify-facebook |
| Cloud API 経由で WhatsApp を送信する | notify-spring-boot-starter + notify-whatsapp |
| AWS SNS 経由で送信する | notify-spring-boot-starter + notify-aws-sns |
| Mailgun 経由で送信する | notify-spring-boot-starter + notify-mailgun |
| PagerDuty インシデントを作成する | notify-spring-boot-starter + notify-pagerduty |
| Kick チャットメッセージを送信する | notify-spring-boot-starter + notify-kick |
| 重複送信を防止する | notify-spring-boot-starter(組み込み、設定で制御) |
| テンプレートを A/B テストする | notify-spring-boot-starter(組み込み、.templateVersion() を使用) |
| トラッキング情報をデータベースに永続化する | notify-spring-boot-starter + notify-tracker-jpa |
| 管理ダッシュボード UI | notify-spring-boot-starter + notify-admin |
| Spring Boot を使わずに利用する | notify-core + 必要なチャネルモジュール |
| RabbitMQ 経由で非同期処理を行う | notify-spring-boot-starter + notify-queue-rabbitmq |
| Kafka 経由で非同期処理を行う | notify-spring-boot-starter + notify-queue-kafka |
| AI エージェントから通知を送信できるようにする | notify-mcp(スタンドアロン JAR) |
| すべてを一度に利用する | notify-spring-boot-starter + 上記のすべてのチャネルモジュール |
ロードマップ
- v0.1.0 — コア API、Email、SMS、WhatsApp、Mustache テンプレート、Spring Boot スターター
- v0.2.0 — Slack、Telegram、Discord、非同期送信、スケジューリング、配信追跡
- v0.3.0 — Teams、Firebase Push、Webhook、添付ファイル、優先度、レート制限、DLQ、i18n、一括送信、JPA トラッカー、Micrometer メトリクス、Actuator ヘルスチェック、Spring イベント、条件付きルーティング、管理ダッシュボード(80 件以上のテスト)
- v0.4.0 — WebSocket チャネル、Google Chat チャネル、メッセージの重複排除、テンプレートのバージョン管理(105 件以上のテスト、16 モジュール)
- v0.5.0 — MCP サーバーモジュール:Claude Desktop、Claude Code、Cursor 経由で通知を送信する 13 個の AI エージェントツール(130 件以上のテスト、17 モジュール)
- v0.6.0 — 名前付き受信者、Docker イメージ(MCP + REST API)、Swagger UI、RabbitMQ + Kafka メッセージキューモジュール、GitHub Pages ランディングページ
- v0.7.0 — Twitter/X、LinkedIn、Notion チャネル(14 チャネル、16 MCP ツール、22 モジュール)
- v0.8.0 — Twitch、YouTube チャネル、管理ダッシュボードの再設計(16 チャネル、18 MCP ツール、24 モジュール)
- v0.9.0 — MCP 高度なツール:オーディエンス、連絡先、一括送信、DLQ、分析(16 チャネル、26 MCP ツール)
- v0.10.0 — Instagram チャネル:Meta Graph API 経由の DM とフィード投稿(17 チャネル、27 MCP ツール、25 モジュール)
- v1.0.0 — SendGrid、TikTok Shop、Facebook、WhatsApp Cloud API、AWS SNS、Mailgun、PagerDuty チャネル、スケジュール通知用 MCP ツール、JaCoCo カバレッジ(25 チャネル、37 MCP ツール、28 モジュール)
- v1.1.0 — アーキテクチャの改善:レジリエンスパイプライン(サーキットブレーカー、バルクヘッド、ハンドラーチェーン)、統合イベントシステム(NotificationEventBus、EventType、MetricsEventListener)、巨大オブジェクトのリファクタリング(NotificationExecutor、NotificationScheduler を NotifyHub から分離)、マルチチャネルオーケストレーション、組み込み A/B テスト、cron スケジューリング、通知抑制時間、TestNotifyHub テストユーティリティ、チャネルテンプレートモジュール、Levenshtein によるエラー候補の提示、サーキットブレーカーの状態を含むヘルスインジケーターの強化
要件
- Java 17 以降
- Spring Boot 3.x(スターター用 — 任意。コアは単独で動作します)
- Maven 3.8 以降(ビルド用)
ライセンス
MIT License — 詳細は LICENSE をご覧ください。
Gabriel Baldez が開発しました
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。