Problem adding files with ColdFusion via API

Hey all. I’ve been playing with the Monday API and have made a lot of progress towards getting it ready to be available in our system and a couple of other tools we use, however, I’ve hit a bit of a snag when it comes to adding files. I’ve been able to do everything else from adding items, updates, columns, boards and reading what I’ve needed, but adding files is what has finally broken me. I’m basing my code off of Uploading a file to monday.com, the hard way. The author is using NodeJS so I’ve tried to convert it as best I can.
My code below:

<cfset dataQuery = 'mutation($file:File!){add_file_to_column(file:$file,item_id:123456789,column_ID:"files"){id}}'>
<cfset boundary = "xxxxxxxxxx">
<cfset upfile = "image1.png">
<cfset base64Sample = SAMPLE_BASE64_STRING>
<cfset data = "">

<!--- Construct Query --->
<cfset data &= "--" & boundary & "">
<cfset data &= 'Content-Disposition: form-data; name="query";'>
<cfset data &= "\r\nContent-Type:application/json">
<cfset data &= "\r\n\r\n" & dataQuery & "">

<!--- Construct File --->
<cfset data &= "--" & boundary & "\r\n">
<cfset data &= 'Content-Disposition: form-data; name="variables[file]"; filename="' & upfile & '";\r\n'>
<cfset data &= "Content-Type:application/octet-stream;\r\n\r\n">
<cfset data &= ToString(ToBinary(base64Sample))>
<cfset data &= "\r\n--" & boundary & "--\r\n">


<cfhttp method="post" url="https://api.monday.com/v2" result="result">
	<cfhttpparam type="Header" name="Content-Type" value="multipart/form-data; boundary=#boundary#">
	<cfhttpparam type="Header" name="Authorization"  value="API_KEY">
	<cfhttpparam type="body" value="#CharsetEncode(ToBinary(ToBase64(data)), "utf-8")#">
</cfhttp>

<cfset returnStruct = DeserializeJSON(result.filecontent)>

<cfdump var="#returnStruct#">

The formatting has gotten shifted a little bit as I tried to get it working but no matter what I do, it always gives me the same error message: “No query string was present”.

I’m hoping someone here who has more knowledge about doing multi-part boundaries and the Monday API can help.

Thanks to @basdebruin for their help! I was able to get a working bit of code!

<cfset dataQuery = "mutation ($file:File!) {add_file_to_column (item_id: 123456789, column_id: files, file: $file){id}}">
<cfset boundary = "xxxxxxxxxx">
<cfset upfile = "image1.png">
<cfset base64Sample = "SAMPLE_BASE64_IMAGE">
<cfset data = "">
<cfset cflf = "#chr(13)##chr(10)#">

<!--- Construct Query --->
<cfset data &= "--" & boundary & "#cflf#">
<cfset data &= 'Content-Disposition: form-data; name="query"#cflf##cflf#'>
<cfset data &= dataQuery & '#cflf#'>
<cfset data &= "--" & boundary & "#cflf#">

<!--- Construct File --->
<cfset data &= "Content-Disposition: form-data; name=""variables[file]""; filename=""#upfile#"";#cflf#">
<cfset data &= "Content-Type:application/octet-stream;#cflf##cflf#">
<cfset data &= ToString(ToBinary(base64Sample))>
<cfset data &= "#cflf#" &"--" & boundary & "--">

<cfdump var="#data#">
<cfhttp method="post" url="https://api.monday.com/v2/file" result="result">
	<cfhttpparam type="Header" name="Content-Type" value="multipart/form-data; boundary=#boundary#">
	<cfhttpparam type="Header" name="Authorization"  value="API_KEY_HERE">
	<cfhttpparam type="body" value="#data#">
</cfhttp>

<cfset returnStruct = DeserializeJSON(result.filecontent)>

<cfdump var="#returnStruct#">

hi @jWilde

Welcome to the community! I have an example in php (from a WordPress site) and hopefully you can recode that to get it working.

//$upload is an array with the file's type (type) and content (value)
	
    //Generate a boundary, needed for the Header (Content-Type) and the Body (to split in multiple parts)
	$boundary = wp_generate_password(24);
	$eol = "\r\n";

	$header = array(
		'User-Agent' => MONDAY_TEAM . ' GraphQL Client',
		'Authorization' => get_field('mondaykey', 'user_' . get_current_user_id()),
		'Content-Type' => 'multipart/form-data; boundary=' . $boundary
	);

	//We need to build the body from scratch because it is multipart with boundaries
	//Take care of the extra empty lines (twice $eol) before the actual query and file, otherwise an error 500 is returned

	$body = '--' . $boundary . $eol;
	$body .= 'Content-Disposition: form-data; name="query"' . $eol . $eol;
	$body .= 'mutation ($file: File!) {add_file_to_column (item_id: ' . $item_id . ', column_id: file, file: $file) {id}}' . $eol;
	$body .= '--' . $boundary . $eol;
	$body .= 'Content-Disposition: form-data; name="variables[file]"; filename="' . $upload['name'] . '"' . $eol;
	$body .= 'Content-Type: ' . $upload['type'] . $eol . $eol;
	$body .= file_get_contents($upload['value']);
	$body .= $eol . '--' . $boundary . '--';

	$response = wp_remote_post( MONDAY_URL . 'file/', ['headers' => $header, 'body' => $body] );

By reformatting it from your code and another bit of sample code I now have this:

<!--- Construct Query --->
<cfset data &= "--" & boundary & "#chr(13)##chr(10)#">
<cfset data &= 'Content-Disposition: form-data; name="query"#chr(13)##chr(10)##chr(13)##chr(10)#'>
<cfset data &= dataQuery & '#chr(13)##chr(10)#'>
<cfset data &= "--" & boundary & "#chr(13)##chr(10)#">

<!--- Construct File --->

<cfset data &= "--" & boundary & "#chr(13)##chr(10)#">
<cfset data &= 'Content-Disposition: form-data; name="variables[file]"; filename="' & upfile & '";#chr(13)##chr(10)#'>
<cfset data &= "Content-Type:application/octet-stream;#chr(13)##chr(10)##chr(13)##chr(10)#">
<cfset data &= ToString(ToBinary(base64Sample))>
<cfset data &= "#chr(13)##chr(10)#--" & boundary & "--#chr(13)##chr(10)#">

<cfdump var="#data#">
<cfhttp method="post" url="https://api.monday.com/v2" result="result">
	<cfhttpparam type="Header" name="Content-Type" value="multipart/form-data; boundary=#boundary#">
	<cfhttpparam type="Header" name="Authorization"  value="#mondayLogin.Token#">
	<cfhttpparam type="body" value="#data#">
</cfhttp>

<cfset returnStruct = DeserializeJSON(result.filecontent)>

<cfdump var="#returnStruct#">

I’m no longer getting my first error, now I’m getting two new errors:

  • Field ‘add_file_to_column’ is missing required arguments: column_id
  • Field ‘add_file_to_column’ doesn’t accept argument ‘column_ID’

That is because your dataQuery specifies column_ID where it should be column_id

HA! It’s days like this that kill me ha! Ok. I’m making progress. I’ve updated that and now I’m getting a 500: Server error…

Oops, those are somewhat harder to solve I guess. Could it be that you need to escape the " surrounding files, like “files”

Worth giving it a try but I don’t know ColdFusion

I’m looking at the compiled payload and I’m seeing the below. Could the ‘"’ be my issue?

Content-Disposition: form-data; name=&quot;query&quot;

mutation ($file:File!) {add_file_to_column (item_id: 2473690812, column_id: files, file: $file){id}}
--xxxxxxxxxx
Content-Disposition: form-data; name=&quot;variables[file]&quot;; filename=&quot;image1.png&quot;;
Content-Type:application/octet-stream;

I think so, I would say the “compiled payload” should look like:

{add_file_to_column (item_id: 2473690812, column_id: "files", file: $file){id}}

As the API require a string for the colum_id

1 Like

Holy smokes! That was it! When ColdFusion compiled the body it replaced the quotes. By escaping them like you eluded to in an earlier comment worked! I got a couple of files to upload! Thank you for helping me walk through some of these issues!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.