figo-connect / ruby-figo Goto Github PK
View Code? Open in Web Editor NEWRuby binding for the figo Connect API.
Home Page: http://figo.io
Ruby binding for the figo Connect API.
Home Page: http://figo.io
The installation of an app with the master branch of this gem in the Gemfile fails on heroku:
sh: 2: Syntax error: Unterminated quoted string sh: 2: Syntax error: Unterminated quoted string ! ! Could not detect rake tasks ! ensure you can run
$ bundle exec rake -Pagainst your app ! and using the production group of your Gemfile. ! rake aborted! ! Bundler::GemRequireError: There was an error while trying to load the gem 'figo'. ! Gem Load Error is: No such file or directory @ rb_sysopen - /tmp/build_1f20d0bf6ddf341f63b62120a3db587f/decimogmbh-client-29150e6ea4c3cfae12e578fe40dc6d7754434a2a/vendor/bundle/ruby/2.3.0/bundler/gems/ruby-figo-257619ed8fb9/lib/../CONFIG.yml
It works locally though. Maybe check why your CI is failing - I assume it is the same problem
In the lib, the HttpUnauthorized error is mapped as raise Error.new("unauthorized", "Missing, invalid or expired access token.")
However I have received this error in two cases when the situation is different:
In both cases I think the problem has nothing to do with the token and the error is a bit misleading.
When I try to create a user with the create_user function I get the following error:
Figo::Error (Invalid parameter send_newsletter)
I dug a bit and tried a local version of the entire library, so after adding some logging I can show this:
Data hash
{"name"=>"Test testing", "email"=>"[email protected]", "password"=>"demo1234", "language"=>"en", "send_newsletter"=>true, "affiliate_client_id"=>"[HIDDEN]"}
Encoded URL
name=Test+testing&email=test%40test.com&password=demo1234&language=en&send_newsletter=true&affiliate_client_id=[HIDDEN]
Response
Completed 500 Internal Server Error in 5254ms
Figo::Error (Invalid parameter send_newsletter):
lib/figo.rb:88:inrequest' lib/figo.rb:140:in
query_api'
lib/figo.rb:211:increate_user' app/controllers/operations_controller.rb:18:in
create_user'
As far as I understand, the backend of the API is not accepting send_newsletter parameter. I have tried to modify the source, let it by default, use "True", "true", "False", 0... None of them is accepted.
It only works if I don't send the parameter at all:
data = { 'name' => name, 'email' => email, 'password' => password, 'language' => language, 'affiliate_client_id' => @client_id}
I will submit a pull request so you can see the problem.
[2015-10-15 12:27:27] INFO WEBrick 1.3.1
[2015-10-15 12:27:27] INFO ruby 2.2.1 (2015-02-26) [x86_64-linux]
== Sinatra/1.4.5 has taken the stage on 3000 for development with backup from WEBrick
[2015-10-15 12:27:27] INFO WEBrick::HTTPServer#start: pid=4074 port=3000
SECURITY WARNING: No secret option provided to Rack::Session::Cookie.
This poses a security threat. It is strongly recommended that you
provide a secret to prevent exploits that may be possible from crafted
cookies. This will not be supported in future versions of Rack, and
future versions will even invalidate your existing user cookies.
Called from: /home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/builder.rb:86:in `new'.
Figo::Error - We are very sorry, but something went wrong.:
/tmp/ruby-figo/lib/figo.rb:100:in `request'
/tmp/ruby-figo/lib/figo.rb:252:in `query_api'
/tmp/ruby-figo/lib/figo.rb:261:in `query_api_object'
/tmp/ruby-figo/lib/figo.rb:380:in `transactions'
app.rb:50:in `block in <main>'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1603:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1603:in `block in compile!'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:966:in `[]'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:966:in `block (3 levels) in route!'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:985:in `route_eval'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:966:in `block (2 levels) in route!'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1006:in `block in process_route'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1004:in `catch'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1004:in `process_route'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:964:in `block in route!'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:963:in `each'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:963:in `route!'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1076:in `block in dispatch!'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1058:in `block in invoke'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1058:in `catch'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1058:in `invoke'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1073:in `dispatch!'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:898:in `block in call!'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1058:in `block in invoke'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1058:in `catch'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1058:in `invoke'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:898:in `call!'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:886:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb:18:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb:16:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb:18:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb:49:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb:31:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/session/abstract/id.rb:225:in `context'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/session/abstract/id.rb:220:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/logger.rb:15:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/commonlogger.rb:33:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:217:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:210:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/head.rb:13:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/methodoverride.rb:22:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/show_exceptions.rb:21:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:180:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:2014:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1478:in `block in call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1788:in `synchronize'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1478:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/handler/webrick.rb:88:in `service'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/2.2.0/webrick/httpserver.rb:138:in `service'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/2.2.0/webrick/httpserver.rb:94:in `run'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/2.2.0/webrick/server.rb:294:in `block in start_thread'
[2015-10-15 12:27:33] ERROR NoMethodError: undefined method `join' for #<String:0x0055d6fe6dbbb0>
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/show_exceptions.rb:37:in `rescue in call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/show_exceptions.rb:21:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:180:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:2014:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1478:in `block in call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1788:in `synchronize'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/sinatra-1.4.5/lib/sinatra/base.rb:1478:in `call'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/handler/webrick.rb:88:in `service'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/2.2.0/webrick/httpserver.rb:138:in `service'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/2.2.0/webrick/httpserver.rb:94:in `run'
/home/aep/.rbenv/versions/2.2.1/lib/ruby/2.2.0/webrick/server.rb:294:in `block in start_thread'
localhost.localdomain - - [15/Oct/2015:12:27:33 CEST] "GET / HTTP/1.1" 500 340
Or provide a way to order transactions by transaction id.
According to the API doc, we can get all transactions back, and also we can provide a transaction_id
so we can get transactions after the transaction_id.
Problem is when I get transactions back, they are not ordered by transaction id, like bellow:
account.transactions(last_transaction_id).map(&:transaction_id)
=> ["T1.72", "T1.73", "T1.74", "T1.75", "T1.76", "T1.77", "T1.78", "T1.79", "T1.64", "T1.65", "T1.66", "T1.67", "T1.68", "T1.69", "T1.70", "T1.71"]
And I am not sure how could I get the last transaction and how this transaction_id is generated, am I safe to order it by numbers after the T1.
part? Will it change to something like T2.
?
require 'figo'
session = Figo::Session.new('ASHWLIkouP2O6_bgA2wWReRhletgWKHYjLqDaqb0LFfamim9RjexTo22ujRIP_cjLiRiSyQXyt2kM1eXU2XLFZQ0Hro15HikJQT_eNeT_9XQ')
puts session.accounts.count
This unfortunately explodes with:
Figo::Error: We are very sorry, but something went wrong.
from /Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/figo-1.4.0/lib/helpers/https.rb:48:in `request'
from /Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/figo-1.4.0/lib/figo.rb:157:in `query_api'
from /Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/figo-1.4.0/lib/figo.rb:166:in `query_api_object'
from /Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/figo-1.4.0/lib/account/api_call.rb:7:in `accounts'
from (irb):3
from /Users/bijan/.rbenv/versions/2.5.0-dev/bin/irb:11:in `<main>'
This error seems to come from an internal server error on the figo side.
I tried it with several ruby versions: 2.2, 2.3, 2.4 and 2.5 just to make sure that it has nothing to do with it.
Further I tried the equivalent node version using the node sdk which also gives me a 500 on the figo side.
PS: Here is the full debug cruft:
โ 14:05:41 figo-ruby $ irb
irb(main):001:0> require 'figo'
=> true
irb(main):002:0> session = Figo::Session.new('ASHWLIkouP2O6_bgA2wWReRhletgWKHYjLqDaqb0LFfamim9RjexTo22ujRIP_cjLiRiSyQXyt2kM1eXU2XLFZQ0Hro15HikJQT_eNeT_9XQ')
=> #<Figo::Session:0x00007f90c09ad4b0 @access_token="ASHWLIkouP2O6_bgA2wWReRhletgWKHYjLqDaqb0LFfamim9RjexTo22ujRIP_cjLiRiSyQXyt2kM1eXU2XLFZQ0Hro15HikJQT_eNeT_9XQ", @https=#<Figo::HTTPS:0x00007f90c09ad438 @name="figo-ASHWLIkouP2O6_bgA2wWReRhletgWKHYjLqDaqb0LFfamim9RjexTo22ujRIP_cjLiRiSyQXyt2kM1eXU2XLFZQ0Hro15HikJQT_eNeT_9XQ", @debug_output=nil, @proxy_uri=nil, @no_proxy=[], @headers={}, @override_headers={}, @http_versions={}, @keep_alive=30, @open_timeout=nil, @read_timeout=nil, @idle_timeout=5, @max_requests=nil, @socket_options=[[6, 1, 1]], @ssl_generation=0, @pool=#<Net::HTTP::Persistent::Pool:0x00007f90c09ad1b8 @SiZe=2500, @timeout=5, @available=#<Net::HTTP::Persistent::TimedStackMulti:0x00007f90c09acda8 @create_block=#Proc:0x00007f90c09acd30@/Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/net-http-persistent-3.0.0/lib/net/http/persistent.rb:525, @created=0, @que=[], @max=2500, @mutex=#Thread::Mutex:0x00007f90c09acc90, @resource=#Thread::ConditionVariable:0x00007f90c09acc68, @shutdown_block=nil, @Enqueued=0, @ques={}, @lru={}, @key=:"connection_args-70129841694420">, @key=:"current-70129841694420">, @certificate=nil, @ca_file="lib/cacert.pem", @ca_path=nil, @ciphers=nil, @private_key=nil, @ssl_timeout=nil, @ssl_version=nil, @verify_callback=#Proc:0x00007f90c09ac308@/Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/figo-1.4.0/lib/helpers/https.rb:13, @verify_depth=nil, @verify_mode=1, @cert_store=nil, @generation=0, @reuse_ssl_sessions=true, @retry_change_requests=false>, @api_endpoint="api.figo.me">
irb(main):003:0> puts session.accounts.count
Figo::Error: We are very sorry, but something went wrong.
from /Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/figo-1.4.0/lib/helpers/https.rb:48:in request' from /Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/figo-1.4.0/lib/figo.rb:157:in
query_api'
from /Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/figo-1.4.0/lib/figo.rb:166:in query_api_object' from /Users/bijan/.rbenv/versions/2.5.0-dev/lib/ruby/gems/2.5.0/gems/figo-1.4.0/lib/account/api_call.rb:7:in
accounts'
from (irb):3
from /Users/bijan/.rbenv/versions/2.5.0-dev/bin/irb:11:in `
Hello,
I've noticed that after a certain number of queries, the following exception occurs:
Failed to open TCP connection to api.figo.me:443 (getaddrinfo: Temporary failure in name resolution)
I've wrote and ran a test to get more insight in the problem. Here is the pseudo code for the test:
loop do
connection = Figo::Connection.new(...)
connection.credential_login(...) #Doesn't matter if the credentials are valid, this is just to send a query
end
On my machine, the loop breaks because of the TCP connection error after exactly 241 iterations.
After looking a the source code for Figo::Connection, I noticed that the HTTP connection was never shutdown. So I extended Figo::Connection like so:
class FigoConnection < Figo::Connection
def done
@https.shutdown
end
end
and modified the test to call done after each query:
loop do
connection = FigoConnection.new(...)
connection.credential_login(...)
connection.done
end
and now the loop keeps on going after 241 iterations.
The same issue exists in Figo::Session (I haven't tested it but the HTTP connection is managed the same way)
For now, I'm going to extend Figo::Connection and Figo::Session to handle the termination of HTTP connections in my application code.
It would be extremely nice if the ruby-figo gem would manage the connection itself, so this would be transparent to the application code.
Best regards.
Hi There,
I'm wondering which of the two create_user calls are authoritative:
Since their signature differ slightly, they are not compatiable.
Cheers!
Figo assumes net-http-persistent (~> 2.9.4)
Now 3.0.0 was released and it breaks some calls for me because of interface changes in net-http-persistent major release.
In general it's a bad practise.
require 'figo'
$api_endpoint
=> "api.figo.me"
$valid_fingerprints
=> ["3A:62:54:4D:86:B4:34:38:EA:34:64:4E:95:10:A9:FF:37:27:69:C0", "CF:C1:BC:7F:6A:16:09:2B:10:83:8A:B0:22:4F:3A:65:D2:70:D7:3E"]
Also the names are not prefixed, some potentially some other libary can introduce $api_endpoint
variable, what can result into errors.
It's better to use constants:
module Figo
API_ENDPOINT = "api.figo.me".freeze
VALID_FINGERPRINTS = [
"3A:62:54:4D:86:B4:34:38:EA:34:64:4E:95:10:A9:FF:37:27:69:C0",
"CF:C1:BC:7F:6A:16:09:2B:10:83:8A:B0:22:4F:3A:65:D2:70:D7:3E"
].freeze
end
Hi guys,
I just installed the latest 1.3.2 gem via bundler into my rails app. i'm using 4.2.7 on ruby 2.3.1.
Unfortunately, it seems that the underlying HTTP API changed and the Session constructor is not working anymore. At least the first demo call from your docs is not working at the moment.
this is my rails console
output:
2.3.1 :001 > session = Figo::Session.new("ASHWLIkouP2O6_bgA2wWReRhletgWKHYjLqDaqb0LFfamim9RjexTo22ujRIP_cjLiRiSyQXyt2kM1eXU2XLFZQ0Hro15HikJQT_eNeT_9XQ")
ArgumentError: wrong number of arguments (given 2, expected 0)
from /Users/magegu/.rvm/gems/ruby-2.3.1/gems/net-http-persistent-3.0.0/lib/net/http/persistent.rb:505:in `initialize'
from /Users/magegu/.rvm/gems/ruby-2.3.1/gems/figo-1.3.2/lib/helpers/https.rb:9:in `initialize'
from /Users/magegu/.rvm/gems/ruby-2.3.1/gems/figo-1.3.2/lib/figo.rb:123:in `new'
from /Users/magegu/.rvm/gems/ruby-2.3.1/gems/figo-1.3.2/lib/figo.rb:123:in `initialize'
from (irb):1:in `new'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.