Google Geocoding API request_denied - ruby-on-rails

I am trying to geocode a batch of around 400 addresses using the Google Geocoding API through my rails app.
In one of my controllers I have these lines
require "net/http"
require "uri"
uri = URI.parse("http://maps.googleapis.com/maps/api/geocode/json?")
response = Net::HTTP.post_form(uri, {"address" => '5032-forbes-ave', 'sensor' => 'false'})
But I always get back ""status": "REQUEST_DENIED" from that.
Does anyone know why I am getting this, or if there is a way I can see exactly the HTTP request that is being sent so I can try to debug it?
Update: This is the request that I am trying to make, if I do this from my browser I get a normal response from the api: http://maps.googleapis.com/maps/api/geocode/json?address=5032-forbes-ave&sensor=false

You are POSTing the request but in your browser you are using GET.
So this work perfectly:
uri = URI.parse("http://maps.googleapis.com/maps/api/geocode/json?address=5032-forbes-ave&sensor=false")
response = Net::HTTP.get(uri)
The response is String itself and it contains some JSON (I'm not Google API's expert)

Related

Twitter API v1.1 media INIT error code 32

I am trying to get the media_id for a media upload. See docs here.
When using postman, my request is processed successfully and I get a response like this:
{
"media_id": 1222234872222222401,
"media_id_string": "1222734822222102201",
"expires_after_secs": 86399
}
Unfortunately, using postman for our app is not an option. However, when I post a tweet with just text, the tweet is posted successfully using our own native code. I have also recreated the request from postman, and can successfully recreated the same oauth_signature needed for the media upload authorization. So I know that the backend is working in that I can create valid credentials, but I think I need some help structuring the POST request itself.
Here is the code (Lucee ColdFusion):
mediaEndpoint = "https://upload.twitter.com/1.1/media/upload.json?command=INIT&total_bytes=10240&media_type=image/jpg&oauth_consumer_key=consumerKeyHere&oauth_token=tokenHere&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1653075352&oauth_nonce=UU5V18WLaPN&oauth_version=1.0&oauth_signature=verifiedSignature";
cfhttp(url=mediaEndpoint, method="POST", result="init") {
cfhttpparam(type="header", name="Content-Type", value="application/x-www-form-urlencoded");
cfhttpparam(type="header", name="Accepts", value="*/*");
cfhttpparam(type="header", name="Accept-Encoding", value="gzip, deflate, br");
cfhttpparam(type="header", name="Connection", value="keep-alive");
cfhttpparam(type="body", value="command=INIT&media_type=#mediaParameters.media_type#&total_bytes=#mediaParameters.total_bytes#");
}
But I keep getting the following 401:
{"errors":[{"code":32,"message":"Could not authenticate you."}]}
I believe you're supposed to send your authorization token in the header. You're sending it in the URL as a query string. Twitter's documentation would indicate you need to include an authorization header as such:
cfhttpparam(type="header", name="Authorization", value="Bearer: #YourAccessToken#");

restsharp and Postman

I am attempting to get an OAuth2 access token from ZOHO using RestSharp code. The Postman simulation works correctly so I know there is something I'm missing in my code.
I always get an "invalid client id" result status. However in Postman, it works and returns a code when I click the "Get new access token". I have the same items as in the Postman authorization tab (client_id, client_secret, etc). In Postman, "Body" is set to "none", and there are no parameters or headers. The only difference between my code and postman, is that Postman requires the Callback URL. My code is trying to get the code using "self-client", which bypasses the callback URL.
I have tried several different alternatives to the request call including ParameterType.Body, and ParameterType.GetOrPost. Is GetOrPost the same as a form?
client = New RestClient(ZOHO_API_URL)
request = New RestRequest(TokenUrl, Method.POST)
request.AddHeader("content-type", "application/x-www-form-urlencoded") ' also tried: "application/json")
request.AddParameter("grant_type", "authorization_code",
ParameterType.GetOrPost)
request.AddParameter("client_id", Client_ID, ParameterType.GetOrPost)
request.AddParameter("client_secret", Client_Secret,
ParameterType.GetOrPost)
request.AddParameter("code", Grant_Token, ParameterType.GetOrPost)
response = client.Execute(request)
This is the translated Postman code for RestSharp:
var client = new RestClient("http://");
var request = new RestRequest(Method.POST);
request.AddHeader("Postman-Token", "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx");
request.AddHeader("cache-control", "no-cache");
IRestResponse response = client.Execute(request);
Any ideas on what I am doing wrong. I have tried to view the raw data coming across with Fiddler, but when I do that, Postman indicates a failure.
What code do I need to use to duplicate what Postman is doing?
How do I implement a callback URL if that is also required?
I quickly checked ZoHo REST API docs and it seems like you should use the Limited Input Device authentication flow.
From what I can understand from their help page, you indeed need to do a POST request, but parameters must be specified as query parameters:
https://accounts.zoho.com/oauth/v3/device/code?
client_id=1000.GMB0YULZHJK411248S8I5GZ4CHUEX0&
scope=AaaServer.profile.READ&
grant_type=device_request
You will also get better off with JSON set as a default for serialisation and content type just by using client.UseJson().
It maybe that Postman is following a redirect from your API endpoint as the functionality is different Postman verses RestSharp (possibly missing a trailing slash or similar).
Try adding
client.FollowRedirects = false;
to your RestSharp code and analyse the result.

Error when POST ing through Ruby. Postman works fine

I have a strange issue when trying to POST to a third party website.
When testing using Postman, I get a correct response. However, when trying the same POST via Ruby code, I get a cryptic HTML response page from the website. HTTP Response code is 200. It's just that the website's internal logic throws an error, which should'nt happen if I'm sending the exact same request via code than the request I'm sending via Postman.
Url is: http://www.sunat.gob.pe/cl-at-ittipcam/tcS01Alias
The POST can be generated in the browser when choosing month ("mes") and day ("dia") in the dropboxes shown in that webpage. I have also inspected the network call in this case in the browser console and can find nothing funny.
My code comes straight from the one generated by Postman. I have also tried HTTParty gem with the same error response
require 'uri'
require 'net/http'
url = URI("http://www.sunat.gob.pe/cl-at-ittipcam/tcS01Alias")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["cache-control"] = 'no-cache'
request["content-type"] = 'application/x-www-form-urlencoded'
request["postman-token"] = '3ba1963c-2874-89c2-5e4d-e5be2c13a560'
request.body = "mes=05&anho=2016"
response = http.request(request)
puts response.read_body
A correct response should show an HTML table filled with values. Instead I'm getting an HTML error page.
Any help figuring out the issue would be appreciated.
Edit: the HTML response is not really relevant, since it is a business logic error, not an HTTP error, but here it is:
The thing is: this internal logic error is being triggered because something is different when sending the POST request via code than when sending it via Postman, and I can't figure out what.
"\r\n\r\n.:: Pagina de Errores
::.\r\n\r\n\r\n\r\nBODY
{font-style:normal;font-size:10pt;font-family:Verdana,Arial,Helvetica,sans-serif;}\r\nH1
{font-size:16pt;color:Navy;}\r\nA {color:Navy;}\r\n.msg
{font-style:bold;font-size:14pt;}\r\n.error
{font-style:bold;font-size:14pt;color:Red;}\r\n.datos
{font-size:12pt;}\r\n.soluc {font-size:12pt;}\r\n\r\n\r\nLa aplicación
ha retornado el siguiente problema :\r\n\r\n\r\n\r\n\r\n\r\nAcción a realizar :\r\n\r\n\r\nPor favor intentente nuevamente
realizar la operación, si el problema persiste, avisar a
nuestro webmaster
o\r\ncomunicarse con Atenci\xF3n a Usuarios.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n(function(){var
f5_cspm={f5_p:'NEHEKPGFEEIGMFMPAJJJKDPGKDEIIJJIDBONLBJECPDLCCOBKCPONGDHNEIJOKPPCGMBMAGEAADECGEHHJAAAPLKAANKMODHPLFBCJKHMMCPOAKONNKGFELHONBMHBIO',setCharAt:function(str,index,chr){if(index>str.length-1)return
str;return
str.substr(0,index)+chr+str.substr(index+1);},get_byte:function(str,i){var
s=(i/16)|0;i=(i&15);s=s*32;return((str.charCodeAt(i+16+s)-65)<<4)|(str.charCodeAt(i+s)-65);},set_byte:function(str,i,b){var
s=(i/16)|0;i=(i&15);s=s*32;str=f5_cspm.setCharAt(str,(i+16+s),String.fromCharCode((b>>4)+65));str=f5_cspm.setCharAt(str,(i+s),String.fromCharCode((b&15)+65));return
str;},set_latency:function(str,latency){latency=latency&0xffff;str=f5_cspm.set_byte(str,40,(latency>>8));str=f5_cspm.set_byte(str,41,(latency&0xff));str=f5_cspm.set_byte(str,35,2);return
str;},wait_perf_data:function(){try{var
wp=window.performance.timing;if(wp.loadEventEnd>0){var
res=wp.loadEventEnd-wp.navigationStart;if(res<60001){var
cookie_val=f5_cspm.set_latency(f5_cspm.f5_p,res);window.document.cookie='f5avr1032272937aaaaaaaaaaaaaaaa='+encodeURIComponent(cookie_val)+';path=/';}\nreturn;}}\ncatch(err){return;}\nsetTimeout(f5_cspm.wait_perf_data,100);return;},go:function(){var
chunk=window.document.cookie.split(/\s*;\s*/);for(var
i=0;i"
You need to probably use a GET request to get the table. The server is not responding on the POST request because it has not been configured to respond to it.
The solution is to use:
uri = URI('http://www.sunat.gob.pe/cl-at-ittipcam/tcS01Alias')
request = Net::HTTP::Get.new(uri)
instead of the code with Post.new

How to get the status after sending data to external server rails

In my rails (3.2.13) app I send data to an external server using a form, then the external server process the data I sent and shows that the result is ok or not, I need to save that result or status to my rails app database, but I'm not sure about how to redirect to another page when the process in the external server is done.
I have a function to ask the server if the process of that data went ok using the reference or id that I sent in the first place using the form but as I said I don't know how to redirect after the process is finish...
please help me
You can use some core Ruby libraries to make a subsequent request on the same endpoint to determine the status code of your request. Try the following, cited in whole from Ruby Inside:
# Basic REST.
# Most REST APIs will set semantic values in response.body and response.code.
require "net/http"
http = Net::HTTP.new("api.restsite.com")
request = Net::HTTP::Post.new("/users")
request.set_form_data({"users[login]" => "quentin"})
response = http.request(request)
# Use nokogiri, hpricot, etc to parse response.body.
request = Net::HTTP::Get.new("/users/1")
response = http.request(request)
# As with POST, the data is in response.body.
request = Net::HTTP::Put.new("/users/1")
request.set_form_data({"users[login]" => "changed"})
response = http.request(request)
request = Net::HTTP::Delete.new("/users/1")
response = http.request(request)
Once you've instantiated a response object, you can operate on it in the following manner:
response.code #=> returns HTTP response code

Google Calendar Data API Integration

We're using Oauth to grab Calendar event data. I have successfully authorized the token and exchange it for an access token. When I perform a get request to the API endpoint I get a page that says "Moved Temporarily" with a link to something like https://www.google.com/calendar/feeds/default?gsessionid=xxxxxxxxxxxx
I'd like to interpret the response, whether it's json or xml but I can't get beyond the redirect it's throwing out. Any idea how to follow this?
Here's my call to the feed:
access_token = current_user.google.client
response = access_token.get(ConsumerToken::GOOGLE_URL).body
Yep, just dealt with this myself. It says "Moved Temporarily" because it's a redirect, which the oauth gem unfortunately doesn't follow automatically. You can do something like this:
calendar_response = client.get "http://www.google.com/calendar/feeds/default"
if calendar_response.kind_of? Net::HTTPFound # a.k.a. 302 redirect
calendar_response = client.get(calendar_response['location'])
end
This might be worthy of a patch to oauth...

Resources