Request with -curl - ruby-on-rails

I would like to run a curl command to request data from an API, but I'm not sure of how to do it. To transform curl request into ruby code, I'm using curl to ruby, which is great by the way.
Following the doc API, I have this :
Step 1 (Get your token) :
curl -X POST https://api.monkey-locky.com/login_check -d _username={usr}
-d _password={pwd}
I have translated this by :
require 'net/http'
require 'uri'
uri = URI.parse("https://api.monkey-locky.com/login_check")
request = Net::HTTP::Post.new(uri)
request.set_form_data(
"_password" => "my_secret_pass",
"_username" => "my#mail.co",
)
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
print response.body
This request give me an Token to use the API.
Step 2 (Verify if the token is working) :
curl -H "Authorization: Bearer [TOKEN]" https://api.monkeylocky.com/bookings
I have translated this by :
require 'net/http'
require 'uri'
uri = URI.parse("https://api.monkeylocky.com/bookings")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer [TOKEN]"
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
But this script is rendering an error like this :
`rescue in block in connect': Failed to open TCP connection to
api.monkeylocky.com:443 (getaddrinfo: nodename nor servname provided,
or not known) (SocketError)
I'm not very comfortable with CURL, I'm just starting to use these request. So I'm not sure of what I'm doing right now. Any suggestion about that ?

You're sending the first request to https://api.monkey-locky.com but the URL in the second request is https://api.monkeylocky.com (no dash)

Related

Rails - How to add contacts to SendGrid marketing campaigns via API

I need to make HTTP get and post requests with SendGrid to add contacts to our account, however there doesn't seem to be a gem for their email marketing functionality.
It boils down to making a few requests however I can't get past their authentication step.
They say to do this
curl -X "GET" "https://api.sendgrid.com/v3/templates" -H "Authorization: Bearer Your.API.Key-HERE" -H "Content-Type: application/json"
And using the Rest-Client gem I'm trying to make the authentication request like so...
username = 'username'
api_key = 'SG.MY_API_KEY'
key = Base64.encode64(username + ":" + api_key)
headers = {"Authorization" => "Bearer #{key}", "Content-Type" => "application/json"}
response = RestClient.get 'https://api.sendgrid.com/v3/templates', headers
which returns...
RestClient::Unauthorized: 401 Unauthorized: {"errors":[{"field":null,"message":"authorization required"}]}
The ultimate objective of using their API is to add contacts.
How am I incorrectly making this get request?
I ended up figuring it out. For future reference, here's the code that worked...
require 'rest_client'
api_key = 'YOUR_API_KEY'
headers = {'Authorization' => "Bearer #{api_key}"}
data = {:email => 'email#website.com'}
response = RestClient.post 'https://api.sendgrid.com/v3/contactdb/recipients', [data].to_json, headers
To add marketing contacts to your SendGrid account via the API,
see the documentation at https://sendgrid.api-docs.io/v3.0/contacts-api-recipients/add-recipients
You can see sample code in the "code generation" section of the page.
require 'uri'
require 'net/http'
url = URI("https://api.sendgrid.com/v3/contactdb/recipients")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["authorization"] = 'Bearer <<YOUR_API_KEY>>'
request["content-type"] = 'application/json'
request.body = "[{\"email\":\"example#example.com\",\"first_name\":\"\",\"last_name\":\"User\",\"age\":25},{\"email\":\"example2#example.com\",\"first_name\":\"Example\",\"last_name\":\"User\",\"age\":25}]"
response = http.request(request)
puts response.read_body

RAILS Send get request to onesignal using API Key RESTApi

Its a RESTAPI and I need to send get request to onesignal.
url = https://onesignal.com/api/v1/apps
All they have mentioned is this:
curl --include \
--header "Authorization: Basic your_key_here" \
https://onesignal.com/api/v1/apps
I have tried something like this:
def index
url = URI.parse('https://onesignal.com/api/v1/apps?apikey=mykey')
req = Net::HTTP::Get.new(url.to_s)
res = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
puts res.body
end
but this doesn't work.
The result should be in json.
I get this error:
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx/1.4.6 (Ubuntu)</center>
</body>
</html>
Based on code from OneSignal webpage your request should be:
uri = URI.parse("https://onesignal.com/api/v1/apps")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(
uri.path,
"Content-Type" => "application/json",
"Authorization" => "Basic NGXXX...XXXBlNjJj"
)
response = http.request(request)
puts response.body
In your case error was associated with not using http.use_ssl = true, but you have several other things to add, like authorization header for example.

Rails Basic Base64 Authentication

I'm trying to replicate this GET curl request:
curl -D- -X GET -H "Authorization: Basic dGVzdEB0YXByZXNlYXJjaC5jb206NGMzMTg2Mjg4YWUyM2ZkOTY2MWNiNWRmY2NlMTkzMGU="
-H "Content-Type: application/json" http://staging.example.com/api/v1/campaigns
The auth is generated with an email + an api key this way in Ruby:
auth = "Basic" + Base64::encode64("test#example.com:4c3186288ae23fd9661cb5dfcce1930e")
What's the best way to replicate this in Ruby/Rails?
Here's what I've been trying:
auth = "Basic" + Base64::encode64("example#example.com#:4c3186288ae23fd9661cb5dfcce1930e")
uri = URI.parse("https://www.staging.example.com/api/v1/campaigns")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
request.env['HTTP_AUTHORIZATION'] = auth
response = http.request(request)
puts response.body
Based off of a few other SO's and blogs I've found, but then I get undefined method 'env' for #<Net::HTTP::Get GET> back.
Any ideas how I can set that so the message comes out like this?
Authorization: Basic dGVzdEB0YXByZXNlYXJjaC5jb206NGMzMTg2Mjg4YWUyM2ZkOTY2MWNiNWRmY2NlMTkzMGU=
request['Authorization'] = "Basic " + Base64::encode64("example#example.com#:4c3186288ae23fd9661cb5dfcce1930e")
Here's a more straightforward way, using request.basic_auth to handle all the messy details:
request = Net::HTTP::Post.new(uri)
request.basic_auth(username, password)
http = Net::HTTP.new(uri.host, uri.port)
response = http.request(request)

curl to Ruby request for connecting to wheniwork

Back story
I've spent a few days on the Ruby gem for wheniwork, and it's been a nightmare. To make a long story short, the gem had a dependency of an older version of activesupport and I basically forked their repo and made a compatible version for my ruby project. I was able to create a new gem and attempted to use it, but I was getting the following json message:
{"error"=>"User login required for this resource.", "code"=>1000}
The username, password, and api key were set. What I basically need to do is access our account on wheniwork, and retrieve data.
This is an example using the curl command
curl https://api.wheniwork.com/2/login \
--data '{"username":"user#example.com","password":"*******"}' \
-H "W-Key: iworksoharditsnotfunny"
Essentially, I would get some kind of return object from wheniwork that would contain the token. I'd use this token for future requests to the wheniwork site.
To (Ruby)
A new attempt to translate this to Ruby
require 'net/http'
data = {'credentials' => {'username' => 'XXXXX#XXXXX.com','password' => 'XXXXX', 'W-Key' => '111111111XXXXX'}}
uri = URI.parse("https://api.wheniwork.com/2/login/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.path, initheader = {'Content-Type' =>'application/json'})
request.add_field('Content-Type', 'application/json')
request.body = data.to_json
response = http.request(request)
Result:
#<Net::HTTPUnauthorized 401 Unauthorized readbody=true>
If you have any idea or clue (or basically anything that would help me here), I would appreciate it beyond words. Thanks!
Got it!! The major issue(s) were that the api key and (username+password) combo are two separate pieces.
I was so close the entire time, but here it is:
data = {'username' => 'XXXX#XXXXXXX.com','password' => 'XXXXX'}
uri = URI.parse("https://api.wheniwork.com/2/login/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.path)
request.add_field('W-Key', 'XXXXXXXXXXXXX')
request.body = data.to_json
response = http.request(request)
puts JSON.parse(response.body)

Running a HTTP request with rails

It has been a while since I have used Rails. I currently have a curl request as follows
curl -X GET -H 'Authorization: Element TOKEN, User TOKEN' 'https://api.cloud-elements.com/elements/api-v2/hubs/marketing/ping'
All I am looking to do is to be able to run this request from inside of a rails controller, but my lack of understanding when it comes to HTTP requests is preventing me from figuring it out to how best handle this. Thanks in advance.
Use this method for HTTP requests:
def api_request(type , url, body=nil, header =nil )
require "net/http"
uri = URI.parse(url)
case type
when :post
request = Net::HTTP::Post.new(uri)
request.body = body
when :get
request = Net::HTTP::Get.new(uri)
when :put
request = Net::HTTP::Put.new(uri)
request.body = body
when :delete
request = Net::HTTP::Delete.new(uri)
end
request.initialize_http_header(header)
#request.content_type = 'application/json'
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') {|http| http.request request}
end
Your example will be:
api_request(:get, "https://api.cloud-elements.com/elements/api-v2/hubs/marketing/ping",nil, {"Authorization" => "Element TOKEN, User TOKEN" })
It would be something like the following. Note that the connection will be blocking, so it can tie up your server depending on how quickly the remote host returns the HTTP response and how many of these requests you are making.
require 'net/http'
# Let Ruby form a canonical URI from our URL
ping_uri = URI('https://api.cloud-elements.com/elements/api-v2/hubs/marketing/ping')
# Pass the basic configuration to Net::HTTP
# Note, this is not asynchronous. Ruby will wait until the HTTP connection
# has closed before moving forward
Net::HTTP.start(ping_uri.host, ping_uri.port, :use_ssl => true) do |http|
# Build the request using the URI as a Net::HTTP::Get object
request = Net::HTTP::Get.new(ping_uri)
# Add the Authorization header
request['Authorization'] = "Element #{ELEMENT_TOKEN}, User #{user.token}"
# Actually send the request
response = http.request(request)
# Ruby will automatically close the connection once we exit the block
end
Once the block exits, you can use the response object as necessary. The response object is always a subclass (or subclass of a subclass) of Net::HTTPResponse and you can use response.is_a? Net::HTTPSuccess to check for a 2xx response. The actual body of the response will be in response.body as a String.

Resources