HTTParty POST call returning invalid JSON - ruby-on-rails

I am looking to post to an API with my email address, but I cannot get a workable response. When I simply cURL the API in the terminal, the data is returned as expected.
#omnics2 = HTTParty.post('https://qo.api.liveramp.com/v1/idl_resolution',
:headers => {
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'X-Api-Key' => 'my api key',
'Accept-Encoding' => 'gzip, deflate',
'Content-Length' => '59148'
},
:body => {'email' => 'me#email.com'}
)
The above returns this error
<HTTParty::Response:0x7ff5b0d49ab0 parsed_response="Invalid JSON in request: invalid character 'e' looking for beginning of value\n", #response=#<Net::HTTPBadRequest 400 Bad Request readbody=true>, #headers={"content-type"=>["text/plain; charset=utf-8"], "x-content-type-options"=>["nosniff"], "date"=>["Fri, 02 Aug 2019 21:41:58 GMT"], "content-length"=>["78"], "via"=>["1.1 google"], "alt-svc"=>["clear"], "connection"=>["close"]}>
I can wrap the entire call with a .to_json method, which allows for a succesful call, I just can't do anything with the response using the standard #omnics.body method. When I wrap everything in a .to_json method, this is the result I get:
=> "{\"content-type\":[\"text/plain; charset=utf-8\"],\"x-content-type-options\":[\"nosniff\"],\"date\":[\"Fri, 02 Aug 2019 21:45:32 GMT\"],\"content-length\":[\"78\"],\"via\":[\"1.1 google\"],\"alt-svc\":[\"clear\"],\"connection\":[\"close\"]}"
I've tried adding to_json methods to the header section and body sections, as recommended here like so:
:body => {'email' => 'me#email.com'}.to_json instead of wrapping the entire function, but that also errors out.
Would love any thoughts here as I am merely a hobbiest developer and am probably overlooking something obvious.

Finally got this to work. I had to make the body values enclosed within an array. Here's the syntax:
#omnics3 = HTTParty.post("https://qo.api.liveramp.com/v1/idl_resolution", options)
options = {
headers: {
"Content-Type": "application/json",
"X-Api-Key" => "my api key"
},
:debug_output => STDOUT,
query: { data: true },
body: [
{ email: ["anemail#address.com"] },
{ email: ["joe#gmail.com"] },
].to_json
}

Related

How can I use Httparty with rails 6

I am working on a rails application to send a post message to a server but each time i tried to send a post request to the sever there seems to be no post data sent to the server. However, if I use postman to send the message with json format the server responds correctly to the post request. I am relatively new to rails and i am not sure if my configuration is wrong. Please I need help. Here is my my code:
def send_information
HTTParty.post("https://example.com/api/json.php",
:body => {
user: 'Nancy Cole',
item: 'mobile phone',
content: 'Hurray the server has received your message',
id: 2,
:headers => {
'Content-Type' => 'application/json' }
}
)
end
I think you have to change your syntax like below :-
response = HTTParty.post("https://example.com/api/json.php",
headers: {
"Content-Type" => "application/json"
},
body: {user: 'Nancy Cole',
item: 'mobile phone',
content: 'Hurray the server has received your message',
id: 2
}.to_json
)
#syntax
response = HTTParty.post(url,
headers: {},
body: {}.to_json
)

How can I increase timeout for HTTParty post method in rails?

I have a method in rails to send post requests to a third party API. The code looks similar to the following:
data = HTTParty.post("url",
:headers=> {'Content-Type' => 'application/json'},
:body=> { update => true, first_name => "name" }
)
With this, after exactly one minute, the process is terminated with the following error.
<Net::HTTPGatewayTimeOut 504 GATEWAY_TIMEOUT readbody=true>
Set the default by:
module HTTParty
default_timeout your_preferred_timeout
end
or set it individually by:
data = HTTParty.post("url",
headers: {"Content-Type" => "application/json"},
body: {update => true, first_name => "name"},
timeout: your_preferred_timeout
)
you can try
data = HTTParty.post("url",
headers: {"Content-Type" => "application/json"},
body: {update => true, first_name => "name"},
open_timeout: 0.5,
write_timeout:1,
read_timeout:3
)
also you can reference
https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP.html#attribute-i-write_timeout

Making POST Request to GCM server for notification key fails from Rails Controller

I have try to making a POST request to google cloud messaging server as follow from my Rails controller using httparty gem
#response = HTTParty.post("https://android.googleapis.com/gcm/notification",
:body => {
:text => '{
"operation" : "remove",
"notification_key_name": "43",
"registration_ids": [
"dmfbvTrqeSo:APA91bFmk_zTryZi-2-BrjZK-zxN3nmQxl8tIUJriTl7EwRZsnHq3UAMNQ2O_mxLVes7WLHnW6INx21UdKwm64ReUpd5bKTE0uinrPau2WVrAUkfUyRKxlIGLD2xLKbNiSGjAeNIDAhe"
]
}'.to_json
},
:headers => {
'Content-Type' => 'application/json',
'Authorization' => 'key=AIzaSyDQiBiYk433JhWKWFZZGAU3c08tWjCzU5o',
'project_id' => '857642310184'
}
)
#json = JSON.parse(#response.body)
render :json => #json
The response I got it not a notification key. It is
{
"error": "BadJsonFormat"
}
What's wrong in my code?
My Rails controller request format is
POST /api/fcm HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: cfd40d1e-81f4-5402-a3cd-f6749f868291
{
"user_id" : "42"
}
I guess httparty gem expects json data
So replace
:body => {
:text => '{
"operation" : "remove",
"notification_key_name": "43",
"registration_ids": [
"dmfbvTrqeSo:APA91bFmk_zTryZi-2-BrjZK-zxN3nmQxl8tIUJriTl7EwRZsnHq3UAMNQ2O_mxLVes7WLHnW6INx21UdKwm64ReUpd5bKTE0uinrPau2WVrAUkfUyRKxlIGLD2xLKbNiSGjAeNIDAhe"
]
}'.to_json
},
:headers => {
'Content-Type' => 'application/json',
'Authorization' => 'key=AIzaSyDQiBiYk433JhWKWFZZGAU3c08tWjCzU5o',
'project_id' => '857642310184'
}
with
:body => {
:text => {
:operation => "remove",
:notification_key_name => "43",
:registration_ids => [
"dmfbvTrqeSo:APA91bFmk_zTryZi-2-BrjZK-zxN3nmQxl8tIUJriTl7EwRZsnHq3UAMNQ2O_mxLVes7WLHnW6INx21UdKwm64ReUpd5bKTE0uinrPau2WVrAUkfUyRKxlIGLD2xLKbNiSGjAeNIDAhe"
]
}
}.to_json,
:headers => {
'Content-Type' => 'application/json',
'Authorization' => 'key=AIzaSyDQiBiYk433JhWKWFZZGAU3c08tWjCzU5o',
'project_id' => '857642310184'
}
Try removing to to_json on post. This would work if you were calling it for a Hash, but what it's doing here is double-escaping your string (which is already valid JSON).
If you want to send a minimal JSON request (i.e. without the extra spaces and carriage returns), you can also use
JSON.parse('{
"operation" : "remove",
...
}').to_json

Instagram API - Unable to request access token

Using HTTParty I tried to request for the access token as below:
result = HTTParty.post("https://api.instagram.com/oauth/access_token",
{
:body => [ { "client_id" => xxxxxxxxxx, "client_secret" => xxxxxxxxxxxxx,
"grant_type" => "authorization_code",
"redirect_url" => 'http://localhost:4000/access_token', "code" => xxxxxxxx } ].to_json,
:headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json'}
})
But the response says that #400, "error_type"=>"OAuthException", "error_message"=>"You must provide a client_id"}, #response=#, #headers={"content-language"=>["en"], "expires"=>["Sat, 01 Jan 2000 00:00:00 GMT"],........
Can't figure out why.. Help!
You can change content-type into:
'Content-Type' => 'application/x-www-form-urlencoded'
For more information click instagram-api-authentication-must-provide-client-id
I hope this help you.

Send array in JSON POST request with HTTParty

I'm trying to work with a 3rd party API that requires an array to be sent within a POST request body. I've already gotten the hang of sending JSON; I've read you just need to set some headers and call to_json on the POST body. However, I'm not sure how to embed an array within that POST body. I've tried the following:
HTTParty.post(url,
:body => {
:things => [{:id => 1}, {:id => 2}, {:id => 3}],
}.to_json,
:headers => {
'Content-Type' => 'application/json',
'Accept' => 'application/json'
}
)
but this is giving me a server error, leading me to believe the array isn't being formatted correctly. Could someone please advise on how to send an array within a JSON POST request? Thanks!
EDIT:
The error I get back is the following:
#<HTTParty::Response:0x10 parsed_response=nil,
#response=#<Net::HTTPInternalServerError 500 Internal Server Error readbody=true>,
#headers={"error_message"=>["Can not deserialize instance of java.lang.Long out of
START_OBJECT token at [Source: org.apache.catalina.connector.CoyoteInputStream#30edd11c;
line: 1, column: 15] (through reference chain: REDACTED[\"things\"])"],
"error_code"=>["0"], "content-length"=>["0"],
"date"=>["Wed, 13 Aug 2014 22:53:49 GMT"], "connection"=>["close"]}>
The JSON should be in the format:
{ "things" : [ {"id": "..."}, {"id: "..."}, ... ] }
The simplest way to embed an array within a POST body using HTTParty in Ruby on Rails is to pass the request to an instance variable (any name of your choice can suffice for the instance variable).
So we will have
#mypost = HTTParty.post(url,
:body => {
:things => {
:id => 1,
:id => 2,
:id => 3
},
}.to_json,
:headers => {
'Content-Type' => 'application/json',
'Authorization' => 'xxxxxxxxxx'
'Accept' => 'application/json'
})
Here is an example of an HTTParty Post Request
#myrequest = HTTParty.post(' https://www.pingme.com/wp-json/wplms/v1/user/register',
:body => {
:books => {
:name => "#{#book.name}",
:author => "#{#book.author}",
:description => "#{#book.description}",
:category_id => "#{#book.category_id}",
:sub_category_id => "#{#book.sub_category_id}"
},
}.to_json,
:headers => { 'Content-Type' => 'application/json',
'Authorization' => '77d22458349303990334xxxxxxxxxx',
'Accept' => 'application/json'})
That's all
I hope this helps.
I had a similar requirement for a SurveyMonkey API, the below will create a params_hash with nested array of hashes
create the fields array of hashes
fields = []
i =0
while i < 10 do
fields << {":id#{i}" => "some value #{i}"}
i += 1
end
method with optional splat field variable
def get_response(survey_id, respondent_ids, *fields )
params_hash = {}
params_hash[:survey_id] = "#{survey_id}"
params_hash[:respondent_ids] = respondent_ids
params_hash[:fields] = fields
#result = HTTParty.post("http://"some.address.here",
#:debug_output => $stdout,
:headers => {'Authorization' => "bearer #{#access_token.to_s}", 'Content-type' => 'application/json'},
:body => params_hash.to_json,
)
end

Resources