Pretty format webhook payload example + unify expected body validation (#13034)

## Webhook Expected Body is automatically pretty formatted


https://github.com/user-attachments/assets/0ca7d621-0c6e-4bef-903f-859efd02f9cc

## Expected body fields can't contain spaces in keys' name


https://github.com/user-attachments/assets/b68d36a6-acd4-4ba2-a99a-5857e30c8582

Closes https://github.com/twentyhq/core-team-issues/issues/1117
This commit is contained in:
Baptiste Devessier
2025-07-04 11:45:14 +02:00
committed by GitHub
parent 92576aec0f
commit 43c3d114bb
5 changed files with 290 additions and 36 deletions
@@ -6,8 +6,10 @@ import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowS
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { useWorkflowActionHeader } from '@/workflow/workflow-steps/workflow-actions/hooks/useWorkflowActionHeader';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { isMethodWithBody } from '@/workflow/workflow-steps/workflow-actions/http-request-action/utils/isMethodWithBody';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
import { useTheme } from '@emotion/react';
import { useEffect } from 'react';
import { useIcons } from 'twenty-ui/display';
import {
@@ -18,8 +20,6 @@ import { useHttpRequestForm } from '../hooks/useHttpRequestForm';
import { useHttpRequestOutputSchema } from '../hooks/useHttpRequestOutputSchema';
import { BodyInput } from './BodyInput';
import { KeyValuePairInput } from './KeyValuePairInput';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useTheme } from '@emotion/react';
type WorkflowEditActionHttpRequestProps = {
action: WorkflowHttpRequestAction;
@@ -109,7 +109,7 @@ export const WorkflowEditActionHttpRequest = ({
)}
<FormRawJsonFieldInput
label="Expected Body Output"
label="Expected Response Body"
placeholder={JSON_RESPONSE_PLACEHOLDER}
defaultValue={outputSchema}
onChange={handleOutputSchemaChange}
@@ -1,5 +1,7 @@
import { WorkflowHttpRequestAction } from '@/workflow/types/Workflow';
import { parseAndValidateVariableFriendlyStringifiedJson } from '@/workflow/utils/parseAndValidateVariableFriendlyStringifiedJson';
import { BaseOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema';
import { isNonEmptyString } from '@sniptt/guards';
import { useState } from 'react';
import { convertOutputSchemaToJson } from '../utils/convertOutputSchemaToJson';
import { getHttpRequestOutputSchema } from '../utils/getHttpRequestOutputSchema';
@@ -30,27 +32,29 @@ export const useHttpRequestOutputSchema = ({
const [error, setError] = useState<string | undefined>();
const handleOutputSchemaChange = (value: string | null) => {
if (value === null || value === '' || readonly === true) {
setError(undefined);
if (readonly === true) {
return;
}
setOutputSchema(value);
try {
const parsedJson = JSON.parse(value);
const outputSchema = getHttpRequestOutputSchema(parsedJson);
onActionUpdate?.({
...action,
settings: {
...action.settings,
outputSchema,
},
});
setError(undefined);
} catch (error) {
setError(String(error));
const parsingResult = parseAndValidateVariableFriendlyStringifiedJson(
isNonEmptyString(value) ? value : '{}',
);
if (!parsingResult.isValid) {
setError(parsingResult.error);
return;
}
setError(undefined);
onActionUpdate?.({
...action,
settings: {
...action.settings,
outputSchema: getHttpRequestOutputSchema(parsingResult.data),
},
});
};
return {