[object Object]

← back to George Gmail

auto-save: 2026-07-10T11:07:57 (1 files) — server.js

b6e91b31400ebe95284fb2650238813c68614d1a · 2026-07-10 11:07:58 -0700 · Steve Abrams

Files touched

Diff

commit b6e91b31400ebe95284fb2650238813c68614d1a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Jul 10 11:07:58 2026 -0700

    auto-save: 2026-07-10T11:07:57 (1 files) — server.js
---
 server.js | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/server.js b/server.js
index 2a8e6d1..4f4b7f9 100644
--- a/server.js
+++ b/server.js
@@ -1448,15 +1448,27 @@ app.delete('/api/drafts/:id', async (req, res) => {
   }
 });
 
-// ─── API: Get Attachment ───
+// ─── API: Get Attachment (account-aware, raw binary) ───
+// Fixed 2026-07-10: was hardcoded to the steve-office `gmail` client AND
+// returned base64 JSON. Cross-account requests (?account=info) failed with a
+// 500 "Permission denied" because steve-office can't read an info@ message id,
+// and the MCP bridge (georgeRaw → arrayBuffer) expects raw bytes, not JSON.
+// Now resolves the correct per-account client and streams raw binary like the
+// /api/info/... route does, so the MCP writes correct file bytes for any account.
 app.get('/api/messages/:messageId/attachments/:attachmentId', async (req, res) => {
   try {
-    const att = await gmail.users.messages.attachments.get({
+    const { key, gmail: gm } = resolveAccount(req);
+    if (!gm) return res.status(503).json({ error: `Gmail not initialized for account '${key}' — authorize via /auth/${key}` });
+    const att = await gm.users.messages.attachments.get({
       userId: 'me', messageId: req.params.messageId, id: req.params.attachmentId
     });
-    res.json({ data: att.data.data, size: att.data.size });
+    const buf = Buffer.from(att.data.data, 'base64url');
+    res.set('Content-Length', buf.length);
+    res.type('application/octet-stream');
+    res.send(buf);
   } catch (e) {
-    res.status(500).json({ error: e.message });
+    console.error('[attachment] error:', e?.code, e?.message, JSON.stringify(e?.errors || e?.response?.data || {}));
+    res.status(500).json({ error: e.message, code: e?.code, detail: e?.errors || e?.response?.data?.error || null });
   }
 });
 

← e86cb67 feat(api): add /api/attachment-local — fetch a Gmail attachm  ·  back to George Gmail  ·  auth: unify both middlewares on resolved GEORGE_BASIC_AUTH c a9140cb →