Created
March 27, 2026 20:05
-
-
Save ssaki/aa6181fb37fba8b19dcf81f18dc50ee3 to your computer and use it in GitHub Desktop.
Print a list of all creations in your Starfield library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * This script will make a text table of all creation in your library - name and author | |
| * | |
| * 1. Go to https://creations.bethesda.net/en/starfield/library and make sure you are logged in! | |
| * 2. Open dev console (F12) and copy/paste this script in it and press enter. | |
| * 3. Force the site to make new request - e.g. change the page | |
| * | |
| * How it works - Once it is started it register a small function to intercept requests and get the key bethesda's site is using to identify you. | |
| * Once it has it - it will pull all pages of creations and will print the tabler in the console. | |
| */ | |
| (async () => { | |
| // Intercept fetch to steal the x-bnet-key from a real request | |
| let BNET_KEY; | |
| const origFetch = window.fetch; | |
| window.fetch = function(...args) { | |
| const [url, opts] = args; | |
| if (opts?.headers) { | |
| // check both Headers object and plain object | |
| if (opts.headers instanceof Headers) { | |
| const k = opts.headers.get('x-bnet-key'); | |
| if (k) BNET_KEY = k; | |
| } else if (typeof opts.headers === 'object') { | |
| const k = opts.headers['x-bnet-key']; | |
| if (k) BNET_KEY = k; | |
| } | |
| } | |
| return origFetch.apply(this, args); | |
| }; | |
| // Also patch XHR | |
| const origOpen = XMLHttpRequest.prototype.open; | |
| const origSetHeader = XMLHttpRequest.prototype.setRequestHeader; | |
| XMLHttpRequest.prototype.setRequestHeader = function(name, value) { | |
| if (name.toLowerCase() === 'x-bnet-key') BNET_KEY = value; | |
| return origSetHeader.call(this, name, value); | |
| }; | |
| console.log('Interceptors set. Waiting for a page request to capture the key...'); | |
| console.log('Scroll down or click something on the page to trigger an API call.'); | |
| // Wait for the key to appear (up to 15s) | |
| for (let i = 0; i < 30; i++) { | |
| if (BNET_KEY) break; | |
| await new Promise(r => setTimeout(r, 500)); | |
| } | |
| // Restore originals | |
| window.fetch = origFetch; | |
| XMLHttpRequest.prototype.setRequestHeader = origSetHeader; | |
| if (!BNET_KEY) { console.error('No key captured. Try scrolling/clicking the page and run again.'); return; } | |
| console.log('Captured key:', BNET_KEY); | |
| const TOKEN = document.cookie.match(/bwa-token=([^;]+)/)?.[1]; | |
| if (!TOKEN) { console.error('No bwa-token cookie found'); return; } | |
| const headers = { | |
| 'authorization': `Bearer ${TOKEN}`, | |
| 'x-bnet-product': 'GENESIS', | |
| 'x-bnet-key': BNET_KEY, | |
| 'content-type': 'application/json' | |
| }; | |
| const all = []; | |
| let page = 1, totalPages = Infinity; | |
| while (page <= totalPages) { | |
| const res = await fetch(`https://api.bethesda.net/ugcmods/v2/content/subscribe?product=GENESIS&sort=subscriptions&time_period=all_time&size=60&page=${page}`, { headers }); | |
| if (!res.ok) { console.error(`Page ${page}: ${res.status}`); break; } | |
| const r = (await res.json()).platform.response; | |
| totalPages = Math.ceil(r.total / r.size); | |
| r.data.forEach(i => all.push({ title: i.title, author: i.author_displayname })); | |
| page++; | |
| } | |
| const max = all.reduce((m, i) => Math.max(m, i.title.length), 0); | |
| console.log(all.map((m, i) => `${String(i+1).padStart(3)} ${m.title.padEnd(max)} ${m.author}`).join('\n')); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment