Ruby POST with custom headers and body? - ruby-on-rails

I'm trying to POST to Mailchimp in Ruby but I can't get any code working which has custom headers and a body. This is the request I am trying to replicate:
curl --request GET \
--url 'https://<dc>.api.mailchimp.com/3.0/' \
--user 'anystring:<your_apikey>'
but I also have to add a JSON body.
If I run this code:
postData = Net::HTTP.post_form(URI.parse('https://xxx.api.mailchimp.com/3.0/lists/xxx/members/'), { ... }})
puts postData.body
I get a response from Mailchimp that the apikey is missing. How do I add the API key?
Based on these posts:
Ruby request to https - "in `read_nonblock': Connection reset by peer (Errno::ECONNRESET)"
Ruby send JSON request
I tried this:
uri = URI('https://xxx.api.mailchimp.com/3.0/lists/xxxx/members/')
req = Net::HTTP::Post.new(uri, initheader = {'Content-Type' =>'application/json'})
req.basic_auth 'anystring', 'xxxx'
req.body = URI.encode_www_form({ ... }})
response = Net::HTTP.new(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https').start {|http| http.request(req) }
puts "Response #{response.code} #{response.message}:#{response.body}"
but I get the error TypeError (no implicit of Hash into String) on the response = ... line. What is the error referring to and how do I fix it?
UPDATE:
using start instead of new:
response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') {|http| http.request(req) }
I am able to send the request, but I get a 400 response: "We encountered an unspecified JSON parsing error"
I get the same response with the posted answer. here is my JSON:
{'email_address' => 'xxxx#gmail.com', 'status' => 'subscribed', 'merge_fields' => {'FNAME' => 'xxx', 'LNAME' => 'xxx' }
I also tried adding the data like this:
req.set_form_data('email_address' => 'xxxx#gmail.com', 'status' => 'subscribed', 'merge_fields' => {'FNAME' => 'xxx', 'LNAME' => 'xxx' } )
but I get the same JSON parse error

Try this, if it works for you
uri = URI('https://api.mailchimp.com/3.0/lists/xxxx/members/')
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req.basic_auth 'username', 'password'
req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')
response = http.request req # Net::HTTPResponse object
end
You need to set form data in post request like
req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')
Updates:
Try posting raw data like
json_data = {'from' => '2005-01-01', 'to' => '2005-03-31'}.to_json
req.body = json_data

Related

How to call JDoodle API from local Rails server?

I am calling the JDoodle API with post request from my local machine Rails server with valid id and secrete. I am not getting desired response. Please suggest me if i am doing wrong....
My Ruby function to make api call
def run_Jddodle_API
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://api.jdoodle.com/v1/execute")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json; charset=UTF-8"
request.body = {
"clientId" => "ddc371fd*************c8efbae",
"clientSecret" => "4ee8e79a225***************************a8ee7f331aeeca603",
"script" => "<?php printf(\"hello RAJA\"); ?>",
"language" => "php",
"versionIndex" => "0"
}.to_json
req_options = { use_ssl: uri.scheme == "https", }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
puts response.body
end
And the response is
{"error":"Unauthorized Request","statusCode":401}
try changing this line:
request.content_type = "application/json; charset=UTF-8"
to this:
request.content_type = "application/json"
I changed the code as below and it worked but can't say why.?
require 'uri'
require 'net/http'
require 'net/https'
url = URI("https://api.jdoodle.com/v1/execute")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url.path)
request["Content-Type"] = 'application/json'
request.body = {
"script" => params[:code],
"language" => params[:lang],
"versionIndex" => params[:version],
"clientId" => "dc37******************efbae",
"clientSecret" => "4ee8e79a225a5525*******************************************"
}.to_json
response = http.request(request)
puts response.read_body`

FCM API Bad Request

I'm trying to push a notification through FCM from my Ruby on Rails project, here is my code:
require 'net/http'
require 'json'
def send_notifications
log = Logger.new("log/notifications.log")
begin
uri = URI.parse("https://fcm.googleapis.com/fcm/send")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
key = '...'
hash = {:notification => {:sound => "default", :title => "test", :text => "test", :badge => "0"}, :data => {:targetID => "1", :to => "..."}}
req = Net::HTTP::Post.new(uri.path, {'Content-Type' => 'application/json', 'Authorization' => "key=#{key}"})
req.body = hash.to_json
response = http.request(req)
log.debug("response #{response.body}")
rescue => e
log.debug("failed #{e}")
end
end
I'm getting Bad Request 400 error, and debugging the response body only shows this: "to"
Please help me debug this issue. Thank you

rails error on curl converted to Net::HTTP

I receive the following error when trying to run a curl command converted to Net::HTTP in Rails. The url+params gives me the expected response when I run it on the client side using AJAX but of course this exposes my API key.
Any idea why this error is occurring?
error:
undefined method `empty?' for #<URI::HTTPS:0x00000006552fe8>
curl:
curl -X POST -d "maxRetrieve=1" -d "outputMode=json" -d "url=https://www.whitehouse.gov/the-press-office/2016/03/19/weekly-address-president-obamas-supreme-court-nomination" "https://gateway-a.watsonplatform.net/calls/url/URLGetRelations?apikey=ABC123"
rails code:
require 'net/http'
require 'uri'
require 'json'
url = "https://gateway-a.watsonplatform.net/calls/url/URLGetRelations?apikey=ABC123"
encoded_url = URI.encode(url)
uri = URI.parse(encoded_url)
request = Net::HTTP::Post.new(uri)
request.set_form_data(
"maxRetrieve" => "1",
"outputMode" => "json",
"url" => "https://www.whitehouse.gov/the-press-office/2016/03/19/weekly-address-president-obamas-supreme-court-nomination",
)
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(request)
end
puts response
Looks like you're using the ruby v1.9.3 so I rewrote your code in the following way:
uri = URI.parse("https://gateway-a.watsonplatform.net/calls/url/URLGetRelations?apikey=ABC123")
args = {
"maxRetrieve" => "1",
"outputMode" => "json",
"url" => "https://www.whitehouse.gov/the-press-office/2016/03/19/weekly-address-president-obamas-supreme-court-nomination",
}
uri.query = URI.encode_www_form(args)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
puts response.body

How to use Azure ML API with Ruby on Rails

I am using the code with a URL and API key but every time i will get the some error of 405 or 400. Is there any proper way to implement Azure ML API in Rails.
The code as below :-
data = {
"Inputs" => {
"input1" =>
{
"ColumnNames" => #a,
"Values" => [ #writer ]
}, },
"GlobalParameters" => {
}
}
body = data.to_json
puts "adssssssssssssssssssssssssssssss#{body}"
url = "https://ussouthcentral.services.azureml.net/workspaces/5aecd8f887e64999a9c854d724e5/services/5f350fa1b48647ce95c5279eee2170d0/execute?api-version=2.0&details=true"
api_key = 'wGMMQGYlo4tttV+oTjrR/tyt6xYSmWskCezNKkbGwvAVt0wsessJUORQ==' # Replace this with the API key for the web service
headers = {'Content-Type' => 'application/json', 'Authorization' => ('Bearer '+ api_key)}
url = URI.parse(url)
req = Net::HTTP::Get.new(url.request_uri,headers)
http = Net::HTTP.new(url.host, url.port)
res = http.request(req)
{"Inputs":{"input1":{"ColumnNames":["encounter_id","patient_nbr","Fname","Lname","Email","Type","race","gender","Birth Date","Birth Year","age","Age Min","Age Max","weight","admission_type_id","discharge_disposition_id","admission_source_id","time_in_hospital","payer_code","medical_specialty","num_lab_procedures","num_procedures","num_medications","number_outpatient","number_emergency","number_inpatient","number_diagnoses","max_glu_serum","A1Cresult","metformin","repaglinide","nateglinide","chlorpropamide","glimepiride","acetohexamide","glipizide","glyburide","tolbutamide","pioglitazone","rosiglitazone","acarbose","miglitol","troglitazone","tolazamide","examide","citoglipton","insulin","glyburide-metformin","glipizide-metformin","glimepiride-pioglitazone","metformin-rosiglitazone","metformin-pioglitazone","change","diabetesMed","readmitted"],"Values":[[[{"$oid":"56b1ab886e75720ba23b5400"},"","Rana","Warhurst",null,"Patient","Caucasian","Male","2012-10-23","",3,"","","","",null,null,null,"",null,"","","","","","",null,"","No","NO"]]]}},"GlobalParameters":{}}
Using Unirest gem
url = "url for ml"
api = "ml API key"
headers = "same as above"
response = Unirest.post url, headers: headers, parameters: body
response.code
response.headers
response.body
response.raw_body
The result values will be stored in response.body

Post to an API using OAuth

I'm trying to post to an API. The API takes files and converts them to JSON
Here is what I am doing:
consumer = OAuth::Consumer.new(consumer_key,secret, :site => uri)
accesstoken = OAuth::AccessToken.new(consumer, core_access_token, core_access_secret)
params = {:body => {
:binaryData => data,
:extension => "txt",
:locale => 'en_gb',
:instanceType => 'xray',
:fieldList => {"field" => ["All"]}
}.to_json,
:headers => {
'Accept' => 'application/json',
'Content-Type' => 'application/json' ,
}
}
result = accesstoken.post(action, params)
And I get back the response:
<Net::HTTPBadRequest 400 Bad Request readbody=true>
What does this error mean? Wrong URI? Wrong access tokens? or Incorrect usage of the OAUTH Gem (ie, my code is wrong)
I think it should be like this:
consumer = OAuth::Consumer.new(consumer_key,secret, :site => uri)
accesstoken = OAuth::AccessToken.new(consumer, core_access_token, core_access_secret)
headers => {
'Accept' => 'application/json',
'Content-Type' => 'application/json'
}
result = accesstoken.post(action, data, headers)

Resources