import { CoreApiClient } from 'twenty-client-sdk/core'; import { defineLogicFunction } from 'twenty-sdk/define'; import { GRANOLA_CONNECTION_LOGIC_FUNCTIONS } from 'src/constants/universal-identifiers'; import { findConnectionByMemberId } from 'src/logic-functions/utils/granola-connection-store'; import { resolveWorkspaceMember } from 'src/logic-functions/utils/resolve-workspace-member'; type GetConnectionResult = { success: boolean; connected: boolean; lastSyncedAt: string | null; lastSyncStatus: string | null; message?: string; }; const DISCONNECTED: GetConnectionResult = { success: true, connected: false, lastSyncedAt: null, lastSyncStatus: null, }; // Returns only the current member's connection status, never the stored key, so // the connect panel can show whether they are connected without ever exposing // the secret back to the browser. const handler = async (): Promise => { const client = new CoreApiClient(); const member = await resolveWorkspaceMember(client); if (!member) { return { ...DISCONNECTED, success: false, message: 'Could not identify your account.', }; } const connection = await findConnectionByMemberId(member.workspaceMemberId); if (!connection || connection.isActive !== true) { return DISCONNECTED; } return { success: true, connected: true, lastSyncedAt: connection.lastSyncedAt, lastSyncStatus: connection.lastSyncStatus, }; }; export default defineLogicFunction({ universalIdentifier: GRANOLA_CONNECTION_LOGIC_FUNCTIONS.getConnection.universalIdentifier, name: 'granola-get-connection', description: "Returns the invoking member's Granola connection status (connected, last sync) without exposing the stored key.", timeoutSeconds: 30, handler, httpRouteTriggerSettings: { path: GRANOLA_CONNECTION_LOGIC_FUNCTIONS.getConnection.path, httpMethod: 'POST', isAuthRequired: true, }, });