diff --git a/extensions/googlechat/src/monitor.test.ts b/extensions/googlechat/src/monitor.test.ts index 5604671ad..c03831021 100644 --- a/extensions/googlechat/src/monitor.test.ts +++ b/extensions/googlechat/src/monitor.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import { isSenderAllowed } from "./monitor.js"; +import { isSenderAllowed, resolveSpaceType } from "./monitor.js"; describe("isSenderAllowed", () => { it("matches allowlist entries with users/", () => { @@ -25,3 +25,85 @@ describe("isSenderAllowed", () => { ); }); }); + +describe("resolveSpaceType", () => { + describe("modern spaceType field", () => { + it("detects DIRECT_MESSAGE as DM", () => { + const result = resolveSpaceType({ spaceType: "DIRECT_MESSAGE" }); + expect(result.spaceType).toBe("DIRECT_MESSAGE"); + expect(result.isGroup).toBe(false); + }); + + it("detects SPACE as group", () => { + const result = resolveSpaceType({ spaceType: "SPACE" }); + expect(result.spaceType).toBe("SPACE"); + expect(result.isGroup).toBe(true); + }); + + it("detects GROUP_CHAT as group", () => { + const result = resolveSpaceType({ spaceType: "GROUP_CHAT" }); + expect(result.spaceType).toBe("GROUP_CHAT"); + expect(result.isGroup).toBe(true); + }); + + it("handles lowercase spaceType", () => { + const result = resolveSpaceType({ spaceType: "direct_message" }); + expect(result.spaceType).toBe("DIRECT_MESSAGE"); + expect(result.isGroup).toBe(false); + }); + }); + + describe("deprecated type field fallback", () => { + it("maps legacy DM to DIRECT_MESSAGE", () => { + const result = resolveSpaceType({ type: "DM" }); + expect(result.spaceType).toBe("DIRECT_MESSAGE"); + expect(result.isGroup).toBe(false); + }); + + it("maps legacy ROOM to SPACE", () => { + const result = resolveSpaceType({ type: "ROOM" }); + expect(result.spaceType).toBe("SPACE"); + expect(result.isGroup).toBe(true); + }); + + it("handles lowercase legacy type", () => { + const result = resolveSpaceType({ type: "dm" }); + expect(result.spaceType).toBe("DIRECT_MESSAGE"); + expect(result.isGroup).toBe(false); + }); + }); + + describe("field priority", () => { + it("prefers modern spaceType over deprecated type", () => { + const result = resolveSpaceType({ spaceType: "SPACE", type: "DM" }); + expect(result.spaceType).toBe("SPACE"); + expect(result.isGroup).toBe(true); + }); + + it("falls back to type only when spaceType is missing", () => { + const result = resolveSpaceType({ type: "DM" }); + expect(result.spaceType).toBe("DIRECT_MESSAGE"); + expect(result.isGroup).toBe(false); + }); + + it("falls back to type when spaceType is empty string", () => { + const result = resolveSpaceType({ spaceType: "", type: "DM" }); + expect(result.spaceType).toBe("DIRECT_MESSAGE"); + expect(result.isGroup).toBe(false); + }); + }); + + describe("edge cases", () => { + it("treats empty space as group", () => { + const result = resolveSpaceType({}); + expect(result.spaceType).toBe(""); + expect(result.isGroup).toBe(true); + }); + + it("treats unknown spaceType as group", () => { + const result = resolveSpaceType({ spaceType: "UNKNOWN_TYPE" }); + expect(result.spaceType).toBe("UNKNOWN_TYPE"); + expect(result.isGroup).toBe(true); + }); + }); +}); diff --git a/extensions/googlechat/src/monitor.ts b/extensions/googlechat/src/monitor.ts index d8ada7566..71d0cb3c8 100644 --- a/extensions/googlechat/src/monitor.ts +++ b/extensions/googlechat/src/monitor.ts @@ -297,6 +297,27 @@ function normalizeUserId(raw?: string | null): string { return trimmed.replace(/^users\//i, "").toLowerCase(); } +/** + * Resolves the space type from Google Chat space object. + * Normalizes to modern 'spaceType' format with fallback for deprecated 'type' field. + */ +export function resolveSpaceType(space: { type?: string; spaceType?: string }): { + spaceType: string; + isGroup: boolean; +} { + // Normalize to modern 'spaceType' format + let spaceType = (space.spaceType ?? "").toUpperCase(); + + // @deprecated fallback: map legacy 'type' to modern values + if (!spaceType && space.type) { + const legacyType = space.type.toUpperCase(); + spaceType = legacyType === "DM" ? "DIRECT_MESSAGE" : "SPACE"; + } + + const isGroup = spaceType !== "DIRECT_MESSAGE"; + return { spaceType, isGroup }; +} + export function isSenderAllowed( senderId: string, senderEmail: string | undefined, @@ -387,8 +408,8 @@ async function processMessageWithPipeline(params: { const spaceId = space.name ?? ""; if (!spaceId) return; - const spaceType = (space.type ?? "").toUpperCase(); - const isGroup = spaceType !== "DM"; + + const { isGroup } = resolveSpaceType(space); const sender = message.sender ?? event.user; const senderId = sender?.name ?? ""; const senderName = sender?.displayName ?? ""; diff --git a/extensions/googlechat/src/types.ts b/extensions/googlechat/src/types.ts index 820c96425..730d889fa 100644 --- a/extensions/googlechat/src/types.ts +++ b/extensions/googlechat/src/types.ts @@ -1,7 +1,9 @@ export type GoogleChatSpace = { name?: string; displayName?: string; + /** @deprecated Use spaceType instead */ type?: string; + spaceType?: string; }; export type GoogleChatUser = {