tumblr / docs

Tumblr's public platform documentation.
Apache License 2.0
109 stars 27 forks source link

Endpoints to block (indivual & bulk) & follow blogs do not accept application/json as a payload - Confirmed user error #105

Closed rmichiels closed 1 year ago

rmichiels commented 1 year ago

So, according to my understanding of the documentation, api.tumblr.com/v2/blog/[blog to block from]/blocks/bulk?blocked_tumblelogs=[comma separated blocklist] would be used to blog multiple blogs at the same time. However, no matter what i do, using the name or uuid, passing the query parameters on along the url or as content in the httprequest, i keep getting bad request responses.

Example of my request:

image image image

i've kept out other blog names for brevity for this example.

when it comes to the endpoint to block a singular blog, api.tumblr.com/v2/blog/[blog to block from]/blocks, with the blog to block as either query parameter or payload, it just gives me a not found response instead.

Is there something i'm missing, is the documentation incomplete, or are these endpoints bugged?

EDIT: during further developtment, i've discovered the same issue with the user/follow endpoint EDIT 2: on suggestion of Cyle, I reformatted the payload to 'form-data' rather than json, this seems to resolve the issue for the user/follow endpoint, I still need to confirm whether this approach works for the endpoints i've described earlier as well. EDIT 3: I have confirmed that the endpoints to block blogs also works using the 'form-data' approach, I've edited the title to fit this conclusion FINAL EDIT: double check your content-type headers, folks, mine were mistakingly being set as text, rather than application/json & I didn't spot because i'd been mixing up the response headers (which were correct) & the request headers (which weren't)

nightpool commented 1 year ago

So, according to my understanding of the documentation, api.tumblr.com/v2/blog/[blog to block from]/blocks/bulk?blocked_tumblelogs=[comma separated blocklist] would be used to blog multiple blogs at the same time

This is incorrect. As indicated in the documentation, /blocks/bulk takes a POST "Request Parameter" of blocked_tumblelogs. Your example passes a "query parameter" instead, which is used for GET requests.. The documentation is a little ambiguous on the specific encoding, but I assume you need to pass a JSON document like {"blocked_tumblelogs": "staff,david,photomatt"}. The fact that blocked_tumblelogs takes a comma-separated parameter instead of a normal JSON array does somewhat confuse the issue, I admit.

marcustyphoon commented 1 year ago

passing the query parameters on along the url or as content in the httprequest

Despite the quoted passage only being about the query parameter method, the original post does both mention and show an attempt to do a POST request with what appears to be the correct body to me!

I receive a 404 from the server when trying to use the blog tienogl as the payload blog, as that does not appear to exist, but I assume it's not just that. Do give it a try with a list of blogs that definitely exist, though.

rmichiels commented 1 year ago

@nightpool

apologies if i wasn't clear enough, but i tried both methods. I tried both passing the comma separated list through the payload, like in the example, and just to double check i added them on another instance through the url instead of the payload, just to see if anything would change.

@marcustyphoon I made a slight error trying to get a screenshot and accidentally cut off the last character of the name, which normally is a comma by way of how i constitute the comma-separated list.

I am trying to use the bulk block to block those empty, 'untitled' bot blogs, so i get the names or uuid's directly from there.

Another example, using the bulk blog for a single blog: image with the following payload: {"blocked_tumblelogs":"aureliavjvbanon54"}

Example payload of bulk using comma separated list, this also returns a bad request:

{"blocked_tumblelogs":"houltbergywxvfelisa57,aureliavjvbanon54,georgianaaoew,juanmtsy,corranfbancarransa"}

Example payload using non-bulk, single blog block, which gives a 404: Capture {"blocked_tumblelog":"houltbergywxvfelisa57"}

I have tried all of these cases with either the blog name, and the uuid, and none of them have worked.

marcustyphoon commented 1 year ago

Hmm. Yep, that indeed looks right to me. (I don't have an API client on me to test; I'm using the web platform API helper, so I can't tell if this is a discrepancy between the actual external API and the internal version). I assume you've tested whether completely unrelated endpoints that require authentication work, like following the staff blog or whatever?

Edit: Also, how many blocked blogs do you have? Seems unlikely, but maybe you hit a maximum?

rmichiels commented 1 year ago

Yeah, currently I have working, using an OAuth2 bearer token:

My tokens are valid & get automatically refreshed.

I don't know how many blocked blogs I have, I do have quite a few, but considering that I can still block blogs through Tumblr normally & that the single-block endpoint returns a 404, I doubt the issues I'm running into have anything to do with a 'block limit'.

Also, I have gotten distinct errors, unrelated to the ones I'm running into now, when it comes to errors based on unauthorized requests, so I doubt Auth has anything to do with these errors at all.

cyle commented 1 year ago

hello @rmichiels , looking into this a little bit, the endpoint does expect a POST request, and:

rmichiels commented 1 year ago

Hi @cyle ,

rmichiels commented 1 year ago

@cyle I seem to be running into the same issue, bad request, when it comes to the endpoint to follow a user:

image image

I've gotten the url by using the blog/{identifier}/info endpoint, and i've tried this with:

is it possible that there might be issues relating to these endpoints because i'm using OAuth2 instead of Oauth1.a? Am i perhaps missing/using the wrong scope? My token is scoped to ""write" &"offline_access". Even though in these cases i'd expect an authentication error.

cyle commented 1 year ago

@rmichiels nothing is different between OAuth2 and OAuth1 on our side for these kinds of requests. I'd suggest trying that same request as a standard form-data body, rather than JSON, i.e.:

POST https://api.tumblr.com/v2/user/follow

url=https://www.tumblr.com/pinkfloralbby

If we couldn't find the blog, we'd return a 404 Not Found. A 400 Bad Request for a POST request almost always means we don't know how to look up what input we're being given.

rmichiels commented 1 year ago

@cyle using form-data seems to have solved the issue when it comes to the 'user/follow' endpoint, I assume that it'll work for the block endpoints as well, but i'll get back to you on that for confirmation.

Is this something that can be specified in the documentation? Or have i just been working on wrong assumptions that are actually standard when it comes to api's? Since all the responses of the api seem to be in json, or at least something so similar to json that it is able to be perfectly parsed into json, I'd expect the api to want json as a payload as well.

The documentation says the following: image But it seems to me to be unclear through the documentation which endpoints require which content-type.

cyle commented 1 year ago

yep, my guess here is that we need to update these endpoints to properly accept application/json -- can you verify that your original attempts were specifically setting Content-type: application/json in your request headers?

rmichiels commented 1 year ago

@cyle I can confirm that switching from standard JSON to form-data has resolved the issue.

For .NET specifically, this means using the MultipartFormDataContent class, and adding a, for example, StringContent value with a key string, rather than serializing, for example, a dictionary & convert that string to your stringcontent. The latter approach having worked for me when it comes to the whole auth flow, but doesn't work for these endpoints. More endpoints might suffer from the same issue as well.

Funnily enough, the headers still say that the content-type is application/json, but the payload is distinctly form data. image image

image image

Either way, I'd like to request for the documentation to reflect this, and ideally the endpoints could be configured to use application/json as well.

cyle commented 1 year ago

Thanks for verifying, I'll pass this along to the team!

sndsgd commented 1 year ago

FWIW I just pulled out a test script from a few years ago, and it looks like the POST /v2/user/follow is still working with the following request body contents types:

I also tested a few variations of the url parameter, and they all worked:

@rmichiels not sure if you saw @cyle's question:

can you verify that your original attempts were specifically setting Content-type: application/json in your request headers?

@rmichiels also, please note your screenshots only show response headers.

Funnily enough, the headers still say that the content-type is application/json, but the payload is distinctly form data.

Want to try to issue the request and include the request headers in the screenshot?

rmichiels commented 1 year ago

@sndsgd I had completely overlooked that, mixed up response & request headers, & as it turns out it was entirely an error on my part. Checking the request headers, instead of the response headers as i'd apparently been doing all this time, showed me that somewhere in my code the content type got set as text, instead of application/json. I'm not sure how the error slipped in there, as it didn't seem to affect the part of my code that is requesting the token, but, i can confirm now without a doubt, that this entire wild goosechase was due to an error on my part. Thanks for adding your two cents & pointing me in the right direction, I'd been staring at the same requests for so long, i'd been mixing response & request up...