跳转至内容
0
  • 版块
  • 讨论
  • 最新
  • 标签
  • 热门
  • 顶端
  • 用户
  • 版块
  • 讨论
  • 最新
  • 标签
  • 热门
  • 顶端
  • 用户
皮肤
  • 浅色
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • 深色
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(不使用皮肤)
  • 不使用皮肤
折叠
JIKE社区
  1. 首页
  2. 讨论区
  3. 技术专区
  4. 这俩天很火的强制进入ChatGPT K12 脚本

这俩天很火的强制进入ChatGPT K12 脚本

已定时 已固定 已锁定 已移动 技术专区
4 帖子 2 发布者 116 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
回复
  • 在新帖中回复
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • 我是小马甲~M 在线
    我是小马甲~M 在线
    我是小马甲~
    🤫
    编写于 最后由 编辑
    #1
    // ==UserScript==
    // @name         ChatGPT Workspace Join Request
    // @namespace    https://chatgpt.com/
    // @version      4.0.0
    // @description  子号自动从 /api/auth/session 获取当前登录账号 AT,向母号 workspace 发送加入申请(request)或接受邀请(accept)。只需 workspace ID,UI 可编辑保存。
    // @author       you
    // @match        https://chatgpt.com/*
    // @run-at       document-idle
    // @grant        none
    // ==/UserScript==
    
    (function () {
      "use strict";
    
      // ===================== 默认配置 =====================
      const DEFAULTS = {
        workspaceIds: "ca0e29ed-a54c-42d9-a50b-2ba5e065296d",
        intervalMs: 1500,
        maxRetries: 3,
        retryBackoffMs: 5000,
        sessionPollMs: 20000,
        panelWidth: 400,
      };
    
      const STORE_KEY = "jr_config_v4";
      function loadConfig() {
        let saved = {};
        try { saved = JSON.parse(localStorage.getItem(STORE_KEY) || "{}"); } catch (_) {}
        return Object.assign({}, DEFAULTS, saved);
      }
      function saveConfig(cfg) {
        try { localStorage.setItem(STORE_KEY, JSON.stringify(cfg)); } catch (_) {}
      }
    
      let CONFIG = loadConfig();
    
      // ---------- 状态 ----------
      const STATE = {
        at: "",
        session: null,
        deviceId: crypto.randomUUID(),
        autoRan: false,
        running: false,
      };
    
      // ---------- /api/auth/session ----------
      async function fetchSession() {
        const res = await fetch("/api/auth/session", {
          headers: { accept: "*/*" },
          credentials: "include",
        });
        if (!res.ok) throw new Error(`session HTTP ${res.status}`);
        return res.json();
      }
    
      function decodeJwt(at) {
        try {
          const p = at.split(".")[1];
          const j = JSON.parse(atob(p.replace(/-/g, "+").replace(/_/g, "/")));
          const auth = j["https://api.openai.com/auth"] || {};
          const prof = j["https://api.openai.com/profile"] || {};
          return {
            account_id: auth.chatgpt_account_id || "",
            email: prof.email || "",
            plan_type: auth.chatgpt_plan_type || "",
            exp: j.exp || 0,
          };
        } catch (_) { return {}; }
      }
    
      function fmtExp(exp) {
        if (!exp) return "?";
        const min = Math.round((exp * 1000 - Date.now()) / 60000);
        if (min > 60) return `剩余 ${Math.round(min/60)} 小时`;
        return `剩余 ${min} 分钟`;
      }
    
      async function refreshSession() {
        try {
          const s = await fetchSession();
          const at = s.accessToken || "";
          if (at && at !== STATE.at) {
            STATE.at = at;
            STATE.session = s;
            const info = decodeJwt(at);
            log(`子号 AT 已更新: ${info.email || "?"}`, "ok");
            updateUserBar(info, "ok");
            onATReady();
          } else if (!at) {
            updateUserBar(null, "warn");
          }
        } catch (e) {
          log(`session 获取失败: ${e.message}`, "warn");
          updateUserBar(null, "err");
        }
      }
    
      // ---------- 发请求 ----------
      async function sendOne(wsId, route, attempt) {
        attempt = attempt || 0;
        const url = `/backend-api/accounts/${wsId}/invites/${route}`;
        const headers = {
          accept: "*/*",
          authorization: "Bearer " + STATE.at,
          "content-type": "application/json",
          "oai-device-id": STATE.deviceId,
          "oai-language": navigator.language || "en-US",
        };
        log(`→ POST /accounts/${wsId.slice(0,8)}/invites/${route} (第 ${attempt+1} 次)`);
        try {
          const res = await fetch(url, {
            method: "POST", headers, body: "", mode: "cors", credentials: "include",
          });
          const text = await res.text();
          if (res.ok) {
            log(`✓ ${wsId.slice(0,8)} HTTP ${res.status}: ${text}`, "ok");
            return true;
          }
          log(`✗ ${wsId.slice(0,8)} HTTP ${res.status}: ${text.slice(0,180)}`, "warn");
          if (res.status === 401 || res.status === 403) {
            log("子号 AT 失效,刷新 session...", "warn");
            STATE.at = "";
            await refreshSession();
            if (attempt < CONFIG.maxRetries) {
              await sleep(2000);
              return sendOne(wsId, route, attempt + 1);
            }
            return false;
          }
          if (attempt < CONFIG.maxRetries) {
            await sleep(CONFIG.retryBackoffMs * (attempt + 1));
            return sendOne(wsId, route, attempt + 1);
          }
          return false;
        } catch (e) {
          log(`网络错误: ${e.message}`, "err");
          if (attempt < CONFIG.maxRetries) {
            await sleep(CONFIG.retryBackoffMs);
            return sendOne(wsId, route, attempt + 1);
          }
          return false;
        }
      }
    
      function parseWorkspaceIds() {
        return CONFIG.workspaceIds.split(/[\n,]+/).map(s => s.trim()).filter(Boolean);
      }
    
      async function runAll(route) {
        if (STATE.running) { log("正在运行中,请稍候", "warn"); return; }
        if (!STATE.at) {
          log("无可用 AT,刷新 session...", "warn");
          await refreshSession();
          if (!STATE.at) { log("仍未取到 AT,请先登录 chatgpt.com", "err"); return; }
        }
        const ids = parseWorkspaceIds();
        if (!ids.length) { log("未配置 workspace ID", "err"); return; }
    
        STATE.running = true;
        setBtns(false);
        log(`开始处理 ${ids.length} 个 workspace(${route})`, "info");
        let ok = 0;
        for (const ws of ids) {
          const r = await sendOne(ws, route);
          if (r) ok++;
          if (ids.length > 1) await sleep(CONFIG.intervalMs);
        }
        log(`完成:成功 ${ok}/${ids.length}`, ok === ids.length ? "ok" : "warn");
        STATE.running = false;
        setBtns(true);
      }
    
      function onATReady() {
        if (!STATE.autoRan) {
          STATE.autoRan = true;
          runAll("request");
        }
      }
    
      function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
    
      // ---------- UI ----------
      let panelBody, userBarEl, reqBtnEl, accBtnEl, wsInputEl, saveBtnEl, dirty = false;
    
      function setBtns(enabled) {
        [reqBtnEl, accBtnEl].forEach(b => {
          if (b) { b.disabled = !enabled; b.style.opacity = enabled ? "1" : "0.5"; }
        });
      }
    
      function updateUserBar(info, status) {
        if (!userBarEl) return;
        const c = { ok: "#2f855a", warn: "#b7791f", err: "#c53030" };
        if (info && info.email) {
          userBarEl.innerHTML =
            `<span style="color:${c.ok}">●</span> <b>${info.email}</b> · ${info.plan_type||"?"} · ` +
            `<code style="background:#edf2f7;padding:1px 4px;border-radius:3px">${(info.account_id||"").slice(0,8)}</code> · ` +
            `<span style="color:#718096">${fmtExp(info.exp)}</span>`;
        } else {
          const msg = status === "err" ? "session 获取失败,请确认已登录" : "未检测到 AT,等待登录...";
          userBarEl.innerHTML = `<span style="color:${c[status]||c.warn}">●</span> ${msg}`;
        }
      }
    
      function markDirty() {
        dirty = true;
        if (saveBtnEl) {
          saveBtnEl.textContent = "保存 *";
          saveBtnEl.style.background = "#d69e2e";
          saveBtnEl.style.color = "#fff";
        }
      }
    
      function markClean() {
        dirty = false;
        if (saveBtnEl) {
          saveBtnEl.textContent = "已保存";
          saveBtnEl.style.background = "#38a169";
          saveBtnEl.style.color = "#fff";
        }
        setTimeout(() => {
          if (!dirty && saveBtnEl) {
            saveBtnEl.textContent = "保存";
            saveBtnEl.style.background = "#edf2f7";
            saveBtnEl.style.color = "#4a5568";
          }
        }, 1500);
      }
    
      function buildPanel() {
        const css = `
          .jr-panel{position:fixed;top:14px;right:14px;width:${CONFIG.panelWidth}px;
            background:#fff;border:1px solid #e2e8f0;border-radius:14px;
            box-shadow:0 12px 32px rgba(0,0,0,.16);z-index:99999;
            font:13px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#1a202c;overflow:hidden}
          .jr-head{padding:11px 16px;background:linear-gradient(135deg,#3182ce,#2b6cb0);color:#fff;
            display:flex;justify-content:space-between;align-items:center}
          .jr-title{font-weight:600;font-size:13px;letter-spacing:.3px;display:flex;align-items:center;gap:6px}
          .jr-title svg{width:16px;height:16px;fill:#fff}
          .jr-ver{font-size:11px;opacity:.85;background:rgba(255,255,255,.2);padding:1px 6px;border-radius:8px}
          .jr-sub{padding:9px 16px;background:#f7fafc;border-bottom:1px solid #edf2f7;font-size:12px;color:#4a5568;min-height:22px}
          .jr-sec{padding:12px 16px;border-bottom:1px solid #edf2f7}
          .jr-label{display:flex;justify-content:space-between;align-items:center;font-size:11px;color:#718096;
            margin-bottom:6px;font-weight:600;letter-spacing:.4px;text-transform:uppercase}
          .jr-label .jr-count{font-size:10px;color:#a0aec0;font-weight:400;text-transform:none;letter-spacing:0}
          .jr-ta{width:100%;box-sizing:border-box;border:1px solid #e2e8f0;border-radius:8px;
            padding:8px 10px;font:12px/1.5 monospace;color:#2d3748;background:#fff;transition:.15s;min-height:64px;resize:vertical}
          .jr-ta:focus{outline:0;border-color:#3182ce;box-shadow:0 0 0 3px rgba(49,130,206,.12)}
          .jr-save-row{display:flex;justify-content:flex-end;margin-top:8px}
          .jr-body{padding:10px 16px;max-height:36vh;overflow:auto}
          .jr-foot{padding:10px 16px;border-top:1px solid #edf2f7;display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap}
          .jr-line{padding:3px 0;word-break:break-all;border-bottom:1px dashed #f1f5f9}
          .jr-line:last-child{border-bottom:0}
          .jr-info{color:#2b6cb0}.jr-ok{color:#2f855a}.jr-warn{color:#b7791f}.jr-err{color:#c53030}
          .jr-btn{cursor:pointer;border:0;border-radius:7px;padding:7px 14px;font-size:12px;font-weight:500;transition:.15s}
          .jr-btn-primary{background:#3182ce;color:#fff}.jr-btn-primary:hover{background:#2b6cb0}
          .jr-btn-green{background:#38a169;color:#fff}.jr-btn-green:hover{background:#2f855a}
          .jr-btn-ghost{background:#edf2f7;color:#4a5568}.jr-btn-ghost:hover{background:#e2e8f0}
          .jr-btn:disabled{cursor:not-allowed;opacity:.5}
          .jr-hint{font-size:11px;color:#a0aec0;padding:6px 0 0 0;line-height:1.5}
        `;
        const style = document.createElement("style");
        style.textContent = css;
        document.head.appendChild(style);
    
        const p = document.createElement("div");
        p.className = "jr-panel";
        p.innerHTML = `
          <div class="jr-head">
            <span class="jr-title">
              <svg viewBox="0 0 24 24"><path d="M15 4l6 6-10 10H5v-6L15 4zm-1 1L7 12l5 5 7-7-5-5z"/></svg>
              Workspace Join Request
            </span>
            <span class="jr-ver">v4.0</span>
          </div>
          <div class="jr-sub" id="jr-user">未检测到 AT,等待登录...</div>
    
          <div class="jr-sec">
            <label class="jr-label">
              <span>母号 Workspace ID</span>
              <span class="jr-count" id="jr-count">0 个</span>
            </label>
            <textarea class="jr-ta" id="jr-ws" placeholder="一行一个 UUID&#10;acfb4e38-524c-4dc8-b4cf-fb3d0ce28b25"></textarea>
            <div class="jr-save-row">
              <button class="jr-btn jr-btn-ghost" id="jr-save" style="padding:5px 14px">保存</button>
            </div>
            <div class="jr-hint">只需子号 AT + workspace ID。request = 主动申请加入;accept = 接受已有邀请。</div>
          </div>
    
          <div class="jr-body" id="jr-body"></div>
    
          <div class="jr-foot">
            <button class="jr-btn jr-btn-ghost" id="jr-refresh">刷新 AT</button>
            <button class="jr-btn jr-btn-green" id="jr-accept">Accept</button>
            <button class="jr-btn jr-btn-primary" id="jr-run">Request</button>
          </div>
        `;
        document.body.appendChild(p);
    
        panelBody = p.querySelector("#jr-body");
        userBarEl = p.querySelector("#jr-user");
        reqBtnEl = p.querySelector("#jr-run");
        accBtnEl = p.querySelector("#jr-accept");
        wsInputEl = p.querySelector("#jr-ws");
        saveBtnEl = p.querySelector("#jr-save");
        const countEl = p.querySelector("#jr-count");
    
        // 填入已保存值
        wsInputEl.value = CONFIG.workspaceIds;
        const updateCount = () => {
          const n = wsInputEl.value.split(/[\n,]+/).map(s=>s.trim()).filter(Boolean).length;
          countEl.textContent = `${n} 个`;
        };
        updateCount();
    
        // 编辑标记 dirty
        wsInputEl.addEventListener("input", () => {
          markDirty();
          updateCount();
        });
    
        // 保存
        saveBtnEl.addEventListener("click", () => {
          CONFIG.workspaceIds = wsInputEl.value;
          saveConfig(CONFIG);
          markClean();
          log("workspace 已保存", "ok");
        });
    
        // 按钮
        reqBtnEl.addEventListener("click", () => runAll("request"));
        accBtnEl.addEventListener("click", () => runAll("accept"));
        p.querySelector("#jr-refresh").addEventListener("click", async () => {
          log("手动刷新 session...", "info");
          await refreshSession();
        });
      }
    
      function log(msg, level) {
        const styles = { info: "jr-info", ok: "jr-ok", warn: "jr-warn", err: "jr-err" };
        const time = new Date().toLocaleTimeString();
        console.log("%c[JoinReq]", "color:#3182ce;font-weight:bold", msg);
        if (panelBody) {
          const line = document.createElement("div");
          line.className = `jr-line ${styles[level] || "jr-info"}`;
          line.textContent = `[${time}] ${msg}`;
          panelBody.appendChild(line);
          panelBody.scrollTop = panelBody.scrollHeight;
        }
      }
    
      // ---------- 启动 ----------
      function boot() {
        buildPanel();
        log("脚本已加载 v4.0", "info");
        log("只需子号 AT + workspace ID", "info");
        log("request = 主动申请 · accept = 接受邀请", "info");
        refreshSession();
        setInterval(refreshSession, CONFIG.sessionPollMs);
        window.addEventListener("focus", () => { if (!STATE.running) refreshSession(); });
      }
    
      if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", boot);
      } else {
        boot();
      }
    })();
    
    

    唐宋元明清,连排小工兵!

    1 条回复 最后回复
    0
    • 我是小马甲~M 在线
      我是小马甲~M 在线
      我是小马甲~
      🤫
      编写于 最后由 编辑
      #2

      255de4a6-96a4-430a-b660-358954424e79
      outlook.com邮箱

      唐宋元明清,连排小工兵!

      1 条回复 最后回复
      0
      • keithK 在线
        keithK 在线
        keith
        🍌
        编写于 最后由 编辑
        #3

        需要提前注册好 ChatGPT 吗?感觉现在注册新号有点难

        我是小马甲~M 1 条回复 最后回复
        0
        • keithK keith

          需要提前注册好 ChatGPT 吗?感觉现在注册新号有点难

          我是小马甲~M 在线
          我是小马甲~M 在线
          我是小马甲~
          🤫
          编写于 最后由 malaohu 编辑
          #4

          @keith
          不难,下面是一些微软邮箱和密码
          1,用下面的邮箱 注册ChatGPT
          2,登录ChatGPT
          3,F12 粘贴主贴的脚本
          4,母号 Workspace ID 输入2楼的ID
          5,点击请求 加入

          账号:ztiqhjusjmuhsxpbqf@outlook.com  密码:FLEdojBO617
          账号:mmvxyfypvtfwsmseng@outlook.com  密码:GJxtpLE3103
          账号:aazzkqathyjaundyfb@outlook.com  密码:XPzruzAr104
          账号:reocjqwpzrbwlimspd@outlook.com  密码:ABEswyzE063
          账号:zfvwnqhepdqesmgnaq@outlook.com  密码:WHiwbCe4882
          账号:whywtndsjwcogzhoui@outlook.com  密码:KScknhID633
          账号:wcvimjahnkbtawwvps@outlook.com  密码:RXLwmwZkR7413
          账号:twtvxadctnwvtsiryu@outlook.com  密码:YTcxlvJ153
          账号:qufaqeiieemfxkmwio@outlook.com  密码:PPLzpdtqR832
          账号:pdkzxqgqldsmpzhlwz@outlook.com  密码:UVXhrvxeX6317
          账号:jvskdefxqqcpoqqlnp@outlook.com  密码:PMmnexFe633
          账号:qhlkzrbkydpavfrwek@outlook.com  密码:MYrsvZyE9044
          账号:ldoefdttkdmpuohmfy@outlook.com  密码:HZvxfXj248
          账号:bvzporwxwfrzgoeult@outlook.com  密码:ILNyrPG027
          账号:aaevqvwmdxhrgihntc@outlook.com  密码:FVxlCd2731
          账号:evwlvhkxvmihvkagra@outlook.com  密码:BERlifdxe390
          账号:zjlipeserivhldxtep@outlook.com  密码:HNscNgA2818
          账号:zyylgbnaoelavzvwdu@outlook.com  密码:AOtfkxU428
          

          唐宋元明清,连排小工兵!

          1 条回复 最后回复
          1

          你好!看起来您对这段对话很感兴趣,但您还没有一个账号。

          厌倦了每次访问都刷到同样的帖子?您注册账号后,您每次返回时都能精准定位到您上次浏览的位置,并可选择接收新回复通知(通过邮件或推送通知)。您还能收藏书签、为帖子顶,向社区成员表达您的欣赏。

          有了你的建议,这篇帖子会更精彩哦 💗

          注册 登录
          回复
          • 在新帖中回复
          登录后回复
          • 从旧到新
          • 从新到旧
          • 最多赞同


          Popular Topics - 热门主题
          • 京东游跟进了0元体重秤
            游魂Y
            游魂
            1
            7
            1.1k

          • 中国广电免费领取30G通用数据流量
            A
            amly
            1
            5
            537

          • 这俩天很火的强制进入ChatGPT K12 脚本
            我是小马甲~M
            我是小马甲~
            0
            4
            116

          • 河北移动放心用流量免费办理 8元套餐可办理!
            游魂Y
            游魂
            0
            4
            219

          • Win 10 RTM Professional Volume:MAK
            V
            vip0546
            0
            3
            53

          • [Android] zip解压缩管理-全格式压缩包一键解压+打包
            0
            1
            1


          • 登录

          • 没有帐号? 注册

          • 登录或注册以进行搜索。
          夸克网盘
          4,399 个主题
          百度网盘
          4,336 个主题
          连续剧
          1,519 个主题
          国产剧
          1,027 个主题
          美剧
          709 个主题
          动作片
          662 个主题
          恐怖片
          529 个主题
          动画片
          401 个主题

          128

          在线

          44.0k

          用户

          50.1k

          主题

          126.1k

          帖子
          • 第一个帖子
            最后一个帖子