レシート

GAS x freeeAPIライブラリのトリセツ「グーグルドライブからレシート等を自動アップロード」

ノンプログラマー(ITを専門職としない人材)が、Google Apps Script(以下GAS)でfreee APIを簡単に操作するためのライブラリを作成しています。

ノンプログラマーのためのスキルアップ研究会(以下ノンプロ研)で受講したfreee API講座の内容をベースに作成しています。

freeeの神機能!DropBoxに保存したレシート類を取り込む

freeeには「Dropboxに保存したレシート類を取り込む」という機能があってとっても便利です。

Dropboxに保存したレシート類を取り込む

適当にフォルダを用意して、そこにスキャンしたレシートなどをポイポイほりこんでおいて、あとからfreeeの操作画面からメニュー > 取引 > ファイルボックス > Dropboxからインポートでフォルダを指定するだけです。

ただ…

  1. Dropboxの容量圧迫が気になる
  2. 同期は手動でちょっと手間
  3. フォルダ内のインポート済ファイルでも名前を変えてしまうと別の証憑と認識されてしまう

など、贅沢な悩みがあります。

1. Dropboxの容量圧迫が気になる

は、Dropboxをメインのクラウドストレージとして使用していない人にとって、 レシート等の画像ファイルは意外と容量も大きく、使用を続けていくうちに無料プランの容量制限に確実に近づいてきプレッシャーを感じます。

2. 同期は手動でちょっと手間

も、 これも完全にわがままな願望なのですが、ものぐさな私はfreeeにログインしてDropboxからレシートを保存するというのを面倒に感じます。

3. フォルダ内のインポート済ファイルでも名前を変えてしまうと別の証憑と認識されてしまう

は、重複登録の原因になりますが、これはどんな運用でも起こり得ることなので、問題というほどのものではないですね。どうチェックするかの仕組み作りが大切だと思います。

GASを用いる場合だとアップロード用のフォルダとアップロード済のフォルダを用意して、アップロードに成功したファイルを移動させることで、重複登録が生じる可能性を下げることができます。

グーグルドライブからレシート等を自動アップロード

早速レシート等をアップロードするGASを書いていきたいと思います。参照するのはfreee APIのReceipts ファイルボックス のエンドポイントです。

このようなファイルボックスの他、どんなデータ種別をAPIで操作することができるかは、freeeの会計APIリファレンスのページで確認できます(GAS x freeeAPIライブラリはすべてのエンドポイントに対応しているわけでありません)。

会計APIリファレンス

1. レシート等を格納するフォルダとアップロード後にファイルを移動させるフォルダを用意

まずは、グーグルドライブで新しいフォルダを2つ作成します。

  • アップロードしたいレシート等を格納するフォルダ
  • アップロード後のレシート等を移動するフォルダ

この新しく作成したフォルダそれぞれのIDがまず必要になります。IDの調べ方は隣ITの以下の記事を参考になります。

基本中の基本!GASでGoogleドライブのファイル・フォルダをIDで取得する

2. アップロードしたファイルの履歴を記録するシートを作成します

続いて、ファイルをアップロードした履歴を記録するためのシートをfreee APIを操作するスプレッドシートに新たに作成します。

シート名は自由につけて大丈夫ですが、後でこのシート名が必要になります。サンプルコードでは「ファイルボックス履歴」としました。

3. GAS x freeeAPIライブラリを利用してレシート等をアップロードするスクリプト

ここまでで事前準備は完了です。

早速、実際の処理を行うコードを紹介します。

function autoUploadFiles() {

  /* 証憑を格納するフォルダとアップロード後移動させるフォルダを指定 */
  const idFolderUpload = 'xxxxxxxxxxxxx'; // アップロードしたいレシート等を格納しているフォルダのID(グーグルドライブ)
  const idFolderSave = 'yyyyyyyyyyyyy'; // アップロード後のレシート等を移動するフォルダのID(グーグルドライブ)

  /* アップロードしたファイルの履歴を記録するシート名を指定 */
  const sheetName = 'ファイルボックス履歴'; // ヘッダー行は、「登録, ファイル名, Google Drive ファイルID, 証憑ファイルID」の4項目

  /* freeeAPI用のアクセストークンと事業所IDを取得 */
  const accessToken = getService().getAccessToken(); // アクセストークン
  // const company_id = freeeAPI.myCompanies(accessToken).getMyCompanyId('開発用テスト事業所'); // APIで事業所IDを取得
  const company_id = Number(PropertiesService.getScriptProperties().getProperty('COMPANY_ID')); // プロパティストアから事業所IDを取得

  /* ここからファイルをアップロードして履歴用シートに記録していく処理 */
  // アップロードしたファイルの履歴を記録するシート
  const sheetRecord = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);

  // アップロードしたいレシート等を格納しているフォルダ
  const folderUpload = DriveApp.getFolderById(idFolderUpload);

  // アップロード後のレシート等を移動するフォルダ
  const folderSave = DriveApp.getFolderById(idFolderSave);

  // ファイルを1つづつ処理し記録用シートに結果を記録(成功した場合はフォルダ移動させる)
  const files = folderUpload.getFiles(); // アップロードフォルダ内のファイルをすべて取得
  while (files.hasNext()) {
    const file = files.next();
    const fileId = file.getId();
    const fileName = file.getName();
    const description = fileName; // メモ欄にファイル名を入力、ここは = 'Google Driveから登録' などとしても良い
    const blob = DriveApp.getFileById(file.getId()).getBlob();

    // レシート等をファイルボックスにアップロードするpostReceiptメソッド
    const response = freeeAPI.receipts(accessToken, company_id).postReceipt(blob, description);

    // ファイルボックスへのアップロードが成功したファイルのみ移動させる
    if (response.receipt) {
      sheetRecord.appendRow(['成功', fileName, fileId, response.receipt.id]);
      file.moveTo(folderSave);
    } else {
      sheetRecord.appendRow(['失敗', fileName, fileId, '']);
    }
  }
}

まず、1. と2. で準備したIDとシート名を以下の定数に代入します。

  • idFolderUpload
  • idFolderSave
  • sheetName

事業所IDをどう取得するか

続いてファイルボックス操作オブジェクトの生成に必要なアクセストークンと事業所IDを取得します。

  // const company_id = freeeAPI.myCompanies(accessToken).getMyCompanyId('開発用テスト事業所'); // APIで事業所IDを取得
  const company_id = Number(Properties.getScriptProperty('COMPANY_ID')); // プロパティストアから事業所IDを取得

company_idという定数に事業所IDを代入しているのですが、最初のコメントアウトしているコードは、APIを使って事業所の表示名から事業所IDを取得するコードです。

ただ、事業所IDを毎回取得するケースは少ないかと思い、決まった事務所IDをプロパティストアに格納した上で利用するのがオススメです。その際、プロパティストアから取得した値を数値型に変換しないとエラーが出てしまうためNumber コンストラクターを利用しています。

プロパティストアに関しては、隣ITの以下の記事を参照してください。

【初心者向けGAS】プロパティストアの概要とスクリプトプロパティの入力方法

アップロードフォルダ内のファイルをすべて取得し、ファイルを1つづつ処理

const files = folderUpload.getFiles(); // アップロードフォルダ内のファイルをすべて取得

まず、定数 filesにフォルダ内のファイルをすべて格納します。そこから…

  • グーグルドライブのファイルID
  • ファイル名

を取得します。

今回はこのファイル名をfreeeのファイルボックスにファイルを登録した際に表示されるメモ欄に反映させました。

const description = fileName; // メモ欄にファイル名を入力、ここは = 'Google Driveから登録' などとしても良い

ここはGoogle Driveから登録など自由に設定してOKです。

レシートサンプル

レシート等をファイルボックスにアップロードするpostReceiptメソッド

GAS x freeeAPIライブラリはここで登場します。

// レシート等をファイルボックスにアップロードするpostReceiptメソッド
const response = freeeAPI.receipts(accessToken, company_id).postReceipt(blob, description);
  1. freeeAPI → ライブラリの呼び出し
  2. receipts(アクセストークン, 事業所ID) → ファイルボックス操作オブジェクトを生成するファクトリ関数
  3. postReceipt(blob, メモ, 取引日) → Receiptsオブジェクトのメンバーであるファイルボックスに指定したファイルをアップロードするメソッド ※メモと取引日は省略可

という3段階で処理を実行してくれます。

ファイルボックス操作クラス(※クラスはオブジェクト生成の雛形)のメソッドはこのpostReceiptメソッドのみです。

ライブラリに定義されているメソッドなどは、GASのコードの自動補完が使用できないので、以下のようなダミーの関数をdummy.gsのように別のgsファイルに用意しておくと便利です。

/* 170 freeeファイルボックスに関するクラス */

/**
 * Receiptsインスタンス生成後、ファイルボックスに指定したファイルをアップロードするメソッド
 * @parama  {Blob}  receipt - ファイルボックスにアップロードしたいファイル(Blob形式)
 * @parama  {string}  description - メモ (255文字以内) *省略可
 * @parama  {string}  issue_date - 取引日 (yyyy-MM-dd) *省略可
 * @return  {HTTPResponse}   response  - ファイルボックスへのアップロード結果に関するレスポンス
 */

function postReceipt(receipt, description, issue_date) {
  throw new Error('Receiptsインスタンスを生成してから実行してください。');
}

ライブラリの導入前の事前準備や導入の仕方などは、以下の記事をご参考ください。

4. トリガーを設定して定期実行する

3. で作成したスクリプトを毎日1回実行するように設定すれば、日常業務ではフォルダにスキャンしたレシート等を保存するだけで完結します。

GASのスクリプトを定期実行するにはトリガーという機能を使います。トリガーに関しても隣ITの以下の記事が参考になります。

【初心者向けGAS】時限式のイベントトリガーを設置して決まった時刻にBotを送信する方法

Amazon欲しい物リスト公開しています。

開発者のモチベーションアップのためにAmazon欲しい物リストを公開しております。役に立ったよ!という方の感謝の気持ちで何かいただけるのであれば嬉しいです笑

Amazon欲しい物リスト

タグ: ,
Share on:
Previous Post
Offsetでレコード全件取得
freeeAPI

offsetを使いこなして1回のAPIリクエストで取得できるレコード数の制限を超える

Next Post
事業所一覧
freeeAPI

GAS x freeeAPIライブラリのトリセツ「事業所IDを取得してみよう」