How to submit Hugo posts to Bing IndexNow API

The following script can be used to automatically identify the most recent 50 blogposts and submit them to the Bing IndexNow API.

It depends on a) hugo -F (build) being run beforehand and b) that the files in the public directory have the following filename format:

public/2019/12/26/how-to-remove-all-event-listeners-from-a-dom-element-in-javascript/index.html

Also make sure to create static/BING_INDEXNOW_API_KEY.txt with your Bing IndexNow API key as content. This is required to authenticate the requests to Bing.

Ensure to modify the parameters at the top of the script (# Configuration) to match your setup.

#!/usr/bin/env python3
import os
import requests
from datetime import datetime

# Configuration
base_url = 'https://mydomain.com'
public_dir = 'public'
indexnow_api_url = 'https://www.bing.com/indexnow'
api_key = 'YOUR_BING_INDEXNOW_API_KEY'  # Replace with your IndexNow API key

def get_recent_posts(public_dir, limit=50):
    post_dates = []
    for root, dirs, files in os.walk(public_dir):
        for file in files:
            if file.endswith('.html'):
                # Extract the date from the directory structure
                parts = root.split(os.sep)
                print(parts)
                if len(parts) > 2:
                    try:
                        date_str = '/'.join(parts[-4:-1])
                        post_date = datetime.strptime(date_str, '%Y/%m/%d')
                        post_dates.append((post_date, os.path.join(root, file)))
                    except ValueError as ex:
                        continue

    # Sort posts by date in descending order and take the most recent 'limit' posts
    post_dates.sort(reverse=True, key=lambda x: x[0])
    recent_posts = post_dates[:limit]
    return recent_posts

def submit_to_indexnow(urls, api_key):
    payload = {
        'host': 'techoverflow.net',
        'key': api_key,
        'urlList': '\n'.join(urls),
    }
    response = requests.post(indexnow_api_url, data=payload)
    if response.status_code == 200:
        print("Successfully submitted URLs to Bing IndexNow API")
    else:
        print(f"Failed to submit URLs: {response.status_code} {response.text}")

def main():
    recent_posts = get_recent_posts(public_dir)
    urls = [f"{base_url}/{os.path.relpath(file_path, public_dir).replace(os.sep, '/')}" for _, file_path in recent_posts]
    if urls:
        print("Submitting:")
        for url in urls:
            print("  ", url)
        submit_to_indexnow(urls, api_key)

if __name__ == '__main__':
    main()