Class: BankScrap::Bbva

Inherits:
Bank
  • Object
show all
Defined in:
lib/bank_scrap/banks/bbva.rb

Constant Summary collapse

BASE_ENDPOINT =
'https://servicios.bbva.es'
LOGIN_ENDPOINT =
'/DFAUTH/slod/DFServletXML'
PRODUCTS_ENDPOINT =
'/ENPP/enpp_mult_web_mobility_02/products/v1'
ACCOUNT_ENDPOINT =
'/ENPP/enpp_mult_web_mobility_02/accounts/'
USER_AGENT =

BBVA expects an identifier before the actual User Agent, but 12345 works fine

'12345;Android;LGE;Nexus 5;1080x1776;Android;5.1.1;BMES;4.4;xxhd'

Constants inherited from Bank

BankScrap::Bank::WEB_USER_AGENT

Instance Attribute Summary

Attributes inherited from Bank

#accounts, #headers, #investments

Instance Method Summary collapse

Methods inherited from Bank

#account_with_iban, #fetch_investments

Constructor Details

#initialize(user, password, log: false, debug: false, extra_args: nil) ⇒ Bbva

Returns a new instance of Bbva.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/bank_scrap/banks/bbva.rb', line 12

def initialize(user, password, log: false, debug: false, extra_args: nil)
  @user = format_user(user.dup)
  @password = password
  @log = log
  @debug = debug

  initialize_connection

  add_headers(
    'User-Agent'       => USER_AGENT,
    'BBVA-User-Agent'  => USER_AGENT,
    'Accept-Language'  => 'spa',
    'Content-Language' => 'spa',
    'Accept'           => 'application/json',
    'Accept-Charset'   => 'UTF-8',
    'Connection'       => 'Keep-Alive',
    'Host'             => 'bancamovil.grupobbva.com',
    'Cookie2'          => '$Version=1'
  )

  
  super
end

Instance Method Details

#fetch_accountsObject

Fetch all the accounts for the given user Returns an array of BankScrap::Account objects



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/bank_scrap/banks/bbva.rb', line 38

def fetch_accounts
  log 'fetch_accounts'

  # Even if the required method is an HTTP POST
  # the API requires a funny header that says is a GET
  # otherwise the request doesn't work.
  response = with_headers('BBVA-Method' => 'GET') do
    post(BASE_ENDPOINT + PRODUCTS_ENDPOINT)
  end

  json = JSON.parse(response)
  json['accounts'].map { |data| (data) }
end

#fetch_transactions_for(account, start_date: Date.today - 1.month, end_date: Date.today) ⇒ Object

Fetch transactions for the given account. By default it fetches transactions for the last month, The maximum allowed by the BBVA API is the last 3 years.

Account should be a BankScrap::Account object Returns an array of BankScrap::Transaction objects



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/bank_scrap/banks/bbva.rb', line 58

def fetch_transactions_for(, start_date: Date.today - 1.month, end_date: Date.today)
  from_date = start_date.strftime('%Y-%m-%d')

  # Misteriously we need a specific content-type here
  funny_headers = {
    'Content-Type' => 'application/json; charset=UTF-8',
    'BBVA-Method' => 'GET'
  }

  # The API accepts a toDate param that we could pass the end_date argument,
  # however when we pass the toDate param, the API stops returning the account balance.
  # Therefore we need to take a workaround: only filter with fromDate and loop
  # over all the available pages, filtering out the movements that doesn't match
  # the end_date argument.
  url = BASE_ENDPOINT +
        ACCOUNT_ENDPOINT +
        .id +
        "/movements/v1?fromDate=#{from_date}"

  offset = nil
  pagination_balance = nil
  transactions = []

  with_headers(funny_headers) do
    # Loop over pagination
    loop do
      new_url = offset ? (url + "&offset=#{offset}") : url
      new_url = pagination_balance ? (new_url + "&paginationBalance=#{pagination_balance}") : new_url
      json = JSON.parse(post(new_url))

      unless json['movements'].blank?
        # As explained before, we have to discard records newer than end_date.
        filtered_movements = json['movements'].select { |m| Date.parse(m['operationDate']) <= end_date }

        transactions += filtered_movements.map do |data|
          build_transaction(data, )
        end
        offset = json['offset']
        pagination_balance = json['paginationBalance']
      end

      break unless json['thereAreMoreMovements'] == true
    end
  end

  transactions
end