Skip to content

Commit e03319b

Browse files
committed
feat(api): enhance workflow execution parameters to support email message simulation and improved body parsing for various content types
1 parent ce0aa8f commit e03319b

1 file changed

Lines changed: 94 additions & 38 deletions

File tree

apps/api/src/routes/workflows.ts

Lines changed: 94 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -398,53 +398,109 @@ workflowRoutes.post(
398398

399399
// Get request body if it exists
400400
let body: any = undefined;
401-
try {
402-
const contentType = c.req.header("content-type");
403-
if (contentType?.includes("application/json")) {
404-
body = await c.req.json();
405-
} else if (
406-
contentType?.includes("multipart/form-data") ||
407-
contentType?.includes("application/x-www-form-urlencoded")
408-
) {
409-
formData = Object.fromEntries(await c.req.formData());
410-
// Convert form data to body for consistency
411-
body = Object.fromEntries(
412-
Object.entries(formData).map(([key, value]) => [
413-
key,
414-
// Try to parse numbers
415-
!isNaN(Number(value)) ? Number(value) : value,
416-
])
417-
);
418-
}
419-
} catch (error) {
420-
console.error("Error parsing request body:", error);
421-
// Continue without body
401+
const contentType = c.req.header("content-type");
402+
if (contentType?.includes("application/json")) {
403+
body = await c.req.json();
404+
} else if (
405+
contentType?.includes("multipart/form-data") ||
406+
contentType?.includes("application/x-www-form-urlencoded")
407+
) {
408+
formData = Object.fromEntries(await c.req.formData());
409+
// Convert form data to body for consistency
410+
body = Object.fromEntries(
411+
Object.entries(formData).map(([key, value]) => {
412+
// Try to parse numbers and booleans
413+
if (typeof value === 'string') {
414+
if (value.toLowerCase() === "true") return [key, true];
415+
if (value.toLowerCase() === "false") return [key, false];
416+
if (!isNaN(Number(value))) return [key, Number(value)];
417+
}
418+
return [key, value];
419+
})
420+
);
422421
}
423422

424-
// Trigger the runtime and get the instance id
425-
const instance = await c.env.EXECUTE.create({
426-
params: {
427-
userId,
428-
organizationId: organizationId,
429-
workflow: {
430-
id: workflow.id,
431-
name: workflow.name,
432-
handle: workflow.handle,
433-
type: workflowData.type,
434-
nodes: workflowData.nodes,
435-
edges: workflowData.edges,
423+
const baseExecutionParams = {
424+
userId,
425+
organizationId: organizationId,
426+
workflow: {
427+
id: workflow.id,
428+
name: workflow.name,
429+
handle: workflow.handle,
430+
type: workflowData.type,
431+
nodes: workflowData.nodes,
432+
edges: workflowData.edges,
433+
},
434+
monitorProgress,
435+
deploymentId,
436+
};
437+
438+
let finalExecutionParams: any;
439+
440+
if (workflowData.type === "email_message") {
441+
const emailFrom = body?.from || "sender@example.com";
442+
const emailSubject = body?.subject || "Default Subject";
443+
const emailBody = body?.body || "Default email body.";
444+
const emailTo = `workflow+${organizationId}+${workflow.handle || workflow.id}@dafthunk.com`;
445+
446+
const simulatedHeaders = {
447+
"from": emailFrom,
448+
"to": emailTo,
449+
"subject": emailSubject,
450+
"content-type": "text/plain; charset=us-ascii",
451+
"date": new Date().toUTCString(),
452+
"message-id": `<${uuid()}@dafthunk.com>`,
453+
};
454+
455+
const simulatedRaw = `Received: from [127.0.0.1] (localhost [127.0.0.1])\n` +
456+
`by dafthunk.com (Postfix) with ESMTP id FAKEIDFORTEST\n` +
457+
`for <${emailTo}>; ${new Date().toUTCString()}\n` +
458+
`From: ${emailFrom}\n` +
459+
`To: ${emailTo}\n` +
460+
`Subject: ${emailSubject}\n` +
461+
`Date: ${new Date().toUTCString()}\n` +
462+
`Message-ID: <${simulatedHeaders["message-id"]}>\n` +
463+
`Content-Type: text/plain; charset=us-ascii\n` +
464+
`Content-Transfer-Encoding: 7bit\n\n` +
465+
`${emailBody}`;
466+
467+
finalExecutionParams = {
468+
...baseExecutionParams,
469+
emailMessage: {
470+
from: emailFrom,
471+
to: emailTo,
472+
headers: simulatedHeaders,
473+
raw: simulatedRaw,
436474
},
437-
monitorProgress,
438-
deploymentId,
475+
};
476+
} else if (workflowData.type === "http_request") {
477+
finalExecutionParams = {
478+
...baseExecutionParams,
439479
httpRequest: {
440480
url,
441481
method,
442482
headers,
443483
query,
444-
formData,
445-
body,
484+
formData, // Will be undefined if not form-data content type
485+
body, // Parsed JSON or converted form-data
446486
},
447-
},
487+
};
488+
} else {
489+
// For other workflow types, include basic HTTP context without payload
490+
finalExecutionParams = {
491+
...baseExecutionParams,
492+
httpRequest: {
493+
url,
494+
method,
495+
headers,
496+
query,
497+
// formData and body are intentionally omitted
498+
},
499+
};
500+
}
501+
502+
const instance = await c.env.EXECUTE.create({
503+
params: finalExecutionParams,
448504
});
449505
const executionId = instance.id;
450506

0 commit comments

Comments
 (0)