diff --git a/packages/backend/src/apps/notion/actions/index.js b/packages/backend/src/apps/notion/actions/index.js index 0b1629e1..17ddaccb 100644 --- a/packages/backend/src/apps/notion/actions/index.js +++ b/packages/backend/src/apps/notion/actions/index.js @@ -1,5 +1,11 @@ import createDatabaseItem from './create-database-item/index.js'; import createPage from './create-page/index.js'; import findDatabaseItem from './find-database-item/index.js'; +import updateDatabaseItem from './update-database-item/index.js'; -export default [createDatabaseItem, createPage, findDatabaseItem]; +export default [ + createDatabaseItem, + createPage, + findDatabaseItem, + updateDatabaseItem, +]; diff --git a/packages/backend/src/apps/notion/actions/update-database-item/index.js b/packages/backend/src/apps/notion/actions/update-database-item/index.js new file mode 100644 index 00000000..79ab0ccc --- /dev/null +++ b/packages/backend/src/apps/notion/actions/update-database-item/index.js @@ -0,0 +1,157 @@ +import defineAction from '../../../../helpers/define-action.js'; + +export default defineAction({ + name: 'Update database item', + key: 'updateDatabaseItem', + description: 'Updates a database item.', + arguments: [ + { + label: 'Database', + key: 'databaseId', + type: 'dropdown', + required: true, + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listDatabases', + }, + ], + }, + }, + { + label: 'Item', + key: 'itemId', + type: 'dropdown', + required: true, + variables: true, + dependsOn: ['parameters.databaseId'], + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listDatabaseItems', + }, + { + name: 'parameters.databaseId', + value: '{parameters.databaseId}', + }, + ], + }, + }, + { + label: 'Name', + key: 'name', + type: 'string', + required: false, + description: + 'This field has a 2000 character limit. Any characters beyond 2000 will not be included.', + variables: true, + }, + { + label: 'Tags', + key: 'tags', + type: 'dynamic', + required: false, + description: '', + fields: [ + { + label: 'Tag', + key: 'tag', + type: 'dropdown', + required: true, + variables: true, + dependsOn: ['parameters.databaseId'], + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listTags', + }, + { + name: 'parameters.databaseId', + value: '{parameters.databaseId}', + }, + ], + }, + }, + ], + }, + { + label: 'Content', + key: 'content', + type: 'string', + required: false, + description: + 'You can choose to add extra text to the database item, with a limit of up to 2000 characters if desired.', + variables: true, + }, + ], + + async run($) { + const itemId = $.step.parameters.itemId; + const name = $.step.parameters.name; + const truncatedName = name.slice(0, 2000); + const content = $.step.parameters.content; + const truncatedContent = content.slice(0, 2000); + const tags = $.step.parameters.tags; + const formattedTags = tags + .filter((tag) => tag.tag !== '') + .map((tag) => tag.tag); + + const body = { + properties: {}, + }; + + if (truncatedName) { + body.properties.Name = { + title: [ + { + text: { + content: truncatedName, + }, + }, + ], + }; + } + + if (formattedTags?.length) { + body.properties.Tags = { + multi_select: formattedTags.map((tag) => ({ name: tag })), + }; + } + + if (truncatedContent) { + const response = await $.http.get(`/v1/blocks/${itemId}/children`); + const firstBlockId = response.data.results[0].id; + + const body = { + paragraph: { + rich_text: [ + { + type: 'text', + text: { + content: truncatedContent, + }, + }, + ], + }, + }; + + await $.http.patch(`/v1/blocks/${firstBlockId}`, body); + } + + const { data } = await $.http.patch(`/v1/pages/${itemId}`, body); + + $.setActionItem({ + raw: data, + }); + }, +}); diff --git a/packages/backend/src/apps/notion/dynamic-data/index.js b/packages/backend/src/apps/notion/dynamic-data/index.js index 3811a7c3..0862a98a 100644 --- a/packages/backend/src/apps/notion/dynamic-data/index.js +++ b/packages/backend/src/apps/notion/dynamic-data/index.js @@ -1,4 +1,6 @@ +import listDatabaseItems from './list-database-items/index.js'; import listDatabases from './list-databases/index.js'; import listParentPages from './list-parent-pages/index.js'; +import listTags from './list-tags/index.js'; -export default [listDatabases, listParentPages]; +export default [listDatabaseItems, listDatabases, listParentPages, listTags]; diff --git a/packages/backend/src/apps/notion/dynamic-data/list-database-items/index.js b/packages/backend/src/apps/notion/dynamic-data/list-database-items/index.js new file mode 100644 index 00000000..1bb6dffb --- /dev/null +++ b/packages/backend/src/apps/notion/dynamic-data/list-database-items/index.js @@ -0,0 +1,38 @@ +export default { + name: 'List database items', + key: 'listDatabaseItems', + + async run($) { + const databases = { + data: [], + error: null, + }; + const payload = { + start_cursor: undefined, + }; + const databaseId = $.step.parameters.databaseId; + + if (!databaseId) { + return databases; + } + + do { + const response = await $.http.post( + `/v1/databases/${databaseId}/query`, + payload + ); + + payload.start_cursor = response.data.next_cursor; + + for (const database of response.data.results) { + databases.data.push({ + value: database.id, + name: + database.properties.Name?.title?.[0]?.plain_text || 'Untitled Page', + }); + } + } while (payload.start_cursor); + + return databases; + }, +}; diff --git a/packages/backend/src/apps/notion/dynamic-data/list-databases/index.js b/packages/backend/src/apps/notion/dynamic-data/list-databases/index.js index da8f27d8..9466b643 100644 --- a/packages/backend/src/apps/notion/dynamic-data/list-databases/index.js +++ b/packages/backend/src/apps/notion/dynamic-data/list-databases/index.js @@ -22,7 +22,7 @@ export default { for (const database of response.data.results) { databases.data.push({ value: database.id, - name: database.title[0].plain_text, + name: database.title?.[0]?.plain_text || 'Untitled Database', }); } } while (payload.start_cursor); diff --git a/packages/backend/src/apps/notion/dynamic-data/list-tags/index.js b/packages/backend/src/apps/notion/dynamic-data/list-tags/index.js new file mode 100644 index 00000000..13d518eb --- /dev/null +++ b/packages/backend/src/apps/notion/dynamic-data/list-tags/index.js @@ -0,0 +1,38 @@ +export default { + name: 'List tags', + key: 'listTags', + + async run($) { + const tags = { + data: [], + error: null, + }; + const databaseId = $.step.parameters.databaseId; + let allTags; + + if (!databaseId) { + return tags; + } + + const response = await $.http.get(`/v1/databases/${databaseId}`); + const tagsExist = + response.data.properties.Tags.multi_select.options.length !== 0; + + if (tagsExist) { + allTags = response.data.properties.Tags.multi_select.options.map( + (tag) => tag.name + ); + } else { + return tags; + } + + for (const tag of allTags) { + tags.data.push({ + value: tag, + name: tag, + }); + } + + return tags; + }, +}; diff --git a/packages/docs/pages/apps/notion/actions.md b/packages/docs/pages/apps/notion/actions.md index d168016d..eaad992d 100644 --- a/packages/docs/pages/apps/notion/actions.md +++ b/packages/docs/pages/apps/notion/actions.md @@ -7,6 +7,8 @@ items: desc: Creates a page inside a parent page. - name: Find database item desc: Searches for an item in a database by property. + - name: Update database item + desc: Updates a database item. ---