AWS, GCP, Circle CI, GitHub, PagerDuty, Mackerel, BugSnagなどなど…を使っていて毎月請求書が飛んでくる。システムの土台を見ている俺だったり会社の金を取り回している人は、金額を管理する必要がある。ということで最近、これらの管理をいいかげん自動化した。年末最後のデプロイ/プロビジョニングが終わってコードを凍結したらやることが減ってしまったので暇つぶしをしたというか。まあみんなの役に立つからいいか。50行くらいのgoogle app scriptで実現できる。



前提

* 請求書の送り先としてgmailを利用している

くらいか。

仕様

* 請求書が飛んできたらそのメールをパースする
* メール本文に書かれた金額はgoogle spread sheet、添付ファイルの請求書はgoogle driveに保存する
* 処理が終わったらそのメールは既読にする
* gasのスケジュール実行は1時間に1回とか。まあ適当に。

ポイント

ソースを全晒しするのはアレなので、ポイントだけ。

gmailからターゲットとなる請求メールを抽出する

これはCircle CIの例。”CircleCI Billing” というfromで、サブジェクトが “Your CircleCI invoice ORGANIZATION NAME” で、かつ、未読のメールを取得する。startとmaxは抽出する件数。適当にstart = 0, max = 100とかでいいんじゃないかな。

var threads = GmailApp.search(‘from:(CircleCI Billing) subject:(Your CircleCI invoice hiroakis) is:unread’, start ,max);

AWSはこんなかんじ。

var threads = GmailApp.search(‘from:(Amazon Web Services) {subject:(Amazon Web Services Invoice Available) subject:(AWS Marketplace Statement Available)} is:unread’, start ,max);

正規表現で金額を抜いてシートに追記する

var sheet = SpreadsheetApp.getActive().getSheetByName(“シート名”);  // 書き込み先のシートを取得
var row = sheet.getLastRow() + 1; // 最後の行+1を取得(その次から書き込みを行う)

for(var n in threads){  // 取得したスレッドを回して….
var the = threads[n];

var msgs = the.getMessages();  // メッセージを取得して
for(var m in msgs){
var msg = msgs[m];
var body = msg.getPlainBody();  // メールテキストを取得

var feeStr = body.match(/[\s\S]*?Amount Due: USD \$(.+)/);  // Circle CIの場合の正規表現

sheet.getRange(row,1).setValue(date);
sheet.getRange(row,2).setValue(feeStr[1]);  // こんな感じでシートに金額を書き込む
sheet.getRange(row,3).setValue(“USD”);  // 単位も

添付ファイルの保存

var folderId = “xxxxxxxxxxxxxxxxxxxxxxxx”; // google driveのフォルダのID。事前に調べておく。
var folder = DriveApp.getFolderById(folderId);
var attachments = msg.getAttachments();  // msgはvar msgs = the.getMessages(); for (var m in msg){ var msg = msgs[m]で調べたやつ

for(var i in attachments){  // 添付ファイルを回して…
var fileName = formattedDate + “_” + attachments[i].getName();  // 保存するファイル名は”yyyymmdd_添付ファイル名”とする
attachments[i].setName(fileName);
folder.createFile(attachments[i]);  // で、保存

スレッドを既読にする

the.markRead();

で。

様子

未読のものがターゲットになるので、過去のメールを全部未読にしてやると、1回目の実行のときにまとめて処理される。こんな感じ。driveの方にもちゃんと保存される。まとめて。

gas01

参考

* 備忘録:Gmailで受け取った内容をGoogleスプレッドシートに自動で読み込んで管理する方法
– http://webimemo.com/web/8403

おわり

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <img localsrc="" alt="">

Set your Twitter account name in your settings to use the TwitterBar Section.