Torn Profile Workstats Viewer

Show total working stats

// ==UserScript==
// @name         Torn Profile Workstats Viewer
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  Show total working stats
// @match        https://www.torn.com/profiles.php*
// @grant        GM_xmlhttpRequest
// @grant        GM_getValue
// @grant        GM_setValue
// @connect      api.torn.com
// @author       aquagloop
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    const STORAGE_KEY = 'tornApiKey';

    const getProfileId = () => {
        const urlParams = new URLSearchParams(window.location.search);
        return urlParams.get('XID');
    };

    const fetchWorkStats = (userId, apiKey) => {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'GET',
                url: `https://api.torn.com/v2/user/${userId}/hof?key=${apiKey}`,
                headers: {
                    Accept: 'application/json'
                },
                onload: (response) => {
                    try {
                        const data = JSON.parse(response.responseText);
                        if (data.error) {
                            reject(data.error.error);
                        } else {
                            resolve(data.hof?.working_stats?.value || 0);
                        }
                    } catch (e) {
                        reject('Failed to parse response');
                    }
                },
                onerror: () => reject('Network error')
            });
        });
    };

    const displayStats = (total) => {
        const box = document.createElement('div');
        box.id = 'workstatsBox';
        Object.assign(box.style, {
            position: 'fixed',
            top: '20px',
            right: '20px',
            background: 'rgba(0,0,0,0.85)',
            color: '#fff',
            padding: '14px 18px',
            borderRadius: '12px',
            fontFamily: 'Arial, sans-serif',
            fontSize: '14px',
            zIndex: '9999',
            boxShadow: '0 0 10px rgba(0,0,0,0.5)',
            textAlign: 'center',
        });

        box.innerHTML = `
            <strong>Total Working Stats</strong><br>
            <span style="font-size: 18px;">${total.toLocaleString()}</span>
        `;

        document.body.appendChild(box);
    };

    const main = async () => {
        const userId = getProfileId();
        if (!userId) return;

        let apiKey = await GM_getValue(STORAGE_KEY, null);
        if (!apiKey) {
            apiKey = prompt('Enter your Torn API key:');
            if (!apiKey) return;
            await GM_setValue(STORAGE_KEY, apiKey);
        }

        try {
            const totalStats = await fetchWorkStats(userId, apiKey);
            displayStats(totalStats);
        } catch (error) {
            console.error('Workstats error:', error);

            // Clear stored key if invalid
            if (error === 2 || error === "Incorrect key") {
                await GM_setValue(STORAGE_KEY, null);
                alert('Invalid API key. Reload the page to enter a new one.');
            }
        }
    };

    window.addEventListener('load', main);
})();