feat(Airtable Node): Access token support (#6160)

This commit is contained in:
Michael Kret 2023-05-04 13:17:22 +03:00 committed by GitHub
parent 91fee0ca66
commit f9fd82040a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 121 additions and 16 deletions

View file

@ -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 <a href="https://support.airtable.com/docs/airtable-api-key-deprecation-notice" target="_blank">this article</a> for more details. We recommend to use Personal Access Token instead.',
name: 'deprecated',
type: 'notice',
default: '',
},
{
displayName: 'API Key',
name: 'apiKey',

View file

@ -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',
},
};
}

View file

@ -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;

View file

@ -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<INodeExecutionData[][] | null> {
const downloadAttachments = this.getNodeParameter('downloadAttachments', 0) as boolean;
const webhookData = this.getWorkflowStaticData('node');
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 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 endpoint = `${base}/${table}`;
const now = moment().utc().format();

View file

@ -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);
}
/**

View file

@ -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",