Class: MFYNAB::MoneyForward

Inherits:
Object
  • Object
show all
Defined in:
lib/mfynab/money_forward.rb

Constant Summary collapse

DEFAULT_BASE_URL =
"https://moneyforward.com"
SIGNIN_PATH =
"/sign_in"
CSV_PATH =
"/cf/csv"
"_moneybook_session"
USER_AGENT =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " \
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"

Instance Method Summary collapse

Constructor Details

#initialize(logger:, base_url: DEFAULT_BASE_URL) ⇒ MoneyForward

Returns a new instance of MoneyForward.



14
15
16
17
# File 'lib/mfynab/money_forward.rb', line 14

def initialize(logger:, base_url: DEFAULT_BASE_URL)
  @base_url = URI(base_url)
  @logger = logger
end

Instance Method Details

#download_csv(session_id:, path:, months:) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/mfynab/money_forward.rb', line 33

def download_csv(session_id:, path:, months:)
  month = Date.today
  month -= month.day - 1 # First day of month

  Net::HTTP.start(base_url.host, use_ssl: true) do |http|
    http.response_body_encoding = Encoding::SJIS

    months.times do
      date_string = month.strftime("%Y-%m")

      logger.info("Downloading CSV for #{date_string}")

      # FIXME: I don't really need to save the CSV files to disk anymore.
      # Maybe just return parsed CSV data?
      File.open(File.join(path, "#{date_string}.csv"), "wb") do |file|
        file << download_csv_string(date: month, session_id: session_id)
      end

      month = month.prev_month
    end
  end
end

#download_csv_string(date:, session_id:) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/mfynab/money_forward.rb', line 56

def download_csv_string(date:, session_id:)
  Net::HTTP.start(base_url.host, use_ssl: true) do |http|
    http.response_body_encoding = Encoding::SJIS

    request = Net::HTTP::Get.new(
      "#{CSV_PATH}?from=#{date.strftime('%Y/%m/%d')}",
      {
        "Cookie" => "#{SESSION_COOKIE_NAME}=#{session_id}",
        "User-Agent" => USER_AGENT,
      },
    )

    result = http.request(request)
    raise unless result.is_a?(Net::HTTPSuccess)
    raise unless result.body.valid_encoding?

    result.body.encode(Encoding::UTF_8)
  end
end

#get_session_id(username:, password:) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/mfynab/money_forward.rb', line 19

def get_session_id(username:, password:)
  with_ferrum do |browser|
    browser.goto("#{base_url}#{SIGNIN_PATH}")
    browser.at_css("input[name='mfid_user[email]']").focus.type(username)
    browser.at_css("input[name='mfid_user[password]']").focus.type(password)
    browser.at_css("button#submitto").click

    # FIXME: use custom error class
    raise "Login failed" unless browser.cookies[SESSION_COOKIE_NAME]

    browser.cookies[SESSION_COOKIE_NAME].value
  end
end