codex重置机会的具体过期时间是什么时候?

Ensoul 2026-06-24 08:48 1

codex重置机会过期时间是你获得重置机会的时间的一个月后还是活动结束的一个月后?


还想等着gpt5.6出来后狠狠的蹬 ^-^

最新回复 (3)
  • orzlee 06-24 08:52
    1

    好像是说领取后30天有效期吧,超过就没了!

  • daom 06-24 11:29
    2

    按获得时间计算 可以调接口查,脚本参考一下


    #!/usr/bin/env python3
    """
    Fetch Codex/WHAM usage-related ChatGPT backend endpoints with the local Codex auth.

    The script reads ~/.codex/auth.json by default, extracts the bearer token, then calls:
    - https://chatgpt.com/backend-api/wham/usage
    - https://chatgpt.com/backend-api/wham/rate-limit-reset-credits
    - https://chatgpt.com/backend-api/wham/referrals/eligibility_rules?referral_key=codex_referral_persistent_invite

    It never prints the token. By default it prints a Chinese human-readable summary.
    Use --json to print raw data.
    """

    from __future__ import annotations

    import argparse
    import json
    import os
    import sys
    import urllib.error
    import urllib.request
    from dataclasses import dataclass
    from pathlib import Path
    from typing import Any

    DEFAULT_ENDPOINTS = [
    "https://chatgpt.com/backend-api/wham/usage",
    "https://chatgpt.com/backend-api/wham/rate-limit-reset-credits",
    "https://chatgpt.com/backend-api/wham/referrals/eligibility_rules?referral_key=codex_referral_persistent_invite",
    ]

    ENDPOINT_TITLES = {
    "https://chatgpt.com/backend-api/wham/usage": "Codex 用量",
    "https://chatgpt.com/backend-api/wham/rate-limit-reset-credits": "重置次数 / 额度",
    "https://chatgpt.com/backend-api/wham/referrals/eligibility_rules?referral_key=codex_referral_persistent_invite": "邀请资格规则",
    }

    FIELD_LABELS = {
    "account_id": "账户 ID",
    "available": "可用",
    "available_credits": "可用额度",
    "balance": "余额",
    "code": "错误代码",
    "count": "数量",
    "created_at": "创建时间",
    "credits": "额度",
    "daily_limit": "每日限制",
    "eligible": "是否符合资格",
    "eligibility": "资格",
    "enabled": "是否启用",
    "error": "错误",
    "expires_at": "过期时间",
    "granted": "已发放",
    "hard_limit": "硬限制",
    "is_eligible": "是否符合资格",
    "limit": "限制",
    "limit_remaining": "剩余额度",
    "message": "消息",
    "model": "模型",
    "next_reset_at": "下次重置时间",
    "period": "周期",
    "plan": "套餐",
    "quota": "配额",
    "rate_limit": "速率限制",
    "remaining": "剩余",
    "remaining_credits": "剩余次数",
    "reset": "重置",
    "reset_at": "重置时间",
    "reset_credits": "重置次数",
    "reset_time": "重置时间",
    "soft_limit": "软限制",
    "status": "状态",
    "total": "总计",
    "total_credits": "总次数",
    "type": "类型",
    "updated_at": "更新时间",
    "usage": "用量",
    "used": "已用",
    "used_credits": "已用次数",
    }

    @dataclass(frozen=True)
    class CodexAuth:
    token: str
    token_source: str
    account_id: str | None = None

    def load_json(path: Path) -> dict[str, Any]:
    try:
    with path.open("r", encoding="utf-8") as f:
    data = json.load(f)
    except FileNotFoundError:
    raise SystemExit(f"auth file not found: {path}") from None
    except json.JSONDecodeError as exc:
    raise SystemExit(f"auth file is not valid JSON: {path}: {exc}") from None

    if not isinstance(data, dict):
    raise SystemExit(f"auth file root must be a JSON object: {path}")
    return data

    def first_string(data: dict[str, Any], paths: list[tuple[str, ...]]) -> tuple[str, str] | tuple[None, None]:
    for path in paths:
    current: Any = data
    for key in path:
    if not isinstance(current, dict) or key not in current:
    current = None
    break
    current = current[key]
    if isinstance(current, str) and current.strip():
    return current.strip(), ".".join(path)
    return None, None

    def extract_auth(data: dict[str, Any], token_kind: str) -> CodexAuth:
    access_paths = [
    ("tokens", "access_token"),
    ("tokens", "accessToken"),
    ("access_token",),
    ("accessToken",),
    ]
    id_paths = [
    ("tokens", "id_token"),
    ("tokens", "idToken"),
    ("id_token",),
    ("idToken",),
    ]

    if token_kind == "access":
    token, source = first_string(data, access_paths)
    elif token_kind == "id":
    token, source = first_string(data, id_paths)
    else:
    token, source = first_string(data, access_paths + id_paths)

    if not token or not source:
    raise SystemExit(
    "could not find a bearer token in auth.json. "
    "Tried tokens.access_token/accessToken and tokens.id_token/idToken. "
    "Run `codex login` again, or pass a different file with --auth."
    )

    account_id, _ = first_string(
    data,
    [
    ("tokens", "account_id"),
    ("tokens", "accountId"),
    ("account_id",),
    ("accountId",),
    ],
    )
    return CodexAuth(token=token, token_source=source, account_id=account_id)

    def decode_body(raw: bytes, content_type: str | None) -> Any:
    text = raw.decode("utf-8", errors="replace")
    if content_type and "json" in content_type.lower():
    try:
    return json.loads(text)
    except json.JSONDecodeError:
    return text

    stripped = text.strip()
    if stripped.startswith("{") or stripped.startswith("["):
    try:
    return json.loads(stripped)
    except json.JSONDecodeError:
    pass
    return text

    def request_json(url: str, auth: CodexAuth, timeout: float) -> dict[str, Any]:
    headers = {
    "Authorization": f"Bearer {auth.token}",
    "Accept": "application/json",
    "User-Agent": "codex-wham-usage-fetcher/1.0",
    "Origin": "https://chatgpt.com",
    "Referer": "https://chatgpt.com/codex",
    }
    if auth.account_id:
    headers["ChatGPT-Account-ID"] = auth.account_id

    req = urllib.request.Request(url=url, headers=headers, method="GET")
    try:
    with urllib.request.urlopen(req, timeout=timeout) as resp:
    raw = resp.read()
    return {
    "ok": 200 <= resp.status < 300,
    "status": resp.status,
    "url": url,
    "body": decode_body(raw, resp.headers.get("Content-Type")),
    }
    except urllib.error.HTTPError as exc:
    raw = exc.read()
    return {
    "ok": False,
    "status": exc.code,
    "url": url,
    "reason": exc.reason,
    "body": decode_body(raw, exc.headers.get("Content-Type")),
    }
    except urllib.error.URLError as exc:
    return {
    "ok": False,
    "status": None,
    "url": url,
    "reason": str(exc.reason),
    "body": None,
    }

    def label_for_key(key: str) -> str:
    if key in FIELD_LABELS:
    return FIELD_LABELS[key]
    return key.replace("_", " ")

    def format_scalar(value: Any) -> str:
    if value is True:
    return "是"
    if value is False:
    return "否"
    if value is None:
    return "无"
    if isinstance(value, (int, float)):
    return str(value)
    if isinstance(value, str):
    return value if value else "空字符串"
    return str(value)

    def format_body(body: Any, indent: int = 0) -> list[str]:
    prefix = " " * indent
    lines: list[str] = []

    if isinstance(body, dict):
    if not body:
    return [f"{prefix}- 无返回字段"]
    for key, value in body.items():
    label = label_for_key(str(key))
    if isinstance(value, dict):
    lines.append(f"{prefix}- {label}:")
    lines.extend(format_body(value, indent + 1))
    elif isinstance(value, list):
    lines.append(f"{prefix}- {label}:")
    lines.extend(format_body(value, indent + 1))
    else:
    lines.append(f"{prefix}- {label}: {format_scalar(value)}")
    return lines

    if isinstance(body, list):
    if not body:
    return [f"{prefix}- 空列表"]
    for index, item in enumerate(body, start=1):
    if isinstance(item, (dict, list)):
    lines.append(f"{prefix}- 第 {index} 项:")
    lines.extend(format_body(item, indent + 1))
    else:
    lines.append(f"{prefix}- 第 {index} 项: {format_scalar(item)}")
    return lines

    return [f"{prefix}- 内容: {format_scalar(body)}"]

    def format_text_report(results: dict[str, Any]) -> str:
    lines = [
    "Codex 用量与额度查询结果",
    "",
    f"认证文件: {results['auth_path']}",
    f"Token 来源: {results['token_source']}",
    f"是否包含账户 ID: {'是' if results['account_id_present'] else '否'}",
    "",
    ]

    for index, item in enumerate(results["results"], start=1):
    title = ENDPOINT_TITLES.get(item["url"], "自定义接口")
    ok_text = "成功" if item["ok"] else "失败"
    status = item["status"] if item["status"] is not None else "无状态码"
    lines.extend(
    [
    f"{index}. {title}",
    f"接口: {item['url']}",
    f"请求结果: {ok_text}",
    f"HTTP 状态: {status}",
    ]
    )
    if item.get("reason"):
    lines.append(f"失败原因: {item['reason']}")
    lines.append("返回信息:")
    lines.extend(format_body(item.get("body"), indent=1))
    lines.append("")

    return "\n".join(lines).rstrip() + "\n"

    def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(
    description="Fetch Codex WHAM usage/rate-limit/referral endpoint data using ~/.codex/auth.json."
    )
    parser.add_argument(
    "--auth",
    type=Path,
    default=Path.home() / ".codex" / "auth.json",
    help="Path to Codex auth.json. Default: ~/.codex/auth.json",
    )
    parser.add_argument(
    "--token-kind",
    choices=["auto", "access", "id"],
    default="auto",
    help="Which bearer token to use from auth.json. Default: auto",
    )
    parser.add_argument(
    "--timeout",
    type=float,
    default=30.0,
    help="HTTP timeout in seconds. Default: 30",
    )
    parser.add_argument(
    "--endpoint",
    action="append",
    dest="endpoints",
    help="Additional endpoint to fetch. Can be provided multiple times.",
    )
    parser.add_argument(
    "--only-extra-endpoints",
    action="store_true",
    help="Fetch only endpoints passed with --endpoint, skipping the built-in list.",
    )
    parser.add_argument(
    "--json",
    action="store_true",
    help="Print raw JSON instead of the default Chinese text report.",
    )
    return parser.parse_args()

    def main() -> int:
    args = parse_args()
    auth_path = args.auth.expanduser()
    auth_data = load_json(auth_path)
    auth = extract_auth(auth_data, args.token_kind)

    endpoints: list[str] = []
    if not args.only_extra_endpoints:
    endpoints.extend(DEFAULT_ENDPOINTS)
    if args.endpoints:
    endpoints.extend(args.endpoints)
    if not endpoints:
    raise SystemExit("no endpoints to fetch")

    results = {
    "auth_path": os.fspath(auth_path),
    "token_source": auth.token_source,
    "account_id_present": bool(auth.account_id),
    "results": [request_json(url, auth, args.timeout) for url in endpoints],
    }
    if args.json:
    json.dump(results, sys.stdout, ensure_ascii=False, indent=2)
    sys.stdout.write("\n")
    else:
    sys.stdout.write(format_text_report(results))
    return 0

    if __name__ == "__main__":
    raise SystemExit(main())

  • 💪 🎯 🚀 ☁️ 06-28 22:21
    3

    试试这个提示词:


    **帮我用本机 Codex 凭证查一下 rate-limit reset credits,读取 ~/.codex/auth.json 里的 tokens.access_token,请求https://chatgpt.com/backend-api/wham/rate-limit-reset-credits

    要求:



    1. 如果 401,说明是凭证失效或没带对Authorization header

    2. 不要打印 access_token、refresh_token、cookie或完整唯一 ID

    3. 只要展示每张重置卡发放时间和过期时间,从 UTC 转成北京时间,用中文回复**

* 帖子来源Linux.do
返回