The function node allows you to use custom javascript code to process within the flow.

It can let you make decision paths based on previous nodes, compute variables for future nodes, log information, and many more features.

Return codes

  • Return 1+ to specify which output is to be called. Define the number of outputs using the “Outputs” fields. This will add more output connections to the node
  • Return 0 to complete the flow successfully. This will immediately stop the flow and mark it as successful
  • Return -1 to indicate an error and stop the flow. This will mark the flow as unsuccessful.


This is a list of available builtin members available to a function

// Flow object that is executing
Flow: object
// The name of the machine executing this 
Hostname: string
// Logger available to log messages
Logger: object
// Sleep the execution for passed in milliseconds
Sleep: function(millisecond: number)
// Variables that can be used in many textfields
Variables: map


It includes the “Variables” object which exposes variables from the flow. And you can set future variables for the flow in here

   Varabiles.MyFutureVariable = 'to be used in another flow node';

   // an example of variables from a 'Video Input' node
   let video =[0];
   // or a safe way to get that incase any of those objects are null
   let video =[0];
   if(!video) return -1; // video was null


Lets you log messages to the flow log

   Logger.ILog('an information log message');
   Logger.WLog('an warning log message');
   Logger.ELog('an error log message');
   Logger.DLog('an debug log message');


Allows you to “Sleep” for a specified amount of milliseconds

// Sleep for 10 seconds (10,000 milliseconds)


The “Flow” object lets you perform actions on the flow, it exposes helper methods to the code.

   // will create a directory if it does not already exist
   // if it does exist this function simply returns 
   // its a safe way to ensure a directory exists 

   // return the size in bytes as a number

   // get/set a parameter value with a given key
   Flow.SetParameter(key, value); 

   // maps a path to the local processing node

   // unmaps a path from the local processing node

   // moves the working file to the destination file

   // this will reset the working file to the original File, 
   // this lets you effectively reprocess the original file.  
   // Useful if you want to perform multiple operations on the same file

   // Sets the current working file to the file passed in
   // don't delete is a boolean that if true will not delete the current working file
   // note: if the current working file is the original file, it will NEVER be deleted
   Flow.SetWorkingFile(filename, dontDelete);

   /// Replaces variables in a given string
   /// @input the input string</param>
   /// @stripMissing if missing variables should be removed</param>
   /// @cleanSpecialCharacters if special characters (eg directory path separator) should be replaced
   /// @returns the string with the variables replaced
   Flow.ReplaceVariables(input: string, stripMissing:bool, cleanSpecialCharacters:bool);
   // returns a new GUID as string

   // the full path of the temp path eg /temp/Runner-42f99fc9-158e-408d-9133-de91a56a6ac8

   // the short name of the temp folder, eg Runner-42f99fc9-158e-408d-9133-de91a56a6ac8

   // Gets the temp path on the host if running on docker from the environmental variable "TempPathHost"
   // If not running on docker just returns TempPath

   // the unique identifier of the runner instance eg 42f99fc9-158e-408d-9133-de91a56a6ac8
   // Note: this is used for the TempPathName

   // the original name fo the file that started the flow

   // the relative filename to the library, eg 
   // library /mnt/media/videos
   // full filename /mnt/media/videos/sub/myfile.mkv
   // relative name would be sub/myfile.mkv

   // the fullname of the working file, eg /mnt/media/videos/myfile.mkv

   // The shortname of the working file, eg myfile.mkv

   // the path of the library the file belongs to

   // Get a variable by it's name.  
   // Note: Variables were formally called "Tools" but to make them more generic they were renamed variables.

   // Tests if a input string matches a variable
   // @param variableName The name of the variable
   // @param input the input string
   // @returns true if matches, otherwise false
   Flow.MatchesVariable(variableName: string, input: string);

   // if the flow is running inside a docker container

   // if the flow is running on windows

   // if the flow is running on linux, will also be true if running inside docker as docker is linux
   // if the flow is running on mac
   // if the flow is running on an ARM processor

   /// Copies a file into the temporary directory if it is not already in the temporary directory
   /// @filename [Optional] the filename to copy, if not set the working file will be set
   /// @returns the new filename

   // Execute a process and capture the output
   // you can use arguments for a string argument list, or argumentList which is an string array and will escape the arguments for you correctly
   // timeout is optional, number of seconds to wait before killing the process
   // returns ProcessResults
   //    Completed:bool; // if the process ran to completion or timedout/was canceled
   //    ExitCode:number; // the exit code of the process, may be null
   //    Output:string; // the output, if error output was detected this will contain that output
   //    StandardOutput: string; // the standard output from the process
   //    StandardError: string; // the standard error from the process if any
   Flow.Execute({command:'somecommand.exe', arguments: '-a -b -c', argumentList: ['can', 'use', 'instead of arguments'], timeout: 0, workingDirectory: 'optional'});


This method allows you to execute any command from within a script.

It takes a ExecuteArgs parameter which has the following properties

/// <summary>
/// The command to execute
/// </summary>
string command;
/// <summary>
/// The arguments of the command
/// </summary>
string arguments;
/// <summary>
/// The arguments of the command as a list and will be correctly escaped
/// </summary>
string[] argumentList;
/// <summary>
/// The timeout in seconds of the process
/// </summary>
int timeout;
/// <summary>
/// When silent, nothing will be logged
/// </summary>
bool silent;
/// <summary>
/// The working directory of the process
/// </summary>
string workingDirectory;


Different outputs based on file size

   if(Variables.file.Size > 10_000_000_000) // 10GB
   	return 1; // output 1
   if(Variables.file.Size > 2_000_000_000) // 2GB
   	return 2; // output 2

   let reducedSize = (Variables.file.Size / Variables.file.Orig.Size) * 100;
   if(reducedSize < 10)
   	return 0; // its too small, something went wrong

   return 3; // output 3

Example showing using the Flow.Execute

    // define the output file, in the temp directory with a guid as the name
    let output = Flow.TempPath + '/' + Flow.NewGuid() + '.mkv';
    // get the ffmpeg tool path
    let ffmpeg = Flow.GetToolPath('ffmpeg');
    // execute the process and capture the result
    let process = Flow.Execute({
    	command: ffmpeg,
      workingDirectory: '/media/my-working/directory',
    	argumentList: [
    // log the standard output/error if found
    	Logger.ILog('Standard output: ' + process.standardOutput);
    	Logger.ILog('Standard error: ' + process.starndardError);
    // check the exit code of the process
    if(process.exitCode !== 0){
    	Logger.ELog('Failed processing ffmpeg: ' + process.exitCode);
    	return -1;
    // update the working file to the newly created file from ffmpeg
    return 1;

Copying files in a Function

// file here is a FileInfo object which makes it easy to get the short filename (file.Name)
for(let file in new System.IO.DirectoryInfo('/mnt/source').GetFiles('*.*'))
   System.IO.File.Copy(file.FullName, '/mnt/destination/' + file.Name);

// alternative, where file is a string of the full filename
for(let file in System.IO.Directory.GetFiles('/mnt/source', '*.*')
   System.IO.File.Copy(file, '/mnt/destination/' + file.substring(file.lastIndexOf('/') + 1));

Note: This uses C# to do the copy and look for files

© 2022 FileFlows