ip_notifier.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import time
  2. import requests
  3. import smtplib
  4. from email.mime.text import MIMEText
  5. import configparser
  6. # Load configuration from config.ini
  7. config = configparser.ConfigParser()
  8. config.read('config/config.ini')
  9. if not config.sections():
  10. raise ValueError("Config file 'config.ini' not found or empty. Please create it with the required settings.")
  11. # General settings
  12. CHECK_INTERVAL = config.getint('General', 'check_interval', fallback=300) # Unused in one-shot mode, but kept for reference
  13. NOTIFY_METHODS_STR = config.get('General', 'notify_methods', fallback='email') # Comma-separated string, default to 'email'
  14. LAST_IP_FILE = config.get('General', 'last_ip_file', fallback='last_ip.txt')
  15. # Parse notify_methods into a list (strip whitespace, lowercase, remove duplicates)
  16. NOTIFY_METHODS = list(set(m.strip().lower() for m in NOTIFY_METHODS_STR.split(',') if m.strip()))
  17. if not NOTIFY_METHODS:
  18. NOTIFY_METHODS = ['email'] # Default to email if empty or invalid
  19. # Email settings
  20. EMAIL_FROM = config.get('Email', 'from', fallback='')
  21. EMAIL_TO = config.get('Email', 'to', fallback='')
  22. SMTP_SERVER = config.get('Email', 'server', fallback='')
  23. SMTP_PORT = config.getint('Email', 'port', fallback=465)
  24. SMTP_USER = config.get('Email', 'user', fallback='')
  25. SMTP_PASS = config.get('Email', 'pass', fallback='')
  26. # Telegram settings
  27. TELEGRAM_BOT_TOKEN = config.get('Telegram', 'bot_token', fallback='')
  28. TELEGRAM_CHAT_ID = config.get('Telegram', 'chat_id', fallback='')
  29. # Nextcloud Talk settings
  30. NEXTCLOUD_URL = config.get('Nextcloud', 'url', fallback='')
  31. NEXTCLOUD_TOKEN = config.get('Nextcloud', 'token', fallback='')
  32. NEXTCLOUD_ROOM = config.get('Nextcloud', 'room', fallback='')
  33. def get_public_ip():
  34. try:
  35. return requests.get("https://api.ipify.org").text.strip()
  36. except Exception as e:
  37. print(f"Error getting public IP: {e}")
  38. return None
  39. def send_email(subject, body):
  40. if not all([EMAIL_FROM, EMAIL_TO, SMTP_SERVER, SMTP_USER, SMTP_PASS]):
  41. print("Email settings incomplete in config.")
  42. return False
  43. try:
  44. msg = MIMEText(body)
  45. msg["Subject"] = subject
  46. msg["From"] = EMAIL_FROM
  47. msg["To"] = EMAIL_TO
  48. with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server:
  49. server.set_debuglevel(1)
  50. # server.starttls() # Commented as in original; using SSL
  51. server.login(SMTP_USER, SMTP_PASS)
  52. server.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string())
  53. return True
  54. except Exception as e:
  55. print(f"Error sending email: {e}")
  56. return False
  57. def send_telegram(message):
  58. if not all([TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID]):
  59. print("Telegram settings incomplete in config.")
  60. return False
  61. try:
  62. url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
  63. data = {"chat_id": TELEGRAM_CHAT_ID, "text": message}
  64. response = requests.post(url, data=data)
  65. return response.status_code == 200
  66. except Exception as e:
  67. print(f"Error sending Telegram message: {e}")
  68. return False
  69. def send_nextcloud_talk(message):
  70. if not all([NEXTCLOUD_URL, NEXTCLOUD_TOKEN, NEXTCLOUD_ROOM]):
  71. print("Nextcloud settings incomplete in config.")
  72. return False
  73. try:
  74. url = f"{NEXTCLOUD_URL}/ocs/v2.php/apps/spreed/api/v1/chat/{NEXTCLOUD_ROOM}"
  75. headers = {
  76. "OCS-APIRequest": "true",
  77. "Authorization": f"Bearer {NEXTCLOUD_TOKEN}"
  78. }
  79. data = {"message": message}
  80. response = requests.post(url, headers=headers, data=data)
  81. return response.status_code == 200
  82. except Exception as e:
  83. print(f"Error sending Nextcloud message: {e}")
  84. return False
  85. def notify(ip):
  86. message = f"Public IP changed to: {ip}"
  87. for method in NOTIFY_METHODS:
  88. if method == "email":
  89. success = send_email("IP Address Changed", message)
  90. print(f"Email notification {'sent' if success else 'failed'}.")
  91. elif method == "telegram":
  92. success = send_telegram(message)
  93. print(f"Telegram notification {'sent' if success else 'failed'}.")
  94. elif method == "nextcloud":
  95. success = send_nextcloud_talk(message)
  96. print(f"Nextcloud notification {'sent' if success else 'failed'}.")
  97. else:
  98. print(f"Unknown notification method: {method}. Skipping.")
  99. def load_last_ip():
  100. try:
  101. with open(LAST_IP_FILE, "r") as f:
  102. return f.read().strip()
  103. except FileNotFoundError:
  104. return None
  105. def save_last_ip(ip):
  106. with open(LAST_IP_FILE, "w") as f:
  107. f.write(ip)
  108. def main():
  109. last_ip = load_last_ip()
  110. while True:
  111. print("Checking for public IP...")
  112. ip = get_public_ip()
  113. if ip and ip != last_ip:
  114. notify(ip)
  115. save_last_ip(ip)
  116. last_ip = ip
  117. time.sleep(CHECK_INTERVAL)
  118. if __name__ == "__main__":
  119. main()