Automating Public IP Monitoring and Email Notifications in Windows
Functionality:
This solution monitors changes in your public IP address and automatically sends notifications to specified email addresses when changes occur. It's particularly useful for environments without dynamic DNS services or port forwarding configurations.
Prerequisites:
- Python 3.x installed on your Windows system
- requests library for Python
pip install requests
Required Files:
- ip_history.txt - Stores the last known IP address
- ip_monitor.py - Main script for IP monitoring and email notifications
- run_monitor.bat - Batch script to execute the Python script
ip_history.txt Content:
Leave this file empty initially.
ip_monitor.py Content:
import smtplib
import ssl
import requests
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
def dispatch_notification(subject, message_body, recipients, sender_email, sender_password, mail_server, mail_port, file_attachment=None):
"""
Compose and send an email notification with optional attachment
"""
email_msg = MIMEMultipart()
email_msg['From'] = sender_email
email_msg['To'] = ', '.join(recipients)
email_msg['Subject'] = subject
email_msg.attach(MIMEText(message_body, 'plain'))
if file_attachment:
try:
with open(file_attachment, 'rb') as attachment_file:
email_part = MIMEBase('application', 'octet-stream')
email_part.set_payload(attachment_file.read())
encoders.encode_base64(email_part)
email_part.add_header('Content-Disposition', f"attachment; filename= {os.path.basename(file_attachment)}")
email_msg.attach(email_part)
except Exception as attachment_error:
print(f"Attachment failed: {attachment_error}")
try:
ssl_context = ssl.create_default_context()
with smtplib.SMTP_SSL(mail_server, mail_port, context=ssl_context) as mail_client:
mail_client.set_debuglevel(1)
mail_client.login(sender_email, sender_password)
email_text = email_msg.as_string()
mail_client.sendmail(sender_email, recipients, email_text)
print("Email notification dispatched successfully")
except smtplib.SMTPAuthenticationError as auth_error:
print(f"Authentication failure: {auth_error.smtp_code} - {auth_error.smtp_error}")
except smtplib.SMTPException as mail_error:
print(f"SMTP error: {mail_error}")
except Exception as general_error:
print(f"Notification dispatch failed: {general_error}")
def retrieve_external_ip():
"""
Fetch the current external IP address from an online service
"""
try:
ip_response = requests.get('https://api.ipify.org?format=', timeout=10)
ip_response.raise_for_status()
ip_data = ip_response.()
return ip_data.get('ip')
except requests.RequestException as ip_error:
print(f"IP retrieval error: {ip_error}")
return None
def main():
# Configuration parameters
ip_storage_file = 'ip_history.txt'
notification_subject = "External IP Address Change Detected"
notification_body = "Your current external IP address is: "
recipient_list = ["your_email@example.com", "backup@example.com"] # Replace with actual email addresses
sender_address = "your_sender@example.com" # Replace with your email address
sender_credentials = "your_email_password" # Replace with your email password or app-specific password
smtp_host = "smtp.example.com" # Replace with your SMTP server
smtp_port = 465 # Standard SSL port for SMTP
attachment_file = None # Set to file path if attachment is needed
# Retrieve current external IP
current_external_ip = retrieve_external_ip()
if current_external_ip:
try:
with open(ip_storage_file, 'r', encoding='utf-8') as ip_file:
previous_external_ip = ip_file.read().strip()
except FileNotFoundError:
previous_external_ip = ""
if current_external_ip != previous_external_ip:
print(f"IP address changed!\nPrevious IP: {previous_external_ip}\nCurrent IP: {current_external_ip}")
# Prepare and send notification
notification_details = notification_body + current_external_ip
dispatch_notification(
notification_subject,
notification_details,
recipient_list,
sender_address,
sender_credentials,
smtp_host,
smtp_port,
attachment_file
)
# Update IP history file
with open(ip_storage_file, 'w', encoding='utf-8') as ip_file:
ip_file.write(current_external_ip)
else:
print("IP address unchanged")
else:
print("Failed to retrieve external IP address")
if __name__ == "__main__":
main()
run_monitor.bat Content:
@echo off
cd /d C:\path\to\your\script\folder
python ip_monitor.py
Scheduling the Task:
To automate this script, create a scheduled task in Windows Task Scheduler that runs the run_monitor.bat file at regular intervals (e.g., every hour).