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

Post Reply
User avatar
bkromer
Member
Posts: 77
Joined: Thu Jul 11, 2019 10:41 am
Location: Germany

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

Post by bkromer » Tue Mar 31, 2020 10:54 pm

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 Kromer

Padawan
Advanced member
Posts: 316
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 » Wed Apr 01, 2020 8:07 am

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?

User avatar
bkromer
Member
Posts: 77
Joined: Thu Jul 11, 2019 10:41 am
Location: Germany

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

Post by bkromer » Wed Apr 01, 2020 9:20 am

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 8248 times
Benjamin Kromer

User avatar
bkromer
Member
Posts: 77
Joined: Thu Jul 11, 2019 10:41 am
Location: Germany

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

Post by bkromer » Wed Apr 01, 2020 9:21 am

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 8247 times
Benjamin Kromer

Padawan
Advanced member
Posts: 316
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 » Wed Apr 01, 2020 10:39 am

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.

User avatar
bkromer
Member
Posts: 77
Joined: Thu Jul 11, 2019 10:41 am
Location: Germany

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

Post by bkromer » Wed Apr 01, 2020 1:22 pm

Yes! It works :)
Thanks a lot Padawan!

Image
Benjamin Kromer

Padawan
Advanced member
Posts: 316
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 » Wed Apr 01, 2020 1:29 pm

You're welcome :)

rgpepper
Member
Posts: 76
Joined: Wed Oct 14, 2015 2:09 am

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

Post by rgpepper » Tue May 04, 2021 7:23 pm

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.

User avatar
bkromer
Member
Posts: 77
Joined: Thu Jul 11, 2019 10:41 am
Location: Germany

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

Post by bkromer » Tue May 04, 2021 11:00 pm

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 Kromer

rgpepper
Member
Posts: 76
Joined: Wed Oct 14, 2015 2:09 am

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

Post by rgpepper » Mon Jun 21, 2021 11:45 pm

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