Skip to content

Conversation

@jkomoros
Copy link
Contributor

@jkomoros jkomoros commented Oct 28, 2025

gmail-importer expects to be linked to a gmail-auth.

This allows authenticating a single time in a space and having multiple gmail-importers that use it.


Summary by cubic

Split the Gmail recipe into two charms: gmail-auth (Google OAuth) and gmail-importer (email fetching). Authenticate once per space and reuse the same auth across multiple importers.

  • New Features

    • Incremental sync via Gmail History API with fallback to full sync; tracks added, deleted, and relabeled messages; updates historyId.
    • Batch message fetch and HTML-to-Markdown conversion; basic UI with status, counts, and a results table.
    • Robust client with token refresh, retries, and backoff for 401/429; configurable limit and Gmail search query.
  • Migration

    • Add one gmail-auth and one or more gmail-importer charms; connect gmail-auth.auth to gmail-importer.auth.
    • Set importer settings: limit and Gmail filter query (default: in:INBOX).

gmail-importer expects to be linked to a gmail-auth.

This allows authenticating a single time in a space and having multiple gmail-importers that use it.
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 2 files

Prompt for AI agents (all 3 issues)

Understand the root cause of the following 3 issues and fix them.


<file name="recipes/gmail-importer.tsx">

<violation number="1" location="recipes/gmail-importer.tsx:126">
Remove logging of the OAuth refresh token; it exposes secrets in logs.</violation>

<violation number="2" location="recipes/gmail-importer.tsx:439">
Add base64 padding before calling atob so Gmail payloads without &#39;=&#39; padding decode correctly.</violation>

<violation number="3" location="recipes/gmail-importer.tsx:698">
Handle Gmail history pagination before advancing the stored historyId; otherwise updates beyond the first page are skipped.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

refreshToken: this.auth.get().refreshToken,
};

console.log("refreshAuthToken", body);
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove logging of the OAuth refresh token; it exposes secrets in logs.

Prompt for AI agents
Address the following comment on recipes/gmail-importer.tsx at line 126:

<comment>Remove logging of the OAuth refresh token; it exposes secrets in logs.</comment>

<file context>
@@ -0,0 +1,952 @@
+      refreshToken: this.auth.get().refreshToken,
+    };
+
+    console.log(&quot;refreshAuthToken&quot;, body);
+
+    const res = await fetch(
</file context>
Fix with Cubic

// Replace URL-safe characters back to their original form
const sanitized = data.replace(/-/g, "+").replace(/_/g, "/");
// Decode the base64 string
return atob(sanitized);
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add base64 padding before calling atob so Gmail payloads without '=' padding decode correctly.

Prompt for AI agents
Address the following comment on recipes/gmail-importer.tsx at line 439:

<comment>Add base64 padding before calling atob so Gmail payloads without &#39;=&#39; padding decode correctly.</comment>

<file context>
@@ -0,0 +1,952 @@
+  // Replace URL-safe characters back to their original form
+  const sanitized = data.replace(/-/g, &quot;+&quot;).replace(/_/g, &quot;/&quot;);
+  // Decode the base64 string
+  return atob(sanitized);
+}
+
</file context>
Suggested change
return atob(sanitized);
return atob(sanitized.padEnd(sanitized.length + ((4 - (sanitized.length % 4)) % 4), "="));
Fix with Cubic

}
}

newHistoryId = historyResponse.historyId;
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle Gmail history pagination before advancing the stored historyId; otherwise updates beyond the first page are skipped.

Prompt for AI agents
Address the following comment on recipes/gmail-importer.tsx at line 698:

<comment>Handle Gmail history pagination before advancing the stored historyId; otherwise updates beyond the first page are skipped.</comment>

<file context>
@@ -0,0 +1,952 @@
+          }
+        }
+
+        newHistoryId = historyResponse.historyId;
+        console.log(&quot;\n=== INCREMENTAL SYNC SUMMARY ===&quot;);
+        console.log(`Messages to fetch: ${messagesToFetch.length}`);
</file context>
Fix with Cubic

@@ -0,0 +1,952 @@
/// <cts-enable />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this differ from gmail.tsx? Does this replace it, augment? The gmail.tsx implementation currently has a lot of extra/unused/untested features AFAIK (history? people?), but handling the batch requests and rate limiting are both a PITA but handled at least for the email portions

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see it takes the auth token from the other charm

@jsantell
Copy link
Collaborator

Looks like this needs a quick format: deno fmt ./recipes

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

@jkomoros jkomoros merged commit feda69f into main Oct 28, 2025
9 checks passed
@jkomoros jkomoros deleted the gmail-refactored-auth branch October 28, 2025 23:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants