fix(Discourse Node): Fix issue with not all posts getting returned and add credential test (#3007)

* 🔨 fix for not all posts returning

*  added credential test

*  Improvements

*  Improvements

*  Define test the new way

*  Remove not needed imports

*  Fix auth test problem

Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
Co-authored-by: Ricardo Espinoza <ricardo@n8n.io>
Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
Michael Kret 2022-04-18 20:31:59 +03:00 committed by GitHub
parent a9653c20ef
commit d68b7a4cf4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 20 deletions

View file

@ -1,5 +1,8 @@
import {
ICredentialDataDecryptedObject,
ICredentialTestRequest,
ICredentialType,
IHttpRequestOptions,
INodeProperties,
} from 'n8n-workflow';
@ -30,4 +33,25 @@ export class DiscourseApi implements ICredentialType {
default: '',
},
];
async authenticate(credentials: ICredentialDataDecryptedObject, requestOptions: IHttpRequestOptions): Promise<IHttpRequestOptions> {
requestOptions.headers = {
'Api-Key': credentials.apiKey,
'Api-Username': credentials.username,
};
if (requestOptions.method === 'GET') {
delete requestOptions.body;
}
return requestOptions;
}
test: ICredentialTestRequest = {
request: {
baseURL: '={{$credentials.url}}',
url: '/admin/groups.json',
method: 'GET',
},
};
}

View file

@ -38,7 +38,7 @@ export class ZendeskApi implements ICredentialType {
password: credentials.apiToken as string,
};
return requestOptions;
}
}
test: ICredentialTestRequest = {
request: {
baseURL: '=https://{{$credentials.subdomain}}.zendesk.com/api/v2',

View file

@ -3,12 +3,16 @@ import {
} from 'n8n-core';
import {
ICredentialsDecrypted,
ICredentialTestFunctions,
IDataObject,
ILoadOptionsFunctions,
INodeCredentialTestResult,
INodeExecutionData,
INodePropertyOptions,
INodeType,
INodeTypeDescription,
JsonObject,
} from 'n8n-workflow';
import {
@ -44,6 +48,7 @@ import {
userGroupFields,
userGroupOperations,
} from './UserGroupDescription';
import { OptionsWithUri } from 'request';
//import moment from 'moment';
@ -117,6 +122,7 @@ export class Discourse implements INodeType {
};
methods = {
loadOptions: {
// Get all the calendars to display them to user so that he can
// select them easily
@ -321,6 +327,7 @@ export class Discourse implements INodeType {
//https://docs.discourse.org/#tag/Posts/paths/~1posts.json/get
if (operation === 'getAll') {
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
const limit = this.getNodeParameter('limit', i, 0) as number;
responseData = await discourseApiRequest.call(
this,
@ -329,11 +336,29 @@ export class Discourse implements INodeType {
{},
qs,
);
responseData = responseData.latest_posts;
//Getting all posts relying on https://github.com/discourse/discourse_api/blob/main/spec/discourse_api/api/posts_spec.rb
let lastPost = responseData.pop();
let previousLastPostID;
while (lastPost.id !== previousLastPostID) {
if (limit && responseData.length > limit) {
break;
}
const chunk = await discourseApiRequest.call(
this,
'GET',
`/posts.json?before=${lastPost.id}`,
{},
qs,
);
responseData = responseData.concat(chunk.latest_posts);
previousLastPostID = lastPost.id;
lastPost = responseData.pop();
}
responseData.push(lastPost);
if (returnAll === false) {
const limit = this.getNodeParameter('limit', i) as number;
responseData = responseData.splice(0, limit);
}
}
@ -495,7 +520,7 @@ export class Discourse implements INodeType {
}
} catch (error) {
if (this.continueOnFail()) {
returnData.push({ error: error.message });
returnData.push({ error: (error as JsonObject).message });
continue;
}
throw error;

View file

@ -9,18 +9,14 @@ import {
} from 'n8n-core';
import {
IDataObject, NodeApiError,
IDataObject, JsonObject, NodeApiError,
} from 'n8n-workflow';
export async function discourseApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, path: string, body: any = {}, qs: IDataObject = {}, option = {}): Promise<any> { // tslint:disable-line:no-any
const credentials = await this.getCredentials('discourseApi');
const credentials = await this.getCredentials('discourseApi') as { url: string };
const options: OptionsWithUri = {
headers: {
'Api-Key': credentials.apiKey,
'Api-Username': credentials.username,
},
method,
body,
qs,
@ -32,10 +28,9 @@ export async function discourseApiRequest(this: IExecuteFunctions | IExecuteSing
if (Object.keys(body).length === 0) {
delete options.body;
}
//@ts-ignore
return await this.helpers.request.call(this, options);
return await this.helpers.requestWithAuthentication.call(this, 'discourseApi', options);
} catch (error) {
throw new NodeApiError(this.getNode(), error);
throw new NodeApiError(this.getNode(), error as JsonObject);
}
}

View file

@ -1,17 +1,10 @@
import {
OptionsWithUri,
} from 'request';
import {
IExecuteFunctions,
} from 'n8n-core';
import {
ICredentialsDecrypted,
ICredentialTestFunctions,
IDataObject,
ILoadOptionsFunctions,
INodeCredentialTestResult,
INodeExecutionData,
INodePropertyOptions,
INodeType,