MCPcopy
hub / github.com/FlowiseAI/Flowise / saveChatflow

Function saveChatflow

packages/server/src/services/chatflows/index.ts:347–452  ·  view source on GitHub ↗
(
    newChatFlow: ChatFlow,
    orgId: string,
    workspaceId: string,
    subscriptionId: string,
    usageCacheManager: UsageCacheManager
)

Source from the content-addressed store, hash-verified

345}
346
347const saveChatflow = async (
348 newChatFlow: ChatFlow,
349 orgId: string,
350 workspaceId: string,
351 subscriptionId: string,
352 usageCacheManager: UsageCacheManager
353): Promise<any> => {
354 validateChatflowType(newChatFlow.type)
355 const appServer = getRunningExpressApp()
356
357 let dbResponse: ChatFlow
358 if (containsBase64File(newChatFlow)) {
359 // we need a 2-step process, as we need to save the chatflow first and then update the file paths
360 // this is because we need the chatflow id to create the file paths
361
362 // step 1 - save with empty flowData
363 const incomingFlowData = newChatFlow.flowData
364 newChatFlow.flowData = JSON.stringify({})
365 const chatflow = appServer.AppDataSource.getRepository(ChatFlow).create(newChatFlow)
366 const step1Results = await appServer.AppDataSource.getRepository(ChatFlow).save(chatflow)
367
368 // step 2 - convert base64 to file paths and update the chatflow
369 step1Results.flowData = await updateFlowDataWithFilePaths(
370 step1Results.id,
371 incomingFlowData,
372 orgId,
373 workspaceId,
374 subscriptionId,
375 usageCacheManager
376 )
377 await _checkAndUpdateDocumentStoreUsage(step1Results, newChatFlow.workspaceId)
378 dbResponse = await appServer.AppDataSource.getRepository(ChatFlow).save(step1Results)
379 } else {
380 const chatflow = appServer.AppDataSource.getRepository(ChatFlow).create(newChatFlow)
381 dbResponse = await appServer.AppDataSource.getRepository(ChatFlow).save(chatflow)
382 }
383
384 // Check if the flow is agentflow and if it has a schedule node, if yes then notify the beat to sync the schedule
385 if (dbResponse.type === EnumChatflowType.AGENTFLOW) {
386 /*** Get chatflows and prepare data ***/
387 const flowData = dbResponse.flowData
388 const parsedFlowData: IReactFlowObject = JSON.parse(flowData)
389 const nodes = (parsedFlowData.nodes || []).filter((node) => node.data.name !== 'stickyNoteAgentflow')
390 const startNode = nodes.find((node) => node.data.name === 'startAgentflow')
391 const startInputType = startNode?.data?.inputs?.startInputType as StartInputType | undefined
392 if (startInputType === 'scheduleInput') {
393 const scheduleInputMode = startNode?.data?.inputs?.scheduleInputMode as ScheduleInputMode | undefined
394 if (!scheduleInputMode) {
395 throw new InternalFlowiseError(
396 StatusCodes.BAD_REQUEST,
397 'Schedule Input Mode is required on the Start node when Start Input Type is Schedule.'
398 )
399 }
400 const resolvedCron = scheduleService.resolveScheduleCron(startNode?.data?.inputs || {})
401 const scheduleTimezone = startNode?.data?.inputs?.scheduleTimezone || 'UTC'
402 const scheduleDefaultInput = startNode?.data?.inputs?.scheduleDefaultInput || ''
403 const scheduleFormDefaultsRaw = startNode?.data?.inputs?.scheduleFormDefaults
404 const scheduleFormDefaults =

Callers

nothing calls this directly

Calls 15

getRunningExpressAppFunction · 0.90
containsBase64FileFunction · 0.90
getAppVersionFunction · 0.90
getTelemetryFlowObjFunction · 0.90
validateChatflowTypeFunction · 0.85
stringifyMethod · 0.80
onScheduleChangedMethod · 0.80
sendTelemetryMethod · 0.80
parseMethod · 0.65
incrementCounterMethod · 0.65

Tested by

no test coverage detected