Describe the problem/error/question
I am working on a custom node for Also Marketplace. Here is a link for Swagger Documentation. Downloadable Postman collection is more up to date.
Basically to retrieve the access token you have to send a POST request with username & password and then use that token in Headers for the operations.
What is the error message (if any)?
500 - "Sender
No session token was provided with the request! Please call Authenticate and pass SessionToken.
If I print the sessionToken from credentials, it seems to be generated and also works if used in Postman for any request. This error appears when Authenticate: ‘token’ is not sent in header for the request.
So my guess is authenticate method doesn’t send the sessionToken correctly for my operations. It is a valid token tho.
Please share your workflow
I cannot share a repo, but this is my credentials file:
import {
IAuthenticateGeneric,
ICredentialDataDecryptedObject,
ICredentialTestRequest,
ICredentialType,
IHttpRequestHelper,
INodeProperties,
} from 'n8n-workflow';
export class AlsoMarketPlaceApi implements ICredentialType {
name = 'alsoMarketPlaceApi';
displayName = 'Also Marketplace API';
properties: INodeProperties[] = [
{
displayName: 'Username',
name: 'username',
type: 'string',
default: '',
required: true,
},
{
displayName: 'Password',
name: 'password',
type: 'string',
typeOptions: {
password: true,
},
default: '',
required: true,
},
{
displayName: 'Base URL',
name: 'baseURL',
type: 'string',
default: '',
required: true,
},
{
displayName: 'Session Token',
name: 'sessionToken',
type: 'hidden',
typeOptions: {
expirable: true,
},
default: '',
},
];
async preAuthentication(this: IHttpRequestHelper, credentials: ICredentialDataDecryptedObject) {
// make reques to get access token
const url = `${credentials.baseURL}/GetSessionToken`;
const access_token = await this.helpers.httpRequest({
method: 'POST',
url: url,
headers: {
},
body: {
username: credentials.username,
password: credentials.password
},
});
console.log('access_token: ')
console.log(access_token)
return { sessionToken: access_token };
}
authenticate: IAuthenticateGeneric = {
type: 'generic',
properties: {
headers: {
Authenticate: '={{$credentials.sessionToken}}'
},
},
};
test: ICredentialTestRequest = {
request: {
method: 'POST',
baseURL: '={{$credentials.baseURL}}',
url: '/GetMarketplaces',
},
};
}
This is the node.ts file with 1 operation:
import {
IExecuteFunctions,
} from 'n8n-core';
import {
IHttpRequestOptions,
INodeExecutionData,
INodeType,
INodeTypeDescription,
} from 'n8n-workflow';
export class Alsomarketplace implements INodeType {
description: INodeTypeDescription = {
displayName: 'Also Marketplace',
name: 'alsomarketplace',
// eslint-disable-next-line n8n-nodes-base/node-class-description-icon-not-svg
icon: 'file:also-marketplace.png',
group: ['transform'],
version: 1,
subtitle: '={{ $parameter["operation"] + ": " + $parameter["resource"] }}',
description: 'Consume Also Marketplace API',
defaults: {
name: 'Also Marketplace',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'alsoMarketPlaceApi',
required: true,
},
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
options: [
{
name: 'Marketplace',
value: 'marketplace',
},
],
default: 'marketplace',
noDataExpression: true,
required: true
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
displayOptions: {
show: {
resource: [
'marketplace',
],
},
},
options: [
{
name: 'Get Many',
value: 'getMany',
description: 'Get many marketplaces',
action: 'Gets company owned marketplaces',
},
],
default: 'getMany',
noDataExpression: true,
}
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
let responseData;
const returnData = [];
const resource = this.getNodeParameter('resource', 0) as string;
const operation = this.getNodeParameter('operation', 0) as string;
const credentials = await this.getCredentials('alsoMarketPlaceApi');
for (let i = 0; i < items.length; i++) {
if (resource === 'marketplace') {
if (operation === 'getMany') {
const options: IHttpRequestOptions = {
headers: {
'Accept': 'application/json'
},
method: 'POST',
body: {},
url: `${credentials.baseURL}/GetMarketplaces`,
json: true,
};
console.log(credentials)
responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'alsoMarketPlaceApi', options);
returnData.push(responseData);
}
}
}
return [this.helpers.returnJsonArray(returnData)];
}
}
Share the output returned by the last node
Here is the form of the request in Postman that is working for get many marketplaces:
Can someone help me with this as project is stopped due to this error? I also noticed the sessionToken is not re-generated between requests. How exactly is that expirable: true working?
If I get the sessionToken from credentials and attach it to header in node.ts file, the request works but this is not ideal as we want to reuse the connection for http request module.
Thank you in advance, let me know if there is any info I should provide!
Information on your n8n setup
- n8n version: 0.236.2
- Running n8n via (Docker, npm, n8n cloud, desktop app): npm
- Operating system: MAC