How can pass parameter with httparty gem after authentication - ruby-on-rails

I am working for importing odesk API into my local project. for that i used omniauth-odesk gem for authentication and httparty gem for call http request for access odesk information.
in my Gemfile.rb
gem 'omniauth-odesk'
gem 'httparty'
in odesk_controller.rb
class OdeskController < ApplicationController
include HTTParty
def user_details
#odesk_user = env["omniauth.auth"]
end
def search_job
#response = HTTParty.get "http://www.odesk.com/api/profiles/v2/search/jobs.json", :headers=>{"Authorization"=>"Token token=\"06ede858bcdf8a5fedfa9119fd7074c4\""}
end
def check_profile
end
end
in view/odesk/search_job.html.erb
<%= #response.inspect %>
inspect information are below :
#<HTTParty::Response:0x3368f40 parsed_response={"server_time"=>1395822483, "error"=>{"status"=>400, "code"=>400, "message"=>"Malformed request: standard autorization is not supported for this API, use an application key"}}, #response=#<Net::HTTPBadRequest 400 Bad Request readbody=true>, #headers={"server"=>["nginx"], "content-type"=>["application/json"], "content-length"=>["155"], "x-odesk-error-code"=>["400"], "x-odesk-error-message"=>["Malformed request: standard autorization is not supported for this API, use an application key"], "expires"=>["Fri, 13 Oct 2000 05:00:00 GMT"], "last-modified"=>["Wed, 26 Mar 2014 08:28:03 GMT"], "cache-control"=>["no-store, no-cache, must-revalidate", "post-check=0, pre-check=0"], "pragma"=>["no-cache"], "vary"=>["Cookie,Accept-Encoding"], "date"=>["Wed, 26 Mar 2014 08:28:03 GMT"], "connection"=>["close"]}>
I am using correct api key and secret key for odesk API. and token is also correct. but where i am wrong please check and let me know.
I am following below link for making http request
http://developers.odesk.com/w/page/12364012/search%20jobs
thanks

Related

I am trying to connect to the Xero API to recipe invoices but getting the following error

When i am trying to get the invoices using the Xero API i get an error with .get_invoices('').invoices.
Please see the error below:
*** XeroRuby::ApiError Exception: Error message: the server returns an error
HTTP status code: 403
Response headers: {"content-length"=>"0", "server"=>"nginx", "xero-correlation-id"=>"c605f5e5-81e7-4763-ae07-093e7cb6f949", "x-appminlimit-remaining"=>"9998", "expires"=>"Thu, 02 Feb 2023 16:45:04 GMT", "cache-control"=>"max-age=0, no-cache, no-store", "pragma"=>"no-cache", "date"=>"Thu, 02 Feb 2023 16:45:04 GMT", "connection"=>"keep-alive", "x-client-tls-ver"=>"tls1.3"}
Response body:
Index Controller
require 'xero-ruby'
creds = {
client_id: '...',
client_secret: '...',
grant_type: 'client_credentials'
}
xero_client = XeroRuby::ApiClient.new(credentials: creds)
#token_set = xero_client.get_client_credentials_token
byebug
#invoices = xero_client.accounting_api.get_invoices('').invoices
Please can you check the tenant id in your call. Looking at the Xero logs for the correlation id you mention, the tenant id is being sent as "page=1-100"

I am trying to integrate Xero API to ruby on rails however am unable to access the Token Set

I am integrating Xero API into my ruby on rails application, however when trying to get a Token Set I am getting the below error:
*** XeroRuby::ApiError Exception: Error message: the server returns an error
HTTP status code: 400
Response headers: {"content-type"=>"application/json; charset=UTF-8", "server"=>"nginx", "xero-origin-id"=>"IdentityServer.Web", "xero-causation-id"=>"63c9c7b03d7f435aa5dd801d96e8c152", "xero-message-id"=>"9e6951801da040ac94f61ab3392e3feb", "xero-activity-id"=>"adbfa8002310478c9d223f71e47b5b17", "xero-correlation-id"=>"6069553f3b9843f992e54f59f7bde8c0", "content-length"=>"26", "expires"=>"Wed, 01 Feb 2023 12:40:41 GMT", "cache-control"=>"max-age=0, no-cache, no-store", "pragma"=>"no-cache", "date"=>"Wed, 01 Feb 2023 12:40:41 GMT", "connection"=>"close", "set-cookie"=>"Device=961bc311701f4e20a0a2a7c0b6900dad; expires=Tue, 01 Feb 2028 12:40:41 GMT; path=/; samesite=none; httponly, _abck=CF3C26F9436304BF37101493FFAD83AF~-1~YAAQscNQaDKxnNKFAQAAPFz+DAnlKYqiZGnjCEbMvoyet1jSR8zH92SopvoLwB4qij7m04HY3vz38HatmtYuYAgN43HShtEj4miB94A9kiGQvrTNgMw9fNcpXV5sZ7JVNARjYdFjRYo0hU/n+qpWeEFH5OgBb8gzYVcOP5KqhPLgOd2ctiJrhmWiEmaeNZVbKj/spi60wt24oTv4jeWSplHq+i1LIzvPWLsVSU8RGKddmx+w7QnmtuWgbogouQljdvXS2Hrp9jDQsQXbvC9cWLy7A4AINQy7DLKP53mRgbqhdl7rG4Zyy8Bkv8nuxJvboM1MmdmorDngUVMNKkxpfdrWfJB5dv1Dbs3BOxJS2s9lRN56ugyI~-1~-1~-1; Domain=.xero.com; Path=/; Expires=Thu, 01 Feb 2024 12:40:41 GMT; Max-Age=31536000; Secure, bm_sz=D5B91089FE0B5C15AAF78A78C3DC4631~YAAQscNQaDOxnNKFAQAAPFz+DBKO2MjN+su/jV34lpo0F8Da/HIe1gG6gWfP7mzR6F7LwAPpRmm2lbXSjxw8/92CaTTcdsebzypKwiiowvOYOOI5/2TdwwcrU2bLSe9jN9YgUIS5izdAcysuz8S4pjx5OnNVe1HvhmUOeX8P/njVXeF7sQbFwmoAz3HyAO2AbJK0FGybHT8Spbfujl91GJ8+8YUf8voUQObj8r7o3K3GbWCycMG0lp6yupNoF7qfkPEuIl2vzMNCF0m2ZLH9a+akzpzc14KqjSwuz3k+++NK~3551286~3225656; Domain=.xero.com; Path=/; Expires=Wed, 01 Feb 2023 16:40:41 GMT; Max-Age=14400"}
Response body: {"error":"invalid_client"}
Please see the command below which I used to try an receive the Token Set:
#token_set = #xero_client.get_token_set_from_callback(params[:code])
class HomeController < ApplicationController
def index
require 'xero-ruby'
require 'httparty'
creds = {
client_id: '...',
client_secret: '...',
redirect_uri: 'http://localhost:3000/login',
scopes: 'accounting.attachments',
state: "Optional value to pass through auth flow"
}
config = { timeout: 30, debugging: true }
#xero_client ||= XeroRuby::ApiClient.new(credentials: creds, config: config)
#authorization_url = #xero_client.authorization_url
end
end
Login controller:
class LoginController < ApplicationController
def index
require 'xero-ruby'
creds = {
client_id: '...',
client_secret: '...',
redirect_uri: 'http://localhost:3000/login',
scopes: 'accounting.attachments',
state: "Optional value to pass through auth flow"
}
config = { timeout: 30, debugging: true }
#xero_client ||= XeroRuby::ApiClient.new(credentials: creds, config: config)
byebug
#token_set = #xero_client.get_token_set_from_callback(params[:code])
end
end
Please can you check your client secret as the error linked to the Xero correlation id is "Client secret validation failed for client"
It may be best to generate a new one from developer.xero.com and then replace this into your code.
We also have a sample app you can use if this makes it easier https://github.com/XeroAPI/Xero-ruby-oauth2-app

Passing cookies with HTTParty

I'm trying to log in a user with HTTParty into a Rails application.
The idea is to send a POST request and get a session cookie with it, then send a GET request with this cookie and log in successfully:
POST request
HTTParty.post('url/login/', basic_auth: {user: 'user', password: 'password'}, follow_redirects: false)
returns
#<HTTParty::Response:0x7f9c71bc4598 parsed_response=nil, #response=#<Net::HTTPFound 302 302 readbody=true>, #headers={"date"=>["Mon, 04 Mar 2019 08:02:26 GMT"], "server"=>["Apache"], "strict-transport-security"=>["max-age=31536000"], "set-cookie"=>["JSESSIONID=6552C1F4FD12D1C5B1D3B42168B9588A.node2; Path=/; Secure; HttpOnly"], "x-content-type-options"=>["nosniff"], "x-xss-protection"=>["1; mode=block"], "cache-control"=>["no-cache, no-store, max-age=0, must-revalidate"], "pragma"=>["no-cache"], "expires"=>["0"], "location"=>["/ipad-api/v20/login/failure/"], "vary"=>["Accept-Encoding,User-Agent"], "content-length"=>["20"], "connection"=>["close"], "content-type"=>["text/plain; charset=UTF-8"]}>
The I send a GET request
HTTParty.get('url/login/success/', cookie: "6552C1F4FD12D1C5B1D3B42168B9588A.node2")
and get
#<HTTParty::Response:0x7f9c71b95950 parsed_response={"head"=>{"apikey"=>nil, "sessionid"=>"320E4C622043566D5424627BDE11997D.node3", "timestamp"=>1551686567666, "sessiontimeout"=>1551689267666, "wishlistItemsCount"=>0, "basketItemsCount"=>0, "loggedIn"=>false, "role"=>"G"}, "data"=>{"user"=>{"profile"=>{"title"=>nil, "firstname"=>nil, "lastname"=>nil, "street"=>nil, "street2"=>nil, "postalcode"=>nil, "city"=>nil, "customerID"=>nil, "customerType"=>0}}, "abandonedBasket"=>false}, "messages"=>[{"code"=>"bmd.api.login.success", "statusCode"=>200, "description"=>"OK"}]}, #response=#<Net::HTTPOK 200 200 readbody=true>, #headers={"date"=>["Mon, 04 Mar 2019 08:02:47 GMT"], "server"=>["Apache"], "strict-transport-security"=>["max-age=31536000"], "set-cookie"=>["JSESSIONID=320E4C622043566D5424627BDE11997D.node3; Path=/; Secure; HttpOnly"], "x-content-type-options"=>["nosniff"], "x-xss-protection"=>["1; mode=block"], "cache-control"=>["no-cache, no-store, max-age=0, must-revalidate"], "pragma"=>["no-cache"], "expires"=>["0"], "vary"=>["Accept-Encoding,User-Agent"], "connection"=>["close"], "transfer-encoding"=>["chunked"], "content-type"=>["application/json;charset=UTF-8"]}>
Session changes and the user isn't logged in. Same requests with curl log a user in successfully.
Research showed that it might be not easy and this solution doesn't work either.
Any ideas what I'm doing wrong and in what direction to think? Change to faraday, as suggested here?
To login using HTTParty you have to look more things than cookies. You have to see CSRF_token too. I think you can get authenticity_token using gsub method but I tried and it was quite difficult to create regex. So I used Nokogiri to get token which is actually present in the sign in form. Following is details and at the end, I will put the whole code.
Adding required Gems, you can add it in Gemfile
gem 'httparty'
gem 'nokogiri'
Run bundle install to get gem installed.
To get CSRF_token we have to get sign_in page.
url = "http://localhost:3000/users/sign_in"
get_response = HTTParty.get(url)
noko_doc = Nokogiri::HTML(get_response)
auth_token = noko_doc.css('form').css('input[name="authenticity_token"]').first.values[2]
This way we got auth_token which was in the form as a hidden field. Now let us get cookies as session cookie may needed.
cookie_hash = HTTParty::CookieHash.new
get_response.get_fields('Set-Cookie').each { |c| cookie_hash.add_cookies(c) }
Here we are getting cookies where session is also present.
Now it is time to get final params and than we will send both cookies and session to login
params = {"utf8" => "✓", "authenticity_token" => auth_token, "user[email]"=>"user#email.com",·
"user[password]"=>"password"}
params["commit"] = "Login"
Now params are ready, you can use following httparty request to login and get cookies.
response = HTTParty.post("http://localhost:3000/users/sign_in", {:body=>params, headers: {'Cookie' => cookie_hash.to_cookie_string }} )
Now for other request you can run same cookies method to get all cookies back
cookie_hash = HTTParty::CookieHash.new
get_response.get_fields('Set-Cookie').each { |c| cookie_hash.add_cookies(c) }
And to access other pages you can send request with cookies as we did in above example. Remember if you again going to use any page which has form, again you need to get its csrf too.
response = HTTParty.post("http://localhost:3000/users/other_urls", {headers: {'Cookie' => cookie_hash.to_cookie_string }} )
I tried this code and it is working perfectly. Here is complete code for your use
require 'httparty'
require 'Nokogiri'
require 'Pry'
url = "http://localhost:3000/users/sign_in"
get_response = HTTParty.get(url)
noko_doc = Nokogiri::HTML(get_response)
auth_token = noko_doc.css('form').css('input[name="authenticity_token"]').first.values[2]
cookie_hash = HTTParty::CookieHash.new
get_response.get_fields('Set-Cookie').each { |c| cookie_hash.add_cookies(c) }
params = {"utf8" => "✓", "authenticity_token" => auth_token, "user[email]"=>"user#example.com",·
"user[password]"=>"password"}
params["commit"] = "Login"
response = HTTParty.post("http://localhost:3000/users/sign_in", {:body=>params, headers: {'Cookie' => cookie_hash.to_cookie_string }} )
puts response

Rails: Parsing HTTParty

I've read other answers on this topic, such as:
Parsing HTTParty response
HTTParty parsing JSON in Rails
However, I still can't figure out how to parse a response I'm receiving.
response.parsed_response = HTTParty.get(url, query: params) returns:
=> #<HTTParty::Response:0x89435d0 parsed_response="http://foo.com", #response=#<Net::HTTPOK 200 OK readbody=true>, #headers={"cache-control"=>["no-cache", "no-store"], "date"=>["Tue, 21 Feb 2017 23:10:47 GMT"], "expires"=>["Thu, 01 Jan 1970 00:00:00 GMT"], "p3p"=>["CP=\"ALL IND DSP COR CUR ADM TAIo PSDo OUR COM INT NAV PUR STA UNI\""], "pragma"=>["no-cache"], "server"=>["Apache-Coyote/1.1"], "set-cookie"=>["bar.Agent.p=c1921b97d1f8a0918621c48bd32ded2b; Domain=.bar.com; Expires=Fri, 19-Feb-2027 23:10:47 GMT; Path=/"], "content-length"=>["366"], "connection"=>["Close"]}>
I need the URL that appears after parsed_response. The other answers seemed to break down hashes that appear after parsed_response, but I'm just looking for the url that appears after parsed_response (and it only appears there in the response).
I tried:
puts response which returns the entire response above.
puts response.parsed_response which returns:
http://foo.com
=> nil
This usually works for me
response = HTTParty.get(url, options)
puts response.body

Unable to parse Sendgrid parse api raw callback into Griddler email object

I am trying to accomplish the following:
Have all emails send to my domain parsed for the content of their to, body, subject line and ... in order for me to construct a fax object from it and send it as a fax
So far I have been able to setup my MX record to point to Sendgrid and from Sendgrid's Parse API using Ngrok I get the callback in my localhost server. The next step is to get the raw object into an object I could work with. This lead me to Thoughbot's Griddler Gem.
This is how I have setup my app so far:
Sendgrid Setup:
URL: https://8c00fab0.ngrok.io/email_processor | Spam Check and Send Raw are both checked
As mentioned before this part works since I do receive this:
Parameters: {"dkim"=>"{#gmail.com : pass}", "email"=>"Received: by mx0034p1mdw1.sendgrid.net with SMTP id 253FfvZ40f Wed, 09 Sep 2015 22:31:48 +0000 (UTC)\nReceived: from mail-qg0-f54.google.com (mail-qg0-f54.google.com [209.85.192.54]) by mx0034p1mdw1.sendgrid.net (Postfix) with ESMTPS id 63848A83017 for <14085552422#faxbyemail.co>; Wed, 9 Sep 2015 22:31:48 +0000 (UTC)\nReceived: by qgx61 with SMTP id 61so21251135qgx.3 for <14085552422#faxbyemail.co>; Wed, 09 Sep 2015 15:31:48 -0700 (PDT)\nDKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:from:date:message-id:subject:to:content-type; bh=Wo6p7CSlR30aGxf5SwjuZ2klt31URDqTZUHrKdmLz7s=; b=fWfFOQ4YOtijYvphYL9/1shyzK8CBTcHS37s89t9Qn4xK8OrXwVKtmGtNnwg7a1n48 JHkEeAdxVvRMpinxPllGiJoPNy0ivVN36uEYbsrLTcZVlx9RIIl8u5PjmrE1aqlnkjPy gOcbfJunVCFZLaLpv3RB/GiNYL1bodgW7nn8sMTmwN5EwoH7SncS7cle4ksPadgiGv9f DVoJniX2yuMqygSVLT4Qrk4JDzR6G2oj1Fz3QkcrQfNKxOS6iyBhpnh3cDuUi8GTSVYl Nqq2dtKlUNqI+U9ojtG1BjGVUKbP0v5apF3Wvmj72p8L0AB3FHqL8uvFnhi2dGTFVq+y 6nUQ==\nX-Received: by 10.140.233.137 with SMTP id e131mr48879201qhc.37.1441837907953; Wed, 09 Sep 2015 15:31:47 -0700 (PDT)\nMIME-Version: 1.0\nFrom: Sam Sedighian <samansb#gmail.com>\nDate: Wed, 09 Sep 2015 22:31:38 +0000\nMessage-ID: <CAEMkzYbhsLLB3NPLznG+-RibP5kzDG5yTT++mQL1ep-vH6_orA#mail.gmail.com>\nSubject: test 20\nTo: \"14085552422#faxbyemail.co\" <14085552422#faxbyemail.co>\nContent-Type: multipart/alternative; boundary=001a11354d8053d2d1051f580c22\n\n--001a11354d8053d2d1051f580c22\nContent-Type: text/plain; charset=UTF-8\n\nbody etxt\n\n--001a11354d8053d2d1051f580c22\nContent-Type: text/html; charset=UTF-8\n\n<div dir=\"ltr\">body etxt</div>\n\n--001a11354d8053d2d1051f580c22--\n", "to"=>"\"14085552422#faxbyemail.co\" <14085552422#faxbyemail.co>", "from"=>"Sam Sedighian <samansb#gmail.com>", "sender_ip"=>"209.85.192.54", "spam_report"=>"Spam detection software, running on the system \"mx0034p1mdw1.sendgrid.net\", has\nidentified this incoming email as possible spam. The original message\nhas been attached to this so you can view it (if it isn't spam) or label\nsimilar future email. If you have any questions, see\n##CONTACT_ADDRESS## for details.\n\nContent preview: body etxt body etxt [...] \n\nContent analysis details: (0.0 points, 5.0 required)\n\n pts rule name description\n---- ---------------------- --------------------------------------------------\n 0.0 FREEMAIL_FROM Sender email is freemail (samansb[at]gmail.com)\n 0.0 HTML_MESSAGE BODY: HTML included in message\n 0.0 T_MIME_NO_TEXT No text body parts\n\n", "envelope"=>"{\"to\":[\"14085552422#faxbyemail.co\"],\"from\":\"samansb#gmail.com\"}", "subject"=>"test 20", "spam_score"=>"0.012", "charsets"=>"{\"to\":\"UTF-8\",\"subject\":\"UTF-8\",\"from\":\"UTF-8\"}", "SPF"=>"pass"}
Gemfile
gem 'griddler'
gem 'griddler-sendgrid'
Gemfile.lock
griddler (1.2.1)
htmlentities
rails (>= 3.2.0)
griddler-sendgrid (0.0.1)
griddler
routes.rb
post '/email_processor' => 'fax#sendgrid'
# this corresponds to the following route when I rake route:
# email_processor POST /email_processor(.:format) fax#sendgrid
config/initializers/griddler.rb
Griddler.configure do |config|
config.processor_class = EmailProcessor
config.processor_method = :process
config.reply_delimiter = '-- REPLY ABOVE THIS LINE --'
config.email_service = :sendgrid
end
app/controllers/fax_controller.rb
def sendgrid
EmailProcessor.new(params).process
end
app/models/email_processor.rb
class EmailProcessor
def initialize(email)
#email = email
#from = email.from
#body = email.body
end
def self.process(email)
Fax.create({params go here})
end
end
I end up giving a Completed 500 Internal server error - Since I do not pass a 200 OK back to Sendgrid but the important part is that I get the following error in my log:
NoMethodError (undefined method `from' for #<ActionController::Parameters:0x007fc742a33070>):
app/models/email_processor.rb:5:in `initialize'
app/controllers/fax_controller.rb:31:in `new'
app/controllers/fax_controller.rb:31:in `sendgrid'
I think the issue is that you're bypassing the work Griddler does on the controller side. You're pointing Sendgrid at a controller and action you created yourself. Instead I think you want to point to Griddler's controller and action. See the README under "Installation".
Change your routes.rb to be:
# your own route
# post '/email_processor' => 'fax#sendgrid'
# griddler's
post '/email_processor' => 'griddler/emails#create'
If you take a look at Griddler's controller you'll see that there are a few things it does for you to get things into your email processor class.
The way I do this in Rails is to gather the email params in the Controller.
For instance, in a sample app I created, people email selfies to our Parse API. In my selfie_controller.rb, I have a route '/inbound' and I have the following:
def inbound
if !params['attachment1'].nil? and params['attachment1'].content_type == "image/jpeg"
Selfy.create!({ pic: params['attachment1'], email: params['from'] })
end
end
The call to Selfy.create! uses the selfy.rb model, but I gather the params from the email to send to that from the controller.
Is this something you could try?

Resources