Skip to content

Commit

Permalink
fix(Notion Node): Regex for block id (#8860)
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-radency authored Mar 13, 2024
1 parent e78cc2d commit a1f6c57
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 10 deletions.
3 changes: 2 additions & 1 deletion packages/nodes-base/nodes/Notion/Notion.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ export class Notion extends VersionedNodeType {
group: ['output'],
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Consume Notion API',
defaultVersion: 2.1,
defaultVersion: 2.2,
};

const nodeVersions: IVersionedNodeType['nodeVersions'] = {
1: new NotionV1(baseDescription),
2: new NotionV2(baseDescription),
2.1: new NotionV2(baseDescription),
2.2: new NotionV2(baseDescription),
};

super(nodeVersions, baseDescription);
Expand Down
42 changes: 42 additions & 0 deletions packages/nodes-base/nodes/Notion/shared/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const apiVersion: { [key: number]: string } = {
1: '2021-05-13',
2: '2021-08-16',
2.1: '2021-08-16',
2.2: '2021-08-16',
};

export async function notionApiRequest(
Expand Down Expand Up @@ -1128,3 +1129,44 @@ export function simplifyBlocksOutput(blocks: IDataObject[], rootId: string) {

return blocks;
}

export function extractBlockId(this: IExecuteFunctions, nodeVersion: number, itemIndex: number) {
let blockId: string;

if (nodeVersion < 2.2) {
blockId = extractPageId(
this.getNodeParameter('blockId', itemIndex, '', { extractValue: true }) as string,
);
} else {
const blockIdRLCData = this.getNodeParameter('blockId', itemIndex, {}) as IDataObject;

if (blockIdRLCData.mode === 'id') {
blockId = blockIdRLCData.value as string;
} else {
const blockRegex = /https:\/\/www\.notion\.so\/.+\?pvs=[0-9]+#([a-f0-9]{2,})/;
const match = (blockIdRLCData.value as string).match(blockRegex);

if (match === null) {
const pageRegex =
/(?:https|http):\/\/www\.notion\.so\/(?:[a-z0-9-]{2,}\/)?(?:[a-zA-Z0-9-]{2,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})/;
const pageMatch = (blockIdRLCData.value as string).match(pageRegex);

if (pageMatch === null) {
throw new NodeOperationError(
this.getNode(),
'Invalid URL, could not find block ID or page ID',
{
itemIndex,
},
);
} else {
blockId = extractPageId(pageMatch[1]);
}
} else {
blockId = match[1];
}
}
}

return blockId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,55 @@ import type { INodeProperties } from 'n8n-workflow';

import { blocks } from './Blocks';

//RLC with fixed regex for blockId
const blockIdRLC: INodeProperties = {
displayName: 'Block',
name: 'blockId',
type: 'resourceLocator',
default: { mode: 'url', value: '' },
required: true,
modes: [
{
displayName: 'Link',
name: 'url',
type: 'string',
placeholder:
'e.g. https://www.notion.so/Block-Test-88888ccc303e4f44847f27d24bd7ad8e?pvs=4#c44444444444bbbbb4d32fdfdd84e',
validation: [
{
type: 'regex',
properties: {
regex:
'(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{2,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*',
errorMessage: 'Not a valid Notion Block URL',
},
},
],
// extractValue: {
// type: 'regex',
// regex: 'https:\\/\\/www\\.notion\\.so\\/.+\\?pvs=[0-9]+#([a-f0-9]{2,})',
// },
},
{
displayName: 'ID',
name: 'id',
type: 'string',
placeholder: 'e.g. ab1545b247fb49fa92d6f4b49f4d8116',
validation: [
{
type: 'regex',
properties: {
regex: '[a-f0-9]{2,}',
errorMessage: 'Not a valid Notion Block ID',
},
},
],
},
],
description:
"The Notion Block to get all children from, when using 'By URL' mode make sure to use the URL of the block itself, you can find it in block parameters in Notion under 'Copy link to block'",
};

export const blockOperations: INodeProperties[] = [
{
displayName: 'Operation',
Expand Down Expand Up @@ -91,9 +140,22 @@ export const blockFields: INodeProperties[] = [
resource: ['block'],
operation: ['append'],
},
hide: {
'@version': [{ _cnd: { gte: 2.2 } }],
},
},
description: 'The Notion Block to append blocks to',
},
{
...blockIdRLC,
displayOptions: {
show: {
resource: ['block'],
operation: ['append'],
'@version': [{ _cnd: { gte: 2.2 } }],
},
},
},
...blocks('block', 'append'),
/* -------------------------------------------------------------------------- */
/* block:getAll */
Expand Down Expand Up @@ -153,9 +215,22 @@ export const blockFields: INodeProperties[] = [
resource: ['block'],
operation: ['getAll'],
},
hide: {
'@version': [{ _cnd: { gte: 2.2 } }],
},
},
description: 'The Notion Block to get all children from',
},
{
...blockIdRLC,
displayOptions: {
show: {
resource: ['block'],
operation: ['getAll'],
'@version': [{ _cnd: { gte: 2.2 } }],
},
},
},
{
displayName: 'Return All',
name: 'returnAll',
Expand Down
12 changes: 4 additions & 8 deletions packages/nodes-base/nodes/Notion/v2/NotionV2.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { jsonParse, NodeApiError } from 'n8n-workflow';
import type { SortData, FileRecord } from '../shared/GenericFunctions';
import {
downloadFiles,
extractBlockId,
extractDatabaseId,
extractDatabaseMentionRLC,
extractPageId,
Expand Down Expand Up @@ -45,6 +46,7 @@ export class NotionV2 implements INodeType {

async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const nodeVersion = this.getNode().typeVersion;
const resource = this.getNodeParameter('resource', 0);
const operation = this.getNodeParameter('operation', 0);

Expand All @@ -60,9 +62,7 @@ export class NotionV2 implements INodeType {
if (operation === 'append') {
for (let i = 0; i < itemsLength; i++) {
try {
const blockId = extractPageId(
this.getNodeParameter('blockId', i, '', { extractValue: true }) as string,
);
const blockId = extractBlockId.call(this, nodeVersion, i);
const blockValues = this.getNodeParameter(
'blockUi.blockValues',
i,
Expand Down Expand Up @@ -100,9 +100,7 @@ export class NotionV2 implements INodeType {
if (operation === 'getAll') {
for (let i = 0; i < itemsLength; i++) {
try {
const blockId = extractPageId(
this.getNodeParameter('blockId', i, '', { extractValue: true }) as string,
);
const blockId = extractBlockId.call(this, nodeVersion, i);
const returnAll = this.getNodeParameter('returnAll', i);
const fetchNestedBlocks = this.getNodeParameter('fetchNestedBlocks', i) as boolean;

Expand Down Expand Up @@ -148,8 +146,6 @@ export class NotionV2 implements INodeType {
..._data,
}));

const nodeVersion = this.getNode().typeVersion;

if (nodeVersion > 2) {
const simplifyOutput = this.getNodeParameter('simplifyOutput', i) as boolean;

Expand Down
2 changes: 1 addition & 1 deletion packages/nodes-base/nodes/Notion/v2/VersionDescription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const versionDescription: INodeTypeDescription = {
name: 'notion',
icon: 'file:notion.svg',
group: ['output'],
version: [2, 2.1],
version: [2, 2.1, 2.2],
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Consume Notion API',
defaults: {
Expand Down

0 comments on commit a1f6c57

Please sign in to comment.