I am trying to translate a curl request that works in the terminal for me into ruby code using the http gem.
This is the curl request that gives me back the valid json I want:
curl -X GET --header 'Accept: application/json' --header 'api_key: somekey' --header 'authtoken: sometoken' 'https://cdn.domain.io/v3/content_types/shirts/entries?environment=dev'
With the http gem I try to do this in my ruby script:
HTTP.headers(:Accept => "application/json", :api_key => 'somekey', :authtoken => 'sometoken').get("https://cdn.domain.io/v3/content_types/shirts/entries", :params => { :environment => 'dev'}).body.readpartial
And this gives my back "api_key":["is not valid."]} error from the server
What am I doing wrong? How do I get this to work?
Typhoeus seems to be working out well:
require "typhoeus"
require 'multi_json'
require "awesome_print"
response = Typhoeus::Request.new(
"https://api.domain.io/v3/content_types/shirts/entries?environment=dev",
headers: { api_key: "somekey", access_token: "sometoken",
accept_encoding: "gzip" }
).run
# puts response.body
begin
ap MultiJson.load(response.body, :symbolize_keys => true)
rescue MultiJson::ParseError => exception
p exception.data # => "{invalid json}"
p exception.cause # => JSON::ParserError: 795: unexpected token at '{invalid json}'
end
Related
I can't upload an image with Messenger bot on Ruby.
Here is a code that works in Bash:
curl \
-F recipient='{"id":"USER_ID"}' \
-F message='{"attachment":{"type":"image", "payload":{}}}' \
-F filedata="#out.jpg" \
"https://graph.facebook.com/v2.6/me/messages?access_token=PAGE_ACCESS"
Here is a translation with RestClient:
require 'rest-client'
require 'json'
file = "out.jpg"
tkn = "PAGE_ACCESS"
params = {
"recipient" => {"id" => "USER_ID"},
"message" => {
"attachment":{"type":"image", "payload":{}}
},
"filedata" => 'out.jpg'
}
puts params.to_json
begin
r = RestClient.post "https://graph.facebook.com/v2.6/me/messages?access_token=#{tkn}", params.to_json, :content_type => :json
rescue => e
puts e.response
end
Here is the answer I get:
{"recipient":{"id":"USER_ID"},"message":{"attachment":{"type":"image","payload":{}}},"filedata":"#out.jpg"}
{"error":{"message":"(#100) Incorrect number of files uploaded. Must upload exactly one file.","type":"OAuthException","code":100,"fbtrace_id":"xxxxx"}}
This is my first experience working with Twitter API's.
I am using the following tools:
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]
gem 'oauth'
oauth (0.5.1)
oauth2 (1.1.0)
omniauth-oauth2 (1.4.0)
I obtained a key and secret from Twitter.
I copied and pasted from the example on Twitter for Ruby.
=begin
code taken directly from the example at
https://dev.twitter.com/oauth/overview/single-user
=end
require 'oauth'
consumer_key, \
consumer_secret = [
'CONSUMER_KEY',
'CONSUMER_SECRET'
].map { |key| ENV[key] }
raise "Some key undefined." unless [consumer_key, consumer_secret].all?
# Exchange your oauth_token and oauth_token_secret for an AccessToken instance.
def prepare_access_token(oauth_token, oauth_token_secret)
consumer = OAuth::Consumer.new("APIKey", "APISecret", { :site => "https://api.twitter.com", :scheme => :header })
# now create the access token object from passed values
token_hash = { :oauth_token => oauth_token, :oauth_token_secret => oauth_token_secret }
access_token = OAuth::AccessToken.from_hash(consumer, token_hash )
return access_token
end
# Exchange our oauth_token and oauth_token secret for the AccessToken instance.
access_token = prepare_access_token(consumer_key, consumer_secret)
p access_token
# use the access token as an agent to get the home timeline
response = access_token.request(:get, "https://api.twitter.com/1.1/statuses/home_timeline.json")
p response
=begin
|| #<OAuth::AccessToken:0x000000021ed938
#token="redacted", #secret="redacted",
#consumer=#<OAuth::Consumer:0x000000021edb68
#key="APIKey",
#secret="APISecret", #options={:signature_method=>"HMAC-SHA1",
:request_token_path=>"/oauth/request_token",
:authorize_path=>"/oauth/authorize",
:access_token_path=>"/oauth/access_token",
:proxy=>nil, :scheme=>:header,
:http_method=>:post, :oauth_version=>"1.0",
:site=>"https://api.twitter.com"}>,
#params={:oauth_token=>"redacted", :oauth_token_secret=>"redacted"}>
|| #<Net::HTTPUnauthorized 401 Authorization Required readbody=true>
=end
What I tried:
Getting a new key and secret.
Result:
Net::HTTPUnauthorized 401 Authorization Required readbody=true
Synchronized my server's time because many Stack Overflow posts mentioned that a 401 is returned if the server time varies beyond a certain point. I installed ntp.
suggestions from this list
set the Callback URL in Twitter settings: http://127.0.0.1:3000/auth/twitter/callback
API Console Tool on Twitter. After authenticating with my Twitter account https://api.twitter.com/1.1/statuses/home_timeline.json returns
HTTP/1.1 200 OK
along with expected data.
checked to see if Twitter API operating normally
Suggestions of where to go from here appreciated.
UPDATE OAuth Tool on Twitter Developer returns the expected result with a curl execution:
curl --get 'https://api.twitter.com/1.1/statuses/home_timeline.json' --header 'Authorization: OAuth oauth_consumer_key="redacted", oauth_nonce="redacted", oauth_signature="redacted", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1463742270", oauth_token="redacted", oauth_version="1.0"' --verbose
Expected data is returned.
[{"created_at":"Fri May 20 11:05:21 +0000
2016","id":733614584754515968,"id_str":
"733614584754515968","text":"Three Skills Every New Programmer Should
Learn https://t. co/1p9AxO5JPg via
#sitepointdotcom","truncated":false,"entities":{"hashtags":[],"symbols"
(truncated)…
On this line, you should replace "APIKey" and "APISecret" with what you pulled from the CONSUMER_* environment variables.
consumer = OAuth::Consumer.new("APIKey", "APISecret", { :site => "https://api.twitter.com", :scheme => :header })
The example code from Twitter works fine for me. The wrong consumer keys will give you 401 for sure.
I am trying to get the following curl command (which works) replicated in some Ruby code, however the 'Customer-Id' header part seems to not get sent/picked up by the API.
The curl command is:
curl -u ‘me#mydomain.com’ -H ‘Customer-Id: 243’ https://192.168.50.50/api/customers
which returns info on that customer. However in Ruby, the following is not working:
auth = {
username: “me#mydomain.com”,
password: "#{pass}"
}
#result = HTTParty.get("https://192.168.50.50/api/customers",:basic_auth => auth, :headers => { ‘Customer-Id: 243’ } ).parsed_response
puts #result
If anyone has any ideas what I am doing wrong here, it would be appreciated!
Looking at your code, there is an error:
:headers => { ‘Customer-Id: 243’ }
Try this way:
:headers => {'Customer-Id' => 243}
I'm new to Ruby, and to using HTTParty, and was trying to follow the HTTParty examples from their github page to execute a basic POST. When I run the code below I get an error:
require 'pp'
require 'HTTParty'
require 'pry'
class Partay
include HTTParty
base_uri "http://<myapidomain>/search/semanticsearch/query/"
end
options= {
query: {
version: "0.4",
query: "lawyer"
}}
response = Partay.post(options)
puts response
The error I get is:
rbenv/versions/2.2.0/lib/ruby/2.2.0/uri/common.rb:715:in `URI': bad argument (expected URI object or URI string) (ArgumentError)
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/httparty/request.rb:47:in `path='
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/httparty/request.rb:34:in `initialize'
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/HTTParty.rb:539:in `new'
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/HTTParty.rb:539:in `perform_request'
from ~/.ruby/2.2.0/gems/httparty-0.13.3/lib/HTTParty.rb:491:in `post'
from json-to-csv.rb:16:in `<main>'
What I am looking for is calling a post that receives JSON in the same way that calling this URL works:
http://somedomain.com/search/semanticsearch/query/?version=0.4&query=lawyer
Noting a solution with the suggested gem - unirest:
require 'unirest'
url = "http://somedomain.com/search/semanticsearch/query"
response = Unirest.post url,
headers:{ "Accept" => "application/json" },
parameters:{ :version => 0.4, :query => "lawyer" }
I'm working on my first Sinatra app and I have an hard time getting parameters from a post request.
I'm using MiniTest::Spec and my spec looks like
payload = File.read("./spec/support/fixtures/payload.json")
post "/api/v1/verify_payload", { payload: payload }, { "CONTENT_TYPE" => "application/json" }
last_response.body.must_eql payload
And this is my route
namespace '/api/v1' do
post '/verify_payload' do
MultiJson.load(params[:payload])
end
end
The spec fails because last_response.body is empty.
Am I missing something here?
I also tried to return the entire params from verify_payload but also in that case it returned an empty string.
Update
curl -X POST -H "Content-Type: application/json" -d '{"payload":"xyz"}' http://localhost:9292/api/v1/verify_payload
does not return anything and no error on the server log
[2014-01-06 01:16:25] INFO WEBrick::HTTPServer#start: pid=10449 port=9292
127.0.0.1 - - [06/Jan/2014 01:16:27] "POST /api/v1/verify_payload HTTP/1.1" 200 6 0.0220
Thanks
Sinatra just doesn't parse this data, because they are not form parameters.
Form parameter would look like this
curl -X POST 127.1:4567/ -d "foo=bar"
Instead of params you can just use request.body.read or use rack contrib.
rack-contrib
Install it with gem install rack-contrib
require it
require 'rack'
require 'rack/contrib'
load it use Rack::PostBodyContentTypeParser
with this you can use params as normal for json post data. Something like this:
curl -X POST -H "Content-Type: application/json" -d '{"payload":"xyz"}' 127.1:4567/
source for this: Sinatra controller params method coming in empty on JSON post request, http://jaywiggins.com/2010/03/using-rack-middleware-to-parse-json/