Using Publish API in JavaScript

Hey everyone,

I am trying to use JavaScript to upload an image to Roblox in a user’s account, and I need help.

So far I’ve found some resources:
https://publish.roblox.com/docs#!/Items/post_v1_assets_upload
https://api.roblox.com/docs
https://api.roblox.com/docs?useconsolidatedpage=true

My JavaScript code:

conn = new Socket();
conn.encoding = "binary";
if (conn.open ("www.roblox.com:80", "binary")) {
	var file = new File(doc.path + "/" + "Home" + ".png");
	if (file.exists) {
		alert("Connected!");
		conn.write("POST https://publish.roblox.com/v1/assets/upload HTTP/1.0\r\nHost:www.roblox.com\r\nConnection: close\r\n\r\n");
		//reply = conn.read(999999);
		//alert(reply); // FULL REPLY
		conn.close();
	}

}

As you can see I have the variable “file” which is an image file named “Home.png”. I want to send this to Roblox and I want it uploaded on my account as an image or decal. I also want it to return me the asset id of the newly uploaded image.

I don’t know how to post the image to the endpoint, and I can’t tell if I am on the right track. Any assistance would be greatly appreciated!

5 Likes

I’ve tried this API before, but it didn’t work.

1 Like

Well I know it’s possible as I’ve seen it done before, I just don’t know how.

Where did you see it? :thinking:
I have never seen it…

1 Like

Someone I saw on Twitter made a program that uploads images to Roblox outside of the website.

1 Like

Just out of curiosity, can you share your code, perhaps our different research can be combined for a solution?

Okay, I think I figured out how to send data to the endpoint, but I don’t fully understand what data I should send.

https://publish.roblox.com/docs#!/Items/post_v1_assets_upload

It gives me a parameter, but I don’t know what exactly to send. Here is my JavaScript code.

var data = $http({
	method: 'POST',
	payload: {type:"formData"},
	url: 'http://publish.roblox.com/v1/assets/upload',
	headers: {'Accept': 'application/json','Content-Type': 'multipart/form-data'}
});

“payload” is the JSON data. What should I put in there?
image

1 Like

I ran the curl command I was running last time.
For some reason InternalServerError 500 is now returned in the header.

1 Like
Command>curl -X POST --header "Content-Type: multipart/form-data" --header "Accept: application/json" --header "Cookie: #ROBLOSECURITY COOKIE, DELETED FOR SECURITY#" --header "X-CSRF-TOKEN: #X-CSRF-TOKEN, DELETED FOR SECURITY#" -F Config=@config.json -F Test=@Test.png "https://publish.roblox.com/v1/assets/upload" --verbose
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 128.116.120.3...
* TCP_NODELAY set
* Connected to publish.roblox.com (128.116.120.3) port 443 (#0)
* schannel: SSL/TLS connection with publish.roblox.com port 443 (step 1/3)
* schannel: checking server certificate revocation
* schannel: sending initial handshake data: sending 189 bytes...
* schannel: sent initial handshake data: sent 189 bytes
* schannel: SSL/TLS connection with publish.roblox.com port 443 (step 2/3)
* schannel: failed to receive handshake, need more data
* schannel: SSL/TLS connection with publish.roblox.com port 443 (step 2/3)
* schannel: encrypted data got 4096
* schannel: encrypted data buffer: offset 4096 length 4096
* schannel: encrypted data length: 4018
* schannel: encrypted data buffer: offset 4018 length 4096
* schannel: received incomplete message, need more data
* schannel: SSL/TLS connection with publish.roblox.com port 443 (step 2/3)
* schannel: encrypted data got 1024
* schannel: encrypted data buffer: offset 5042 length 5042
* schannel: encrypted data length: 919
* schannel: encrypted data buffer: offset 919 length 5042
* schannel: received incomplete message, need more data
* schannel: SSL/TLS connection with publish.roblox.com port 443 (step 2/3)
* schannel: encrypted data got 1185
* schannel: encrypted data buffer: offset 2104 length 5042
* schannel: sending next handshake data: sending 93 bytes...
* schannel: SSL/TLS connection with publish.roblox.com port 443 (step 2/3)
* schannel: encrypted data got 258
* schannel: encrypted data buffer: offset 258 length 5042
* schannel: SSL/TLS handshake complete
* schannel: SSL/TLS connection with publish.roblox.com port 443 (step 3/3)
* schannel: stored credential handle in session cache
> POST /v1/assets/upload HTTP/1.1
> Host: publish.roblox.com
> User-Agent: curl/7.55.1
> Accept: application/json
> Cookie: #REMOVED FOR SECURITY#
> X-CSRF-TOKEN: #REMOVED FOR SECURITY#
> Content-Length: 19055
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------fbdc429d9104c960
>
* schannel: client wants to read 102400 bytes
* schannel: encdata_buffer resized 103424
* schannel: encrypted data buffer: offset 0 length 103424
* schannel: encrypted data got 54
* schannel: encrypted data buffer: offset 54 length 103424
* schannel: decrypted data length: 25
* schannel: decrypted data added: 25
* schannel: decrypted data cached: offset 25 length 102400
* schannel: encrypted data buffer: offset 0 length 103424
* schannel: decrypted data buffer: offset 25 length 102400
* schannel: schannel_recv cleanup
* schannel: decrypted data returned 25
* schannel: decrypted data buffer: offset 0 length 102400
< HTTP/1.1 100 Continue
* schannel: client wants to read 102400 bytes
* schannel: encrypted data buffer: offset 0 length 103424
* schannel: encrypted data got 407
* schannel: encrypted data buffer: offset 407 length 103424
* schannel: decrypted data length: 378
* schannel: decrypted data added: 378
* schannel: decrypted data cached: offset 378 length 102400
* schannel: encrypted data buffer: offset 0 length 103424
* schannel: decrypted data buffer: offset 378 length 102400
* schannel: schannel_recv cleanup
* schannel: decrypted data returned 378
* schannel: decrypted data buffer: offset 0 length 102400
< HTTP/1.1 500 Internal Server Error
< cache-control: no-cache
< pragma: no-cache
< content-length: 55
< content-type: application/json
< expires: -1
< x-frame-options: SAMEORIGIN
< roblox-machine-id: CHI1-WEB2979
< p3p: CP="CAO DSP COR CURa ADMa DEVa OUR IND PHY ONL UNI COM NAV INT DEM PRE"
< date: Thu, 08 Oct 2020 10:19:40 GMT
* HTTP error before end of send, stop sending
<
{"errors":[{"code":0,"message":"InternalServerError"}]}* Closing connection 0
* schannel: shutting down SSL/TLS connection with publish.roblox.com port 443
* schannel: clear security context handle

Okay so I managed to connect to it and send it data, and it did return the data it said it would. I am getting an Error 403, and according to the documentation, that means I don’t have proper authorization and the token validation has failed. I don’t know how to get permission.

Maybe you haven’t sent the cookie with .ROBLOSECURITY

I don’t know much about this, but isn’t this not allowed? If this were allowed people could upload images that aren’t appropriate for roblox, that might be why you don’t have authorization to do this

Images still get sent the the regular upload process, including moderation. It just automates it.

2 Likes

As @bestw9, the endpoint moderates it. I believe the problem was that I didn’t use an HTTPS connection which it required.

1 Like

The http service is restricted from using roblox. This is to prevent people from spamming and causing bugs.

1 Like

I am trying to do this in a JavaScript file, not through Roblox’s HTTP service.

2 Likes

Did you ever figure this out? I have a project I’m working on and this would be very helpful.

Are you trying to upload an image asset or something similar? If so, I found out this actually was not the right API.

There is a data API too. I learned this from someone else, but I couldn’t find it documented anywhere.

https://data.roblox.com/data/upload/json?assetTypeId=13

It doesn’t seem to have any documentation, so I used Tarmac.

I used Python for this. If you are not using Python, reply back telling me what you are using so I can see if I can help.

def sendImageToServer(sendingfile,Retry = True, Token=XCSRFTOKEN):
	API_ENDPOINT = "https://data.roblox.com/data/upload.json"
	data = {
			'uploadAssetRequest.files':sendingfile, #base64.b64encode()
			'content-length': '75174'
			}
	headers = {'Accept': 'application/json','Content-Type': 'multipart/form-data','X-CSRF-TOKEN': Token}
	cookies = {'.ROBLOSECURITY': 'put your roblo security in here'}
	r = requests.post(url = API_ENDPOINT, data = data, headers = headers, cookies=cookies)
	print(r)
	print(r.text)
	print(r.headers)
	if r.status_code == 403: # If the response is 403...
		try:
			JSON = json.loads(r.text)
			ResponseCode = JSON["errors"][0]["code"]
			if ResponseCode == 0: # And Roblox response is 0...
				if Retry == True: # If retry is enabled...
					return sendImageToServer(sendingfile,False, r.headers["x-csrf-token"]) # Re-do the request, but this time, with the `x-csrf-token` supplied as well.
		except:
			return r
	return r, Token

I got help from @Batman212369 who also made this post:

I also found https://github.com/Corecii/RbxUpload by @Corecii

I have not tried this one, but it looks interesting.

3 Likes

What’s inside the sendingfile?
Is it a base64 encoded png?

Roblox certainly does a horrible job documenting how their API works, so most of the time you have to suffer to be able to find out how it works (kind of like with the 403 error I was getting). From what I know, a lot of API calls that aren’t ‘GET’ methods require an X-CSRF-TOKEN. If it is giving you a 403, then it is probably because of the Cookie or the X-CSRF-TOKEN.

When it comes to JavaScript, I have no idea how to do web-requests, so I cannot really help with that, but I can suggest a few ways to solve the problem. The way I solved my problem was by looking into finished APIs, such as roblox.js. If you want to make it a bit easer, you could just use the API out of the box, or if you want to hard-code it, then I do recommend going in and looking for that exact API call you require and seeing how the person implemented it. That is how I got the concept of the X-CSRF-TOKEN, which I really do believe Roblox should have documented somewhere.

Since you are trying to upload an image using JS, I highly recommend you check out the uploadItem.js script from roblox.js as it seems like you can upload images using it. I also recommend looking at the documentation to see what type of arguments it retrieves so you know what is being passed in. You can find the uploadItems.js here, or just go under roblox-js/lib/asset/uploadItem.js. I believe that script does exactly what you want, so do take a look and get a basic idea of how it’s done. From there, now that you have the basic idea, you can implement it on your own.

I hope this helped. I know it is a bit long, so I apologize for that.

1 Like