https://developers.google.com/gdata/articles/using_ruby
I'm following the "Authentication | Using the Google Spreadsheets API" section in above tutorial.
rb(main):008:0> require 'net/https'
=> true
irb(main):009:0> http = Net::HTTP.new('www.google.com', 443)
=> #<Net::HTTP www.google.com:443 open=false>
irb(main):010:0> http.use_ssl = true
=> true
irb(main):011:0> path = '/accounts/ClientLogin'
=> "/accounts/ClientLogin"
# Now we are passing in our actual authentication data.
# Please visit OAuth For Installed Apps for more information
# about the accountType parameter
irb(main):014:0> data = \
irb(main):015:0* 'accountType=HOSTED_OR_GOOGLE&Email=your email' \
irb(main):016:0* '&Passwd=your password' \
irb(main):017:0* '&service=wise'
irb(main):018:0> headers = \
irb(main):019:0* { 'Content-Type' => 'application/x-www-form-urlencoded'}
=> {"Content-Type"=>"
application/x-www-form-urlencoded"}
# Post the request and print out the response to retrieve our authentication token
irb(main):020:0> resp, data = http.post(path, data, headers)
=> #<Net::HTTPLengthRequired 411 Length Required readbody=true>
I'm supposed to get "=> [#, "SID=DQAAAIIAAADgV7j4F-QVQjnxdDRjpslHKC3M ... [ snipping out the rest of the authentication strings ]" after the POST. I put my gmail id and password in email and password.
What is problem?
It's possible that they removed the service today. When I request this page https://www.google.com/accounts/ClientLogin I receive 404 (not found).
Related
I am trying to get the API Token from this api.
https://docs.bigmarker.com/#login
Basically below is the API format and it works with PostMan as well
curl -i -X POST --data "email=youremail#email.com&password=yourpassword" https://www.bigmarker.com/api/v1/members/login
I didn't specify any Headers, Just use the POST form data with email & password.
And this is my rails code.
require 'net/http'
require 'net/https'
uri = URI("https://www.bigmarker.com/api/v1/members/login")
res = Net::HTTP.post_form(uri, {'email' => email, 'passowrd' => password})
But it returns HTTP 500 Error.
#<Net::HTTPInternalServerError 500 Internal Server Error readbody=true>
Any idea?
Thanks
My mistake.
There was a spelling error.
res = Net::HTTP.post_form(uri, {'email' => email, 'passowrd' => password})
'passowrd' should be 'password'
I want to consume some API data from a Rails app. A curl example is curl --data 'api_key=your_api_key&api_secret=your_api_secret&host_id=your_user_host_id' https://api.zoom.us/v1/webinar/list I have experimented with this at the terminal and I am seeing expected responses. I’m now experimenting in a ruby script using httparty. My question is how should I handle the ‘stuff’ before the endpoint (api_key…secret…ect)? Are these headers?
In regard to curl --data only tells me that it is a post request, but I'm not sure how that translates to httparty.
Here is a first attempt:
require 'httparty'
api_key = 'myKey'
api_secret = 'secret'
host_id = 'host'
data_type = 'JSON'
response = HTTParty.post("api_key&api_secret&host_id&data_type https://api.zoom.us/v1/webinar/list/registration")
puts response.parsed_response
But this gives me a bad URI response. If I run this same script with the endpoint only I do get a response code back from zoom saying that API key and secret are required.
Looking at this example I think this should work:
require 'httparty'
api_key = 'myKey'
api_secret = 'secret'
host_id = 'host'
data_type = 'JSON'
options = {
body: {
api_key: api_key,
api_secret: api_secret,
host_id: host_id,
data_type: data_type
}
}
response = HTTParty.post("https://api.zoom.us/v1/webinar/list/registration", options)
puts response.parsed_response
I get the response:
{"error"=>{"code"=>200, "message"=>"Invalid api key or secret."}}
which I think is a step in the right direction.
No those are not headers those are parameters. Header are usually denoated by the -H flag.
Try this:
require 'httparty'
query_params = {api_key: 'myKey',
api_secret: 'secret',
host_id: 'host',
data_type: 'JSON'}
response = HTTParty.post("api_key&api_secret&host_id&data_type https://api.zoom.us/v1/webinar/list/registration", :query => query_params)
puts response.parsed_response
I have multiple bruises today, trying to learn two things at once... the API for Postmark and Rails HTTP requests.
Goal: Use Postmark add-on for Heroku to send production email.
I am trying to combine this article on HTTP requests...
http://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html
... with this API reference for Postmark...
http://developer.postmarkapp.com/developer-send-api.html
Unfortunately, the examples from Postmark are done in curl and I have not succeeded in translating them into a HTTP request. I suspect the problem centers around the headers -- the parts of the transmission other than the body.
The rescue clause seen in the code below traps the error 'connection reset by peer'. At this point I don't know if I am even close to the right format for the headers that provide Postmark authentication.
I have the proper server token (in the config entry) and the From email has been given the required Postmark signature.
def send_production_email(email_address, subject, email_body)
# Use API to interact with Heroku add-on Postmark
# http://developer.postmarkapp.com/developer-send-api.html
uri = URI('https://api.postmarkapp.com/email')
# Form the request
req = Net::HTTP::Post.new(uri)
# Set request headers -- SUSPECT THIS IS WRONG
req['Accept'] = 'application/json'
req['Content-Type'] = 'application/json'
req['X-Postmark-Server-Token'] = Rails.application.config.postmark_token
rbody ={
'From' => 'Support <michael#mydomain.com>',
'To' => email_address,
'Subject' => subject,
'HtmlBody' => wrap_html(email_body),
'TextBody' => email_body
}.to_json
req.body = rbody
# Send the request, waiting for the response
begin
response = Net::HTTP.new(uri.host, uri.port).start {|http| http.request(req) }
rescue Exception => e
logthis("http request error: #{e.message}")
return
end
# ...parsing section omitted since I do not get that far...
end
A second attempt was formatted this way, but results in the same peer reset error:
rbody ={
'From' => 'Support <michael#disambiguator.com>', # TODO: replace email when domain is live
'To' => email_address,
'Subject' => subject,
'HtmlBody' => wrap_html(email_body),
'TextBody' => email_body
}.to_json
uri = URI('https://api.postmarkapp.com/email')
http = Net::HTTP.new(uri.host, uri.port)
# http.use_ssl = true
request = Net::HTTP::Post.new(uri.path, {'Content-Type' => 'application/json', 'Accept' => 'application/json', 'X-Postmark-Server-Token' => Rails.application.config.postmark_token})
request.body = rbody
# Send the request, waiting for the response
begin
response = http.request(request)
rescue Exception => e
logthis("http request error: #{e.message}")
return
end
I am grateful for any guidance!
I’m a Wildbit’s employee and the maintainer of the official Postmark Ruby gem.
The "connection reset by peer" error is the result of you trying to send an unencrypted HTTP request to an endpoint expecting secure communication via HTTPS. So, if you change this line:
Net::HTTP.new(uri.host, uri.port).start {|http| http.request(req) }
to:
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
response = http.start { |http| http.request(req) }
then you should be able to receive a response from the API. I see that you have this line in the second example, but it is commented. Since you’re doing this as an exercise, I’d like to add that when using net/http you don’t usually have to work with the underlying classes like Net::HTTP::Post. It’s generally simpler to use the higher level API provided by instances of the Net::HTTP class. Here is an example of how your method could be simplified by using it:
def send_production_email(email_address, subject, email_body)
uri = URI('https://api.postmarkapp.com/email')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
headers = {'Accept' => 'application/json',
'Content-Type' => 'application/json',
'X-Postmark-Server-Token' => Rails.application.config.postmark_token}
payload = {'From' => 'tema#wildbit.com',
'To' => email_address,
'Subject' => subject,
'HtmlBody' => email_body,
'TextBody' => email_body}
http.post(uri.request_uri, payload.to_json, headers)
rescue => e
puts "http request error: #{e.message}"
end
And, if you’re interested in how net/http is used in the official Postmark Ruby gem, check out the HttpClient class’ source.
I am trying to setup the Spotify IOS API but everytime I run this Ruby file and go to http://localhost:1234/swap I get "Sinatra doesn't know this ditty".
Here is my code:
require 'sinatra'
require 'net/http'
require 'net/https'
require 'base64'
require 'json'
require 'encrypted_strings'
# This is an example token swap service written
# as a Ruby/Sinatra service. This is required by
# the iOS SDK to authenticate a user.
#
# The service requires the Sinatra and
# encrypted_strings gems be installed:
#
# $ gem install sinatra encrypted_strings
#
# To run the service, enter your client ID, client
# secret and client callback URL below and run the
# project.
#
# $ ruby spotify_token_swap.rb
#
# IMPORTANT: The example credentials will work for the
# example apps, you should use your own in your real
# environment. as these might change at any time.
#
# Once the service is running, pass the public URI to
# it (such as http://localhost:1234/swap if you run it
# with default settings on your local machine) to the
# token swap method in the iOS SDK:
#
# NSURL *swapServiceURL = [NSURL urlWithString:#"http://localhost:1234/swap"];
#
# -[SPAuth handleAuthCallbackWithTriggeredAuthURL:url
# tokenSwapServiceEndpointAtURL:swapServiceURL
# callback:callback];
#
print "\e[31m------------------------------------------------------\e[0m\n"
print "\e[31mYou're using example credentials, please replace these\e[0m\n"
print "\e[31mwith your own and remove this silly warning.\e[0m\n"
print "\e[31m------------------------------------------------------\e[0m\n"
print "\7\7"
sleep(2)
CLIENT_ID = ""
CLIENT_SECRET = ""
ENCRYPTION_SECRET = ""
CLIENT_CALLBACK_URL = "dawgone://returnhere"
AUTH_HEADER = "Basic " + Base64.strict_encode64(CLIENT_ID + ":" + CLIENT_SECRET)
SPOTIFY_ACCOUNTS_ENDPOINT = URI.parse("https://accounts.spotify.com")
set :port, 1234 # The port to bind to.
set :bind, '0.0.0.0' # IP address of the interface to listen on (all)
post '/swap' do
# This call takes a single POST parameter, "code", which
# it combines with your client ID, secret and callback
# URL to get an OAuth token from the Spotify Auth Service,
# which it will pass back to the caller in a JSON payload.
auth_code = params[:code]
http = Net::HTTP.new(SPOTIFY_ACCOUNTS_ENDPOINT.host, SPOTIFY_ACCOUNTS_ENDPOINT.port)
http.use_ssl = true
request = Net::HTTP::Post.new("/api/token")
request.add_field("Authorization", AUTH_HEADER)
request.form_data = {
"grant_type" => "authorization_code",
"redirect_uri" => CLIENT_CALLBACK_URL,
"code" => auth_code
}
response = http.request(request)
# encrypt the refresh token before forwarding to the client
if response.code.to_i == 200
token_data = JSON.parse(response.body)
refresh_token = token_data["refresh_token"]
encrypted_token = refresh_token.encrypt(:symmetric, :password => ENCRYPTION_SECRET)
token_data["refresh_token"] = encrypted_token
response.body = JSON.dump(token_data)
end
status response.code.to_i
return response.body
end
post '/refresh' do
# Request a new access token using the POST:ed refresh token
http = Net::HTTP.new(SPOTIFY_ACCOUNTS_ENDPOINT.host, SPOTIFY_ACCOUNTS_ENDPOINT.port)
http.use_ssl = true
request = Net::HTTP::Post.new("/api/token")
request.add_field("Authorization", AUTH_HEADER)
encrypted_token = params[:refresh_token]
refresh_token = encrypted_token.decrypt(:symmetric, :password => ENCRYPTION_SECRET)
request.form_data = {
"grant_type" => "refresh_token",
"refresh_token" => refresh_token
}
response = http.request(request)
status response.code.to_i
return response.body
end
This is because swap is a POST endpoint. When you pull up a URL in your browser you are doing an HTTP GET.
If you want to see that the sinatra service is running and you can at least talk to it you could try hitting it with curl from the command line with the right POST parameters.
I'm building an app in Rails using the Spotify web API. I built a method to refresh a user's token, but am receiving a 400 error. According the the Spotify Web API docs, the header of my request needs to be in the following format:
Authorization: Basic <base64 encoded client_id:client_secret>
Using Httparty gem, here's the POST method to refresh the access token:
def refresh_token
client_id = "foo"
client_secret = "bar"
client_id_and_secret = Base64.encode64("#{client_id}:#{client_secret}")
result = HTTParty.post(
"https://accounts.spotify.com/api/token",
:body => {:grant_type => "refresh_token",
:refresh_token => "#{self.oauth_refresh_token}"},
:headers => {"Authorization" => "Basic #{client_id_and_secret}"}
)
end
Here's what "result" ends up being:
=> #<HTTParty::Response:0x7f92190b2978 parsed_response={"error"=>"invalid_client", "error_description"=>"Invalid client secret"}, #response=#<Net::HTTPBadRequest 400 Bad Request readbody=true>, #headers={"server"=>["nginx"], "date"=>["Sun, 31 Aug 2014 22:28:38 GMT"], "content-type"=>["application/json"], "content-length"=>["70"], "connection"=>["close"]}>
I can decode client_id_and_secret and it returns "foo:bar", so I'm at a loss as to why I'm receiving a 400 error. Any insight is much appreciated.
Found the issue... it was with the Base64 encoding in Ruby. Apparently (as shown in Strange \n in base64 encoded string in Ruby) using the Base64.encode64('') method adds an extra line within the code. Using Base64.strict_encode64('') solved the issue.
Updated code:
def refresh_token
client_id = "foo"
client_secret = "bar"
client_id_and_secret = Base64.strict_encode64("#{client_id}:#{client_secret}")
result = HTTParty.post(
"https://accounts.spotify.com/api/token",
:body => {:grant_type => "refresh_token",
:refresh_token => "#{self.oauth_refresh_token}"},
:headers => {"Authorization" => "Basic #{client_id_and_secret}"}
)
end