feat(Discord Node): New sendAndWait operation (#12894)

Co-authored-by: Dana <152518854+dana-gill@users.noreply.github.com>
This commit is contained in:
Michael Kret
2025-01-31 13:44:42 +02:00
committed by GitHub
parent 066908060f
commit d47bfddd65
17 changed files with 379 additions and 135 deletions

View File

@@ -8,10 +8,11 @@ import type {
INode,
INodeExecutionData,
} from 'n8n-workflow';
import { jsonParse, NodeOperationError } from 'n8n-workflow';
import { jsonParse, NodeApiError, NodeOperationError } from 'n8n-workflow';
import { getSendAndWaitConfig } from '../../../../utils/sendAndWait/utils';
import { capitalize } from '../../../../utils/utilities';
import { discordApiRequest } from '../transport';
import { discordApiMultiPartRequest, discordApiRequest } from '../transport';
export const createSimplifyFunction =
(includedFields: string[]) =>
@@ -285,3 +286,141 @@ export async function setupChannelGetter(this: IExecuteFunctions, userGuilds: ID
return channelId;
};
}
export async function sendDiscordMessage(
this: IExecuteFunctions,
{
guildId,
userGuilds,
isOAuth2,
body,
items,
files = [],
itemIndex = 0,
}: {
guildId: string;
userGuilds: IDataObject[];
isOAuth2: boolean;
body: IDataObject;
items: INodeExecutionData[];
files?: IDataObject[];
itemIndex?: number;
},
) {
const sendTo = this.getNodeParameter('sendTo', itemIndex) as string;
let channelId = '';
if (sendTo === 'user') {
const userId = this.getNodeParameter('userId', itemIndex, undefined, {
extractValue: true,
}) as string;
if (isOAuth2) {
try {
await discordApiRequest.call(this, 'GET', `/guilds/${guildId}/members/${userId}`);
} catch (error) {
if (error instanceof NodeApiError && error.httpCode === '404') {
throw new NodeOperationError(
this.getNode(),
`User with the id ${userId} is not a member of the selected guild`,
{
itemIndex,
},
);
}
throw new NodeOperationError(this.getNode(), error, {
itemIndex,
});
}
}
channelId = (
(await discordApiRequest.call(this, 'POST', '/users/@me/channels', {
recipient_id: userId,
})) as IDataObject
).id as string;
if (!channelId) {
throw new NodeOperationError(
this.getNode(),
'Could not create a channel to send direct message to',
{ itemIndex },
);
}
}
if (sendTo === 'channel') {
channelId = this.getNodeParameter('channelId', itemIndex, undefined, {
extractValue: true,
}) as string;
}
if (isOAuth2 && sendTo !== 'user') {
await checkAccessToChannel.call(this, channelId, userGuilds, itemIndex);
}
if (!channelId) {
throw new NodeOperationError(this.getNode(), 'Channel ID is required', {
itemIndex,
});
}
let response: IDataObject[] = [];
if (files?.length) {
const multiPartBody = await prepareMultiPartForm.call(this, items, files, body, itemIndex);
response = await discordApiMultiPartRequest.call(
this,
'POST',
`/channels/${channelId}/messages`,
multiPartBody,
);
} else {
response = await discordApiRequest.call(this, 'POST', `/channels/${channelId}/messages`, body);
}
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(response),
{ itemData: { item: itemIndex } },
);
return executionData;
}
export function createSendAndWaitMessageBody(context: IExecuteFunctions) {
const config = getSendAndWaitConfig(context);
const instanceId = context.getInstanceId();
const attributionText = 'This message was sent automatically with ';
const link = `https://n8n.io/?utm_source=n8n-internal&utm_medium=powered_by&utm_campaign=${encodeURIComponent(
'n8n-nodes-base.telegram',
)}${instanceId ? '_' + instanceId : ''}`;
const description = `${config.message}\n\n_${attributionText}_[n8n](${link})`;
const body = {
embeds: [
{
description,
color: 5814783,
},
],
components: [
{
type: 1,
components: config.options.map((option) => {
return {
type: 2,
style: 5,
label: option.label,
url: `${config.url}?approved=${option.value}`,
};
}),
},
],
};
return body;
}