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 ""