diff --git a/apps/sim/lib/selectors/server/providers/notion.test.ts b/apps/sim/lib/selectors/server/providers/notion.test.ts index 345dace389f..55b955fb5db 100644 --- a/apps/sim/lib/selectors/server/providers/notion.test.ts +++ b/apps/sim/lib/selectors/server/providers/notion.test.ts @@ -47,7 +47,7 @@ describe('Notion server selector adapter', () => { object: 'page', id: 'page-provider-id', properties: { - Name: { type: 'title', title: [{ plain_text: 'Planning' }] }, + Project: { type: 'title', title: [{ plain_text: 'Planning' }] }, }, }), { status: 200 } diff --git a/apps/sim/tools/notion/create_page.ts b/apps/sim/tools/notion/create_page.ts index 0fe31f852bb..335b639ff37 100644 --- a/apps/sim/tools/notion/create_page.ts +++ b/apps/sim/tools/notion/create_page.ts @@ -1,5 +1,6 @@ import type { NotionCreatePageParams, NotionResponse } from '@/tools/notion/types' import { PAGE_OUTPUT_PROPERTIES } from '@/tools/notion/types' +import { extractTitle } from '@/tools/notion/utils' import type { ToolConfig } from '@/tools/types' export const notionCreatePageTool: ToolConfig = { @@ -105,18 +106,7 @@ export const notionCreatePageTool: ToolConfig { const data = await response.json() - let pageTitle = 'Untitled' - - if (data.properties?.title) { - const titleProperty = data.properties.title - if ( - titleProperty.title && - Array.isArray(titleProperty.title) && - titleProperty.title.length > 0 - ) { - pageTitle = titleProperty.title.map((t: any) => t.plain_text || '').join('') - } - } + const pageTitle = extractTitle(data.properties ?? {}) || 'Untitled' return { success: true, @@ -178,18 +168,7 @@ export const notionCreatePageV2Tool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() - let pageTitle = 'Untitled' - - if (data.properties?.title) { - const titleProperty = data.properties.title - if ( - titleProperty.title && - Array.isArray(titleProperty.title) && - titleProperty.title.length > 0 - ) { - pageTitle = titleProperty.title.map((t: any) => t.plain_text || '').join('') - } - } + const pageTitle = extractTitle(data.properties ?? {}) || 'Untitled' return { success: true, diff --git a/apps/sim/tools/notion/read.ts b/apps/sim/tools/notion/read.ts index 91017ddf93b..00d91321c5e 100644 --- a/apps/sim/tools/notion/read.ts +++ b/apps/sim/tools/notion/read.ts @@ -1,5 +1,6 @@ import type { NotionReadParams, NotionResponse } from '@/tools/notion/types' import { PAGE_OUTPUT_PROPERTIES } from '@/tools/notion/types' +import { extractTitle } from '@/tools/notion/utils' import type { ToolConfig } from '@/tools/types' export const notionReadTool: ToolConfig = { @@ -49,19 +50,7 @@ export const notionReadTool: ToolConfig = { transformResponse: async (response: Response, params?: NotionReadParams) => { const data = await response.json() - let pageTitle = 'Untitled' - - // Extract title from properties - if (data.properties?.title) { - const titleProperty = data.properties.title - if ( - titleProperty.title && - Array.isArray(titleProperty.title) && - titleProperty.title.length > 0 - ) { - pageTitle = titleProperty.title.map((t: any) => t.plain_text || '').join('') - } - } + const pageTitle = extractTitle(data.properties ?? {}) || 'Untitled' // Now fetch the page content using blocks endpoint const pageId = params?.pageId?.trim() @@ -199,18 +188,7 @@ export const notionReadV2Tool: ToolConfig { const data = await response.json() - let pageTitle = 'Untitled' - - if (data.properties?.title) { - const titleProperty = data.properties.title - if ( - titleProperty.title && - Array.isArray(titleProperty.title) && - titleProperty.title.length > 0 - ) { - pageTitle = titleProperty.title.map((t: any) => t.plain_text || '').join('') - } - } + const pageTitle = extractTitle(data.properties ?? {}) || 'Untitled' const pageId = params?.pageId?.trim() const accessToken = params?.accessToken diff --git a/apps/sim/tools/notion/responses.test.ts b/apps/sim/tools/notion/responses.test.ts new file mode 100644 index 00000000000..d971bb6feb6 --- /dev/null +++ b/apps/sim/tools/notion/responses.test.ts @@ -0,0 +1,63 @@ +/** + * @vitest-environment node + */ +import { describe, expect, it } from 'vitest' +import { notionCreatePageTool, notionCreatePageV2Tool } from '@/tools/notion/create_page' +import { notionReadTool, notionReadV2Tool } from '@/tools/notion/read' +import { notionUpdatePageTool, notionUpdatePageV2Tool } from '@/tools/notion/update_page' + +const PAGE_TITLE = 'Project Apollo' + +function pageResponse(): Response { + return Response.json({ + id: 'page-1', + url: 'https://www.notion.so/page-1', + created_time: '2026-08-01T00:00:00.000Z', + last_edited_time: '2026-08-02T00:00:00.000Z', + properties: { + Project: { + id: 'title', + type: 'title', + title: [{ plain_text: PAGE_TITLE }], + }, + }, + }) +} + +const responseCases = [ + { + id: notionReadTool.id, + title: async () => + (await notionReadTool.transformResponse!(pageResponse())).output.metadata.title, + }, + { + id: notionReadV2Tool.id, + title: async () => (await notionReadV2Tool.transformResponse!(pageResponse())).output.title, + }, + { + id: notionCreatePageTool.id, + title: async () => + (await notionCreatePageTool.transformResponse!(pageResponse())).output.metadata.title, + }, + { + id: notionCreatePageV2Tool.id, + title: async () => + (await notionCreatePageV2Tool.transformResponse!(pageResponse())).output.title, + }, + { + id: notionUpdatePageTool.id, + title: async () => + (await notionUpdatePageTool.transformResponse!(pageResponse())).output.metadata.title, + }, + { + id: notionUpdatePageV2Tool.id, + title: async () => + (await notionUpdatePageV2Tool.transformResponse!(pageResponse())).output.title, + }, +] + +describe('Notion page title responses', () => { + it.each(responseCases)('$id reads a custom-named title property', async ({ title }) => { + await expect(title()).resolves.toBe(PAGE_TITLE) + }) +}) diff --git a/apps/sim/tools/notion/update_page.ts b/apps/sim/tools/notion/update_page.ts index 7b36c0b9f21..46008012889 100644 --- a/apps/sim/tools/notion/update_page.ts +++ b/apps/sim/tools/notion/update_page.ts @@ -1,5 +1,6 @@ import type { NotionResponse, NotionUpdatePageParams } from '@/tools/notion/types' import { PAGE_OUTPUT_PROPERTIES } from '@/tools/notion/types' +import { extractTitle } from '@/tools/notion/utils' import type { ToolConfig } from '@/tools/types' export const notionUpdatePageTool: ToolConfig = { @@ -57,19 +58,7 @@ export const notionUpdatePageTool: ToolConfig { const data = await response.json() - let pageTitle = 'Untitled' - - // Try to extract the title from properties - if (data.properties?.title) { - const titleProperty = data.properties.title - if ( - titleProperty.title && - Array.isArray(titleProperty.title) && - titleProperty.title.length > 0 - ) { - pageTitle = titleProperty.title.map((t: any) => t.plain_text || '').join('') - } - } + const pageTitle = extractTitle(data.properties ?? {}) || 'Untitled' return { success: true, @@ -133,18 +122,7 @@ export const notionUpdatePageV2Tool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() - let pageTitle = 'Untitled' - - if (data.properties?.title) { - const titleProperty = data.properties.title - if ( - titleProperty.title && - Array.isArray(titleProperty.title) && - titleProperty.title.length > 0 - ) { - pageTitle = titleProperty.title.map((t: any) => t.plain_text || '').join('') - } - } + const pageTitle = extractTitle(data.properties ?? {}) || 'Untitled' return { success: true,