chore(googlechat): fix lint and formatting issues
- Add node: protocol to imports - Remove unused imports - Fix any type to unknown with proper typing - Fix non-null assertions with optional chaining - Change let to const where appropriate - Apply formatting and import organization Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
6208f7da36
commit
34fb5ca9c6
@ -16,7 +16,9 @@ export type ResolvedGoogleChatAccount = {
|
||||
};
|
||||
|
||||
function listConfiguredAccountIds(cfg: ClawdbotConfig): string[] {
|
||||
const googlechat = (cfg as { googlechat?: { accounts?: Record<string, unknown> } }).googlechat;
|
||||
const googlechat = (
|
||||
cfg as { googlechat?: { accounts?: Record<string, unknown> } }
|
||||
).googlechat;
|
||||
const accounts = googlechat?.accounts;
|
||||
if (!accounts || typeof accounts !== "object") return [];
|
||||
return Object.keys(accounts).filter(Boolean);
|
||||
@ -38,7 +40,11 @@ function resolveAccountConfig(
|
||||
cfg: ClawdbotConfig,
|
||||
accountId: string,
|
||||
): GoogleChatAccountConfig | undefined {
|
||||
const googlechat = (cfg as { googlechat?: { accounts?: Record<string, GoogleChatAccountConfig> } }).googlechat;
|
||||
const googlechat = (
|
||||
cfg as {
|
||||
googlechat?: { accounts?: Record<string, GoogleChatAccountConfig> };
|
||||
}
|
||||
).googlechat;
|
||||
const accounts = googlechat?.accounts;
|
||||
if (!accounts || typeof accounts !== "object") return undefined;
|
||||
return accounts[accountId];
|
||||
@ -48,7 +54,9 @@ function mergeGoogleChatAccountConfig(
|
||||
cfg: ClawdbotConfig,
|
||||
accountId: string,
|
||||
): GoogleChatAccountConfig {
|
||||
const googlechat = (cfg as { googlechat?: GoogleChatAccountConfig & { accounts?: unknown } }).googlechat ?? {};
|
||||
const googlechat =
|
||||
(cfg as { googlechat?: GoogleChatAccountConfig & { accounts?: unknown } })
|
||||
.googlechat ?? {};
|
||||
const { accounts: _ignored, ...base } = googlechat;
|
||||
const account = resolveAccountConfig(cfg, accountId) ?? {};
|
||||
return { ...base, ...account };
|
||||
@ -58,7 +66,8 @@ export function resolveGoogleChatAccount(params: {
|
||||
cfg: ClawdbotConfig;
|
||||
accountId?: string | null;
|
||||
}): ResolvedGoogleChatAccount {
|
||||
const googlechat = (params.cfg as { googlechat?: { enabled?: boolean } }).googlechat;
|
||||
const googlechat = (params.cfg as { googlechat?: { enabled?: boolean } })
|
||||
.googlechat;
|
||||
const baseEnabled = googlechat?.enabled !== false;
|
||||
|
||||
const resolve = (accountId: string) => {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { PubSub, type Message } from "@google-cloud/pubsub";
|
||||
import { type Message, PubSub } from "@google-cloud/pubsub";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import type { ResolvedGoogleChatAccount } from "./accounts.js";
|
||||
import type { GoogleChatEvent, GoogleChatMessage } from "./types.js";
|
||||
import type { GoogleChatEvent } from "./types.js";
|
||||
|
||||
export type GoogleChatMonitorOptions = {
|
||||
account: ResolvedGoogleChatAccount;
|
||||
@ -86,8 +86,8 @@ function checkMessagePolicy(
|
||||
): boolean {
|
||||
const policy =
|
||||
message.chat.type === "dm"
|
||||
? account.config.dmPolicy ?? "pairing"
|
||||
: account.config.spacePolicy ?? "disabled";
|
||||
? (account.config.dmPolicy ?? "pairing")
|
||||
: (account.config.spacePolicy ?? "disabled");
|
||||
|
||||
switch (policy) {
|
||||
case "disabled":
|
||||
@ -157,7 +157,10 @@ export async function monitorGoogleChatProvider(
|
||||
};
|
||||
|
||||
const errorHandler = (error: Error) => {
|
||||
console.error(`[googlechat:${account.accountId}] Subscription error:`, error);
|
||||
console.error(
|
||||
`[googlechat:${account.accountId}] Subscription error:`,
|
||||
error,
|
||||
);
|
||||
};
|
||||
|
||||
subscription.on("message", messageHandler);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env npx tsx
|
||||
import { execSync } from "node:child_process";
|
||||
import express, { type Request, type Response } from "express";
|
||||
import { execSync } from "child_process";
|
||||
|
||||
const PORT = 18792;
|
||||
const app = express();
|
||||
@ -21,7 +21,11 @@ app.post("/webhook/googlechat", async (req: Request, res: Response) => {
|
||||
const isAddedToSpace = !!chat.addedToSpacePayload;
|
||||
const isMessage = !!chat.messagePayload;
|
||||
|
||||
const eventType = isAddedToSpace ? "ADDED_TO_SPACE" : isMessage ? "MESSAGE" : "UNKNOWN";
|
||||
const eventType = isAddedToSpace
|
||||
? "ADDED_TO_SPACE"
|
||||
: isMessage
|
||||
? "MESSAGE"
|
||||
: "UNKNOWN";
|
||||
console.log(`[googlechat] Received event: ${eventType}`);
|
||||
|
||||
if (isAddedToSpace) {
|
||||
@ -55,21 +59,27 @@ app.post("/webhook/googlechat", async (req: Request, res: Response) => {
|
||||
const escapedText = text.replace(/'/g, "'\\''");
|
||||
const sessionId = `googlechat:${spaceId}`;
|
||||
const result = execSync(
|
||||
`clawdbot agent --message '${escapedText}' --session-id '${sessionId}' --local 2>&1`,
|
||||
`clawdbot agent --message '${escapedText}' --session-id '${sessionId}' --local`,
|
||||
{
|
||||
timeout: 25000, // 25 second timeout (Google Chat times out at ~30s)
|
||||
encoding: 'utf-8',
|
||||
timeout: 25000, // 25 second timeout (Google Chat times out at ~30s)
|
||||
encoding: "utf-8",
|
||||
maxBuffer: 1024 * 1024,
|
||||
}
|
||||
},
|
||||
);
|
||||
responseText = result.trim() || "I processed your message but have no response.";
|
||||
console.log(`[googlechat] AI Response: ${responseText.slice(0, 100)}...`);
|
||||
} catch (err: any) {
|
||||
console.error(`[googlechat] CLI error:`, err.message);
|
||||
if (err.killed) {
|
||||
responseText = "Sorry, the request timed out. Please try a simpler question.";
|
||||
responseText =
|
||||
result.trim() || "I processed your message but have no response.";
|
||||
console.log(
|
||||
`[googlechat] AI Response: ${responseText.slice(0, 100)}...`,
|
||||
);
|
||||
} catch (err: unknown) {
|
||||
const error = err as { message?: string; killed?: boolean };
|
||||
console.error(`[googlechat] CLI error:`, error.message);
|
||||
if (error.killed) {
|
||||
responseText =
|
||||
"Sorry, the request timed out. Please try a simpler question.";
|
||||
} else {
|
||||
responseText = "Sorry, I encountered an error processing your message.";
|
||||
responseText =
|
||||
"Sorry, I encountered an error processing your message.";
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,6 +106,10 @@ app.post("/webhook/googlechat", async (req: Request, res: Response) => {
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`[googlechat] Webhook server running on port ${PORT}`);
|
||||
console.log(`[googlechat] Local: http://localhost:${PORT}/webhook/googlechat`);
|
||||
console.log(`[googlechat] Use ngrok URL + /webhook/googlechat for Google Chat config`);
|
||||
console.log(
|
||||
`[googlechat] Local: http://localhost:${PORT}/webhook/googlechat`,
|
||||
);
|
||||
console.log(
|
||||
`[googlechat] Use ngrok URL + /webhook/googlechat for Google Chat config`,
|
||||
);
|
||||
});
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { google, type chat_v1 } from "googleapis";
|
||||
import { type chat_v1, google } from "googleapis";
|
||||
import type { ResolvedGoogleChatAccount } from "./accounts.js";
|
||||
|
||||
let chatClients: Map<string, chat_v1.Chat> = new Map();
|
||||
const chatClients: Map<string, chat_v1.Chat> = new Map();
|
||||
|
||||
async function getChatClient(account: ResolvedGoogleChatAccount): Promise<chat_v1.Chat> {
|
||||
async function getChatClient(
|
||||
account: ResolvedGoogleChatAccount,
|
||||
): Promise<chat_v1.Chat> {
|
||||
const cacheKey = `${account.accountId}:${account.credentialsPath ?? "default"}`;
|
||||
const cached = chatClients.get(cacheKey);
|
||||
if (cached) return cached;
|
||||
@ -127,8 +129,8 @@ export async function sendGoogleChatMedia(
|
||||
},
|
||||
};
|
||||
|
||||
if (options.caption) {
|
||||
card.card!.sections![0].widgets!.unshift({
|
||||
if (options.caption && card.card?.sections?.[0]?.widgets) {
|
||||
card.card.sections[0].widgets.unshift({
|
||||
textParagraph: { text: options.caption },
|
||||
});
|
||||
}
|
||||
|
||||
@ -59,11 +59,7 @@ export type GoogleChatMessage = {
|
||||
};
|
||||
|
||||
export type GoogleChatEvent = {
|
||||
type:
|
||||
| "MESSAGE"
|
||||
| "ADDED_TO_SPACE"
|
||||
| "REMOVED_FROM_SPACE"
|
||||
| "CARD_CLICKED";
|
||||
type: "MESSAGE" | "ADDED_TO_SPACE" | "REMOVED_FROM_SPACE" | "CARD_CLICKED";
|
||||
eventTime: string;
|
||||
message?: GoogleChatMessage;
|
||||
user?: {
|
||||
|
||||
@ -83,7 +83,11 @@ function normalizeMessage(
|
||||
|
||||
export async function startGoogleChatWebhookServer(
|
||||
options: GoogleChatWebhookOptions,
|
||||
): Promise<{ server: ReturnType<typeof express>; port: number; stop: () => void }> {
|
||||
): Promise<{
|
||||
server: ReturnType<typeof express>;
|
||||
port: number;
|
||||
stop: () => void;
|
||||
}> {
|
||||
const { account, port = 18792 } = options;
|
||||
|
||||
const app = express();
|
||||
@ -91,7 +95,11 @@ export async function startGoogleChatWebhookServer(
|
||||
|
||||
// Health check endpoint
|
||||
app.get("/health", (_req: Request, res: Response) => {
|
||||
res.json({ ok: true, provider: "googlechat", accountId: account.accountId });
|
||||
res.json({
|
||||
ok: true,
|
||||
provider: "googlechat",
|
||||
accountId: account.accountId,
|
||||
});
|
||||
});
|
||||
|
||||
// Google Chat webhook endpoint
|
||||
@ -99,7 +107,9 @@ export async function startGoogleChatWebhookServer(
|
||||
try {
|
||||
const event = req.body as GoogleChatEvent;
|
||||
|
||||
console.log(`[googlechat:${account.accountId}] Received event: ${event.type}`);
|
||||
console.log(
|
||||
`[googlechat:${account.accountId}] Received event: ${event.type}`,
|
||||
);
|
||||
|
||||
// Handle different event types
|
||||
if (event.type === "ADDED_TO_SPACE") {
|
||||
@ -142,8 +152,12 @@ export async function startGoogleChatWebhookServer(
|
||||
|
||||
// Start server
|
||||
const server = app.listen(port, () => {
|
||||
console.log(`[googlechat:${account.accountId}] Webhook server listening on port ${port}`);
|
||||
console.log(`[googlechat:${account.accountId}] Webhook URL: http://localhost:${port}/webhook/googlechat`);
|
||||
console.log(
|
||||
`[googlechat:${account.accountId}] Webhook server listening on port ${port}`,
|
||||
);
|
||||
console.log(
|
||||
`[googlechat:${account.accountId}] Webhook URL: http://localhost:${port}/webhook/googlechat`,
|
||||
);
|
||||
});
|
||||
|
||||
const stop = () => {
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
import { chunkMarkdownText } from "../../auto-reply/chunk.js";
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js";
|
||||
import {
|
||||
listGoogleChatAccountIds,
|
||||
type ResolvedGoogleChatAccount,
|
||||
@ -13,6 +10,7 @@ import {
|
||||
sendGoogleChatMedia,
|
||||
sendGoogleChatText,
|
||||
} from "../../googlechat/send.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js";
|
||||
import { getChatProviderMeta } from "../registry.js";
|
||||
import {
|
||||
deleteAccountFromConfigSection,
|
||||
@ -57,7 +55,12 @@ export const googlechatPlugin: ProviderPlugin<ResolvedGoogleChatAccount> = {
|
||||
cfg,
|
||||
sectionKey: "googlechat",
|
||||
accountId,
|
||||
clearBaseFields: ["projectId", "subscriptionName", "credentialsPath", "name"],
|
||||
clearBaseFields: [
|
||||
"projectId",
|
||||
"subscriptionName",
|
||||
"credentialsPath",
|
||||
"name",
|
||||
],
|
||||
}),
|
||||
isConfigured: (account) =>
|
||||
Boolean(account.projectId?.trim() && account.subscriptionName?.trim()),
|
||||
@ -78,7 +81,9 @@ export const googlechatPlugin: ProviderPlugin<ResolvedGoogleChatAccount> = {
|
||||
},
|
||||
security: {
|
||||
resolveDmPolicy: ({ cfg, accountId, account }) => {
|
||||
const googlechat = (cfg as { googlechat?: { accounts?: Record<string, unknown> } }).googlechat;
|
||||
const googlechat = (
|
||||
cfg as { googlechat?: { accounts?: Record<string, unknown> } }
|
||||
).googlechat;
|
||||
const resolvedAccountId =
|
||||
accountId ?? account.accountId ?? DEFAULT_ACCOUNT_ID;
|
||||
const useAccountPath = Boolean(googlechat?.accounts?.[resolvedAccountId]);
|
||||
@ -107,9 +112,7 @@ export const googlechatPlugin: ProviderPlugin<ResolvedGoogleChatAccount> = {
|
||||
if (!trimmed) {
|
||||
return {
|
||||
ok: false,
|
||||
error: new Error(
|
||||
"Delivering to Google Chat requires --to <spaceId>",
|
||||
),
|
||||
error: new Error("Delivering to Google Chat requires --to <spaceId>"),
|
||||
};
|
||||
}
|
||||
return { ok: true, to: trimmed };
|
||||
|
||||
@ -101,7 +101,8 @@ const CHAT_PROVIDER_META: Record<ChatProviderId, ChatProviderMeta> = {
|
||||
selectionLabel: "Google Chat (Pub/Sub)",
|
||||
docsPath: "/googlechat",
|
||||
docsLabel: "googlechat",
|
||||
blurb: "Google Workspace only; uses Pub/Sub for firewall-friendly operation.",
|
||||
blurb:
|
||||
"Google Workspace only; uses Pub/Sub for firewall-friendly operation.",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user