ライフハック。RubyとGoogleドライブでiTunesの支払いを見える化しよう【後編】

こんにちは。野口です。

前編をお読みでない方へ。
本記事は前後編の2部構成となっています。
後編だけでは意味の伝わらない箇所が多々出てくることかと思いますので、
↓リンクの前編を先にお読みいただくことをおススメします。
ライフハック。RubyとGoogleドライブでiTunesの支払いを見える化しよう【前編】

chokin
http://www.photo-ac.com/

私がこれまでにiTunesで課金した金額の合計を知るために(知らない方が幸せなことって、人生にはありますよね)
gmailの受信ボックスに貯め込まれたiTunesのレシートメールを取り出して明細行を抜き出すというプログラムを作りました。

何がとは申しませんが、前回はそこで非常に悲しい気持ちにされる出来事に遭遇したため、ええ、それはもう深い悲しみに包まれました。
その先に予定していた「Googleドライブ」との連携という部分には手を付けずに後編へ続くとなったわけです。

では、前置きはここまでにしてさっそくソースコードを見ていきたいと思います。

ソースコード(rgdrive.rb)

require 'google/api_client'
require 'google_drive'
require 'yaml'

class RGDrive
  def initialize
    config ||= YAML.load_file('./config/configuration.yml')['development']
    client             = Google::APIClient.new
    auth               = client.authorization
    auth.client_id     = config[:client_id]
    auth.client_secret = config[:secret]
    auth.scope         = "https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds/"
    auth.redirect_uri  = "urn:ietf:wg:oauth:2.0:oob"

    print("1. Open this page:\n%s\n\n" % auth.authorization_uri)
    print("2. Enter the authorization code shown in the page: ")
    auth.code = $stdin.gets.chomp
    auth.fetch_access_token!
    access_token = auth.access_token
    @session = GoogleDrive.login_with_oauth(access_token)
  end

  def worksheet(key)
    @session.spreadsheet_by_key(key).worksheets[0]
  end
end

こちらが、Googleドライブのスプレッドシートに接続するためのコードです。
前回、作成したgmailからレシートを抜き出してくるプログラムから呼出すためにクラス化しています。
Googleドライブへの接続と操作はgoogle_driveというgemを利用しています。

 

尚、Google Driveへのアクセスはoauthにより行います。
コンストラクタの中で行っているのは、ほぼそのための処理です(9行目から20行目)。

特に10行目と9行目で設定しているクライアントIDとシークレットIDを得るには、皆様がお持ちのGoogleアカウントに今回のアプリを登録する設定を行っていただく必要があります。
設定は↓から行うことが出来ます。

 

15行目から20行目がGoogleドライブへ接続するためのアクセストークンを得る処理です。
プログラムを実行するとターミナルにOAuth認証を行うためのページへのURLが出力されるので、そこにアクセスして認証を行ってください。
認証を行うと遷移する先のページに表示されているアクセストークンをターミナルに張り付けて「ッターン!!」してもらえればめでたくGoogleドライブへの接続は完了です。

ソースコード(rgmail.rb)

require 'gmail'
require 'yaml'
require 'time'
require File.expand_path('rgdrive')

if __FILE__ == $0
  config ||= YAML.load_file('./config/configuration.yml')['development']
  worksheet = RGDrive.new.worksheet(config[:worksheet_key])
  Gmail.new(config[:username], config[:password]) do |gmail|
    index = 1
    gmail.inbox.emails(from: 'do_not_reply@itunes.com').each do |mail|
      if mail.text_part
        mail.text_part.decoded.scan(/.+App.+|.+アドオン.+/).each do |payment_record|
          payment_datetime = Time.parse(mail.date.to_s).strftime("%Y/%m/%d %H:%M:%S")
          payment_columns  = payment_record.split(/\¥|\\/)
          worksheet[index, 1] = %Q|#{payment_datetime}|
          worksheet[index, 2] = payment_columns[0]
          worksheet[index, 3] = payment_columns[1]
          index += 1
        end
      end
    end
    worksheet.save
    worksheet.reload
  end
end

こちらが前回作成した悲しみのiTunesレシート収集プログラムを改修して、Googleドライブのスプレッドシートに結果を出力するようにしたものです。

主な変更点は、8行目と15行目から18行目の部分です。
8行目で上で解説したGoogleドライブへの接続を行い、スプレッドシートを操作するためのオブジェクトを取り出します。
スプレッドシートの指定は、スプレッドシートIDで指定しています。
ブラウザでスプレッドシートを開くとURLに含まれている長い文字列がそれです。
※実際にお試しになられる方は、くれぐれもシェアされているスプレッドシートを指定することのないようにご注意ください。

15行目から18行目の部分は、メールから抜き出したレシートの明細行をスプレッドシート用に分割して書きだす処理を行っています。
明細行の分割ですが、iTunesのレシートの明細行を見ると円記号もしくはバックスラッシュの後ろに金額が書かれています。
なので、単純に円記号もしくはバックスラッシュの位置で行を分割するという処理を行いました。
はい。手抜きです。もし請求元やアプリ名などに円記号やバックスラッシュが含まれていたら悲劇が訪れることでしょう。
そのような場合は適宜、修正していただければ幸甚です。
行の後ろから見て最初の円記号もしくはバックスラッシュのみを変換する処理を入れてあげれば問題ないでしょう。

ターミナルからrgmail.rbを実行すると、rgdrive.rbの解説に書いたようにOAuth認証に必要な情報の入力が求められます。
アクセストークンですね。それを入力してしばらく待っていると、指定したスプレッドシートにiTunesレシートの明細行がずらずらと書きだされるはずです。
金額部分は別カラムに分けているので、取り敢えず全額知りたい場合はそのカラムを全選択すると簡単に知ることが出来るはずです。

以上が、iTunesで今まで課金した金額がいくらなのか知りたいという馬鹿げた妄想に取りつかれた不幸な男の顛末です。
やらなきゃ良かったって後悔していますよ。本当にorz

尚、環境はMac OS X Yosemite, ruby 2.2.0devでのみ動作確認しています。
他の環境での動作は保証しません。特にWindows上での動作は全く保証できませんのであしからず。

・ さいごに

この物語はフィクションです。
このブログに登場する人物およびその発言は全て架空のものであり、
筆者の実体験に基づくものではありません。
現実の私はiTunesカードを買ったことすらありません。

ソースコードだけがこのブログ内で唯一の真実です。
(バグも含めて)真実です。

それでは皆さま、今後も良き課金ライフを。

コメントを残す

メールアドレスが公開されることはありません。

ABOUTこの記事をかいた人

僕と契約してアーティストになってよ。 普段はJavaやPHPで業務Webアプリばっかり作っています。 安西先生、Rubyで仕事がしたいです・・・。