How to POST a file to an API (Content-Type: multipart/formdata)

Post Reply
bkromer
Member
Posts: 99
Joined: Thu Jul 11, 2019 10:41 am

How to POST a file to an API (Content-Type: multipart/formdata)

Post by bkromer »

Hello Everyone,

I try to upload a file to ninox (https://ninox.com/) a cloud database with a REST-API (docs: https://ninox.com/de/manual/ninox-api/rest-api). Content-Type must be multipart/formdata.

I tried:

Code: Select all

function jobArrived( s : Switch, job : Job )
{
	// VIA API TO NINOX DATABASE
	var theHTTP = new HTTP( HTTP.SSL );
	theHTTP.authScheme = HTTP.OauthAuth;
	theHTTP.authorization = "Bearer "+apiKey;
	theHTTP.setAttachedFile( job.getPath() );
	theHTTP.url = "https://api.ninoxdb.de/v1/teams/asdFGW849643dad/databases/fwa469844dawd/tables/C/records/76/files"; 
	theHTTP.setPostData("Content-Type: multipart/form-data");
	theHTTP.post();
	while( !theHTTP.waitForFinished( 3 ) )
	  {
	       job.log( 1, "API CALL IN PROGRESS!" );
	  } 
		
	if( theHTTP.finishedStatus == HTTP.Ok && theHTTP.statusCode == 200 )
	  {
			
	       
			job.log(1,"API CALL successfull RESPONSE: "+theHTTP.getServerResponse().toString( "UTF-8" ));
	  }
	else
	{
		job.log(3,"API CALL Failed:  "+theHTTP.getServerResponse().toString( "UTF-8" )+ "  Status Code: "+theHTTP.statusCode.toString( "UTF-8" ));
	}
	
	 
// outgoing conn
	job.sendToSingle( job.getPath() );
}

I get an error:
31.03.2020 22:33,Error,,Test Flow,Script Element,00001,sc1.jpg,Error in line 10 of script : No matching slot found_ available overloads are:; void SHTTP::setPostData(Utility8::SByteArray_QString);
Does anybody know how to handle those Multipart/form-data posts? I have no clue. :?
It works in postman. But it's easy there.

Kind regards
Ben
Benjamin
Padawan
Advanced member
Posts: 358
Joined: Mon Jun 12, 2017 8:48 pm
Location: Belgium
Contact:

Re: How to POST a file to an API (Content-Type: multipart/formdata)

Post by Padawan »

Hi Ben,

Can you try this?

Code: Select all

function jobArrived( s : Switch, job : Job )
{
	// VIA API TO NINOX DATABASE
	var theHTTP = new HTTP( HTTP.SSL );
	theHTTP.authScheme = HTTP.OauthAuth;
	theHTTP.authorization = "Bearer "+apiKey;
	theHTTP.setAttachedFile( job.getPath() ); // You can add the multipart form name as a second argument
	theHTTP.url = "https://api.ninoxdb.de/v1/teams/asdFGW849643dad/databases/fwa469844dawd/tables/C/records/76/files"; 
	theHTTP.enableMime = true;
	theHTTP.post();
	while( !theHTTP.waitForFinished( 3 ) )
	  {
	       job.log( 1, "API CALL IN PROGRESS!" );
	  } 
		
	if( theHTTP.finishedStatus == HTTP.Ok && theHTTP.statusCode == 200 )
	  {
			
	       
			job.log(1,"API CALL successfull RESPONSE: "+theHTTP.getServerResponse().toString( "UTF-8" ));
	  }
	else
	{
		job.log(3,"API CALL Failed:  "+theHTTP.getServerResponse().toString( "UTF-8" )+ "  Status Code: "+theHTTP.statusCode.toString( "UTF-8" ));
	}
	
	 
// outgoing conn
	job.sendToSingle( job.getPath() );
}
I didn't really check the ninox documentation, but this should be the correct way to do multi part form according to the Switch scripting documentation.

Interesting that you want to use Ninox, I looked at it in the past but my customer didn't want to move forward with it. Would you mind explaining your usecase?
bkromer
Member
Posts: 99
Joined: Thu Jul 11, 2019 10:41 am

Re: How to POST a file to an API (Content-Type: multipart/formdata)

Post by bkromer »

Thanks for your reply Padawan.

This doesn't work, I also tried putting in the filename as second argument for the "setAttatchedFile()" function.
But I guess that was not what you meant with "...multipart form name..." right?

Code: Select all

function jobArrived( s : Switch, job : Job )
{
	filename = job.getName();
	// VIA API TO NINOX DATABASE
	var theHTTP = new HTTP( HTTP.SSL );
	theHTTP.authScheme = HTTP.OauthAuth;
	theHTTP.authorization = "Bearer "+apikey;
	theHTTP.setAttachedFile(filename,job.getPath() ); // You can add the multipart form name as a second argument
	theHTTP.url = "https://api.ninoxdb.de/v1/teams/uvasdarz7twsCfQ/databases/j8bert0e3uxf60/tables/C/records/37/files"; 
	theHTTP.enableMime = true;
	theHTTP.post();
	while( !theHTTP.waitForFinished( 3 ) )
	  {
	       job.log( 1, "API CALL IN PROGRESS!" );
	  } 
		
	if( theHTTP.finishedStatus == HTTP.Ok && theHTTP.statusCode == 200 )
	  {
			
	       
			job.log(1,"API CALL successfull RESPONSE: "+theHTTP.getServerResponse().toString( "UTF-8" ));
	  }
	else
	{
		job.log(3,"API CALL Failed:  "+theHTTP.getServerResponse().toString( "UTF-8" )+ "  Status Code: "+theHTTP.statusCode.toString( "UTF-8" ));
	}
	
	 
// outgoing conn
	job.sendToSingle( job.getPath() );
}
The use-case is rather simple. I try to replace an Integromat Workflow we use as the scenario running over there is getting quite expensive.

Every time a new file is dropped in a switch folder it creates a png from it and saves both files in a google drive sync folder. Integromat watches this folder looks for the filename in ninox if the filename is found it updates the file and share link if not it creates a new dataset in ninox with the png attached and it also creates a share link to the file in google drive and writes it in a field as well. The database is from the sales department and they create orders within this table and as there are many types of products they cant imagine everyone by the name so they need to have a view.
Also the order documents created in ninox will use the png`s as well.
Attachments
Bildschirmfoto 2020-04-01 um 08.56.28.png
Bildschirmfoto 2020-04-01 um 08.56.28.png (65.57 KiB) Viewed 20828 times
Benjamin
bkromer
Member
Posts: 99
Joined: Thu Jul 11, 2019 10:41 am

Re: How to POST a file to an API (Content-Type: multipart/formdata)

Post by bkromer »

That's the integromat flow:
Attachments
Bildschirmfoto 2020-04-01 um 09.21.01.png
Bildschirmfoto 2020-04-01 um 09.21.01.png (160.6 KiB) Viewed 20827 times
Benjamin
Padawan
Advanced member
Posts: 358
Joined: Mon Jun 12, 2017 8:48 pm
Location: Belgium
Contact:

Re: How to POST a file to an API (Content-Type: multipart/formdata)

Post by Padawan »

This line is wrong:

theHTTP.setAttachedFile(filename,job.getPath() ); // You can add the multipart form name as a second argument

the first argument should be the path to the file, the second argument the name of the form field. So it should be this:

theHTTP.setAttachedFile(job.getPath(),filename); // You can add the multipart form name as a second argument

I also don't see anything saying Oauth in the Ninox documentation, so I think you should use HTTP.ProprietaryAuth instead of HTTP.OauthAuth.

This gives the following code:

Code: Select all

function jobArrived( s : Switch, job : Job )
{
	filename = job.getName();
	// VIA API TO NINOX DATABASE
	var theHTTP = new HTTP( HTTP.SSL );
	theHTTP.authScheme = HTTP.ProprietaryAuth;
	theHTTP.authorization = "Bearer "+apikey;
	theHTTP.setAttachedFile(job.getPath(), filename ); // You can add the multipart form name as a second argument
	theHTTP.url = "https://api.ninoxdb.de/v1/teams/uvasdarz7twsCfQ/databases/j8bert0e3uxf60/tables/C/records/37/files"; 
	theHTTP.enableMime = true;
	theHTTP.post();
	while( !theHTTP.waitForFinished( 3 ) )
	  {
	       job.log( 1, "API CALL IN PROGRESS!" );
	  } 
		
	if( theHTTP.finishedStatus == HTTP.Ok && theHTTP.statusCode == 200 )
	  {
			
	       
			job.log(1,"API CALL successfull RESPONSE: "+theHTTP.getServerResponse().toString( "UTF-8" ));
	  }
	else
	{
		job.log(3,"API CALL Failed:  "+theHTTP.getServerResponse().toString( "UTF-8" )+ "  Status Code: "+theHTTP.statusCode.toString( "UTF-8" ));
	}
	
	 
// outgoing conn
	job.sendToSingle( job.getPath() );
}
Can you try this?

Edit: Also, that is a very interesting usecase, thanks for sharing! Ninox seems like something interesting to keep in mind for future projects.
bkromer
Member
Posts: 99
Joined: Thu Jul 11, 2019 10:41 am

Re: How to POST a file to an API (Content-Type: multipart/formdata)

Post by bkromer »

Yes! It works :)
Thanks a lot Padawan!

Image
Benjamin
Padawan
Advanced member
Posts: 358
Joined: Mon Jun 12, 2017 8:48 pm
Location: Belgium
Contact:

Re: How to POST a file to an API (Content-Type: multipart/formdata)

Post by Padawan »

You're welcome :)
rgpepper
Member
Posts: 80
Joined: Wed Oct 14, 2015 2:09 am

Re: How to POST a file to an API (Content-Type: multipart/formdata)

Post by rgpepper »

I have a similar question except for two things:
I need to do this without scripting.
I need to provide the HTTP POST as "multi-part/related" to the Muller-Martini "Connex" software (if anyone is familiar with that).

Sending a .jmf file using HTTP POST from the stock "HTTP request" configurator. Tried MIME encoding on/off, no joy.
bkromer
Member
Posts: 99
Joined: Thu Jul 11, 2019 10:41 am

Re: How to POST a file to an API (Content-Type: multipart/formdata)

Post by bkromer »

Cant find a Documentation for that API. Can you provide some more information on Müller Martini Connex?
rgpepper wrote: Tue May 04, 2021 7:23 pm ...I need to do this without scripting....
Why :?:
Benjamin
rgpepper
Member
Posts: 80
Joined: Wed Oct 14, 2015 2:09 am

Re: How to POST a file to an API (Content-Type: multipart/formdata)

Post by rgpepper »

This ended up working:

URL - http://172.##.##.##:55000

Header (this was the final piece to make it work) Content-Type: multipart/related; boundary="____MM-Part-Boundary____"

The main reason I didn't want to use scripting is I haven't conquered that hill yet, and wasn't going to try and drag someone through going back and forth to get it working.
Post Reply