Cbas Cbas - 6 months ago 82
Ruby Question

Ruby POST with custom headers and body?

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

Answer

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