帖子

  • GodKing

    食用方法 ^-^

    1、执行脚本

    网页端登录chatgpt账号,f12执行以下脚本```
    (async () => {
    const uuid = () =>
    crypto.randomUUID?.() ||
    "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
    const r = (Math.random() * 16) | 0;
    return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
    });

    // 1) 取 Web access token
    const sess = await fetch("/api/auth/session", { credentials: "include" }).then((r) => r.json());
    const accessToken = sess?.accessToken;
    if (!accessToken) throw new Error("未拿到 accessToken,确认已登录 chatgpt.com");

    // 2) 设备 / 会话 id(尽量复用页面已有值)
    const deviceId =
    localStorage.getItem("oai-device-id") ||
    document.cookie.match(/(?:^|;\s*)oai-did=([^;]+)/)?.[1] ||
    uuid();
    const sessionId =
    sessionStorage.getItem("oai-session-id") ||
    localStorage.getItem("oai-session-id") ||
    uuid();

    // 3) 取账号列表,筛 Team workspace
    const accountsRes = await fetch("https://chatgpt.com/backend-api/accounts/check/v4-2023-04-27", {
    headers: {
    Authorization: Bearer ${accessToken},
    "oai-device-id": deviceId,
    "oai-session-id": sessionId,
    },
    credentials: "include",
    }).then((r) => r.json());

    const accounts = Object.entries(accountsRes?.accounts || {}).map(([id, v]) => ({
    account_id: id,
    plan_type: v?.account?.plan_type,
    structure: v?.account?.structure,
    name: v?.account?.name,
    is_deactivated: v?.account?.is_deactivated,
    }));

    const teams = accounts.filter(
    (a) =>
    !a.is_deactivated &&
    (a.structure === "workspace" ||
    a.plan_type === "team" ||
    a.plan_type === "business" ||
    String(a.plan_type || "").includes("team"))
    );

    if (!teams.length) {
    console.warn("未找到 Team/Business workspace,全部账号:", accounts);
    console.log("accessToken 前缀:", accessToken.slice(0, 20) + "...");
    return { accessToken, accounts, invoices: [] };
    }

    // 4) 拉每个 Team 的下期预计账单
    const invoices = [];
    for (const t of teams) {
    const accountId = t.account_id;
    const encoded = encodeURIComponent(accountId);
    const path = /backend-api/invoices/upcoming?account_id=${encoded};
    const res = await fetch(https://chatgpt.com${path}, {
    method: "GET",
    headers: {
    Authorization: Bearer ${accessToken},
    "chatgpt-account-id": accountId,
    "oai-device-id": deviceId,
    "oai-session-id": sessionId,
    "x-openai-target-path": path,
    "x-openai-target-route": path,
    },
    credentials: "include",
    });
    const text = await res.text();
    let body;
    try {
    body = JSON.parse(text);
    } catch {
    body = text;
    }
    const amountDue = body?.amount_due ?? body?.total;
    const currency = (body?.currency || "").toUpperCase();
    const major =
    typeof amountDue === "number" ? (amountDue / 100).toFixed(2) : null;

    invoices.push({
    account_id: accountId,
    name: t.name,
    plan_type: t.plan_type,
    http_status: res.status,
    amount_due_minor: amountDue,
    amount_due_display: major != null && currency ? ${currency} ${major} : null,
    subtotal: body?.subtotal,
    total: body?.total,
    currency: body?.currency,
    period_start: body?.period_start,
    period_end: body?.period_end,
    next_payment_attempt: body?.next_payment_attempt,
    customer_email: body?.customer_email,
    lines: body?.lines?.data?.map((l) => ({
    description: l.description,
    quantity: l.quantity,
    amount: l.amount,
    unit_amount: l.price?.unit_amount ?? l.plan?.amount,
    })),
    raw: body,
    });
    }

    console.table(
    invoices.map(({ account_id, name, plan_type, http_status, amount_due_display, customer_email }) => ({
    account_id,
    name,
    plan_type,
    http_status,
    amount_due_display,
    customer_email,
    }))
    );
    console.log("完整结果:", invoices);
    return { accessToken, deviceId, sessionId, accounts, teams, invoices };
    })().catch((e) => console.error(e));
    ```2、network 搜索

    搜索这个接口 backend-api/invoices/upcoming ,查看response

    可以把返回的json直接丢给ai给你分析账单信息(grok5秒就出来了 ^-^)

    图片

    3、账单示例

    图片

    4、参考字段

    图片

    主楼
  • Sinohunk

    补充一下,建议大家以续费前看到的账单为准,你现在看的下期账单和续费前看的账单可能不一样,做了什么骚操作的话要考虑cd,比如踢人依然会有七天的cd,时间不够的话也就是会计入下一期账单

    #1

发表回复

登录后回复