code icon Code

List Gmail Messages

List Gmail message IDs with pagination. Returns IDs only (fast).

Source Code

import fs from "fs";
import path from "path";

const [query = "", maxResults = "100", outputPath = ""] = process.argv.slice(2);
const maxResultsNum = Math.min(parseInt(maxResults) || 100, 1000);

/**
 * Fetch message IDs matching a query with pagination
 */
async function fetchMessageIds(query, maxResults) {
  const ids = [];
  let pageToken = null;
  let totalEstimate = null;

  while (ids.length < maxResults) {
    const remaining = maxResults - ids.length;
    const pageSize = Math.min(remaining, 100);

    const url = new URL("https://gmail.googleapis.com/gmail/v1/users/me/messages");
    url.searchParams.set("maxResults", pageSize.toString());
    if (query) url.searchParams.set("q", query);
    if (pageToken) url.searchParams.set("pageToken", pageToken);

    const res = await fetch(url.toString(), {
      headers: { Authorization: "Bearer PLACEHOLDER_TOKEN" },
    });

    if (!res.ok) {
      const errorText = await res.text();
      throw new Error(`Gmail API failed: ${res.status} - ${errorText.slice(0, 200)}`);
    }

    const data = await res.json();

    if (totalEstimate === null && data.resultSizeEstimate) {
      totalEstimate = data.resultSizeEstimate;
    }

    if (!data.messages || data.messages.length === 0) break;

    ids.push(...data.messages.map(m => m.id).slice(0, remaining));
    pageToken = data.nextPageToken;
    if (!pageToken) break;
  }

  return { ids, totalEstimate };
}

try {
  console.log(`Listing messages${query ? ` matching: ${query}` : ""} (max ${maxResultsNum})`);

  const { ids, totalEstimate } = await fetchMessageIds(query, maxResultsNum);

  const result = {
    query: query || null,
    listedAt: new Date().toISOString(),
    count: ids.length,
    totalEstimate,
    ids,
  };

  if (outputPath) {
    const dir = path.dirname(outputPath);
    if (dir && dir !== ".") fs.mkdirSync(dir, { recursive: true });
    fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
    console.log(`Written to: ${outputPath}`);
  }

  console.log(`Found ${ids.length} messages${totalEstimate && totalEstimate > ids.length ? ` (~${totalEstimate} total matches)` : ""}`);
  console.log(JSON.stringify({ success: true, count: ids.length, totalEstimate }));
} catch (error) {
  console.error("Error:", error.message);
  throw error;
}