I am making the following API GET request, using ruby 1.9.3 and the httparty gem:
uri= HTTParty.post("www.surveys.com/api/v2/contacts",
:basic_auth => auth,
:headers => { 'ContentType' => 'application/json' },
:body => {
"custom_test" => test,
"name" => firstname,
"email" => emailaddress
}
)
The variables auth,test,firstname, and emailaddress are valid. This is the response I am receiving back from my request:
{
"code": "invalid_json",
"description": "Request sent with Content-Type: application/json but was unable to decode request body as valid json.",
"success": false
}
500
#<Net::HTTPInternalServerError:0x007fe4eb98bde0>
What is wrong with the way I am posting this JSON request?
EDIT: It's probably worth noting that the API allows you to define custom attributes to a contact, hence the "custom_test" attribute in the body.
Since you are receiving an internal server error (500) instead of a not accepted (406), most likely there is coding problem on the server, because an exception that he is not expecting is happening instead of delivery to you a nice error explaining what is wrong (and this would be my first guess).
But let's say it is a problem with the JSON communication. Maybe you have to specify that you are accepting json format?
Try
:headers => { 'ContentType' => 'application/json', 'Accept' => 'application/json' },
Accept header definition from w3:
The Accept request-header field can be used to specify certain media types which are acceptable for the response. Accept headers can be used to indicate that the request is specifically limited to a small set of desired types, as in the case of a request for an in-line image.
And content-type header definition:
The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET.
You're sending a regular HTTP query string while saying it's json.
From HTTParty manual: "body: The body of the request. If it‘s a Hash, it is converted into query-string format, otherwise it is sent as-is."
Try:
:body => JSON.generate({
"custom_test" => test,
"name" => firstname,
"email" => emailaddress
})
You need to require 'JSON'
Related
I am trying to fetch a public API. When I do it from the postman everything works fine however when I do it from my app I get and error message: <META NAME=\"robots\" CONTENT=\"noindex,nofollow\"
I do not understand how this is possible?
Here is are the headers variables I adjust when I make my request with postman:
Cookie:"some cookie"
Cache-Control: no-cache
Content-Type:application/json
Host:"some host"
Here is my httparty request:
response = HTTParty.post(url,
:body => body_request (same as with postman),
:headers => {
'Content-Type' => 'application/json',
'cookie' => 'same cookie as above',
'Host' => 'same host as above',
'Cache-Control' => 'no-cache'
}
)
Why would it work with postman but not with a httparty request?
Thank you
I would look into User-Agent, even if you don't explicitely set the header, your http client is still sending one.
Postman uses :
"User-Agent": "PostmanRuntime/7.26.8",
while HTTParty is simply
"User-Agent": "Ruby"
Maybe your public API (could be more precise if we knew which) has a whitelist of 'non-bot' user agents and HTTParty is not among them
Try overriding it
resp = HTTParty.get 'https://httpbin.org/headers' , headers: {'User-Agent': 'xx'}
I am trying to make an output POST message with the http module. I have the following config:
http {
http_method => "post"
url => "http://localhost:40104/api/message"
format => "message"
content_type => "application/json"
message => "Test"
}
It calls the API, but the POST has no body. I expect it to contain "Test".
We are using Logstash version 1.5 on Windows.
We tried using as_json after the message, we tried formatting the message as JSON, we tried sending content_type text and we tried a few other things.
Why does it not work and how can it be solved?
With this configuration I can get the message as raw body :
http {
http_method => "post"
url => "http://requestb.in/1mcpwx51"
format => "message"
content_type => "text/plain"
message => "Test"
}
I suggest you could test your output with the http://requestb.in service, it's really useful to see what input your server will get on request.
I hope that helps.
I have the following code:
require 'Typhoeus'
url = Typhoeus::Request.new("https://fluidsurveys.com/api/v2/webhooks/subscribe/",
userpwd: "username_test:password_test",
method: :post,
body: {
'subscription_url' => 'http://glacial-spire-test.herokuapp.com/hooks/response_created_callback',
'event' => 'response_complete'
},
headers: { 'Content-Type' => "application/json"})
response = url.run.body
puts response
This returns a response code of 400 and an error:
Content-Type set to application/json but could not decode valid JSON in request body.
Here are the docs for the API call I am making: http://docs.fluidsurveys.com/api/webhooks.html
POST /api/v2/webhooks/subscribe/¶
Returns a status of 409 if a webhook with the subscription url already exists. Returns a
status of 201 if the webhook was successfully created. Requests must be sent as an
application/json-encoded dictionary with the required fields subscription_url and event
Sample request (ACCORDING TO DOCS):
{
"subscription_url": "http://fluidsurveys.com/api/v2/callback/",
"event": "response_complete",
"survey": 1,
"collector": 1
}
What am I doing wrong here? survey and collector are optional params, and I don't see an issue with the json in my body.
I am guessing you might need to convert the request body into JSON using a library like Oj (https://github.com/ohler55/oj). Using the Oj library:
requestBody = {
'subscription_url' => 'http://glacial-spire-test.herokuapp.com/hook/response_created_callback',
'event' => 'response_complete'
}
url = Typhoeus::Request.new("https://fluidsurveys.com/api/v2/webhooks/subscribe/",
userpwd: "username_test:password_test",
method: :post,
body: Oj.dump(requestBody, mode: :compat),
headers: { 'Content-Type' => "application/json"})
response = url.run.body
puts response
The critical line is:
body: Oj.dump(requestBody, mode: :compat)
If you need to load any JSON content to Ruby, just use Oj.load
I'm losing my sanity trying to parse an incoming request on a Sinatra app.
This is my spec
payload = File.read("./spec/support/fixtures/payload.json")
post "/api/v1/verify_payload", { :payload => payload }
last_response.body.must_equal payload
where is simply spec/support/fixtures/payload.json
{"ref":"refs/heads/master"}
My route looks like
post '/verify_payload' do
params = MultiJson.load(request.body.read, symbolize_keys: true)
params[:payload]
end
And running the spec I get the following error:
MultiJson::LoadError: 795: unexpected token at 'payload=%7B%22ref%22%3A%22refs%2Fheads%2Fmaster%22%7D'
I have tried to parse the body request in different ways without luck.
How can I make the request valid JSON?
THANKS
If you want to send a JSON-encoded POST body, you have to set the Content-Type header to application/json. With Rack::Test, you should be able to do this:
post "/api/v1/verify_payload", payload, 'CONTENT_TYPE' => 'application/json'
Alternatively:
header 'Content-Type' => 'application/json'
post '/api/v1/verify_payload'
More info here: http://www.sinatrarb.com/testing.html
The problem it is that you are passing a ruby hash, that is not well formated, you should pass a json object.
Something like this, should work:
post "/api/v1/verify_payload", { :payload => payload.to_json }
I am trying to call a URL using Ruby's OpenURI gem, however it needs me to pass certain values inside its HTTP request header.
Any idea how to do this?
According to the documentation, you can pass a hash of http headers as the second argument to open:
open("http://www.ruby-lang.org/en/",
"User-Agent" => "Ruby/#{RUBY_VERSION}",
"From" => "foo#bar.invalid",
"Referer" => "http://www.ruby-lang.org/") {|f|
# ...
}