Oups the script was not complete :( Here an updated version :)
#!/var/www/cloudflare/venv/bin/python3
# -*- coding: utf-8 -*-
import requests
import json
import re
import os
# Cloudflare API settings
API_TOKEN = 'my_api_token'
ZONE_ID = 'my_zone_id'
# TTL constant (120 = "Auto" on Cloudflare)
AUTO = 120
# DNS records to update
RECORDS_TO_UPDATE = [
    {'name': 'domain.org', 'type': 'A', 'proxied': True, 'ttl': AUTO},
    {'name': '*.domain.org', 'type': 'A', 'proxied': True, 'ttl': AUTO},
    {'name': 'minecraft.domain.org', 'type': 'A', 'proxied': False, 'ttl': AUTO}
]
# API headers
HEADERS = {
    'Authorization': f'Bearer {API_TOKEN}',
    'Content-Type': 'application/json',
}
# File path to store last known IP
LAST_IP_FILE = os.path.join(os.path.dirname(__file__), 'last_ip.txt')
def get_public_ip():
    """Fetch current public IP from checkip.dyndns.org"""
    try:
        response = requests.get("http://checkip.dyndns.org/")
        ip = re.search(r"Current IP Address: ([\d.]+)", response.text).group(1)
        return ip
    except Exception as e:
        raise RuntimeError(f"Failed to detect public IP: {e}")
def load_last_ip():
    """Read the last saved public IP address"""
    try:
        with open(LAST_IP_FILE, 'r') as f:
            return f.read().strip()
    except FileNotFoundError:
        return None
def save_current_ip(ip):
    """Save the current public IP address"""
    with open(LAST_IP_FILE, 'w') as f:
        f.write(ip)
def get_all_dns_records():
    """Fetch all DNS records in the Cloudflare zone"""
    url = f'https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/dns_records'
    response = requests.get(url, headers=HEADERS)
    if response.status_code != 200:
        raise RuntimeError(f"Failed to fetch DNS records: {response.text}")
    return response.json().get('result', [])
def update_dns_record(record_id, name, record_type, proxied, ttl, new_ip):
    """Update a DNS record on Cloudflare"""
    url = f'https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/dns_records/{record_id}'
    payload = { 'type': record_type, 'name': name, 'content': new_ip, 'ttl': ttl, 'proxied': proxied }
    response = requests.put(url, headers=HEADERS, data=json.dumps(payload))
    if response.status_code == 200:
        print(f"✅ Updated {name} to {new_ip}")
    else:
        raise RuntimeError(f"Failed to update {name}: {response.text}")
def main():
    # Output HTTP header (for CGI)
    print('Content-Type: text/plain; charset=utf-8\n')
    try:
        current_ip = get_public_ip()
        last_ip = load_last_ip()
        print(f"🌍 Current Public IP: {current_ip}")
        if current_ip == last_ip:
            print("⏸️  Public IP has not changed. Skipping update.")
            return
        all_records = get_all_dns_records()
        record_id_map = {(rec['name'], rec['type']): rec['id'] for rec in all_records}
        all_success = True
        for record in RECORDS_TO_UPDATE:
            key = (record['name'], record['type'])
            record_id = record_id_map.get(key)
            if not record_id:
                print(f"⚠️ No record ID found for {record['name']} ({record['type']})")
                all_success = False
                continue
            try:
                update_dns_record(record_id, record['name'], record['type'], record['proxied'], record['ttl'], current_ip)
            except Exception as e:
                print(f"❌ Failed to update {record['name']}: {e}")
                all_success = False
        if all_success:
            save_current_ip(current_ip)
            print("✅ All records updated successfully. IP saved.")
        else:
            print("⚠️ Some updates failed. IP not saved to ensure retry next time.")
    except Exception as e:
        print(f"🚫 Script failed: {e}")
if __name__ == '__main__':
    main()