feat(Chat Trigger Node): Add support for file uploads & harmonize public and development chat (#9802)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
This commit is contained in:
@@ -5,15 +5,23 @@ async function getAccessToken() {
|
||||
export async function authenticatedFetch<T>(...args: Parameters<typeof fetch>): Promise<T> {
|
||||
const accessToken = await getAccessToken();
|
||||
|
||||
const body = args[1]?.body;
|
||||
const headers: RequestInit['headers'] & { 'Content-Type'?: string } = {
|
||||
...(accessToken ? { authorization: `Bearer ${accessToken}` } : {}),
|
||||
...args[1]?.headers,
|
||||
};
|
||||
|
||||
// Automatically set content type to application/json if body is FormData
|
||||
if (body instanceof FormData) {
|
||||
delete headers['Content-Type'];
|
||||
} else {
|
||||
headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
const response = await fetch(args[0], {
|
||||
...args[1],
|
||||
mode: 'cors',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(accessToken ? { authorization: `Bearer ${accessToken}` } : {}),
|
||||
...args[1]?.headers,
|
||||
},
|
||||
headers,
|
||||
});
|
||||
|
||||
return (await response.json()) as T;
|
||||
@@ -37,6 +45,28 @@ export async function post<T>(url: string, body: object = {}, options: RequestIn
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
}
|
||||
export async function postWithFiles<T>(
|
||||
url: string,
|
||||
body: Record<string, unknown> = {},
|
||||
files: File[] = [],
|
||||
options: RequestInit = {},
|
||||
) {
|
||||
const formData = new FormData();
|
||||
|
||||
for (const key in body) {
|
||||
formData.append(key, body[key] as string);
|
||||
}
|
||||
|
||||
for (const file of files) {
|
||||
formData.append('files', file);
|
||||
}
|
||||
|
||||
return await authenticatedFetch<T>(url, {
|
||||
...options,
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
}
|
||||
|
||||
export async function put<T>(url: string, body: object = {}, options: RequestInit = {}) {
|
||||
return await authenticatedFetch<T>(url, {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { get, post } from '@n8n/chat/api/generic';
|
||||
import { get, post, postWithFiles } from '@n8n/chat/api/generic';
|
||||
import type {
|
||||
ChatOptions,
|
||||
LoadPreviousSessionResponse,
|
||||
@@ -20,7 +20,27 @@ export async function loadPreviousSession(sessionId: string, options: ChatOption
|
||||
);
|
||||
}
|
||||
|
||||
export async function sendMessage(message: string, sessionId: string, options: ChatOptions) {
|
||||
export async function sendMessage(
|
||||
message: string,
|
||||
files: File[],
|
||||
sessionId: string,
|
||||
options: ChatOptions,
|
||||
) {
|
||||
if (files.length > 0) {
|
||||
return await postWithFiles<SendMessageResponse>(
|
||||
`${options.webhookUrl}`,
|
||||
{
|
||||
action: 'sendMessage',
|
||||
[options.chatSessionKey as string]: sessionId,
|
||||
[options.chatInputKey as string]: message,
|
||||
...(options.metadata ? { metadata: options.metadata } : {}),
|
||||
},
|
||||
files,
|
||||
{
|
||||
headers: options.webhookConfig?.headers,
|
||||
},
|
||||
);
|
||||
}
|
||||
const method = options.webhookConfig?.method === 'POST' ? post : get;
|
||||
return await method<SendMessageResponse>(
|
||||
`${options.webhookUrl}`,
|
||||
|
||||
Reference in New Issue
Block a user