Files
openclaw/skills/gmail-reader/create-draft.cjs
Clawd Bot ca9b510922 chore: align with upstream openclaw/openclaw and overlay local additions
- 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 <noreply@anthropic.com>
2026-03-03 07:40:46 +01:00

134 lines
4.1 KiB
JavaScript

#!/usr/bin/env node
const fs = require("fs");
const https = require("https");
const { homedir } = require("os");
const { join } = require("path");
function httpsRequest(url, options = {}) {
return new Promise((resolve, reject) => {
const req = https.request(url, 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);
if (options.body) req.write(options.body);
req.end();
});
}
async function getAccessToken(creds) {
const body = new URLSearchParams({
client_id: creds.client_id,
client_secret: creds.client_secret,
refresh_token: creds.refresh_token,
grant_type: "refresh_token",
}).toString();
const data = await httpsRequest("https://oauth2.googleapis.com/token", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": Buffer.byteLength(body),
},
body,
});
return data.access_token;
}
async function createDraft(accessToken, to, subject, body) {
const email = [
`To: ${to}`,
`Subject: ${subject}`,
`Content-Type: text/plain; charset=UTF-8`,
``,
body,
].join("\r\n");
const encodedEmail = Buffer.from(email).toString("base64url");
const draftPayload = JSON.stringify({
message: {
raw: encodedEmail,
},
});
const url = "https://gmail.googleapis.com/gmail/v1/users/me/drafts";
return await httpsRequest(url, {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(draftPayload),
},
body: draftPayload,
});
}
async function main() {
const to = "Do-NOT-REPLY@sapphiretech.com";
const subject = "Re: Reply your question #174364 - VBIOS Backup and Card Information";
const body = `Dear Sapphire Support Team,
Thank you for your reply regarding ticket #174364.
I have successfully backed up the VBIOS from my graphics card using Linux tools. Please find the requested information below:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GRAPHICS CARD INFORMATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Card Model: Sapphire PULSE RX 7900 XTX
GPU Chip: AMD Navi 31 [Radeon RX 7900 XTX] (rev c8)
P/N: 113-3E4710U-O4O
PCI ID: [1002:744c]
VBIOS Backup File: sapphire_vbios_backup.rom (109 KB)
Operating System: Linux (CachyOS)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Note: I was unable to retrieve the SKU and Serial Number (S/N) through software commands on Linux. These details are typically printed on a sticker on the back of the physical card.
If you require the SKU and S/N, I will need to physically inspect the graphics card to read the label. Alternatively, if the P/N provided above is sufficient to identify the correct BIOS version, please let me know.
The VBIOS backup file is ready to be uploaded to the support ticket portal.
Please advise on the next steps.
Best regards,
Alexander Wärme
Ticket Link: https://support.sapphiretech.com/ticket-record.asp?id=0C6571C9-8B19-4EDE-B550-6D2D30ADFA51
NOTE: VBIOS file is located at /tmp/sapphire_vbios_backup.rom and needs to be uploaded via the support portal.`;
console.log("📧 Creating Gmail draft...\n");
const creds = JSON.parse(
fs.readFileSync(join(homedir(), ".openclaw/secrets/google-oauth.json"), "utf8"),
);
const accessToken = await getAccessToken(creds);
const result = await createDraft(accessToken, to, subject, body);
console.log("✅ Draft created successfully!");
console.log(`Draft ID: ${result.id}`);
console.log(
`\n🌐 View in Gmail: https://mail.google.com/mail/u/0/#drafts?compose=${result.message.id}`,
);
}
main().catch((err) => {
console.error("Error:", err.message);
process.exit(1);
});