mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
feat(Slack Node): Update to use the new API method for file uploads (#9323)
This commit is contained in:
parent
435272b568
commit
695e762663
|
@ -14,13 +14,14 @@ export class Slack extends VersionedNodeType {
|
||||||
group: ['output'],
|
group: ['output'],
|
||||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||||
description: 'Consume Slack API',
|
description: 'Consume Slack API',
|
||||||
defaultVersion: 2.1,
|
defaultVersion: 2.2,
|
||||||
};
|
};
|
||||||
|
|
||||||
const nodeVersions: IVersionedNodeType['nodeVersions'] = {
|
const nodeVersions: IVersionedNodeType['nodeVersions'] = {
|
||||||
1: new SlackV1(baseDescription),
|
1: new SlackV1(baseDescription),
|
||||||
2: new SlackV2(baseDescription),
|
2: new SlackV2(baseDescription),
|
||||||
2.1: new SlackV2(baseDescription),
|
2.1: new SlackV2(baseDescription),
|
||||||
|
2.2: new SlackV2(baseDescription),
|
||||||
};
|
};
|
||||||
|
|
||||||
super(nodeVersions, baseDescription);
|
super(nodeVersions, baseDescription);
|
||||||
|
|
|
@ -47,6 +47,7 @@ export const fileFields: INodeProperties[] = [
|
||||||
show: {
|
show: {
|
||||||
operation: ['upload'],
|
operation: ['upload'],
|
||||||
resource: ['file'],
|
resource: ['file'],
|
||||||
|
'@version': [2, 2.1],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
description: 'Whether the data to upload should be taken from binary field',
|
description: 'Whether the data to upload should be taken from binary field',
|
||||||
|
@ -61,6 +62,7 @@ export const fileFields: INodeProperties[] = [
|
||||||
operation: ['upload'],
|
operation: ['upload'],
|
||||||
resource: ['file'],
|
resource: ['file'],
|
||||||
binaryData: [false],
|
binaryData: [false],
|
||||||
|
'@version': [2, 2.1],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
placeholder: '',
|
placeholder: '',
|
||||||
|
@ -76,6 +78,23 @@ export const fileFields: INodeProperties[] = [
|
||||||
operation: ['upload'],
|
operation: ['upload'],
|
||||||
resource: ['file'],
|
resource: ['file'],
|
||||||
binaryData: [true],
|
binaryData: [true],
|
||||||
|
'@version': [2, 2.1],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
placeholder: '',
|
||||||
|
description: 'Name of the binary property which contains the data for the file to be uploaded',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'File Property',
|
||||||
|
name: 'binaryPropertyName',
|
||||||
|
type: 'string',
|
||||||
|
default: 'data',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: ['upload'],
|
||||||
|
resource: ['file'],
|
||||||
|
'@version': [2.2],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
placeholder: '',
|
placeholder: '',
|
||||||
|
@ -102,10 +121,31 @@ export const fileFields: INodeProperties[] = [
|
||||||
typeOptions: {
|
typeOptions: {
|
||||||
loadOptionsMethod: 'getChannels',
|
loadOptionsMethod: 'getChannels',
|
||||||
},
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'@version': [2, 2.1],
|
||||||
|
},
|
||||||
|
},
|
||||||
default: [],
|
default: [],
|
||||||
description:
|
description:
|
||||||
'The channels to send the file to. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
'The channels to send the file to. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Channel Name or ID',
|
||||||
|
name: 'channelId',
|
||||||
|
type: 'options',
|
||||||
|
typeOptions: {
|
||||||
|
loadOptionsMethod: 'getChannels',
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'@version': [2.2],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: [],
|
||||||
|
description:
|
||||||
|
'The channel to send the file to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'File Name',
|
displayName: 'File Name',
|
||||||
name: 'fileName',
|
name: 'fileName',
|
||||||
|
|
|
@ -29,7 +29,7 @@ export async function slackApiRequest(
|
||||||
},
|
},
|
||||||
body,
|
body,
|
||||||
qs: query,
|
qs: query,
|
||||||
uri: `https://slack.com/api${resource}`,
|
uri: resource.startsWith('https') ? resource : `https://slack.com/api${resource}`,
|
||||||
json: true,
|
json: true,
|
||||||
};
|
};
|
||||||
options = Object.assign({}, options, option);
|
options = Object.assign({}, options, option);
|
||||||
|
@ -78,6 +78,7 @@ export async function slackApiRequest(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new NodeOperationError(
|
throw new NodeOperationError(
|
||||||
this.getNode(),
|
this.getNode(),
|
||||||
'Slack error response: ' + JSON.stringify(response.error),
|
'Slack error response: ' + JSON.stringify(response.error),
|
||||||
|
|
|
@ -38,7 +38,7 @@ export class SlackV2 implements INodeType {
|
||||||
constructor(baseDescription: INodeTypeBaseDescription) {
|
constructor(baseDescription: INodeTypeBaseDescription) {
|
||||||
this.description = {
|
this.description = {
|
||||||
...baseDescription,
|
...baseDescription,
|
||||||
version: [2, 2.1],
|
version: [2, 2.1, 2.2],
|
||||||
defaults: {
|
defaults: {
|
||||||
name: 'Slack',
|
name: 'Slack',
|
||||||
},
|
},
|
||||||
|
@ -1040,11 +1040,13 @@ export class SlackV2 implements INodeType {
|
||||||
if (operation === 'upload') {
|
if (operation === 'upload') {
|
||||||
const options = this.getNodeParameter('options', i);
|
const options = this.getNodeParameter('options', i);
|
||||||
const body: IDataObject = {};
|
const body: IDataObject = {};
|
||||||
|
const fileBody: IDataObject = {};
|
||||||
|
|
||||||
if (options.channelIds) {
|
if (options.channelIds) {
|
||||||
body.channels = (options.channelIds as string[]).join(',');
|
body.channels = (options.channelIds as string[]).join(',');
|
||||||
}
|
}
|
||||||
if (options.fileName) {
|
if (options.channelId) {
|
||||||
body.filename = options.fileName as string;
|
body.channel_id = options.channelId as string;
|
||||||
}
|
}
|
||||||
if (options.initialComment) {
|
if (options.initialComment) {
|
||||||
body.initial_comment = options.initialComment as string;
|
body.initial_comment = options.initialComment as string;
|
||||||
|
@ -1053,18 +1055,27 @@ export class SlackV2 implements INodeType {
|
||||||
body.thread_ts = options.threadTs as string;
|
body.thread_ts = options.threadTs as string;
|
||||||
}
|
}
|
||||||
if (options.title) {
|
if (options.title) {
|
||||||
|
if (nodeVersion <= 2.1) {
|
||||||
body.title = options.title as string;
|
body.title = options.title as string;
|
||||||
}
|
}
|
||||||
if (this.getNodeParameter('binaryData', i)) {
|
}
|
||||||
|
|
||||||
|
if (this.getNodeParameter('binaryData', i, false) || nodeVersion > 2.1) {
|
||||||
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
|
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
|
||||||
const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
|
const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
|
||||||
|
|
||||||
|
let fileSize: number;
|
||||||
let uploadData: Buffer | Readable;
|
let uploadData: Buffer | Readable;
|
||||||
if (binaryData.id) {
|
if (binaryData.id) {
|
||||||
uploadData = await this.helpers.getBinaryStream(binaryData.id);
|
uploadData = await this.helpers.getBinaryStream(binaryData.id);
|
||||||
|
const metadata = await this.helpers.getBinaryMetadata(binaryData.id);
|
||||||
|
fileSize = metadata.fileSize;
|
||||||
} else {
|
} else {
|
||||||
uploadData = Buffer.from(binaryData.data, BINARY_ENCODING);
|
uploadData = Buffer.from(binaryData.data, BINARY_ENCODING);
|
||||||
|
fileSize = uploadData.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nodeVersion <= 2.1) {
|
||||||
body.file = {
|
body.file = {
|
||||||
value: uploadData,
|
value: uploadData,
|
||||||
options: {
|
options: {
|
||||||
|
@ -1072,6 +1083,7 @@ export class SlackV2 implements INodeType {
|
||||||
contentType: binaryData.mimeType,
|
contentType: binaryData.mimeType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
responseData = await slackApiRequest.call(
|
responseData = await slackApiRequest.call(
|
||||||
this,
|
this,
|
||||||
'POST',
|
'POST',
|
||||||
|
@ -1082,6 +1094,48 @@ export class SlackV2 implements INodeType {
|
||||||
{ formData: body },
|
{ formData: body },
|
||||||
);
|
);
|
||||||
responseData = responseData.file;
|
responseData = responseData.file;
|
||||||
|
} else {
|
||||||
|
fileBody.file = {
|
||||||
|
value: uploadData,
|
||||||
|
options: {
|
||||||
|
filename: binaryData.fileName,
|
||||||
|
contentType: binaryData.mimeType,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadUrl = await slackApiRequest.call(
|
||||||
|
this,
|
||||||
|
'GET',
|
||||||
|
'/files.getUploadURLExternal',
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
filename: options.fileName ? options.fileName : binaryData.fileName,
|
||||||
|
length: fileSize,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
await slackApiRequest.call(
|
||||||
|
this,
|
||||||
|
'POST',
|
||||||
|
uploadUrl.upload_url,
|
||||||
|
{},
|
||||||
|
qs,
|
||||||
|
{ 'Content-Type': 'multipart/form-data' },
|
||||||
|
{ formData: fileBody },
|
||||||
|
);
|
||||||
|
body.files = [
|
||||||
|
{
|
||||||
|
id: uploadUrl.file_id,
|
||||||
|
title: options.title ? options.title : binaryData.fileName,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
responseData = await slackApiRequest.call(
|
||||||
|
this,
|
||||||
|
'POST',
|
||||||
|
'/files.completeUploadExternal',
|
||||||
|
body,
|
||||||
|
);
|
||||||
|
responseData = responseData.files;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const fileContent = this.getNodeParameter('fileContent', i) as string;
|
const fileContent = this.getNodeParameter('fileContent', i) as string;
|
||||||
body.content = fileContent;
|
body.content = fileContent;
|
||||||
|
|
Loading…
Reference in a new issue