monzo-cli 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +5 -0
- data/.travis.yml +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +102 -0
- data/README.md +64 -0
- data/Rakefile +5 -0
- data/bin/monzo-cli +115 -0
- data/extras/header.jpg +0 -0
- data/features/monzo.feature +8 -0
- data/features/step_definitions/monzo_steps.rb +6 -0
- data/features/support/env.rb +15 -0
- data/lib/api/mondo/account.rb +12 -0
- data/lib/api/mondo/address.rb +6 -0
- data/lib/api/mondo/attachment.rb +26 -0
- data/lib/api/mondo/balance.rb +15 -0
- data/lib/api/mondo/card.rb +26 -0
- data/lib/api/mondo/client.rb +236 -0
- data/lib/api/mondo/errors.rb +50 -0
- data/lib/api/mondo/feed_item.rb +31 -0
- data/lib/api/mondo/merchant.rb +15 -0
- data/lib/api/mondo/resource.rb +52 -0
- data/lib/api/mondo/response.rb +29 -0
- data/lib/api/mondo/transaction.rb +80 -0
- data/lib/api/mondo/utils.rb +16 -0
- data/lib/api/mondo/version.rb +3 -0
- data/lib/api/mondo/web_hook.rb +15 -0
- data/lib/api/mondo.rb +21 -0
- data/lib/monzo/config_parser.rb +31 -0
- data/lib/monzo/monzo_api.rb +27 -0
- data/lib/monzo/version.rb +3 -0
- data/lib/monzo.rb +4 -0
- data/monzo.gemspec +36 -0
- data/spec/assets/bad_test_config.yml +2 -0
- data/spec/assets/test_config.yml +3 -0
- data/spec/config_parser_spec.rb +48 -0
- data/spec/monzo_api_spec.rb +22 -0
- data/spec/spec_helper.rb +25 -0
- metadata +236 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 21dff323f90b59f5cf45fbb4a19fc6691e92581f
|
4
|
+
data.tar.gz: 3cd737d3b095fcfbe16785c4df077e03c11111aa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3e408ce3f8fae7694e35a38d81a2884deadbcfd540bf92f9f41adf197b27a976ff5f35955a6b35ad7cade613315fd8f469037d509574c687ff49c8f6749dabee
|
7
|
+
data.tar.gz: 8c8f099184b7f6987f493e33501a793675fe31886b0306ed5c2f7ff7a592935372c7e63f94702f35148e7a04131776688d6603d4f026bb1ad5f83924d0dad87b
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
monzo-cli (0.0.1)
|
5
|
+
activesupport (~> 3.2)
|
6
|
+
colorize (~> 0.7)
|
7
|
+
gli (= 2.14.0)
|
8
|
+
money
|
9
|
+
multi_json (~> 1.10)
|
10
|
+
oauth2 (~> 1.0)
|
11
|
+
terminal-table (>= 1.7.3)
|
12
|
+
|
13
|
+
GEM
|
14
|
+
remote: https://rubygems.org/
|
15
|
+
specs:
|
16
|
+
activesupport (3.2.22.5)
|
17
|
+
i18n (~> 0.6, >= 0.6.4)
|
18
|
+
multi_json (~> 1.0)
|
19
|
+
aruba (0.14.2)
|
20
|
+
childprocess (~> 0.5.6)
|
21
|
+
contracts (~> 0.9)
|
22
|
+
cucumber (>= 1.3.19)
|
23
|
+
ffi (~> 1.9.10)
|
24
|
+
rspec-expectations (>= 2.99)
|
25
|
+
thor (~> 0.19)
|
26
|
+
builder (3.2.2)
|
27
|
+
childprocess (0.5.9)
|
28
|
+
ffi (~> 1.0, >= 1.0.11)
|
29
|
+
coderay (1.1.1)
|
30
|
+
colorize (0.8.1)
|
31
|
+
contracts (0.14.0)
|
32
|
+
cucumber (2.4.0)
|
33
|
+
builder (>= 2.1.2)
|
34
|
+
cucumber-core (~> 1.5.0)
|
35
|
+
cucumber-wire (~> 0.0.1)
|
36
|
+
diff-lcs (>= 1.1.3)
|
37
|
+
gherkin (~> 4.0)
|
38
|
+
multi_json (>= 1.7.5, < 2.0)
|
39
|
+
multi_test (>= 0.1.2)
|
40
|
+
cucumber-core (1.5.0)
|
41
|
+
gherkin (~> 4.0)
|
42
|
+
cucumber-wire (0.0.1)
|
43
|
+
diff-lcs (1.2.5)
|
44
|
+
faraday (0.9.2)
|
45
|
+
multipart-post (>= 1.2, < 3)
|
46
|
+
ffi (1.9.14)
|
47
|
+
gherkin (4.0.0)
|
48
|
+
gli (2.14.0)
|
49
|
+
i18n (0.7.0)
|
50
|
+
jwt (1.5.6)
|
51
|
+
method_source (0.8.2)
|
52
|
+
money (6.7.1)
|
53
|
+
i18n (>= 0.6.4, <= 0.7.0)
|
54
|
+
sixarm_ruby_unaccent (>= 1.1.1, < 2)
|
55
|
+
multi_json (1.12.1)
|
56
|
+
multi_test (0.1.2)
|
57
|
+
multi_xml (0.5.5)
|
58
|
+
multipart-post (2.0.0)
|
59
|
+
oauth2 (1.2.0)
|
60
|
+
faraday (>= 0.8, < 0.10)
|
61
|
+
jwt (~> 1.0)
|
62
|
+
multi_json (~> 1.3)
|
63
|
+
multi_xml (~> 0.5)
|
64
|
+
rack (>= 1.2, < 3)
|
65
|
+
pry (0.10.4)
|
66
|
+
coderay (~> 1.1.0)
|
67
|
+
method_source (~> 0.8.1)
|
68
|
+
slop (~> 3.4)
|
69
|
+
rack (2.0.1)
|
70
|
+
rake (11.3.0)
|
71
|
+
rspec (3.5.0)
|
72
|
+
rspec-core (~> 3.5.0)
|
73
|
+
rspec-expectations (~> 3.5.0)
|
74
|
+
rspec-mocks (~> 3.5.0)
|
75
|
+
rspec-core (3.5.4)
|
76
|
+
rspec-support (~> 3.5.0)
|
77
|
+
rspec-expectations (3.5.0)
|
78
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
79
|
+
rspec-support (~> 3.5.0)
|
80
|
+
rspec-mocks (3.5.0)
|
81
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
82
|
+
rspec-support (~> 3.5.0)
|
83
|
+
rspec-support (3.5.0)
|
84
|
+
sixarm_ruby_unaccent (1.1.1)
|
85
|
+
slop (3.6.0)
|
86
|
+
terminal-table (1.7.3)
|
87
|
+
unicode-display_width (~> 1.1.1)
|
88
|
+
thor (0.19.1)
|
89
|
+
unicode-display_width (1.1.1)
|
90
|
+
|
91
|
+
PLATFORMS
|
92
|
+
ruby
|
93
|
+
|
94
|
+
DEPENDENCIES
|
95
|
+
aruba
|
96
|
+
monzo-cli!
|
97
|
+
pry
|
98
|
+
rake
|
99
|
+
rspec
|
100
|
+
|
101
|
+
BUNDLED WITH
|
102
|
+
1.13.6
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# monzo-cli
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/monzo-cli.svg)](https://badge.fury.io/rb/monzo-cli)
|
3
|
+
[![Build Status](https://travis-ci.org/cesarferreira/lasertag.svg?branch=master)](https://travis-ci.org/cesarferreira/lasertag) [![security](https://hakiri.io/github/cesarferreira/lasertag/master.svg)](https://hakiri.io/github/cesarferreira/lasertag/master)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/cesarferreira/monzo-cli/badges/gpa.svg)](https://codeclimate.com/github/cesarferreira/monzo-cli)
|
5
|
+
[![Inline docs](http://inch-ci.org/github/cesarferreira/monzo-cli.svg?branch=master)](http://inch-ci.org/github/cesarferreira/monzo-cli)
|
6
|
+
|
7
|
+
> Finally a bank with an API
|
8
|
+
|
9
|
+
![Image](extras/header.jpg)
|
10
|
+
|
11
|
+
# Usage
|
12
|
+
## Balance
|
13
|
+
|
14
|
+
```bash
|
15
|
+
$ monzo-cli balance
|
16
|
+
|
17
|
+
+---------+-------------+
|
18
|
+
| Balance | Spent today |
|
19
|
+
+---------+-------------+
|
20
|
+
| £490 | £10 |
|
21
|
+
+---------+-------------+
|
22
|
+
```
|
23
|
+
|
24
|
+
## Accounts
|
25
|
+
|
26
|
+
```bash
|
27
|
+
$ monzo-cli accounts
|
28
|
+
|
29
|
+
+---------------------+----------------------+
|
30
|
+
| Description | Date created |
|
31
|
+
+---------------------+----------------------+
|
32
|
+
| Peter Pans Account | 2015-11-13T12:17:42Z |
|
33
|
+
+---------------------+----------------------+
|
34
|
+
```
|
35
|
+
|
36
|
+
## Install
|
37
|
+
|
38
|
+
```bash
|
39
|
+
gem install monzo-cli
|
40
|
+
```
|
41
|
+
|
42
|
+
Get your access tokens from this URL: https://developers.getmondo.co.uk/api/playground
|
43
|
+
|
44
|
+
|
45
|
+
Please create/edit it on `~/.monzo-cli.yml` with this format:
|
46
|
+
|
47
|
+
|
48
|
+
```yml
|
49
|
+
user_id: 18231092askdas9212
|
50
|
+
account_id: acc_0aksdaklsjSh28181
|
51
|
+
access_token: Qnjdas8hakxdjasQscGVgnVGIVXpvpZ5uCxkQ5XLnDHnOPoBtXreQ6adBo
|
52
|
+
|
53
|
+
```
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
I welcome and encourage all pull requests. It usually will take me within 24-48 hours to respond to any issue or request. Here are some basic rules to follow to ensure timely addition of your request:
|
57
|
+
1. If its a feature, bugfix, or anything please only change code to what you specify.
|
58
|
+
2. Please keep PR titles easy to read and descriptive of changes, this will make them easier to merge :)
|
59
|
+
3. Pull requests _must_ be made against `develop` branch. Any other branch (unless specified by the maintainers) will get rejected.
|
60
|
+
4. Check for existing [issues](https://github.com/cesarferreira/monzo-cli/issues) first, before filing an issue.
|
61
|
+
5. Have fun!
|
62
|
+
|
63
|
+
### Created & Maintained By
|
64
|
+
[Cesar Ferreira](https://github.com/cesarferreira) ([@cesarmcferreira](https://www.twitter.com/cesarmcferreira))
|
data/Rakefile
ADDED
data/bin/monzo-cli
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gli'
|
3
|
+
require 'monzo'
|
4
|
+
require 'terminal-table'
|
5
|
+
require 'colorize'
|
6
|
+
require 'monzo/config_parser'
|
7
|
+
require 'monzo/monzo_api'
|
8
|
+
|
9
|
+
include GLI::App
|
10
|
+
|
11
|
+
program_desc 'Monzo command line interface client'
|
12
|
+
|
13
|
+
version Monzo::VERSION
|
14
|
+
|
15
|
+
@path_to_config = Dir.home + '/.monzo-cli.yml'
|
16
|
+
|
17
|
+
subcommand_option_handling :normal
|
18
|
+
arguments :strict
|
19
|
+
|
20
|
+
desc 'List all of your accounts'
|
21
|
+
command :accounts do |c|
|
22
|
+
|
23
|
+
c.action do |global_options, options, args|
|
24
|
+
|
25
|
+
# Your command logic here
|
26
|
+
|
27
|
+
# If you have any errors, just raise them
|
28
|
+
# raise "that command made no sense"
|
29
|
+
|
30
|
+
table = Terminal::Table.new do |t|
|
31
|
+
t << ['Description', 'Date created']
|
32
|
+
t << :separator
|
33
|
+
t.add_row ['Peter Pan\'s Account', '2015-11-13T12:17:42Z']
|
34
|
+
end
|
35
|
+
|
36
|
+
puts table
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'States your account balance'
|
42
|
+
command :balance do |c|
|
43
|
+
c.action do |global_options, options, args|
|
44
|
+
|
45
|
+
result = MonzoApi.new(@config).balance
|
46
|
+
|
47
|
+
balance = result.balance
|
48
|
+
spent_today = result.spent_today
|
49
|
+
|
50
|
+
table = Terminal::Table.new do |t|
|
51
|
+
t << ['Balance', 'Spent today']
|
52
|
+
t << :separator
|
53
|
+
t << ["£#{balance}".green, "£#{spent_today}".green]
|
54
|
+
end
|
55
|
+
|
56
|
+
puts table
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
desc 'List your transactions'
|
62
|
+
arg_name 'Maybe pagination'
|
63
|
+
command :transactions do |c|
|
64
|
+
c.action do |global_options, options, args|
|
65
|
+
puts 'transactions command ran'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
pre do |global, command, options, args|
|
70
|
+
|
71
|
+
@config = ConfigParser.new(@path_to_config)
|
72
|
+
|
73
|
+
# Pre logic here
|
74
|
+
# Return true to proceed; false to abort and not call the
|
75
|
+
# chosen command
|
76
|
+
# Use skips_pre before a command to skip this block
|
77
|
+
# on that command only
|
78
|
+
|
79
|
+
if @config.valid?
|
80
|
+
true
|
81
|
+
else
|
82
|
+
show_no_config_found_error
|
83
|
+
false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
post do |global, command, options, args|
|
88
|
+
# Post logic here
|
89
|
+
# Use skips_post before a command to skip this
|
90
|
+
# block on that command only
|
91
|
+
end
|
92
|
+
|
93
|
+
on_error do |exception|
|
94
|
+
# Error logic here
|
95
|
+
# return false to skip default error handling
|
96
|
+
true
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
def show_no_config_found_error
|
101
|
+
|
102
|
+
open_operation = "vim #{@path_to_config}".green
|
103
|
+
|
104
|
+
puts "\nError reading from #{@path_to_config.green}"
|
105
|
+
puts "Get your information from this URL: https://developers.getmondo.co.uk/api/playground"
|
106
|
+
puts "Please create/edit it with #{open_operation} with this format:\n\n"
|
107
|
+
|
108
|
+
puts " user_id: user_18231092askdas9212".yellow
|
109
|
+
puts " account_id: acc_0aksdaklsjSh28181".yellow
|
110
|
+
puts " access_token: Qnjdas8hakxdjasQscGVgnVGIVXpvpZ5uCxkQ5XLnDHnOPoBtXreQ6adBo".yellow
|
111
|
+
|
112
|
+
puts "\n\n"
|
113
|
+
end
|
114
|
+
|
115
|
+
exit run(ARGV)
|
data/extras/header.jpg
ADDED
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
|
3
|
+
ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
4
|
+
LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
|
5
|
+
|
6
|
+
Before do
|
7
|
+
# Using "announce" causes massive warnings on 1.9.2
|
8
|
+
@puts = true
|
9
|
+
@original_rubylib = ENV['RUBYLIB']
|
10
|
+
ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
After do
|
14
|
+
ENV['RUBYLIB'] = @original_rubylib
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mondo
|
2
|
+
class Attachment < Resource
|
3
|
+
attr_accessor :id, :user_id, :external_id, :file_url, :file_type, :url, :type
|
4
|
+
|
5
|
+
date_accessor :created
|
6
|
+
|
7
|
+
|
8
|
+
def register
|
9
|
+
raise ClientError.new("You have already registered this attachment") unless self.id.nil?
|
10
|
+
|
11
|
+
self.client.api_post("attachment/register", registration_data)
|
12
|
+
end
|
13
|
+
|
14
|
+
def deregister
|
15
|
+
self.client.api_post("attachment/deregister", id: self.id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def registration_data
|
19
|
+
{
|
20
|
+
external_id: self.external_id,
|
21
|
+
file_url: self.file_url,
|
22
|
+
file_type: self.file_type,
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Mondo
|
2
|
+
class Balance < Resource
|
3
|
+
def balance
|
4
|
+
Money.new(raw_data['balance'], currency)
|
5
|
+
end
|
6
|
+
|
7
|
+
def spent_today
|
8
|
+
Money.new(raw_data['spent_today'], currency)
|
9
|
+
end
|
10
|
+
|
11
|
+
def currency
|
12
|
+
Money::Currency.new(raw_data['currency'])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mondo
|
2
|
+
class Card < Resource
|
3
|
+
attr_accessor :id, :processor_token, :processor, :account_id,
|
4
|
+
:last_digits, :name, :expires, :status
|
5
|
+
|
6
|
+
date_accessor :created
|
7
|
+
|
8
|
+
def active?
|
9
|
+
status == 'ACTIVE'
|
10
|
+
end
|
11
|
+
|
12
|
+
def freeze
|
13
|
+
self.client.api_put("/card/toggle", {
|
14
|
+
card_id: id,
|
15
|
+
status: 'INACTIVE'
|
16
|
+
})
|
17
|
+
end
|
18
|
+
|
19
|
+
def unfreeze
|
20
|
+
self.client.api_put("/card/toggle", {
|
21
|
+
card_id: id,
|
22
|
+
status: 'ACTIVE'
|
23
|
+
})
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
require 'active_support/core_ext/hash'
|
2
|
+
require 'active_support/core_ext/object/to_query'
|
3
|
+
require 'multi_json'
|
4
|
+
require 'oauth2'
|
5
|
+
require 'openssl'
|
6
|
+
require 'uri'
|
7
|
+
require 'cgi'
|
8
|
+
require 'time'
|
9
|
+
require 'base64'
|
10
|
+
require 'money'
|
11
|
+
|
12
|
+
module Mondo
|
13
|
+
class Client
|
14
|
+
DEFAULT_API_URL = 'https://api.monzo.com'
|
15
|
+
|
16
|
+
attr_accessor :access_token, :account_id, :api_url
|
17
|
+
|
18
|
+
def initialize(args = {})
|
19
|
+
args.symbolize_keys!
|
20
|
+
self.access_token = args.fetch(:token)
|
21
|
+
self.account_id = args.fetch(:account_id, nil)
|
22
|
+
self.api_url = args.fetch(:api_url, DEFAULT_API_URL)
|
23
|
+
raise ClientError.new("You must provide a token") unless self.access_token
|
24
|
+
set_account unless account_id
|
25
|
+
end
|
26
|
+
|
27
|
+
# Hacky
|
28
|
+
def set_account
|
29
|
+
acc = accounts.first
|
30
|
+
return unless acc
|
31
|
+
self.account_id = acc.id
|
32
|
+
end
|
33
|
+
|
34
|
+
# Replies "pong"
|
35
|
+
def ping
|
36
|
+
api_request(:get, "/ping").parsed["ping"]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Issue an GET request to the API server
|
40
|
+
#
|
41
|
+
# @note this method is for internal use
|
42
|
+
# @param [String] path the path that will be added to the API prefix
|
43
|
+
# @param [Hash] params query string parameters
|
44
|
+
# @return [Hash] hash the parsed response data
|
45
|
+
def api_get(path, params = {})
|
46
|
+
api_request(:get, path, :params => params)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Issue a POST request to the API server
|
50
|
+
#
|
51
|
+
# @note this method is for internal use
|
52
|
+
# @param [String] path the path that will be added to the API prefix
|
53
|
+
# @param [Hash] data a hash of data that will be sent as the request body
|
54
|
+
# @return [Hash] hash the parsed response data
|
55
|
+
def api_post(path, data = {})
|
56
|
+
api_request(:post, path, :data => data)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Issue a PUT request to the API server
|
60
|
+
#
|
61
|
+
# @note this method is for internal use
|
62
|
+
# @param [String] path the path that will be added to the API prefix
|
63
|
+
# @param [Hash] data a hash of data that will be sent as the request body
|
64
|
+
# @return [Hash] hash the parsed response data
|
65
|
+
def api_put(path, data = {})
|
66
|
+
api_request(:put, path, :data => data)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Issue a PATCH request to the API server
|
70
|
+
#
|
71
|
+
# @note this method is for internal use
|
72
|
+
# @param [String] path the path that will be added to the API prefix
|
73
|
+
# @param [Hash] data a hash of data that will be sent as the request body
|
74
|
+
# @return [Hash] hash the parsed response data
|
75
|
+
def api_patch(path, data = {})
|
76
|
+
api_request(:patch, path, :data => data)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Issue a DELETE request to the API server
|
80
|
+
#
|
81
|
+
# @note this method is for internal use
|
82
|
+
# @param [String] path the path that will be added to the API prefix
|
83
|
+
# @param [Hash] data a hash of data that will be sent as the request body
|
84
|
+
# @return [Hash] hash the parsed response data
|
85
|
+
def api_delete(path, data = {})
|
86
|
+
api_request(:delete, path, :data => data)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Issue a request to the API server, returning the full response
|
90
|
+
#
|
91
|
+
# @note this method is for internal use
|
92
|
+
# @param [Symbol] method the HTTP method to use (e.g. +:get+, +:post+)
|
93
|
+
# @param [String] path the path that will be added to the API prefix
|
94
|
+
# @option [Hash] opts additional request options (e.g. form data, params)
|
95
|
+
def api_request(method, path, opts = {})
|
96
|
+
request(method, path, opts)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @method accounts
|
100
|
+
# @return [Accounts] all accounts for this user
|
101
|
+
def accounts(opts = {})
|
102
|
+
resp = api_get("/accounts", opts)
|
103
|
+
return resp if resp.error.present?
|
104
|
+
resp.parsed["accounts"].map { |acc| Account.new(acc, self) }
|
105
|
+
end
|
106
|
+
|
107
|
+
# @method cards
|
108
|
+
# @return [Cards] all cards for this user
|
109
|
+
def cards(opts = {})
|
110
|
+
raise ClientError.new("You must provide an account id to query transactions") unless self.account_id
|
111
|
+
opts.merge!(account_id: self.account_id)
|
112
|
+
resp = api_get("/card/list", opts)
|
113
|
+
return resp if resp.error.present?
|
114
|
+
resp.parsed["cards"].map { |tx| Card.new(tx, self) }
|
115
|
+
end
|
116
|
+
|
117
|
+
# @method transactions
|
118
|
+
# @return [Transactions] all transactions for this user
|
119
|
+
def transactions(opts = {})
|
120
|
+
raise ClientError.new("You must provide an account id to query transactions") unless self.account_id
|
121
|
+
opts.merge!(account_id: self.account_id)
|
122
|
+
resp = api_get("/transactions", opts)
|
123
|
+
return resp if resp.error.present?
|
124
|
+
resp.parsed["transactions"].map { |tx| Transaction.new(tx, self) }
|
125
|
+
end
|
126
|
+
|
127
|
+
# @method transaction
|
128
|
+
# @return <Transaction> of the transaction information
|
129
|
+
def transaction(transaction_id, opts = {})
|
130
|
+
raise ClientError.new("You must provide an transaction id to query transactions") unless transaction_id
|
131
|
+
resp = api_get("/transactions/#{transaction_id}", opts)
|
132
|
+
return resp if resp.error.present?
|
133
|
+
Transaction.new(resp.parsed['transaction'], self)
|
134
|
+
end
|
135
|
+
|
136
|
+
# @method balance
|
137
|
+
# @return <Balance> of the balance information
|
138
|
+
def balance(account_id = nil)
|
139
|
+
account_id ||= self.account_id
|
140
|
+
raise ClientError.new("You must provide an account id to see your balance") unless account_id
|
141
|
+
resp = api_get("balance", account_id: account_id)
|
142
|
+
return resp if resp.error.present?
|
143
|
+
Balance.new(resp.parsed, self)
|
144
|
+
end
|
145
|
+
|
146
|
+
def create_feed_item(params)
|
147
|
+
FeedItem.new(params, self).save
|
148
|
+
end
|
149
|
+
|
150
|
+
def register_web_hook(url)
|
151
|
+
raise ClientError.new("You must provide an account id to register webhooks") unless self.account_id
|
152
|
+
hook = WebHook.new(
|
153
|
+
{
|
154
|
+
account_id: self.account_id,
|
155
|
+
url: url
|
156
|
+
},
|
157
|
+
self
|
158
|
+
)
|
159
|
+
hook.save
|
160
|
+
web_hooks << hook
|
161
|
+
end
|
162
|
+
|
163
|
+
def web_hooks
|
164
|
+
raise ClientError.new("You must provide an account id to list webhooks") unless self.account_id
|
165
|
+
@web_hooks ||= begin
|
166
|
+
resp = api_get("webhooks", account_id: self.account_id)
|
167
|
+
|
168
|
+
puts resp.inspect
|
169
|
+
|
170
|
+
resp.parsed['webhooks'].map { |hook| WebHook.new(hook, self) }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def user_agent
|
175
|
+
@user_agent ||= begin
|
176
|
+
gem_info = "mondo-ruby/v#{Mondo::VERSION}"
|
177
|
+
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
178
|
+
ruby_version = RUBY_VERSION
|
179
|
+
ruby_version += " p#{RUBY_PATCHLEVEL}" if defined?(RUBY_PATCHLEVEL)
|
180
|
+
comment = ["#{ruby_engine} #{ruby_version}"]
|
181
|
+
comment << RUBY_PLATFORM if defined?(RUBY_PLATFORM)
|
182
|
+
"#{gem_info} (#{comment.join("; ")})"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# Send a request to the Mondo API servers
|
187
|
+
#
|
188
|
+
# @param [Symbol] method the HTTP method to use (e.g. +:get+, +:post+)
|
189
|
+
# @param [String] path the path fragment of the URL
|
190
|
+
# @option [Hash] opts query string parameters, headers
|
191
|
+
def request(method, path, opts = {})
|
192
|
+
raise ClientError, 'Access token missing' unless @access_token
|
193
|
+
|
194
|
+
opts[:headers] = {} if opts[:headers].nil?
|
195
|
+
opts[:headers]['Accept'] = 'application/json'
|
196
|
+
opts[:headers]['Content-Type'] = 'application/json' unless method == :get
|
197
|
+
opts[:headers]['User-Agent'] = user_agent
|
198
|
+
opts[:headers]['Authorization'] = "Bearer #{@access_token}"
|
199
|
+
|
200
|
+
if !opts[:data].nil?
|
201
|
+
opts[:body] = opts[:data].to_param
|
202
|
+
|
203
|
+
puts "SETTING BODY #{opts[:body]}"
|
204
|
+
|
205
|
+
opts[:headers]['Content-Type'] = 'application/x-www-form-urlencoded' # sob sob
|
206
|
+
end
|
207
|
+
|
208
|
+
path = URI.encode(path)
|
209
|
+
|
210
|
+
resp = connection.run_request(method, path, opts[:body], opts[:headers]) do |req|
|
211
|
+
req.params = opts[:params] if !opts[:params].nil?
|
212
|
+
end
|
213
|
+
|
214
|
+
response = Response.new(resp)
|
215
|
+
|
216
|
+
case response.status
|
217
|
+
when 301, 302, 303, 307
|
218
|
+
# TODO
|
219
|
+
when 200..299, 300..399
|
220
|
+
# on non-redirecting 3xx statuses, just return the response
|
221
|
+
response
|
222
|
+
when 400..599
|
223
|
+
error = ApiError.new(response)
|
224
|
+
raise(error, "Status code #{response.status}")
|
225
|
+
else
|
226
|
+
error = ApiError.new(response)
|
227
|
+
raise(error, "Unhandled status code value of #{response.status}")
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# The Faraday connection object
|
232
|
+
def connection
|
233
|
+
@connection ||= Faraday.new(self.api_url, { ssl: { verify: false } })
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|