ChatGPT AccessToken 自动更新

根据token过期时间自动获取accessToken并发送POST请求后自动跳转到new.oaifree.com

目前为 2024-08-13 提交的版本。查看 最新版本

// ==UserScript==
// @name         ChatGPT AccessToken 自动更新
// @namespace    http://tampermonkey.net/
// @version      2.5
// @description  根据token过期时间自动获取accessToken并发送POST请求后自动跳转到new.oaifree.com
// @author       AMT
// @match        *://new.oaifree.com/*
// @grant        GM_xmlhttpRequest
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @connect      chatgpt.com
// @connect      new.oaifree.com
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 定义获取accessToken的URL
    const tokenUrl = "https://chatgpt.com/api/auth/session";
    // 定义POST请求的目标URL
    const postUrl = "https://new.oaifree.com/auth/login_token";
    // 定义跳转的目标URL
    const redirectUrl = "https://new.oaifree.com";
    // 定义GM存储时间的key
    const expiresKey = 'tokenExpires'; // 保存token过期时间的key
    // 获取当前时间的时间戳(毫秒)
    let currentTime = new Date().getTime();

    // 从GM存储获取token过期时间
    let expires = GM_getValue(expiresKey, 0); // 读取上次保存的token过期时间

    // 计算距离token过期的时间
    function calculateTimeUntilExpiry() {
        currentTime = new Date().getTime();
        const timeUntilExpiry = expires - currentTime;
        const daysUntilExpiry = Math.floor(timeUntilExpiry / (24 * 60 * 60 * 1000));
        const hoursUntilExpiry = Math.floor((timeUntilExpiry % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000));
        return { daysUntilExpiry, hoursUntilExpiry };
    }

    // 创建可视化窗口
    const panel = document.createElement('div');
    panel.id = 'script-panel';
    const { daysUntilExpiry, hoursUntilExpiry } = calculateTimeUntilExpiry();
    panel.innerHTML = `
    <div id="panel-content">
        <p>距离AccessToken过期还有:<br>
        <span id="time-until-expiry">${daysUntilExpiry}天${hoursUntilExpiry}小时</span></p>
        <button id="run-script-button">立即获取AccessToken并POST</button>
    </div>
    `;
    document.body.appendChild(panel);

    // 添加样式
    GM_addStyle(`
        #script-panel {
            position: fixed;
            top: 10%;
            right: 0;
            width: 300px;
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 15px;
            border-radius: 10px 0 0 10px;
            box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
            z-index: 10000;
            transform: translateX(98%);
            transition: transform 0.5s ease-in-out;
            cursor: move;
        }
        #panel-content {
            display: block;
            text-align: center;
        }
        #script-panel:hover {
            transform: translateX(0);
        }
        #run-script-button {
            background-color: #4CAF50;
            color: white;
            border: none;
            padding: 10px 15px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 14px;
            margin: 10px 0;
            cursor: pointer;
            border-radius: 5px;
            transition: background-color 0.3s, box-shadow 0.1s;
        }
        #run-script-button:hover {
            background-color: #45a049;
        }
        #run-script-button:active {
            box-shadow: inset 0px 3px 5px rgba(0, 0, 0, 0.2);
            background-color: #39843b;
        }
    `);

    // 添加拖动功能
    let isDragging = false;
    let startY = 0;
    let startTop = 0;

    panel.addEventListener('mousedown', function(e) {
        isDragging = true;
        startY = e.clientY;
        startTop = panel.offsetTop;
        document.addEventListener('mousemove', onMouseMove);
        document.addEventListener('mouseup', onMouseUp);
    });

    function onMouseMove(e) {
        if (isDragging) {
            const deltaY = e.clientY - startY;
            panel.style.top = `${startTop + deltaY}px`;
        }
    }

    function onMouseUp() {
        isDragging = false;
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
    }

    // 添加时间自动更新功能
    setInterval(() => {
        const { daysUntilExpiry, hoursUntilExpiry } = calculateTimeUntilExpiry();
        document.getElementById('time-until-expiry').textContent = `${daysUntilExpiry}天${hoursUntilExpiry}小时`;
        // 检测是否需要获取token
        if (shouldFetchToken()) {
            fetchAndPostToken();
        }
    }, 60000 * 60); // 每小时更新一次

    // 添加按钮点击事件
    document.getElementById('run-script-button').addEventListener('click', function() {
        fetchAndPostToken();
    });

    // 检查是否需要获取token
    if (shouldFetchToken()) {
        fetchAndPostToken();
    } else {
        console.log("Script not run: Token is still valid.");
    }

    // 判断是否需要获取token
    function shouldFetchToken() {
        currentTime = new Date().getTime();
        return currentTime > expires;
    }

    // 获取token并发送POST请求的函数
    function fetchAndPostToken() {
        GM_xmlhttpRequest({
            method: "GET",
            url: tokenUrl,
            onload: function(response) {
                if (response.status === 200) {
                    // 解析返回的JSON
                    const responseData = JSON.parse(response.responseText);
                    // 提取accessToken和expires
                    const accessToken = responseData.accessToken;
                    const tokenExpires = new Date(responseData.expires).getTime(); // 将expires转换为时间戳

                    // 如果获取到accessToken,则发送POST请求
                    sendPostRequest(accessToken, tokenExpires);
                } else {
                    console.error("Failed to fetch accessToken. Status:", response.status);
                }
            }
        });
    }

    // 发送POST请求的函数
    function sendPostRequest(accessToken, tokenExpires) {
        const data = {
            action: "token",
            access_token: accessToken
        };

        GM_xmlhttpRequest({
            method: "POST",
            url: postUrl,
            headers: {
                "Content-Type": "application/x-www-form-urlencoded"
            },
            data: Object.keys(data).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`).join('&'),
            onload: function(response) {
                console.log("Status Code:", response.status);
                console.log("Response:", response.responseText);

                // 成功发送POST请求后自动跳转
                if (response.status === 200) {
                    // 更新token过期时间
                    GM_setValue(expiresKey, tokenExpires);
                    window.location.href = redirectUrl;
                }
            },
            onerror: function(error) {
                console.error("Error in POST request:", error);
            }
        });
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址