diff --git a/packages/nodes-base/credentials/AirtableApi.credentials.ts b/packages/nodes-base/credentials/AirtableApi.credentials.ts index 09eee15b4cb70..857ce45eaa8f5 100644 --- a/packages/nodes-base/credentials/AirtableApi.credentials.ts +++ b/packages/nodes-base/credentials/AirtableApi.credentials.ts @@ -8,6 +8,13 @@ export class AirtableApi implements ICredentialType { documentationUrl = 'airtable'; properties: INodeProperties[] = [ + { + displayName: + 'API Keys will be deprecated by the end of January 2024, see this article for more details. We recommend to use Personal Access Token instead.', + name: 'deprecated', + type: 'notice', + default: '', + }, { displayName: 'API Key', name: 'apiKey', diff --git a/packages/nodes-base/credentials/AirtableTokenApi.credentials.ts b/packages/nodes-base/credentials/AirtableTokenApi.credentials.ts new file mode 100644 index 0000000000000..b63a80d236033 --- /dev/null +++ b/packages/nodes-base/credentials/AirtableTokenApi.credentials.ts @@ -0,0 +1,39 @@ +import type { + IAuthenticateGeneric, + ICredentialTestRequest, + ICredentialType, + INodeProperties, +} from 'n8n-workflow'; + +export class AirtableTokenApi implements ICredentialType { + name = 'airtableTokenApi'; + + displayName = 'Airtable Personal Access Token API'; + + documentationUrl = 'airtable'; + + properties: INodeProperties[] = [ + { + displayName: 'Access Token', + name: 'accessToken', + type: 'string', + typeOptions: { password: true }, + default: '', + }, + ]; + + authenticate: IAuthenticateGeneric = { + type: 'generic', + properties: { + headers: { + Authorization: '=Bearer {{$credentials.accessToken}}', + }, + }, + }; + + test: ICredentialTestRequest = { + request: { + baseURL: 'https://api.airtable.com/v0/meta/whoami', + }, + }; +} diff --git a/packages/nodes-base/nodes/Airtable/Airtable.node.ts b/packages/nodes-base/nodes/Airtable/Airtable.node.ts index eb8d499b32022..49c54919769a7 100644 --- a/packages/nodes-base/nodes/Airtable/Airtable.node.ts +++ b/packages/nodes-base/nodes/Airtable/Airtable.node.ts @@ -27,9 +27,39 @@ export class Airtable implements INodeType { { name: 'airtableApi', required: true, + displayOptions: { + show: { + authentication: ['airtableApi'], + }, + }, + }, + { + name: 'airtableTokenApi', + required: true, + displayOptions: { + show: { + authentication: ['airtableTokenApi'], + }, + }, }, ], properties: [ + { + displayName: 'Authentication', + name: 'authentication', + type: 'options', + options: [ + { + name: 'API Key', + value: 'airtableApi', + }, + { + name: 'Access Token', + value: 'airtableTokenApi', + }, + ], + default: 'airtableApi', + }, { displayName: 'Operation', name: 'operation', @@ -546,14 +576,15 @@ export class Airtable implements INodeType { delete (row.fields as any).id; } else { // Add only the specified fields - row.fields = {} as IDataObject; + const rowFields: IDataObject = {}; fields = this.getNodeParameter('fields', i, []) as string[]; for (const fieldName of fields) { - // @ts-ignore - row.fields[fieldName] = items[i].json[fieldName]; + rowFields[fieldName] = items[i].json[fieldName]; } + + row.fields = rowFields; } rows.push(row); @@ -761,10 +792,12 @@ export class Airtable implements INodeType { } else { fields = this.getNodeParameter('fields', i, []) as string[]; + const rowFields: IDataObject = {}; for (const fieldName of fields) { - // @ts-ignore - row.fields[fieldName] = items[i].json[fieldName]; + rowFields[fieldName] = items[i].json[fieldName]; } + + row.fields = rowFields; } row.id = this.getNodeParameter('id', i) as string; diff --git a/packages/nodes-base/nodes/Airtable/AirtableTrigger.node.ts b/packages/nodes-base/nodes/Airtable/AirtableTrigger.node.ts index b54ae8f8da0f4..ce3b868c4f559 100644 --- a/packages/nodes-base/nodes/Airtable/AirtableTrigger.node.ts +++ b/packages/nodes-base/nodes/Airtable/AirtableTrigger.node.ts @@ -28,12 +28,42 @@ export class AirtableTrigger implements INodeType { { name: 'airtableApi', required: true, + displayOptions: { + show: { + authentication: ['airtableApi'], + }, + }, + }, + { + name: 'airtableTokenApi', + required: true, + displayOptions: { + show: { + authentication: ['airtableTokenApi'], + }, + }, }, ], polling: true, inputs: [], outputs: ['main'], properties: [ + { + displayName: 'Authentication', + name: 'authentication', + type: 'options', + options: [ + { + name: 'API Key', + value: 'airtableApi', + }, + { + name: 'Access Token', + value: 'airtableTokenApi', + }, + ], + default: 'airtableApi', + }, { displayName: 'Base', name: 'baseId', @@ -192,19 +222,14 @@ export class AirtableTrigger implements INodeType { async poll(this: IPollFunctions): Promise { const downloadAttachments = this.getNodeParameter('downloadAttachments', 0) as boolean; - const webhookData = this.getWorkflowStaticData('node'); - - const qs: IDataObject = {}; - const additionalFields = this.getNodeParameter('additionalFields') as IDataObject; - const base = this.getNodeParameter('baseId', '', { extractValue: true }) as string; - const table = this.getNodeParameter('tableId', '', { extractValue: true }) as string; - const triggerField = this.getNodeParameter('triggerField') as string; + const qs: IDataObject = {}; + const endpoint = `${base}/${table}`; const now = moment().utc().format(); diff --git a/packages/nodes-base/nodes/Airtable/GenericFunctions.ts b/packages/nodes-base/nodes/Airtable/GenericFunctions.ts index 80e769e18a22b..3b2b3c7b61f16 100644 --- a/packages/nodes-base/nodes/Airtable/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Airtable/GenericFunctions.ts @@ -58,8 +58,8 @@ export async function apiRequest( if (Object.keys(body).length === 0) { delete options.body; } - - return this.helpers.requestWithAuthentication.call(this, 'airtableApi', options); + const authenticationMethod = this.getNodeParameter('authentication', 0) as string; + return this.helpers.requestWithAuthentication.call(this, authenticationMethod, options); } /** diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index fdc95810ccb8c..97c4239261764 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -39,6 +39,7 @@ "dist/credentials/AffinityApi.credentials.js", "dist/credentials/AgileCrmApi.credentials.js", "dist/credentials/AirtableApi.credentials.js", + "dist/credentials/AirtableTokenApi.credentials.js", "dist/credentials/Amqp.credentials.js", "dist/credentials/ApiTemplateIoApi.credentials.js", "dist/credentials/AsanaApi.credentials.js",