import time import requests import smtplib from email.mime.text import MIMEText import configparser # Load configuration from config.ini config = configparser.ConfigParser() config.read('config/config.ini') if not config.sections(): raise ValueError("Config file 'config.ini' not found or empty. Please create it with the required settings.") # General settings CHECK_INTERVAL = config.getint('General', 'check_interval', fallback=300) # Unused in one-shot mode, but kept for reference NOTIFY_METHODS_STR = config.get('General', 'notify_methods', fallback='email') # Comma-separated string, default to 'email' LAST_IP_FILE = config.get('General', 'last_ip_file', fallback='last_ip.txt') # Parse notify_methods into a list (strip whitespace, lowercase, remove duplicates) NOTIFY_METHODS = list(set(m.strip().lower() for m in NOTIFY_METHODS_STR.split(',') if m.strip())) if not NOTIFY_METHODS: NOTIFY_METHODS = ['email'] # Default to email if empty or invalid # Email settings EMAIL_FROM = config.get('Email', 'from', fallback='') EMAIL_TO = config.get('Email', 'to', fallback='') SMTP_SERVER = config.get('Email', 'server', fallback='') SMTP_PORT = config.getint('Email', 'port', fallback=465) SMTP_USER = config.get('Email', 'user', fallback='') SMTP_PASS = config.get('Email', 'pass', fallback='') # Telegram settings TELEGRAM_BOT_TOKEN = config.get('Telegram', 'bot_token', fallback='') TELEGRAM_CHAT_ID = config.get('Telegram', 'chat_id', fallback='') # Nextcloud Talk settings NEXTCLOUD_URL = config.get('Nextcloud', 'url', fallback='') NEXTCLOUD_TOKEN = config.get('Nextcloud', 'token', fallback='') NEXTCLOUD_ROOM = config.get('Nextcloud', 'room', fallback='') def get_public_ip(): try: return requests.get("https://api.ipify.org").text.strip() except Exception as e: print(f"Error getting public IP: {e}") return None def send_email(subject, body): if not all([EMAIL_FROM, EMAIL_TO, SMTP_SERVER, SMTP_USER, SMTP_PASS]): print("Email settings incomplete in config.") return False try: msg = MIMEText(body) msg["Subject"] = subject msg["From"] = EMAIL_FROM msg["To"] = EMAIL_TO with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server: server.set_debuglevel(1) # server.starttls() # Commented as in original; using SSL server.login(SMTP_USER, SMTP_PASS) server.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string()) return True except Exception as e: print(f"Error sending email: {e}") return False def send_telegram(message): if not all([TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID]): print("Telegram settings incomplete in config.") return False try: url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" data = {"chat_id": TELEGRAM_CHAT_ID, "text": message} response = requests.post(url, data=data) return response.status_code == 200 except Exception as e: print(f"Error sending Telegram message: {e}") return False def send_nextcloud_talk(message): if not all([NEXTCLOUD_URL, NEXTCLOUD_TOKEN, NEXTCLOUD_ROOM]): print("Nextcloud settings incomplete in config.") return False try: url = f"{NEXTCLOUD_URL}/ocs/v2.php/apps/spreed/api/v1/chat/{NEXTCLOUD_ROOM}" headers = { "OCS-APIRequest": "true", "Authorization": f"Bearer {NEXTCLOUD_TOKEN}" } data = {"message": message} response = requests.post(url, headers=headers, data=data) return response.status_code == 200 except Exception as e: print(f"Error sending Nextcloud message: {e}") return False def notify(ip): message = f"Public IP changed to: {ip}" for method in NOTIFY_METHODS: if method == "email": success = send_email("IP Address Changed", message) print(f"Email notification {'sent' if success else 'failed'}.") elif method == "telegram": success = send_telegram(message) print(f"Telegram notification {'sent' if success else 'failed'}.") elif method == "nextcloud": success = send_nextcloud_talk(message) print(f"Nextcloud notification {'sent' if success else 'failed'}.") else: print(f"Unknown notification method: {method}. Skipping.") def load_last_ip(): try: with open(LAST_IP_FILE, "r") as f: return f.read().strip() except FileNotFoundError: return None def save_last_ip(ip): with open(LAST_IP_FILE, "w") as f: f.write(ip) def main(): last_ip = load_last_ip() while True: print("Checking for public IP...") ip = get_public_ip() if ip and ip != last_ip: notify(ip) save_last_ip(ip) last_ip = ip time.sleep(CHECK_INTERVAL) if __name__ == "__main__": main()