Hallo @kjooleng, danke für den Vorschlag!
Ich bin auf 2 Probleme gestoßen: Zum einen funktioniert dein Construct Multipart Body gut für Text, aber Dateien wie PDF und DOCX werden durch diesen Ansatz absolut verstümmelt.
Ich habe es modifiziert zu:
{
"nodes": \[
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": \[
48,
32
\],
"id": "fb16aeab-57ba-485f-8c6e-7bc015bd1e28",
"name": "When clicking 'Execute workflow'"
},
{
"parameters": {
"jsCode": "const source = $('When Executed by Another Workflow').first();\\nconst sourceBinary = { ...(source.binary || {}) };\\nconst paramsPayload = {\\n projectId: \[source.json.fields.projectID\],\\n language: source.json.fields.language,\\n filterNestedConcepts: source.json.fields.FilterNestedConcepts,\\n numberOfConcepts: source.json.fields.LabelsPerPage,\\n numberOfTerms: source.json.fields.LabelsPerPage,\\n};\\n\\nsourceBinary.params = {\\n data: Buffer.from(JSON.stringify(paramsPayload), 'utf8').toString('base64'),\\n mimeType: 'application/json',\\n fileName: 'params.json',\\n fileExtension: 'json',\\n};\\nreturn \[\\n {\\n binary: sourceBinary,\\n },\\n\];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": \[
272,
32
\],
"id": "100a0875-9bce-4790-be6c-da7a31407523",
"name": "Prepare Extraction Input"
},
{
"parameters": {
"method": "POST",
"url": "https://service.127.0.0.1.nip.io/extractor/api/tag/async",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendBody": true,
"contentType": "binary",
"options": {
"response": {
"response": {
"fullResponse": true,
"neverError": true
}
}
}
},
"id": "ad21249d-27c4-4880-b90a-d747b712cf39",
"name": "TaggingSuggested",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": \[
688,
32
\],
"credentials": {
"httpBasicAuth": {
"id": "abCwyM6KmpPSdwff",
"name": "cred"
}
}
},
{
"parameters": {
"jsCode": "return (async () =\\ > {\\n const CRLF = '\\r\\n';\\n const items = $input.all();\\n const result = [ ];\\n\\n for (let itemIndex = 0; itemIndex \\ < items.length; itemIndex++) {\\n const item = items\[itemIndex\];\\n const boundary = `----n8n${Math.random().toString(36).slice(2, 11)}`;\\n const chunks = [ ];\\n\\n const pushText = (text) =\\ > chunks.push(Buffer.from(text, 'utf8'));\\n\\n pushText(`--${boundary}${CRLF}`);\\n pushText(`Content-Disposition: form-data; name=\"aggregate\"${CRLF}${CRLF}`);\\n pushText(`true${CRLF}`);\\n\\n if (item.binary?.params) {\\n const paramsMeta = item.binary.params;\\n const paramsBuf = await this.helpers.getBinaryDataBuffer(itemIndex, 'params');\\n const fileName = paramsMeta.fileName || 'params.json';\\n const mimeType = paramsMeta.mimeType || 'application/json';\\n\\n pushText(`--${boundary}${CRLF}`);\\n pushText(`Content-Disposition: form-data; name=\"params\"; filename=\"${fileName}\"${CRLF}`);\\n pushText(`Content-Type: ${mimeType}${CRLF}${CRLF}`);\\n chunks.push(paramsBuf);\\n pushText(CRLF);\\n }\\n\\n if (item.binary) {\\n for (const key of Object.keys(item.binary).filter((k) =\\ > k !== 'params')) {\\n const fileMeta = item.binary\[key\];\\n const fileBuf = await this.helpers.getBinaryDataBuffer(itemIndex, key);\\n const fileName = fileMeta.fileName || key;\\n const mimeType = fileMeta.mimeType || 'application/octet-stream';\\n\\n pushText(`--${boundary}${CRLF}`);\\n pushText(`Content-Disposition: form-data; name=\"data\"; filename=\"${fileName}\"${CRLF}`);\\n pushText(`Content-Type: ${mimeType}${CRLF}${CRLF}`);\\n chunks.push(fileBuf);\\n pushText(CRLF);\\n }\\n }\\n\\n pushText(`--${boundary}--${CRLF}`);\\n\\n const body = Buffer.concat(chunks);\\n const contentType = `multipart/form-data; boundary=${boundary}`;\\n\\n result.push({\\n json: {\\n ...(item.json || {}),\\n contentType,\\n },\\n binary: {\\n multipartBody: await this.helpers.prepareBinaryData(\\n body,\\n 'request.bin',\\n contentType\\n ),\\n },\\n });\\n }\\n\\n return result;\\n})();"
},
"id": "505a7281-fd86-41fa-8c28-1cc51187e8b7",
"name": "Construct Multipart Body1",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": \[
480,
32
\]
}
\],
"connections": {
"When clicking 'Execute workflow'": {
"main": \[
\[
{
"node": "Prepare Extraction Input",
"type": "main",
"index": 0
}
\]
\]
},
"Prepare Extraction Input": {
"main": \[
\[
{
"node": "Construct Multipart Body1",
"type": "main",
"index": 0
}
\]
\]
},
"Construct Multipart Body1": {
"main": \[
\[
{
"node": "TaggingSuggested",
"type": "main",
"index": 0
}
\]
\]
}
},
"pinData": {},
"meta": {
"instanceId": "982a83c4fa14b8860ea8391b8f766ad449d7431aac64126d0b9fc936877b58be"
}
}
Das zweite Problem ist, dass ich bei der Anfrage an den Service jetzt eine Fehlermeldung erhalte:
Content-Type is not supported
Ich habe das noch nicht zu debuggen angefangen.