您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
获取Augment API的访问令牌
// ==UserScript== // @name Augment API Token Tool // @namespace http://tampermonkey.net/ // @version 1.0 // @description 获取Augment API的访问令牌 // @author backgroundPower // @license MIT // @match https://*.augmentcode.com/* // @match https://augmentcode.com/* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_setClipboard // @grant unsafeWindow // @connect * // ==/UserScript== (function() { 'use strict'; const clientID = "v"; // 工具函数 function base64URLEncode(buffer) { return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer))) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=/g, ""); } async function sha256Hash(input) { const encoder = new TextEncoder(); const data = encoder.encode(input); const hashBuffer = await crypto.subtle.digest('SHA-256', data); return hashBuffer; } async function createOAuthState() { // 生成随机字节 const codeVerifierArray = new Uint8Array(32); window.crypto.getRandomValues(codeVerifierArray); const codeVerifier = base64URLEncode(codeVerifierArray.buffer); // 创建 code challenge const codeChallenge = base64URLEncode(await sha256Hash(codeVerifier)); // 生成随机 state const stateArray = new Uint8Array(8); window.crypto.getRandomValues(stateArray); const state = base64URLEncode(stateArray.buffer); const oauthState = { codeVerifier, codeChallenge, state, creationTime: Date.now() }; // 存储状态以供后续使用 GM_setValue('oauthState', JSON.stringify(oauthState)); return oauthState; } function generateAuthorizeURL(oauthState) { const params = new URLSearchParams({ response_type: "code", code_challenge: oauthState.codeChallenge, client_id: clientID, state: oauthState.state, prompt: "login", }); return `https://auth.augmentcode.com/authorize?${params.toString()}`; } // 解析授权码函数 function parseCode(code) { try { const parsed = JSON.parse(code); if (!parsed.code || !parsed.tenant_url) { throw new Error("缺少必要的code或tenant_url字段"); } return { code: parsed.code, state: parsed.state, tenant_url: parsed.tenant_url }; } catch (e) { throw new Error("JSON解析失败: " + e.message); } } async function getAccessToken(tenant_url, codeVerifier, code) { // 确保tenant_url以/结尾 if (!tenant_url.endsWith('/')) { tenant_url = tenant_url + '/'; } console.log("正在请求token..."); console.log("URL:", `${tenant_url}token`); console.log("codeVerifier:", codeVerifier); console.log("code:", code); const data = { grant_type: "authorization_code", client_id: clientID, code_verifier: codeVerifier, redirect_uri: "", code: code, }; console.log("请求数据:", JSON.stringify(data)); return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "POST", url: `${tenant_url}token`, headers: { "Content-Type": "application/json" }, data: JSON.stringify(data), onload: function(response) { try { console.log("API响应状态:", response.status); console.log("API响应头:", response.responseHeaders); console.log("API响应内容:", response.responseText); const json = JSON.parse(response.responseText); console.log("解析后的响应:", json); if (json.access_token) { resolve(json.access_token); } else { reject(`No access token found in response. Full response: ${JSON.stringify(json)}`); } } catch (e) { reject(`Error parsing response: ${e}. Raw response: ${response.responseText}`); } }, onerror: function(error) { console.error("请求错误:", error); reject(`Request error: ${error}`); } }); }); } // 启动认证流程 async function startAuthFlow() { const oauthState = await createOAuthState(); const url = generateAuthorizeURL(oauthState); window.location.href = url; } // 处理授权回调 function handleAuthCallback() { // 检查URL中是否有code参数 const urlParams = new URLSearchParams(window.location.search); const code = urlParams.get('code'); const state = urlParams.get('state'); if (code && state) { const storedState = GM_getValue('oauthState'); if (!storedState) { showMessage('认证状态丢失,请重试'); return; } const oauthState = JSON.parse(storedState); if (state !== oauthState.state) { showMessage('状态验证失败,可能存在安全风险'); return; } // 提取tenant_url const tenant_url = window.location.origin + '/'; // 构建结果对象 const result = { code: code, state: state, tenant_url: tenant_url }; // 显示结果 showMessage(` <h3>认证成功!</h3> <p>代码:${code}</p> <button id="getToken">获取令牌</button> `); document.getElementById('getToken').addEventListener('click', async () => { try { const token = await getAccessToken(tenant_url, oauthState.codeVerifier, code); GM_setValue('access_token', token); // 创建持久性浮窗 createCredentialsFloater(tenant_url, token); } catch (error) { showMessage(`获取令牌失败: ${error}`); } }); } } function sendChatMessage(tenant_url, token) { GM_xmlhttpRequest({ method: "POST", url: `${tenant_url}chat-stream`, headers: { "Content-Type": "application/json", "Authorization": `Bearer ${token}` }, data: JSON.stringify({ chat_history: [ { response_text: "你好! 我是 Augment,很高兴为你提供帮助。", request_message: "你好,我是用户" } ], message: "我叫什么名字", mode: "CHAT" }), onload: function(response) { showMessage(`<h3>聊天响应:</h3><pre>${response.responseText}</pre>`); }, onerror: function(error) { showMessage(`发送聊天请求失败: ${error}`); } }); } // 显示消息的UI函数 function showMessage(message, autoHide = false) { try { let messageDiv = document.getElementById('augment-api-message'); if (!messageDiv) { messageDiv = document.createElement('div'); messageDiv.id = 'augment-api-message'; messageDiv.style.cssText = ` position: fixed; bottom: 90px; right: 20px; background: white; border: 1px solid #ccc; padding: 20px; z-index: 10000; max-width: 400px; box-shadow: 0 0 10px rgba(0,0,0,0.2); border-radius: 5px; font-family: Arial, sans-serif; animation: fadeIn 0.3s; `; // 添加关闭按钮 const closeBtn = document.createElement('div'); closeBtn.style.cssText = ` position: absolute; top: 5px; right: 10px; cursor: pointer; font-size: 18px; color: #999; `; closeBtn.innerHTML = '×'; closeBtn.onclick = () => { messageDiv.style.display = 'none'; }; messageDiv.appendChild(closeBtn); document.body.appendChild(messageDiv); // 添加样式 const style = document.createElement('style'); style.textContent = ` @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } #augment-api-message button:hover { opacity: 0.9; } `; document.head.appendChild(style); } // 内容容器,避免覆盖关闭按钮 let contentDiv = messageDiv.querySelector('.message-content'); if (!contentDiv) { contentDiv = document.createElement('div'); contentDiv.className = 'message-content'; messageDiv.appendChild(contentDiv); } contentDiv.innerHTML = message; messageDiv.style.display = 'block'; // 如果设置了自动隐藏 if (autoHide) { setTimeout(() => { messageDiv.style.display = 'none'; }, 8000); } } catch (e) { console.error('显示消息时出错:', e); alert('Augment API Tool: ' + message.replace(/<[^>]*>/g, ' ')); } } // 显示JSON处理界面 function showJsonProcessingUI() { showMessage(` <h3>处理授权 JSON</h3> <p>请在下方粘贴授权码 JSON:</p> <textarea id="authCodeInput" style="width:100%;height:100px;margin:10px 0;padding:8px;border:1px solid #ccc;border-radius:4px;"></textarea> <button id="processAuthCode" style="background:#4285f4;color:white;padding:10px;border:none;border-radius:4px;cursor:pointer;width:100%;">处理授权码</button> `); document.getElementById('processAuthCode')?.addEventListener('click', processAuthCode); } // 处理授权码 function processAuthCode() { const authCodeInput = document.getElementById('authCodeInput'); const clipText = authCodeInput ? authCodeInput.value : ""; if (!clipText) { alert('请先输入授权码'); return; } // 将输入的代码发送到处理函数 const storedState = GM_getValue('oauthState'); if (!storedState) { showMessage('认证状态丢失,请重新开始流程'); return; } console.log("开始处理授权码..."); console.log("授权码原文:", clipText); const oauthState = JSON.parse(storedState); console.log("存储的OAuth状态:", oauthState); try { const parsedCode = parseCode(clipText); console.log("解析后的授权码数据:", parsedCode); if (parsedCode && parsedCode.code) { // 显示处理中的消息 showMessage(`<h3>正在处理...</h3><p>请稍候</p><pre style="font-size:12px;max-height:200px;overflow:auto;background:#f5f5f5;padding:5px;margin-top:10px;">正在向 ${parsedCode.tenant_url} 请求访问令牌...</pre>`); getAccessToken(parsedCode.tenant_url, oauthState.codeVerifier, parsedCode.code) .then(token => { console.log("成功获取令牌:", token); GM_setValue('access_token', token); // 创建持久性浮窗 createCredentialsFloater(parsedCode.tenant_url, token); }) .catch(err => { console.error("获取令牌失败:", err); // 尝试使用code作为token的后备方案 const tryUseCodeAsToken = confirm("获取令牌失败。可能是因为授权码无法转换为访问令牌。\n\n您想要尝试直接使用授权码(code)作为令牌吗?"); if (tryUseCodeAsToken) { console.log("使用code作为token:", parsedCode.code); createCredentialsFloater(parsedCode.tenant_url, parsedCode.code); } else { showMessage(`获取令牌失败: ${err}`); } }); } else { showMessage(`授权码格式不正确,请确保包含code和tenant_url信息`); } } catch (e) { showMessage(`解析授权码失败: ${e.message},请确保输入的是完整的JSON格式授权码`); } } // 注册(不可用)菜单命令 GM_registerMenuCommand("获取Augment API令牌", startAuthFlow); GM_registerMenuCommand("处理授权JSON", showJsonProcessingUI); // 确保DOM完全加载后执行 function init() { // 检查是否在授权回调页面 const currentUrl = window.location.href; if (currentUrl.includes('code=') && currentUrl.includes('state=')) { handleAuthCallback(); return; } // 检查是否在授权码复制页面 if (currentUrl.includes('augmentcode.com') && document.title.includes('Augment')) { // 尝试找到并自动点击复制按钮 setTimeout(() => { const copyButtons = Array.from(document.querySelectorAll('button')).filter(button => button.textContent && button.textContent.toLowerCase().includes('copy') ); if (copyButtons.length > 0) { console.log('找到复制按钮,自动点击...'); copyButtons[0].click(); } }, 1000); } // 只在 augmentcode.com 域名下显示界面元素 const isAugmentDomain = window.location.hostname.includes('augmentcode.com'); if (isAugmentDomain) { // 创建固定的悬浮菜单按钮 createFloatingMenu(); } else { console.log('Augment API Token Tool 已加载 - 仅在 augmentcode.com 显示界面'); } } // 创建浮动菜单 function createFloatingMenu() { // 创建菜单按钮 const menuBtn = document.createElement('div'); menuBtn.id = 'augment-api-menu-btn'; menuBtn.style.cssText = ` position: fixed; bottom: 20px; right: 20px; background: #4285f4; color: white; width: 50px; height: 50px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 20px; font-weight: bold; cursor: pointer; box-shadow: 0 2px 10px rgba(0,0,0,0.2); z-index: 9998; `; menuBtn.textContent = "A"; menuBtn.title = "Augment API 工具"; // 创建菜单容器 const menuContainer = document.createElement('div'); menuContainer.id = 'augment-api-menu'; menuContainer.style.cssText = ` position: fixed; bottom: 80px; right: 20px; background: white; border-radius: 5px; box-shadow: 0 2px 10px rgba(0,0,0,0.2); z-index: 9997; display: none; overflow: hidden; `; // 添加菜单项 const menuItems = [ { text: "1. 登录(不可用)获取授权 JSON", action: startAuthFlow }, { text: "2. 处理 JSON 信息", action: showJsonProcessingUI } ]; menuItems.forEach(item => { const menuItem = document.createElement('div'); menuItem.style.cssText = ` padding: 12px 20px; cursor: pointer; white-space: nowrap; border-bottom: 1px solid #eee; color: #000; `; menuItem.textContent = item.text; menuItem.onmouseover = () => menuItem.style.backgroundColor = '#f5f5f5'; menuItem.onmouseout = () => menuItem.style.backgroundColor = 'white'; menuItem.onclick = () => { menuContainer.style.display = 'none'; item.action(); }; menuContainer.appendChild(menuItem); }); // 点击按钮显示/隐藏菜单 menuBtn.onclick = () => { if (menuContainer.style.display === 'none') { menuContainer.style.display = 'block'; } else { menuContainer.style.display = 'none'; } }; // 点击其他地方隐藏菜单 document.addEventListener('click', (e) => { if (e.target !== menuBtn && !menuContainer.contains(e.target) && menuContainer.style.display === 'block') { menuContainer.style.display = 'none'; } }); // 添加到页面 document.body.appendChild(menuBtn); document.body.appendChild(menuContainer); console.log('Augment API Token Tool 已加载'); } // 确保DOM加载完成后执行初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } // 创建固定浮窗显示凭证信息 function createCredentialsFloater(tenant_url, token) { // 删除已有的浮窗(如果存在) const existingFloater = document.getElementById('augment-api-floater'); if (existingFloater) { existingFloater.remove(); } // 创建新浮窗 const floater = document.createElement('div'); floater.id = 'augment-api-floater'; floater.style.cssText = ` position: fixed; right: 20px; top: 20%; width: 350px; background: white; border: 1px solid #ccc; box-shadow: 0 0 10px rgba(0,0,0,0.2); border-radius: 5px; z-index: 9999; font-family: Arial, sans-serif; padding: 15px; `; // 添加标题栏 const header = document.createElement('div'); header.style.cssText = ` display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; border-bottom: 1px solid #eee; padding-bottom: 10px; `; const title = document.createElement('h3'); title.textContent = 'Augment API 凭证'; title.style.margin = '0'; const closeBtn = document.createElement('div'); closeBtn.innerHTML = '×'; closeBtn.style.cssText = ` cursor: pointer; font-size: 20px; color: #999; `; closeBtn.onclick = () => floater.style.display = 'none'; header.appendChild(title); header.appendChild(closeBtn); floater.appendChild(header); // 内容区域 const content = document.createElement('div'); // tenant_url 部分 const tenantUrlDiv = document.createElement('div'); tenantUrlDiv.style.marginBottom = '15px'; const tenantUrlLabel = document.createElement('div'); tenantUrlLabel.innerHTML = '<strong>tenant_url:</strong>'; tenantUrlLabel.style.marginBottom = '5px'; const tenantUrlValue = document.createElement('div'); tenantUrlValue.textContent = tenant_url; tenantUrlValue.style.cssText = ` padding: 8px; background: #f5f5f5; border-radius: 4px; word-break: break-all; font-family: monospace; margin-bottom: 5px; `; const copyTenantUrlBtn = document.createElement('button'); copyTenantUrlBtn.textContent = '复制 tenant_url'; copyTenantUrlBtn.style.cssText = ` background: #4285f4; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; font-size: 12px; `; copyTenantUrlBtn.onclick = () => { GM_setClipboard(tenant_url); copyTenantUrlBtn.textContent = '✓ 已复制'; setTimeout(() => { copyTenantUrlBtn.textContent = '复制 tenant_url'; }, 1500); }; tenantUrlDiv.appendChild(tenantUrlLabel); tenantUrlDiv.appendChild(tenantUrlValue); tenantUrlDiv.appendChild(copyTenantUrlBtn); // token 部分 const tokenDiv = document.createElement('div'); const tokenLabel = document.createElement('div'); tokenLabel.innerHTML = '<strong>token:</strong>'; tokenLabel.style.marginBottom = '5px'; const tokenValue = document.createElement('div'); tokenValue.textContent = token; tokenValue.style.cssText = ` padding: 8px; background: #f5f5f5; border-radius: 4px; word-break: break-all; font-family: monospace; margin-bottom: 5px; max-height: 100px; overflow-y: auto; font-size: 12px; `; const copyTokenBtn = document.createElement('button'); copyTokenBtn.textContent = '复制 token'; copyTokenBtn.style.cssText = ` background: #4285f4; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; font-size: 12px; `; copyTokenBtn.onclick = () => { GM_setClipboard(token); copyTokenBtn.textContent = '✓ 已复制'; setTimeout(() => { copyTokenBtn.textContent = '复制 token'; }, 1500); }; tokenDiv.appendChild(tokenLabel); tokenDiv.appendChild(tokenValue); tokenDiv.appendChild(copyTokenBtn); content.appendChild(tenantUrlDiv); content.appendChild(tokenDiv); floater.appendChild(content); // 添加到页面 document.body.appendChild(floater); // 使浮窗可拖动 makeElementDraggable(floater, header); return floater; } // 使元素可拖动的函数 function makeElementDraggable(element, handle) { let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; if (handle) { // 如果指定了拖动把手,则把手触发拖动事件 handle.style.cursor = 'move'; handle.onmousedown = dragMouseDown; } else { // 否则,整个元素触发拖动事件 element.onmousedown = dragMouseDown; } function dragMouseDown(e) { e = e || window.event; e.preventDefault(); // 获取鼠标初始位置 pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; // 鼠标移动时调用elementDrag document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); // 计算新位置 pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; // 设置元素的新位置 element.style.top = (element.offsetTop - pos2) + "px"; element.style.left = (element.offsetLeft - pos1) + "px"; } function closeDragElement() { // 停止拖动 document.onmouseup = null; document.onmousemove = null; } } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址