diff --git a/app/api/twenty-crm/tasks/route.ts b/app/api/twenty-crm/tasks/route.ts index 1a8fc44..9f0736f 100644 --- a/app/api/twenty-crm/tasks/route.ts +++ b/app/api/twenty-crm/tasks/route.ts @@ -43,15 +43,13 @@ async function fetchTwentyTasks(): Promise { today.setHours(0, 0, 0, 0); const todayISO = today.toISOString(); - // GraphQL query to fetch activities (tasks) that are not completed and due before today - // Using findManyActivities which is the standard query for Twenty CRM - // Note: The exact filter syntax may vary based on your Twenty CRM version - // If this doesn't work, try using REST API or adjust the filter syntax + // GraphQL query to fetch tasks from Twenty CRM + // Twenty CRM uses different query structures - trying tasks query first + // If this doesn't work, we may need to use REST API or check the actual schema const query = ` query GetOverdueTasks { - findManyActivities( - filter: { - type: { eq: Task } + tasks( + where: { completedAt: { is: NULL } dueAt: { lt: "${todayISO}" } } @@ -64,7 +62,6 @@ async function fetchTwentyTasks(): Promise { body dueAt completedAt - type assigneeId assignee { id @@ -121,29 +118,55 @@ async function fetchTwentyTasks(): Promise { return []; } - if (!data.data?.findManyActivities?.edges) { + // Try different possible response structures + // Twenty CRM may use different field names depending on version + let activitiesData = null; + if (data.data?.tasks?.edges) { + activitiesData = data.data.tasks.edges; + } else if (data.data?.activities?.edges) { + activitiesData = data.data.activities.edges; + } else if (data.data?.findManyTasks?.edges) { + activitiesData = data.data.findManyTasks.edges; + } else if (data.data?.findManyActivities?.edges) { + activitiesData = data.data.findManyActivities.edges; + } else if (Array.isArray(data.data?.tasks)) { + // Direct array response + activitiesData = data.data.tasks.map((node: any) => ({ node })); + } else if (Array.isArray(data.data?.activities)) { + // Direct array response + activitiesData = data.data.activities.map((node: any) => ({ node })); + } else if (Array.isArray(data.data)) { + // Root level array + activitiesData = data.data.map((node: any) => ({ node })); + } + + if (!activitiesData) { logger.warn('[TWENTY_CRM_TASKS] Unexpected response format from Twenty CRM', { dataKeys: Object.keys(data.data || {}), + fullData: JSON.stringify(data.data).substring(0, 1000), }); return []; } // Transform Twenty CRM tasks to match our Task interface - const tasks: TwentyTask[] = data.data.findManyActivities.edges.map((edge: any) => ({ - id: edge.node.id, - title: edge.node.title || 'Untitled Task', - body: edge.node.body || null, - dueAt: edge.node.dueAt || null, - completedAt: edge.node.completedAt || null, - type: edge.node.type || 'Task', - assigneeId: edge.node.assigneeId || null, - assignee: edge.node.assignee ? { - id: edge.node.assignee.id, - firstName: edge.node.assignee.firstName || null, - lastName: edge.node.assignee.lastName || null, - email: edge.node.assignee.email || null, - } : null, - })); + const tasks: TwentyTask[] = activitiesData.map((edge: any) => { + const node = edge.node || edge; // Handle both edge.node and direct node + return { + id: node.id, + title: node.title || 'Untitled Task', + body: node.body || null, + dueAt: node.dueAt || null, + completedAt: node.completedAt || null, + type: node.type || 'Task', + assigneeId: node.assigneeId || null, + assignee: node.assignee ? { + id: node.assignee.id, + firstName: node.assignee.firstName || null, + lastName: node.assignee.lastName || null, + email: node.assignee.email || null, + } : null, + }; + }); logger.debug('[TWENTY_CRM_TASKS] Successfully fetched tasks from Twenty CRM', { count: tasks.length,