diff --git a/src/hooks/gmail-ops.ts b/src/hooks/gmail-ops.ts index be8d74cac..b99e7d8fb 100644 --- a/src/hooks/gmail-ops.ts +++ b/src/hooks/gmail-ops.ts @@ -134,6 +134,11 @@ export async function runGmailSetup(opts: GmailSetupOptions) { const serveBind = opts.bind ?? DEFAULT_GMAIL_SERVE_BIND; const servePort = opts.port ?? DEFAULT_GMAIL_SERVE_PORT; const configuredServePath = opts.path ?? baseConfig.hooks?.gmail?.serve?.path; + const normalizedServePath = + typeof configuredServePath === "string" && + configuredServePath.trim().length > 0 + ? normalizeServePath(configuredServePath) + : DEFAULT_GMAIL_SERVE_PATH; const includeBody = opts.includeBody ?? true; const maxBytes = opts.maxBytes ?? DEFAULT_GMAIL_MAX_BYTES; @@ -142,18 +147,14 @@ export async function runGmailSetup(opts: GmailSetupOptions) { const tailscaleMode = opts.tailscale ?? "funnel"; // Tailscale strips the path before proxying; keep a public path while gog - // listens on "/" unless the user explicitly configured a serve path. + // listens on "/" whenever Tailscale is enabled. const servePath = normalizeServePath( - tailscaleMode !== "off" && !configuredServePath - ? "/" - : (configuredServePath ?? DEFAULT_GMAIL_SERVE_PATH), + tailscaleMode !== "off" ? "/" : normalizedServePath, ); const tailscalePath = normalizeServePath( opts.tailscalePath ?? baseConfig.hooks?.gmail?.tailscale?.path ?? - (tailscaleMode !== "off" - ? (configuredServePath ?? DEFAULT_GMAIL_SERVE_PATH) - : servePath), + (tailscaleMode !== "off" ? normalizedServePath : servePath), ); await runGcloud(["config", "set", "project", projectId, "--quiet"]); diff --git a/src/hooks/gmail.test.ts b/src/hooks/gmail.test.ts index 3956d33a8..2dd69295e 100644 --- a/src/hooks/gmail.test.ts +++ b/src/hooks/gmail.test.ts @@ -85,7 +85,30 @@ describe("gmail hook config", () => { } }); - it("keeps explicit serve path for tailscale when set", () => { + it("keeps the default public path when serve path is explicit", () => { + const result = resolveGmailHookRuntimeConfig( + { + hooks: { + token: "hook-token", + gmail: { + account: "clawdbot@gmail.com", + topic: "projects/demo/topics/gog-gmail-watch", + pushToken: "push-token", + serve: { path: "/gmail-pubsub" }, + tailscale: { mode: "funnel" }, + }, + }, + }, + {}, + ); + expect(result.ok).toBe(true); + if (result.ok) { + expect(result.value.serve.path).toBe("/"); + expect(result.value.tailscale.path).toBe("/gmail-pubsub"); + } + }); + + it("keeps custom public path when serve path is set", () => { const result = resolveGmailHookRuntimeConfig( { hooks: { @@ -103,7 +126,7 @@ describe("gmail hook config", () => { ); expect(result.ok).toBe(true); if (result.ok) { - expect(result.value.serve.path).toBe("/custom"); + expect(result.value.serve.path).toBe("/"); expect(result.value.tailscale.path).toBe("/custom"); } }); diff --git a/src/hooks/gmail.ts b/src/hooks/gmail.ts index f14de6899..772903356 100644 --- a/src/hooks/gmail.ts +++ b/src/hooks/gmail.ts @@ -160,23 +160,22 @@ export function resolveGmailHookRuntimeConfig( ? Math.floor(servePortRaw) : DEFAULT_GMAIL_SERVE_PORT; const servePathRaw = overrides.servePath ?? gmail?.serve?.path; - const hasExplicitServePath = - typeof servePathRaw === "string" && servePathRaw.trim().length > 0; + const normalizedServePathRaw = + typeof servePathRaw === "string" && servePathRaw.trim().length > 0 + ? normalizeServePath(servePathRaw) + : DEFAULT_GMAIL_SERVE_PATH; const tailscaleMode = overrides.tailscaleMode ?? gmail?.tailscale?.mode ?? "off"; - // When exposing the push endpoint via Tailscale, the public path is stripped - // before proxying; use "/" internally unless the user set a path explicitly. + // Tailscale strips the public path before proxying, so listen on "/" when on. const servePath = normalizeServePath( - tailscaleMode !== "off" && !hasExplicitServePath ? "/" : servePathRaw, + tailscaleMode !== "off" ? "/" : normalizedServePathRaw, ); const tailscalePathRaw = overrides.tailscalePath ?? gmail?.tailscale?.path; const tailscalePath = normalizeServePath( - tailscaleMode !== "off" && !tailscalePathRaw - ? hasExplicitServePath - ? servePathRaw - : DEFAULT_GMAIL_SERVE_PATH + tailscaleMode !== "off" + ? (tailscalePathRaw ?? normalizedServePathRaw) : (tailscalePathRaw ?? servePath), );