Files
2026-09-04 14:58:42 +08:00

131 lines
3.3 KiBLFS
JavaScript

#!/usr/bin/env node
import { google } from 'googleapis';
import minimist from 'minimist';
import { getAuthClient, parseAccountArg } from './auth/auth-utils.js';
import { logAction } from './action-logger.js';
function decodeBody(body) {
if (!body.data) return '';
return Buffer.from(body.data, 'base64').toString('utf-8');
}
function extractBody(payload) {
if (payload.body && payload.body.data) {
return decodeBody(payload.body);
}
if (payload.parts) {
// Try to find text/plain first, fall back to text/html
const textPart = payload.parts.find(part => part.mimeType === 'text/plain');
if (textPart && textPart.body.data) {
return decodeBody(textPart.body);
}
const htmlPart = payload.parts.find(part => part.mimeType === 'text/html');
if (htmlPart && htmlPart.body.data) {
return decodeBody(htmlPart.body);
}
// Recursively search nested parts
for (const part of payload.parts) {
if (part.parts) {
const body = extractBody(part);
if (body) return body;
}
}
}
return '';
}
async function readMessage(args) {
if (!args.id) {
throw new Error('Missing required argument: --id (message ID)');
}
// Get authenticated client for specified account (or default)
const accountId = parseAccountArg(args);
const oauth2Client = await getAuthClient(accountId);
const gmail = google.gmail({ version: 'v1', auth: oauth2Client });
// Get message details
const message = await gmail.users.messages.get({
userId: 'me',
id: args.id,
format: 'full'
});
const headers = message.data.payload.headers;
const getHeader = (name) => headers.find(h => h.name === name)?.value || '';
const result = {
success: true,
id: message.data.id,
threadId: message.data.threadId,
from: getHeader('From'),
to: getHeader('To'),
cc: getHeader('Cc'),
bcc: getHeader('Bcc'),
subject: getHeader('Subject'),
date: getHeader('Date'),
labels: message.data.labelIds || [],
snippet: message.data.snippet,
body: extractBody(message.data.payload),
account: accountId || 'default'
};
// Optionally get thread if requested
if (args.thread) {
const thread = await gmail.users.threads.get({
userId: 'me',
id: message.data.threadId
});
result.thread = {
id: thread.data.id,
messageCount: thread.data.messages.length,
messages: thread.data.messages.map(msg => ({
id: msg.id,
snippet: msg.snippet,
from: msg.payload.headers.find(h => h.name === 'From')?.value,
date: msg.payload.headers.find(h => h.name === 'Date')?.value
}))
};
}
return result;
}
// Main execution
const args = minimist(process.argv.slice(2));
const startTime = Date.now();
readMessage(args)
.then(result => {
// Log the action
logAction('read', args, result, {
account: result.account,
duration: Date.now() - startTime
});
console.log(JSON.stringify(result, null, 2));
})
.catch(error => {
const errorResult = {
success: false,
error: error.message
};
// Log the failed action
logAction('read', args, errorResult, {
account: args.account || 'default',
duration: Date.now() - startTime,
failed: true
});
console.error(JSON.stringify(errorResult, null, 2));
process.exit(1);
});