diff --git a/scripts/mac-mini/health-check.sh b/scripts/mac-mini/health-check.sh
index ab90834f4..f4c049a21 100755
--- a/scripts/mac-mini/health-check.sh
+++ b/scripts/mac-mini/health-check.sh
@@ -1,6 +1,11 @@
#!/bin/bash
# ManaCore Health Check Script
-# Checks all services and optionally sends notifications
+# Checks all services and sends notifications on failure
+#
+# Notification channels (configure via environment or .env.notifications):
+# - Telegram: TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID
+# - Email: EMAIL_TO + EMAIL_FROM + SMTP_* settings
+# - ntfy: NTFY_TOPIC
# Ensure PATH includes docker
export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH"
@@ -8,6 +13,11 @@ export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
+# Load notification config if exists
+if [ -f "$PROJECT_ROOT/.env.notifications" ]; then
+ source "$PROJECT_ROOT/.env.notifications"
+fi
+
# Colors for terminal output
RED='\033[0;31m'
GREEN='\033[0;32m'
@@ -17,6 +27,125 @@ NC='\033[0m' # No Color
# Track failures
FAILURES=()
+# ============================================
+# Notification Functions
+# ============================================
+
+send_telegram() {
+ local message="$1"
+
+ if [ -z "$TELEGRAM_BOT_TOKEN" ] || [ -z "$TELEGRAM_CHAT_ID" ]; then
+ return 0
+ fi
+
+ curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
+ -d "chat_id=${TELEGRAM_CHAT_ID}" \
+ -d "text=${message}" \
+ -d "parse_mode=HTML" \
+ >/dev/null 2>&1
+
+ if [ $? -eq 0 ]; then
+ echo " [Telegram] Notification sent"
+ else
+ echo " [Telegram] Failed to send"
+ fi
+}
+
+send_email() {
+ local subject="$1"
+ local body="$2"
+
+ if [ -z "$EMAIL_TO" ]; then
+ return 0
+ fi
+
+ # Use msmtp if available, otherwise try mail command
+ if command -v msmtp &> /dev/null; then
+ echo -e "Subject: ${subject}\nFrom: ${EMAIL_FROM:-manacore@localhost}\nTo: ${EMAIL_TO}\n\n${body}" | \
+ msmtp -a default "$EMAIL_TO" 2>/dev/null
+ elif command -v mail &> /dev/null; then
+ echo "$body" | mail -s "$subject" "$EMAIL_TO" 2>/dev/null
+ elif command -v sendmail &> /dev/null; then
+ echo -e "Subject: ${subject}\nFrom: ${EMAIL_FROM:-manacore@localhost}\nTo: ${EMAIL_TO}\n\n${body}" | \
+ sendmail "$EMAIL_TO" 2>/dev/null
+ else
+ echo " [Email] No mail client available (install msmtp)"
+ return 1
+ fi
+
+ if [ $? -eq 0 ]; then
+ echo " [Email] Notification sent to $EMAIL_TO"
+ else
+ echo " [Email] Failed to send"
+ fi
+}
+
+send_ntfy() {
+ local message="$1"
+
+ if [ -z "$NTFY_TOPIC" ]; then
+ return 0
+ fi
+
+ curl -s -d "$message" \
+ -H "Title: Mac Mini Alert" \
+ -H "Priority: high" \
+ -H "Tags: warning" \
+ "https://ntfy.sh/$NTFY_TOPIC" >/dev/null 2>&1
+
+ if [ $? -eq 0 ]; then
+ echo " [ntfy] Notification sent"
+ else
+ echo " [ntfy] Failed to send"
+ fi
+}
+
+send_all_notifications() {
+ local failed_services="$1"
+ local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
+
+ # Telegram message (HTML format)
+ local telegram_msg="🚨 ManaCore Health Check Failed
+
+Time: ${timestamp}
+Host: $(hostname)
+
+Failed Services:
+${failed_services}
+
+Check logs: ssh mac-mini"
+
+ # Email message
+ local email_subject="[ALERT] ManaCore Health Check Failed"
+ local email_body="ManaCore Health Check Failed
+=============================
+
+Time: ${timestamp}
+Host: $(hostname)
+
+Failed Services:
+${failed_services}
+
+To investigate:
+ ssh mac-mini
+ cd ~/projects/manacore-monorepo
+ ./scripts/mac-mini/status.sh
+ docker logs "
+
+ # Plain text for ntfy
+ local ntfy_msg="ManaCore Failed: ${failed_services}"
+
+ echo ""
+ echo "Sending notifications..."
+ send_telegram "$telegram_msg"
+ send_email "$email_subject" "$email_body"
+ send_ntfy "$ntfy_msg"
+}
+
+# ============================================
+# Health Check Functions
+# ============================================
+
check_service() {
local name=$1
local url=$2
@@ -34,6 +163,10 @@ check_service() {
fi
}
+# ============================================
+# Main Health Check
+# ============================================
+
echo ""
echo "=== ManaCore Health Check ==="
echo "Time: $(date)"
@@ -59,27 +192,27 @@ fi
echo ""
echo "Auth & Dashboard:"
check_service "Auth API" "http://localhost:3001/api/v1/health"
-check_service "Dashboard Web" "http://localhost:5173/" # SvelteKit - check root
+check_service "Dashboard Web" "http://localhost:5173/"
echo ""
echo "Chat:"
check_service "Chat Backend" "http://localhost:3002/api/v1/health"
-check_service "Chat Web" "http://localhost:3000/" # SvelteKit - check root
+check_service "Chat Web" "http://localhost:3000/"
echo ""
echo "Todo:"
check_service "Todo Backend" "http://localhost:3018/api/v1/health"
-check_service "Todo Web" "http://localhost:5188/" # SvelteKit - check root
+check_service "Todo Web" "http://localhost:5188/"
echo ""
echo "Calendar:"
check_service "Calendar Backend" "http://localhost:3016/api/v1/health"
-check_service "Calendar Web" "http://localhost:5186/" # SvelteKit - check root
+check_service "Calendar Web" "http://localhost:5186/"
echo ""
echo "Clock:"
check_service "Clock Backend" "http://localhost:3017/api/v1/health"
-check_service "Clock Web" "http://localhost:5187/" # SvelteKit - check root
+check_service "Clock Web" "http://localhost:5187/"
echo ""
echo "Cloudflare Tunnel:"
@@ -98,20 +231,14 @@ if [ ${#FAILURES[@]} -eq 0 ]; then
exit 0
else
echo -e "${RED}Failed services (${#FAILURES[@]}):${NC}"
+ FAILED_LIST=""
for f in "${FAILURES[@]}"; do
echo " - $f"
+ FAILED_LIST="${FAILED_LIST}- ${f}\n"
done
- # Send notification if ntfy is configured
- NTFY_TOPIC="${NTFY_TOPIC:-}"
- if [ -n "$NTFY_TOPIC" ]; then
- FAILED_LIST=$(printf '%s, ' "${FAILURES[@]}")
- curl -s -d "ManaCore Health Check Failed: ${FAILED_LIST%, }" \
- -H "Title: Mac Mini Alert" \
- -H "Priority: high" \
- -H "Tags: warning" \
- "https://ntfy.sh/$NTFY_TOPIC" >/dev/null 2>&1 || true
- fi
+ # Send notifications
+ send_all_notifications "$(echo -e "$FAILED_LIST")"
exit 1
fi
diff --git a/scripts/mac-mini/notifications.env.example b/scripts/mac-mini/notifications.env.example
new file mode 100644
index 000000000..8290a43d0
--- /dev/null
+++ b/scripts/mac-mini/notifications.env.example
@@ -0,0 +1,36 @@
+# ManaCore Notification Configuration
+# Copy this file to the project root as .env.notifications
+# cp scripts/mac-mini/notifications.env.example .env.notifications
+
+# ============================================
+# Telegram Bot
+# ============================================
+# 1. Message @BotFather on Telegram
+# 2. Send /newbot and follow instructions
+# 3. Copy the bot token here
+TELEGRAM_BOT_TOKEN=
+
+# To get your Chat ID:
+# 1. Message your bot
+# 2. Visit: https://api.telegram.org/bot/getUpdates
+# 3. Find "chat":{"id": YOUR_CHAT_ID}
+TELEGRAM_CHAT_ID=
+
+# ============================================
+# Email (via msmtp)
+# ============================================
+# Email address to send alerts to
+EMAIL_TO=
+
+# From address (optional)
+EMAIL_FROM=manacore@mana.how
+
+# Note: For email to work, install and configure msmtp on Mac Mini:
+# brew install msmtp
+# Create ~/.msmtprc with your SMTP settings (see below)
+
+# ============================================
+# ntfy.sh (optional, simple push notifications)
+# ============================================
+# Create a topic at ntfy.sh and subscribe in the app
+NTFY_TOPIC=
diff --git a/scripts/mac-mini/setup-notifications.sh b/scripts/mac-mini/setup-notifications.sh
new file mode 100755
index 000000000..fddfec50f
--- /dev/null
+++ b/scripts/mac-mini/setup-notifications.sh
@@ -0,0 +1,207 @@
+#!/bin/bash
+# Setup notifications for ManaCore Health Checks
+# Run this script on the Mac Mini to configure alerts
+
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
+ENV_FILE="$PROJECT_ROOT/.env.notifications"
+
+echo "=== ManaCore Notification Setup ==="
+echo ""
+
+# ============================================
+# Check for existing config
+# ============================================
+
+if [ -f "$ENV_FILE" ]; then
+ echo "Existing configuration found at $ENV_FILE"
+ read -p "Do you want to reconfigure? [y/N] " -n 1 -r
+ echo
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ echo "Keeping existing configuration."
+ exit 0
+ fi
+fi
+
+# ============================================
+# Telegram Setup
+# ============================================
+
+echo ""
+echo "=== Telegram Bot Setup ==="
+echo ""
+echo "To create a Telegram bot:"
+echo " 1. Open Telegram and message @BotFather"
+echo " 2. Send /newbot"
+echo " 3. Choose a name (e.g., 'ManaCore Alerts')"
+echo " 4. Choose a username (e.g., 'manacore_alerts_bot')"
+echo " 5. Copy the bot token"
+echo ""
+
+read -p "Enter Telegram Bot Token (or press Enter to skip): " TELEGRAM_BOT_TOKEN
+
+if [ -n "$TELEGRAM_BOT_TOKEN" ]; then
+ echo ""
+ echo "To get your Chat ID:"
+ echo " 1. Send a message to your new bot in Telegram"
+ echo " 2. Open this URL in your browser:"
+ echo " https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates"
+ echo " 3. Find the 'chat' -> 'id' value"
+ echo ""
+ read -p "Enter your Telegram Chat ID: " TELEGRAM_CHAT_ID
+fi
+
+# ============================================
+# Email Setup
+# ============================================
+
+echo ""
+echo "=== Email Setup ==="
+echo ""
+echo "For email alerts, you need:"
+echo " 1. An SMTP server (Gmail, Mailgun, etc.)"
+echo " 2. msmtp installed (brew install msmtp)"
+echo ""
+
+read -p "Enter email address for alerts (or press Enter to skip): " EMAIL_TO
+
+if [ -n "$EMAIL_TO" ]; then
+ read -p "Enter 'From' email address [$EMAIL_TO]: " EMAIL_FROM
+ EMAIL_FROM=${EMAIL_FROM:-$EMAIL_TO}
+
+ echo ""
+ echo "You need to configure msmtp separately."
+ echo "Create ~/.msmtprc with contents like:"
+ echo ""
+ echo " defaults"
+ echo " auth on"
+ echo " tls on"
+ echo " tls_trust_file /etc/ssl/cert.pem"
+ echo " logfile ~/.msmtp.log"
+ echo ""
+ echo " account default"
+ echo " host smtp.gmail.com"
+ echo " port 587"
+ echo " from $EMAIL_FROM"
+ echo " user your-email@gmail.com"
+ echo " password your-app-password"
+ echo ""
+ echo "For Gmail, use an App Password (not your regular password)."
+ echo ""
+
+ # Check if msmtp is installed
+ if ! command -v msmtp &> /dev/null; then
+ echo "msmtp is not installed. Install with:"
+ echo " brew install msmtp"
+ echo ""
+ fi
+fi
+
+# ============================================
+# ntfy Setup
+# ============================================
+
+echo ""
+echo "=== ntfy.sh Setup (optional) ==="
+echo ""
+echo "ntfy.sh is a simple push notification service."
+echo "No account needed - just choose a unique topic name."
+echo ""
+
+read -p "Enter ntfy topic name (or press Enter to skip): " NTFY_TOPIC
+
+# ============================================
+# Write configuration
+# ============================================
+
+echo ""
+echo "=== Writing Configuration ==="
+
+cat > "$ENV_FILE" << EOF
+# ManaCore Notification Configuration
+# Generated on $(date)
+
+# Telegram
+TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
+TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
+
+# Email
+EMAIL_TO=${EMAIL_TO}
+EMAIL_FROM=${EMAIL_FROM}
+
+# ntfy.sh
+NTFY_TOPIC=${NTFY_TOPIC}
+EOF
+
+chmod 600 "$ENV_FILE"
+echo "Configuration saved to $ENV_FILE"
+
+# ============================================
+# Test notifications
+# ============================================
+
+echo ""
+read -p "Do you want to send a test notification? [Y/n] " -n 1 -r
+echo
+
+if [[ ! $REPLY =~ ^[Nn]$ ]]; then
+ echo ""
+ echo "Sending test notifications..."
+
+ # Source the new config
+ source "$ENV_FILE"
+
+ # Test Telegram
+ if [ -n "$TELEGRAM_BOT_TOKEN" ] && [ -n "$TELEGRAM_CHAT_ID" ]; then
+ echo -n " Testing Telegram... "
+ RESULT=$(curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
+ -d "chat_id=${TELEGRAM_CHAT_ID}" \
+ -d "text=✅ ManaCore notification test successful!" \
+ -d "parse_mode=HTML")
+
+ if echo "$RESULT" | grep -q '"ok":true'; then
+ echo "OK"
+ else
+ echo "FAILED"
+ echo " Response: $RESULT"
+ fi
+ fi
+
+ # Test Email
+ if [ -n "$EMAIL_TO" ] && command -v msmtp &> /dev/null; then
+ echo -n " Testing Email... "
+ echo -e "Subject: ManaCore Test Notification\nFrom: ${EMAIL_FROM}\nTo: ${EMAIL_TO}\n\nThis is a test notification from ManaCore health check." | \
+ msmtp -a default "$EMAIL_TO" 2>/dev/null && echo "OK" || echo "FAILED (check ~/.msmtprc)"
+ elif [ -n "$EMAIL_TO" ]; then
+ echo " Email configured but msmtp not installed"
+ fi
+
+ # Test ntfy
+ if [ -n "$NTFY_TOPIC" ]; then
+ echo -n " Testing ntfy... "
+ curl -s -d "ManaCore notification test successful!" \
+ -H "Title: Test" \
+ "https://ntfy.sh/$NTFY_TOPIC" >/dev/null && echo "OK" || echo "FAILED"
+ fi
+fi
+
+# ============================================
+# Summary
+# ============================================
+
+echo ""
+echo "=== Setup Complete ==="
+echo ""
+echo "Configured notifications:"
+[ -n "$TELEGRAM_BOT_TOKEN" ] && echo " ✓ Telegram"
+[ -n "$EMAIL_TO" ] && echo " ✓ Email ($EMAIL_TO)"
+[ -n "$NTFY_TOPIC" ] && echo " ✓ ntfy ($NTFY_TOPIC)"
+echo ""
+echo "Health checks run every 5 minutes and will send"
+echo "notifications when services fail."
+echo ""
+echo "To test manually:"
+echo " ./scripts/mac-mini/health-check.sh"
+echo ""