gravityflow_webhook_args

The gravityflow_webhook_args filter allows the webhook to be modified before it's sent.

Example 1 - Processing request as per a specific Step ID.

add_filter( 'gravityflow_webhook_args', 'sh_filter_gravityflow_webhook_args', 10, 3 ); 
function sh_filter_gravityflow_webhook_args( $args, $entry, $current_step ) {  
	$step_id = $current_step->get_id(); 
	// only processing for a particular step, exampe step id 87
	if ( $step_id == 87 ) {
		// Add process specific to the selected step here.
	}
	return $args;
}

Example 2 - Modify arguments based on method (get/post/etc)

add_filter( 'gravityflow_webhook_args', 'sh_filter_gravityflow_webhook_args', 10, 3 );
function sh_filter_gravityflow_webhook_args( $args, $entry, $current_step ) {
	// POST only the value of field 2 with a custom key
	if ( $args['method'] == 'POST' ) {
		$args['body'] = array( 'my_value' => $entry['2'] );
	}
	return $args;
}

Example 3 - Add basic authentication using username and password

add_filter( 'gravityflow_webhook_args', 'sh_filter_gravityflow_webhook_args', 10, 3 );
function sh_filter_gravityflow_webhook_args( $args, $entry, $current_step ) {
	$args['headers'] = array(
            'Authorization' => 'Basic ' . base64_encode( YOUR_USERNAME . ':' . YOUR_PASSWORD )
       );

    return $args;
}

Example 4 - Checking URL to determine whether additional webhook arguments are required.

add_filter( 'gravityflow_webhook_args', 'sh_filter_gravityflow_webhook_args', 10, 3 );
function sh_filter_gravityflow_webhook_args( $args, $entry, $current_step ) {
  if ($current_step->url == "test.salesforce.com") {
    // modifying the authentication headers conditionally
    $args['headers'] = array(
      'Authorization' => 'Basic ' . base64_encode( YOUR_USERNAME . ':' . YOUR_PASSWORD )
    );
  }
  return $args;
}

Example 5 - Add custom headers based on step settings

By default, when you select the outgoing webhook format to be FORM, the headers are ignored. This snippet will allow you to override/customize based on step settings to include extra headers.

add_filter( 'gravityflow_webhook_args', 'jo_filter_gravityflow_webhook_args', 10, 3 );
function jo_filter_gravityflow_webhook_args( $args, $entry, $current_step ) {
	if ( $current_step->get_id() == 128 && $current_step->get_setting('format') == 'form' ) {
		//Apply request headers based on step setting defined header key/values
		$headers = gravity_flow()->get_generic_map_fields( $current_step->get_feed_meta(), 'requestHeaders', $current_step->get_form(), $entry );
		// Remove request headers with undefined name.
		unset( $headers[ null ] );
		//To customize headers with separate logic based on step settings header key/values
		//$headers = $current_step->get_setting('requestHeaders');
		$args['headers'] = $headers;

	}
	return $args;
}

Example 6 - Send the admin label as key

If admin label is defined for a field send the admin label as key

add_filter( 'gravityflow_webhook_args', 'sh_filter_gravityflow_webhook_args_subset', 10, 3 );
function sh_filter_gravityflow_webhook_args_subset( $args, $entry, $current_step ) {
	$form = GFAPI::get_form( $entry['form_id'] );

	if ( empty( $current_step->body_type ) || $current_step->body_type == 'all_fields' ){
		$new = array();
		foreach ( $form['fields'] as $key => $field ) {
			//The entry values for checkbox (and other select fields) are not stored against their ID but ID.choice.
			//You should be able to add to the following array for other select based field types.
			if ( in_array( $field->type, array( 'checkbox' ) ) ) {
				foreach ( $field->choices as $choice_key => $choice ) {
					if ( isset( $entry[ $field->id . '.' . $choice_key ] ) && strlen( $entry[ $field->id . '.' . $choice_key ] ) > 0 ) {
						//Will create either "adminlabel.2" or "4.2" depending on the admin label being set
						if ( isset( $form['fields'][ $key ]->adminLabel ) && strlen( $form['fields'][ $key ]->adminLabel ) > 0 ) {
							$new[ $form['fields'][ $key ]->adminLabel . '.' . $choice_key ] = $entry[ $field->id . '.' . $choice_key ];
						} else {
							$new[ $field->id . '.' . $choice_key ] = $entry[ $field->id . '.' . $choice_key ];
						}
					}
				}
				//Assume it is a direct access item by entry field ID
			} else {
				if ( isset( $form['fields'][ $key ]->adminLabel ) && strlen( $form['fields'][ $key ]->adminLabel ) > 0 ) {
					$new[ $form['fields'][ $key ]->adminLabel ] = $entry[ $field->id ];
				} else {
					$new[ $field->id ] = $entry[ $field->id ];
				}
			}
		}
		$args['body'] = json_encode( $new );
	}
	return $args;
}

Example 7 - Post multipart/form-data with single file upload.

By default the value in an outgoing webhook for an upload field will be the path to the file as URL - https://gravity.local/wp-content/gravity_forms/...../example.pdf - but some scenarios will want to send the actual file as a multipart/form-data POST. This example snippet shows how you might do that,

Note that the values you may need to change to work for your use case would be:
- 513 = The Step ID for which you want the logic to execute
- fileToUpload = The Request Field Value Key that your API/form expects the upload file payload to be in
- Ensure in the step settings for your webhook you specify the format as 'Form'

add_filter( 'gravityflow_webhook_args', 'custom_gravityflow_webhook_args', 10, 3 );
function custom_gravityflow_webhook_args( $args, $entry, $current_step ) {

    if ( $current_step->get_id() != '531') {
        return $args;
    }

    $boundary  = md5( microtime() );
    $body_data = $args['body'];
    $payload   = '';

    //Build the HTTP Form Data.
    foreach ( $body_data as $name => $value ) {
        if ( $name == "mimefile" ) {
            // Build the Payload for Resume File
            $file_path = GFFormsModel::get_physical_file_path( $value );
            $base_filename = basename( $value );

            if ( file_exists( $file_path ) ) {
                $payload .= '--' . $boundary;
                $payload .= "\r\n";
                $payload .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $base_filename . '"' . "\r\n\r\n";
                $payload .= file_get_contents( $file_path );
                $payload .= "\r\n";
            }
        } else {
            // Build the Payload for String Data
            $payload .= '--' . $boundary;
            $payload .= "\r\n";
            $payload .= 'Content-Disposition: form-data; name="' . $name . '"' . "\r\n\r\n";
            $payload .= $value;
            $payload .= "\r\n";
        }
        $payload .= '--' . $boundary . '--';
    }

    // HTTP Headers
    $args['headers'] = array(
        'content-type' => 'multipart/form-data;boundary=' . $boundary,
    );
    $args['body'] = $payload;
    return $args;
}

Troubleshooting:

If you are encountering issues with an API receiving results in the proper format we recommend that you:

  • Test your API independently by creating a similar request via a tool like Postman.
    This will rule out WordPress, Gravity Forms, Gravity Flow or the snippet code as potential source of issue.
  • Test your webhook independently by creating a basic file upload form/script
    This will let you test your webhook (and Postman request) to ensure they produce similar results before focusing on API unique elements.

Advanced API scenarios

  • If your API requires providing a CSRF token, it is recommended thatYou use wp_remote_head to make the initial request and then store the response header (x-csrf-token) into a header for the actual outgoing request.
  • $args['headers'] = array(
            'X-Csrf-Token' => 'custom-value-from-wp-remote-head-request'
    );
    	
  • If your API also requires providing a custom SSL cert, wp_remote_request does not support that. You would need to perform a curl request instead that you should consider creating a custom step type that extends the outgoing webhook step for that use case. It is also recommended that secure values related to the SSL cert are not defined through code, but maintained as environment variables and read in via a library such as vlucas/dotenv

Placement

This code should be placed in the functions.php file of your active theme.