// ==UserScript== // @name Team长链接 // @namespace local.long2.checkout // @version 1.0.0 // @description 在 ChatGPT 页面中输入可修改参数,并提取官方返回的长链接。 // @author local // @match https://chatgpt.com/* // @match https://chat.openai.com/* // @grant GM_setClipboard // @run-at document-start // @noframes // ==/UserScript== (function () { "use strict"; const DEFAULTS = { coupon: "", // 可修改 workspaceName: "workspace", // 可自行修改 country: "US", // 可修改 currency: "USD", // 可修改 cancelPromoCode: "", // 只修改 cancel_url 里 promoCode= 后面的值 }; const FIXED = { planName: "chatgptteamplan", priceInterval: "month", seatQuantity: 2, checkoutUiMode: "hosted", }; const css = ` #long2-checkout-panel { position: fixed; right: 18px; bottom: 18px; z-index: 2147483647; width: min(380px, calc(100vw - 28px)); color: #111827; background: #ffffff; border: 1px solid #d1d5db; border-radius: 8px; box-shadow: 0 18px 46px rgba(17, 24, 39, 0.18); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; font-size: 13px; line-height: 1.4; } #long2-checkout-panel * { box-sizing: border-box; } #long2-checkout-panel header { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border-bottom: 1px solid #e5e7eb; font-weight: 700; } #long2-checkout-panel .long2-body { display: grid; gap: 9px; padding: 12px; } #long2-checkout-panel label { display: grid; gap: 4px; color: #374151; font-weight: 600; } #long2-checkout-panel input, #long2-checkout-panel textarea { width: 100%; min-height: 34px; color: #111827; background: #ffffff; border: 1px solid #cbd5e1; border-radius: 6px; padding: 7px 8px; font: inherit; outline: none; } #long2-checkout-panel textarea { min-height: 88px; resize: vertical; word-break: break-all; } #long2-checkout-panel .long2-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } #long2-checkout-panel .long2-hint { margin-top: -2px; color: #6b7280; font-size: 12px; font-weight: 500; } #long2-checkout-panel .long2-actions { display: flex; gap: 8px; flex-wrap: wrap; } #long2-checkout-panel button, #long2-checkout-launch { min-height: 34px; border: 1px solid #9ca3af; border-radius: 6px; padding: 7px 10px; color: #111827; background: #f9fafb; font: inherit; font-weight: 650; cursor: pointer; } #long2-checkout-panel button:hover, #long2-checkout-launch:hover { background: #f3f4f6; } #long2-checkout-panel .long2-primary, #long2-checkout-launch { color: #ffffff; background: #2563eb; border-color: #2563eb; } #long2-checkout-panel .long2-primary:hover, #long2-checkout-launch:hover { background: #1d4ed8; } #long2-checkout-panel .long2-close { width: 28px; min-height: 28px; padding: 0; border-color: transparent; background: transparent; font-size: 18px; line-height: 1; } #long2-checkout-panel .long2-status { min-height: 18px; color: #4b5563; overflow-wrap: anywhere; } #long2-checkout-panel .long2-status.is-error { color: #b91c1c; } #long2-checkout-panel .long2-status.is-ok { color: #047857; } #long2-checkout-launch { position: fixed; right: 18px; bottom: 18px; z-index: 2147483646; min-height: 38px; border-radius: 8px; box-shadow: 0 12px 30px rgba(37, 99, 235, 0.25); font: 650 13px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; } `; let panel; let launcher; function addCss() { const style = document.createElement("style"); style.textContent = css; document.head.appendChild(style); } function getInput(id) { return panel.querySelector(`#${id}`).value.trim(); } function setStatus(message, state) { const status = panel.querySelector("#long2-status"); status.textContent = message; status.className = `long2-status${state ? ` is-${state}` : ""}`; } function buildCancelUrl() { const cancelPromoCode = getInput("long2-cancel-promo") || DEFAULTS.cancelPromoCode; return `https://chatgpt.com/?promoCode=${encodeURIComponent(cancelPromoCode)}`; } function buildPayload() { const coupon = getInput("long2-coupon") || DEFAULTS.coupon; return { plan_name: FIXED.planName, team_plan_data: { workspace_name: getInput("long2-workspace") || DEFAULTS.workspaceName, price_interval: FIXED.priceInterval, seat_quantity: FIXED.seatQuantity, }, billing_details: { country: (getInput("long2-country") || DEFAULTS.country).toUpperCase(), currency: (getInput("long2-currency") || DEFAULTS.currency).toUpperCase(), }, cancel_url: buildCancelUrl(), promo_code: coupon, checkout_ui_mode: FIXED.checkoutUiMode, }; } async function getAccessToken() { const response = await fetch("/api/auth/session", { credentials: "include", }); if (!response.ok) { throw new Error(`获取 Token 失败:HTTP ${response.status}`); } const session = await response.json(); if (!session?.accessToken) { throw new Error("accessToken 为空,请确认当前页面已经登录。"); } return session.accessToken; } async function generateLink() { const button = panel.querySelector("#long2-generate"); const output = panel.querySelector("#long2-output"); button.disabled = true; output.value = ""; setStatus("正在获取 Session Token...", ""); try { const accessToken = await getAccessToken(); const payload = buildPayload(); setStatus("正在请求 长链接...", ""); const response = await fetch("https://chatgpt.com/backend-api/payments/checkout", { method: "POST", credentials: "include", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify(payload), }); const data = await response.json().catch(() => ({})); if (!response.ok) { throw new Error(`请求失败 HTTP ${response.status}:${JSON.stringify(data)}`); } const hostedUrl = data?.url || data?.stripe_hosted_url || data?.checkout_url; if (!hostedUrl) { throw new Error(`未找到长链接,原始响应:${JSON.stringify(data)}`); } output.value = hostedUrl; setStatus("ChatGPT Team 链接生成成功。", "ok"); } catch (error) { setStatus(error.message || String(error), "error"); console.error("[long2 checkout]", error); } finally { button.disabled = false; } } async function copyLink() { const output = panel.querySelector("#long2-output"); if (!output.value) { setStatus("当前没有可复制的长链接。", "error"); return; } if (typeof GM_setClipboard === "function") { GM_setClipboard(output.value, "text"); } else { await navigator.clipboard.writeText(output.value); } setStatus("长链接已复制。", "ok"); } function createPanel() { panel = document.createElement("section"); panel.id = "long2-checkout-panel"; panel.innerHTML = `
ChatGPT Team 长链接
实际 cancel_url 固定为 https://chatgpt.com/?promoCode=输入值
`; document.body.appendChild(panel); panel.querySelector("#long2-generate").addEventListener("click", generateLink); panel.querySelector("#long2-copy").addEventListener("click", copyLink); panel.querySelector("#long2-close").addEventListener("click", hidePanel); } function createLauncher() { launcher = document.createElement("button"); launcher.id = "long2-checkout-launch"; launcher.type = "button"; launcher.textContent = "长链接"; launcher.addEventListener("click", showPanel); document.body.appendChild(launcher); } function showPanel() { panel.hidden = false; launcher.hidden = true; } function hidePanel() { panel.hidden = true; launcher.hidden = false; } function init() { if (document.getElementById("long2-checkout-panel")) return; if (!document.body) { window.setTimeout(init, 100); return; } addCss(); createPanel(); createLauncher(); showPanel(); console.log("[long2 checkout] 面板已加载"); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init, { once: true }); window.setTimeout(init, 1500); } else { init(); } })();