- Reset master to upstream/main (16,697 commits) - Overlay 2,271 local-only files (skills, tools, workspace, configs, apps) - Restore IDENTITY.md and USER.md templates - Build verified, gateway running, Discord working Co-Authored-By: Claude Opus 4.6 <[email protected]>
97 lines
3.1 KiB
JavaScript
97 lines
3.1 KiB
JavaScript
#!/usr/bin/env node
|
|
const fs = require("fs");
|
|
const { homedir } = require("os");
|
|
const { join } = require("path");
|
|
const https = require("https");
|
|
|
|
const CLIENT_ID = "557905848788-p1pih5mpsuli2fa0rmh7d94megbau6o7.apps.googleusercontent.com";
|
|
const CLIENT_SECRET = "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";
|
|
const REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
|
|
|
|
const SCOPES = [
|
|
"https://www.googleapis.com/auth/gmail.readonly",
|
|
"https://www.googleapis.com/auth/gmail.compose",
|
|
"https://www.googleapis.com/auth/gmail.send",
|
|
].join(" ");
|
|
|
|
const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=${encodeURIComponent(SCOPES)}&access_type=offline&prompt=consent`;
|
|
|
|
console.log("\n🔐 Gmail OAuth Re-authorization\n");
|
|
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
console.log("\n📋 STEP 1: Open this URL in your browser:\n");
|
|
console.log(authUrl);
|
|
console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
console.log("\n📋 STEP 2: After authorizing, copy the CODE and paste it below\n");
|
|
|
|
process.stdin.setEncoding("utf8");
|
|
process.stdout.write("Paste authorization code here: ");
|
|
|
|
let code = "";
|
|
process.stdin.on("data", async (chunk) => {
|
|
code += chunk;
|
|
if (code.includes("\n")) {
|
|
code = code.trim();
|
|
|
|
console.log("\n🔄 Exchanging code for tokens...\n");
|
|
|
|
try {
|
|
const tokens = await exchangeCode(code);
|
|
|
|
const newConfig = {
|
|
client_id: CLIENT_ID,
|
|
client_secret: CLIENT_SECRET,
|
|
refresh_token: tokens.refresh_token,
|
|
};
|
|
|
|
const configPath = join(homedir(), ".openclaw/secrets/google-oauth.json");
|
|
fs.writeFileSync(configPath, JSON.stringify(newConfig, null, 2));
|
|
|
|
console.log("✅ SUCCESS! Token updated at:", configPath);
|
|
console.log("\n📧 You can now create Gmail drafts and send emails!\n");
|
|
process.exit(0);
|
|
} catch (err) {
|
|
console.error("❌ Error:", err.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
});
|
|
|
|
function exchangeCode(code) {
|
|
return new Promise((resolve, reject) => {
|
|
const postData = new URLSearchParams({
|
|
code: code,
|
|
client_id: CLIENT_ID,
|
|
client_secret: CLIENT_SECRET,
|
|
redirect_uri: REDIRECT_URI,
|
|
grant_type: "authorization_code",
|
|
}).toString();
|
|
|
|
const options = {
|
|
hostname: "oauth2.googleapis.com",
|
|
port: 443,
|
|
path: "/token",
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
"Content-Length": Buffer.byteLength(postData),
|
|
},
|
|
};
|
|
|
|
const req = https.request(options, (res) => {
|
|
let data = "";
|
|
res.on("data", (chunk) => (data += chunk));
|
|
res.on("end", () => {
|
|
if (res.statusCode >= 400) {
|
|
reject(new Error(`HTTP ${res.statusCode}: ${data}`));
|
|
} else {
|
|
resolve(JSON.parse(data));
|
|
}
|
|
});
|
|
});
|
|
|
|
req.on("error", reject);
|
|
req.write(postData);
|
|
req.end();
|
|
});
|
|
}
|