ynab / ynab-sdk-ruby Goto Github PK
View Code? Open in Web Editor NEWYNAB API Client for Ruby
Home Page: https://api.ynab.com
License: Apache License 2.0
YNAB API Client for Ruby
Home Page: https://api.ynab.com
License: Apache License 2.0
Hi,
The currency format data is returned in the raw API response but not in the YnabApi::CurrencyFormat
objects of the client:
irb(main):084:0> client.budgets.api_client.config.debugging = true
=> true
irb(main):085:0> response = client.budgets.get_budgets
D, [2018-04-07T16:46:59.417961 #52429] DEBUG -- : Calling API: BudgetsApi.get_budgets ...
Connection 3 seems to be dead!
Closing connection 3
Trying 50.16.212.181...
TCP_NODELAY set
Connected to api.youneedabudget.com (50.16.212.181) port 443 (#4)
SSL re-using session ID
TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Server certificate: api.youneedabudget.com
Server certificate: Let's Encrypt Authority X3
Server certificate: DST Root CA X3
GET /v1/budgets HTTP/1.1
Host: api.youneedabudget.com
User-Agent: api_client/ruby/0.6.0
Content-Type: application/json
Accept: application/json
Authorization: Bearer TOKEN_HIDDEN
HTTP/1.1 200 OK
Server: Cowboy
Date: Sat, 07 Apr 2018 14:47:01 GMT
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Rate-Limit: 8/200
Vary: Accept-Encoding, Origin
Etag: W/"99f504dcdedffbe6138d381fb76b034e"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: b3bada1d-4f97-4144-b7c4-040a422e662a
X-Runtime: 0.030880
Strict-Transport-Security: max-age=15552000
Transfer-Encoding: chunked
Via: 1.1 vegur
Connection #4 to host api.youneedabudget.com left intact
D, [2018-04-07T16:47:01.508452 #52429] DEBUG -- : HTTP response body ~BEGIN~
{"data":{"budgets":[{"id":"budget_id_hidden","name":"Cuentas","last_modified_on":"2018-04-07T14:23:45+00:00","date_format":{"format":"DD/MM/YYYY"},"currency_format":{"iso_code":"EUR","example_format":"123 456,78","decimal_digits":2,"decimal_separator":",","symbol_first":false,"group_separator":" ","currency_symbol":"€","display_symbol":true},"first_month":"2014-09-01","last_month":"2018-04-01"}]}}
~END~
D, [2018-04-07T16:47:01.509703 #52429] DEBUG -- : API called: BudgetsApi#get_budgets
Data: #<YnabApi::BudgetSummaryResponse:0x00007fe80caf3718 @data=#<YnabApi::BudgetSummaryWrapper:0x00007fe80caf34c0 @budgets=[#<YnabApi::BudgetSummary:0x00007fe80caf31a0 @id="budget_id_hidden", @name="Cuentas", @last_modified_on=#<DateTime: 2018-04-07T14:23:45+00:00 ((2458216j,51825s,0n),+0s,2299161j)>, @date_format=#<YnabApi::DateFormat:0x00007fe80caf28b8>, @currency_format=#<YnabApi::CurrencyFormat:0x00007fe80caf2660>>]>>
Status code: 200
Headers: {"Server"=>"Cowboy", "Date"=>"Sat, 07 Apr 2018 14:47:01 GMT", "Connection"=>"keep-alive", "Content-Type"=>"application/json; charset=utf-8", "X-Rate-Limit"=>"8/200", "Vary"=>"Accept-Encoding, Origin", "Etag"=>"W/\"99f504dcdedffbe6138d381fb76b034e\"", "Cache-Control"=>"max-age=0, private, must-revalidate", "X-Request-Id"=>"b3bada1d-4f97-4144-b7c4-040a422e662a", "X-Runtime"=>"0.030880", "Strict-Transport-Security"=>"max-age=15552000", "Transfer-Encoding"=>"chunked", "Via"=>"1.1 vegur"}
=> #<YnabApi::BudgetSummaryResponse:0x00007fe80caf3718 @data=#<YnabApi::BudgetSummaryWrapper:0x00007fe80caf34c0 @budgets=[#<YnabApi::BudgetSummary:0x00007fe80caf31a0 @id="budget_id_hidden", @name="Cuentas", @last_modified_on=#<DateTime: 2018-04-07T14:23:45+00:00 ((2458216j,51825s,0n),+0s,2299161j)>, @date_format=#<YnabApi::DateFormat:0x00007fe80caf28b8>, @currency_format=#<YnabApi::CurrencyFormat:0x00007fe80caf2660>>]>>
irb(main):086:0> response.data.budgets.first.currency_format.to_hash
=> {}
Looking at your API docs it seems that the only field in the currency model is locale
, so even though values such as iso_code
are returned by the API, they are skipped by the client.
I've got an app which syncs my bank transactions (via browser automation) to my YNAB budget. This morning I upgraded to SDK version 2.0.
I tested the upgrade locally and it worked fine syncing to my test YNAB budget. However on my server, while syncing to my real YNAB budget, I got the following error:
/Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:326:in `debt_transaction_type=': invalid value for "debt_transaction_type", must be one of ["payment", "refund", "fee", "interest", "escrow", "balancedAdjustment", "credit", "charge", "null"]. (ArgumentError)
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:391:in `block in build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:381:in `each_pair'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:381:in `build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/transaction_summary.rb:372:in `build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:354:in `_deserialize'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:305:in `block (2 levels) in build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:305:in `map'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:305:in `block in build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:298:in `each_pair'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:298:in `build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail.rb:289:in `build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:187:in `_deserialize'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:141:in `block in build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:131:in `each_pair'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:131:in `build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response_data.rb:122:in `build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:172:in `_deserialize'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:126:in `block in build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:116:in `each_pair'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:116:in `build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/models/budget_detail_response.rb:107:in `build_from_hash'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api_client.rb:285:in `convert_to_type'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api_client.rb:245:in `deserialize'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api_client.rb:76:in `call_api'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api/budgets_api.rb:81:in `get_budget_by_id_with_http_info'
from /Users/jordancrawford/.rbenv/versions/3.0.6/lib/ruby/gems/3.0.0/gems/ynab-2.0.0/lib/ynab/api/budgets_api.rb:29:in `get_budget_by_id'
from bin/fetch_budget:12:in `<main>'
The contents of fetch_budget
is a simple script to output the result of budgets.get_budget_by_id
.
#!/usr/bin/env ruby
require 'ynab'
api_key = ARGV.shift
budget_id = ARGV.shift
api = YNAB::API.new(api_key)
puts "Fetching budget..."
budget = api.budgets.get_budget_by_id(budget_id).data.budget
puts budget
Digging a bit further, I see that the transaction it's trying to present is:
{:id=>"the id", :date=>"date", :amount=>-11111, :memo=>"Entered automatically by YNAB", :cleared=>"reconciled", :approved=>true, :flag_color=>nil, :account_id=>"the acc id", :payee_id=>"the payee id", :category_id=>nil, :transfer_account_id=>nil, :transfer_transaction_id=>nil, :matched_transaction_id=>nil, :import_id=>nil, :import_payee_name=>nil, :import_payee_name_original=>nil, :debt_transaction_type=>"balanceAdjustment", :deleted=>false}
It appears that there's a typo- the API returns balanceAdjustment
but the validations expect balancedAdjustment
.
I replaced all references to balancedAdjustment
in the gem with balanceAdjustment
and it worked fine.
This appears to have been a typo.
I don't know how the API client generation stuff works so I haven't created a PR.
Update GitHub Releases when releasing to RubyGems
examples
folder@bradymholt Can you explain more about rake generate
? Why would someone run that task?
Hey
I have an old account with the type of "cash" in my YNAB. When calling the get_accounts
method, i get the following error:
ArgumentError: invalid value for 'type', must be one of ["checking", "savings", "creditCard"].
I believe this is coming from this area of the code base.
ynab-sdk-ruby/lib/ynab/models/account.rb
Line 188 in 5c3cec8
Here is the JSON node from the account, if you want to take a look
{
"id": "a35e190a-d4fb-4079-ae54-343afdc80669",
"name": "Cash",
"type": "cash",
"on_budget": true,
"closed": true,
"note": null,
"balance": 0,
"cleared_balance": 0,
"uncleared_balance": 0
},
This is the same for "investmentAccount" and "otherAsset". I assume there will be others too, i just don't have any of those accounts.
The docs for update transactions say that the PATCH will update multiple transactions with changes by transaction id or import id.
However, the API doesn't accept id
as a field in the transaction change. I get a 400 back when I try to, say, change the flag color on a group of transactions.
For example, the following doesn't work.
require 'date'
require 'ynab'
def update_transactions
access_token = ENV['YNAB_ACCESS_TOKEN']
budget_id = ENV['YNAB_BUDGET_ID']
account_id = ENV['YNAB_ACCOUNT_ID']
ynab = YNAB::API.new(access_token)
since_date = Date.parse("2018-11-01")
target_color = 'purple'
transactions_response = ynab.transactions.get_transactions_by_account(
budget_id, account_id, since_date: since_date)
my_tx = transactions_response.data.transactions
updated_tx = my_tx.select{ |x| x.flag_color == target_color }.map do |t|
{ id: t.id, flag_color: "red" }
end
puts updated_tx
ynab.transactions.update_transactions(budget_id, { transactions: updated_tx })
puts "all done"
end
update_transactions
Hi there! 👋🏻
The YNAB API is working very well and I'm thankful this gem is available, making it super easy to write scripts to import transactions.
However, I am experiencing an error which to me looks weird and unjustified. I'm not sure whether this is a bug, but I thought I'd report what I'm seeing and ask for opinions.
I have a script which goal is to create YNAB transactions in my account, based on local CSV data. It initializes a YNAB::PostTransactionsWrapper
in which the transactions
keyword argument is an Array of Hashes with the necessary transaction keys/properties.
The script then uses the TransactionsApi's #create_transaction
method to send the data to YNAB, which usually goes well.
Sometimes though, that calls raises an exception:
#<ArgumentError: invalid value for "import_payee_name", the character length must be smaller than or equal to 200.>
I can verify on my YNAB account that all the transactions were created correctly, so my guess is that the error is raised after the gem received a successful response from the API.
It looks like the gem attempts to deserialize the response into a SaveTransactionResponse
, which is supposed to include each created transaction, deserialized as a TransactionDetail
. Unfortunately, it seems that the deserialization fails when the import_payee_name
validation fails:
ynab-sdk-ruby/lib/ynab/models/transaction_detail.rb
Lines 280 to 282 in f14a866
I don't recall ever importing data with 200+ character long payee names, but even if I did, I think there is a consistency problem between the gem and the API:
import_payee_names
in a successful response (so they're valid data, right?)The error does not really impact my process: the transactions I want to create get created with no issue, and I'm currently not making any use of the response, but I think this is a smell that might be worth fixing.
Please let me know if I can help in any way.
(@bradymholt It looks like you've been maintaining this gem for a while, so please allow me to ping you in the issue. 🙇🏻♂️ )
Hi, I've just read the great news that now internal transactions are supported.
I was checking the documentation and is it correct that the only thing that needs to be changed here is this comment?
😍I am getting the following error when trying to retrieve retrieve a budget by ID using the latest version of this gem (1.6.0):
ArgumentError: invalid value for "goal_type", must be one of #{validator.allowable_values}.
The code that triggers this error is:
api = YNAB::API.new(YNAB_ACCESS_TOKEN)
api.budgets.get_budget_by_id('last-used').data.budget
The error is occurring in /lib/ynab/models/category.rb:281
I found the following from debugging:
[1] pry(#<YNAB::Category>)> goal_type
=> "NEED"
[2] pry(#<YNAB::Category>)> validator.allowable_values
=> ["TB", "TBD", "MF"]
I noticed that the YNAB goal types in the UI have changed, so I'm guessing that the validation just needs to be updated to match?
Why is this defined in the readme
months.get_month_category_by_id(budget_id, month, category_id)
When it doesnt even exist in the code
Hey there!
The Documentation specifies that the amount parameter should be a float. If I provide a float in my request I get a YNAB::ApiError: Bad Request
error which I found strange.
Upon further investigation and playing with the API over at api.youneedabudget.com it seems that the API requires an Integer not a Float.
{
"error": {
"id": "400",
"name": "bad_request",
"detail": "{\"amount\":[\"must be an integer\"],\"date\":[\"must be an ISO formatted date\"]}"
}
}
I'm currently writing an integration for a Swiss bank – but only being able to write Integers via the API would be a major letdown. 😔
Thanks for your time.
Best,
Rodrigo
Hi - I recently upgraded to version 3.2 from a 2.x version. I had code which was using SaveTransaction with the create transaction API (https://github.com/ynab/ynab-sdk-ruby/blob/main/docs/TransactionsApi.md#create_transaction).
I noticed that the SaveTransaction class and it's docs still exists but isn't referenced in lib/ynab.rb
so cannot be loaded.
Is the class meant to be loadable? Or is it meant to be removed?
I switched my code over to use NewTransaction and so far it's working as intended.
Hey @bradymholt! I see that you guys recently put together this SDK for Ruby. Will you guys be creating an SDK for PHP?
Hi there,
I'm using the get_transactions method but weirdly, there is one transaction that is not returned.
I made several tests to be sure it wasn't my code, and everything works properly except one transaction never returned...
How can this be? Some caching?
My code below:
require 'ynab'
require 'date'
require 'money'
I18n.config.available_locales = :en
Money.locale_backend = :i18n
ynab = YNAB::API.new('MY-API-KEY')
budget_id = 'MY-BUDGET-ID'
year = 2018
month = 12
begin
puts 'Fetching data from YNAB...'
first_day_of_month_iso = Date.new(year, month, 30).iso8601
puts "Numbers from #{first_day_of_month_iso}"
transactions_response = ynab.transactions.get_transactions(budget_id, since_date: first_day_of_month_iso)
total_incomes = 0
transactions_response.data.transactions.each do |transaction|
puts "#{transaction.date} - #{transaction.payee_name} - #{transaction.amount/1000}"
total_incomes += transaction.amount
end
puts "Total incomes : #{Money.from_amount(total_incomes/1000, "CHF").format}"
end
Hi,
I installed the YNAB gem. I'm using Ruby version "ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin18]".
Then I created a ynab.rb script, in which I copied your usage script into.
Then I ran from the command line "ruby ynab.rb" and I always get the following:
Traceback (most recent call last):
3: from ynab.rb:6:in <main>' 2: from /Users/thomas/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/ynab-1.10.0/lib/ynab/api/budgets_api.rb:134:in
get_budgets'
1: from /Users/thomas/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/ynab-1.10.0/lib/ynab/api/budgets_api.rb:163:in get_budgets_with_http_info' /Users/thomas/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/ynab-1.10.0/lib/ynab/api_client.rb:68:in
call_api': Unauthorized (YNAB::ApiError)
I checked my Personal Access Token twice, and even generated a new one, and each time I get: "`call_api': Unauthorized (YNAB::ApiError)".
From the command line, with CURL, my token works.
Can you please help?
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.