定期的に届くWebサービスのシステム利用料のお知らせメールからfreeeの取引を作成しよう!という挑戦の続きです。
前回の記事はこちら。
今回は、freee APIにPOST(データ登録)するために雛形となる過去の取引をGET(データ取得)したいと思います。
freee APIはじめ多くのAPIの使用の際には、データのやりとりをJSONというフォーマットの文字列でおこなっています。このJSON形式のデータは複雑な構造になっていることも多く、データ登録の際には、この複雑な構造のJSONを自分で用意しなければいけません。
そこでノンプログラマーのためのスキルアップ研究会(以下ノンプロ研)のfreeeAPI講座では、雛形となるデータを一度取得して、加工、登録としていく方法を学びます。
今回はこのアプローチを踏襲します。
雛形となる取引をメモタグでマーキングする
ます雛形となる取引をマーキングします。その際に便利なのがfreeeのメモタグです。ターゲットとなる取引に特別なメモタグを付与しておき、後で大量の取引のなかからそのメモタグが付与された取引を絞り込みます。
上記のような携帯電話料金の支払の取引があったとします。ここに「*雛形」という名称のメモタグを付与します。
付与されたことを確認して、下準備は完了です。
雛形取引が含まれる期間の取引を全て取得する
続いて、雛形取引が含まれる期間のfreeeの取引オブジェクトを全て取得します。
指定期間の取引が記録されたオブジェクトを取得するのは
- リクエストURLの作成
- オプションパラメーターの作成
- リクエストの送信
と少々手間なのですが、ここでGAS x freeeAPIライブラリの登場です。このライブラリを使用して簡単に取引オブジェクトを取得できます。
GAS x freeeAPIライブラリの導入などの事前準備はこちらの記事を参考にしてください。
事前準備を終えた上で、必要になってくるのは、いつもの通りアクセストークンと操作対象の事業所IDです。
事業所IDの取得方法は以下で紹介しています。
今回は、前月はじめからの期間の全取引を取得してみました。
function getSampleDeal_01() {
const accessToken = getService().getAccessToken(); // アクセストークンを取得
const company_id = freeeAPI.myCompanies(accessToken).getMyCompanyId('開発用テスト事業所');
const deals_freeeAPI = freeeAPI.deals(accessToken, company_id); //freeeAPIライブラリのdeals操作オブジェクトを作成
deals_freeeAPI.queries.start_issue_date = '2022-06-01'; // 取引発生日の期間開始日を指定
const aryAllDeals = deals_freeeAPI.getAllDeals();
console.log(aryAllDeals);
}
freeeAPIライブラリの取引操作オブジェクト(上記の例では、deals_freeeAPI)にはqueriesというプロパティを持たせてあります。このqueriesにはさらにfreeeの会計APIリファレンスに示されているdealsエンドポイントのパラメーターに対応したプロパティをもたせています。
このqueries以下のプロパティに自由に値を代入することで、リクエストURLに反映され絞り込みができるようになります。
このあたりは、GASでのfreee APIの操作の基本を学ぶと理解しやすいと思いますので、気になった方はぜひノンプロ研でfreeeAPI講座を受講してみてください(私は講師は卒業しました!)。
いつも隣にITのお仕事|コミュニティ「ノンプログラマーのためのスキルアップ研究会」についてのお知らせ #ノンプロ研
今回は、前月はじめからと期間を指定してみました。
deals_freeeAPI.queries.start_issue_date = '2022-06-01'; // 取引発生日の期間開始日を指定
ちなみに期間指定をしない場合はデフォルトで1年分の取引が取得されます。
また、getAllDeals()
は「指定した条件の全ての取引一覧を配列で取得するメソッド」です。戻り値に各取引が記録されたJSONオブジェクトが格納された配列が返ってきます。
雛形となるオブジェクトの抽出
さあ、ここが今回のハイライトです。多数ある取引から雛形となる取引を見つけ出し、その取引オブジェクトを取得するのが目下の目標です。
freee APIからのレスポンスには、残念ながら取引先やメモタグなどのIDが記録されているのみで、日本語での表記はありません。そのため、今回のケースで言うと「*雛形」というメモタグのシステムIDを知る必要があります。
これもGAS x freeeAPIライブラリのtagsクラスにgetIdByName(name)というメソッドを用意しました。引数にメモタグ名を渡すとシステムIDを返してくれるメソッドです。
const targetTagId = freeeAPI.tags(accessToken, company_id).getIdByName('*雛形');
これで「*雛形」メモタグのシステムIDを知ることができたので、後はこのメモタグIDが含まれる取引オブジェクトを抽出するだけです。
ただ少々厄介なのは、このメモタグはfreee APIのレスポンスだとdetailsという取引のさらに内部の明細データ内にtag_idsとして存在しています。
{
"deals": [
{
"id": 101,
"company_id": 1,
"issue_date": "2019-12-17",
"due_date": "2019-12-17",
"amount": 5250,
"due_amount": 0,
"type": "expense",
"partner_id": 201,
"partner_code": "code001",
"ref_number": "123-456",
"status": "settled",
"details": [
{
"id": 11,
"account_item_id": 803,
"tax_code": 2,
"item_id": 501,
"section_id": 1,
"tag_ids": [
1,
2,
3
],
"segment_1_tag_id": 1,
"segment_2_tag_id": 1,
"segment_3_tag_id": 1,
"amount": 5250,
"vat": 250,
"description": "備考",
"entry_side": "debit"
}
],
"renews": [
{
"id": 11,
"update_date": "2019-12-17",
"renew_target_id": 12,
"renew_target_type": "detail",
"details": [
{
"id": 1,
"entry_side": "debit",
"account_item_id": 1,
"tax_code": 1,
"item_id": 1,
"section_id": 1,
"tag_ids": [
1
],
"segment_1_tag_id": 1,
"segment_2_tag_id": 1,
"segment_3_tag_id": 1,
"amount": 108000,
"vat": 8000,
"description": "備考"
}
]
}
],
"payments": [
{
"id": 202,
"date": "2019-12-17",
"from_walletable_type": "bank_account",
"from_walletable_id": 103,
"amount": 5250
}
],
"receipts": [
{
"id": 1,
"status": "unconfirmed",
"description": "タクシー利用",
"mime_type": "image/png",
"issue_date": "2019-12-17",
"origin": "public_api",
"created_at": "2019-12-17T18:30:24+09:00",
"user": {
"id": 1,
"email": "contact@example.com",
"display_name": "フリー太郎"
}
}
]
}
],
"meta": {
"total_count": 100
}
}
この深い階層まで探索していく必要があります。
配列の各要素に対して条件に合致したものを絞り込むという場合は、filter()メソッドが使えます。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
filter()メソッドやmap()メソッドなどの反復メソッドは、ノンプロ研で言うとGAS中級講座の範囲ですが、freee APIの複雑な構造のデータを取り扱うには非常に便利なメソッドになります。ぜひ習得しておきたいメソッドです。
同時に、それぞれのメソッドの戻り値が何であるのかを意識するのが重要になってきます。今回のfilter()メソッドでいうと
テストに合格した要素からなる新しい配列です。テストに合格した要素がなかった場合は、空の配列が返されます。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
で、つまり条件に合致した要素を格納した配列を返してくれるメソッドです。また条件に合致した要素がない場合は空の配列が返ってきます。
これを利用しました。
const aryTatgetDeals = allDeals.filter(deal => deal.details.filter(detail => detail.tag_ids.includes(targetTagId)).length);
子階層のdetails配列内の要素のtag_ids配列にターゲットとなるIDが含まれているかをテストしています。含まれていれば、deal.details.filterの戻り値は要素数1以上の配列になりますし、含まれていなければ空の配列です。それをさらに親階層のdeals配列の各要素でテストして、条件に合致する取引オブジェクトを抽出しています。
function getSampleDeal_02() {
const accessToken = getService().getAccessToken(); // アクセストークンを取得
const company_id = freeeAPI.myCompanies(accessToken).getMyCompanyId('開発用テスト事業所');
const deals_freeeAPI = freeeAPI.deals(accessToken, company_id); //freeeAPIライブラリのdeals操作オブジェクトを作成
deals_freeeAPI.queries.start_issue_date = '2022-06-01'; // 取引発生日の期間開始日を指定
const aryAllDeals = deals_freeeAPI.getAllDeals(); // 指定条件の全取引を取得
// ターゲットマーカーとなるメモタグIDを取得
const targetTagId = freeeAPI.tags(accessToken, company_id).getIdByName('*雛形');
// ターゲットマーカーとなるメモタグを含む取引を抽出
const aryTatgetDeals = aryAllDeals.filter(deal => deal.details.filter(detail => detail.tag_ids.includes(targetTagId)).length);
console.log(aryTatgetDeals);
}
これで雛形となる取引オブジェクトを格納した配列が取得できました。
このターゲットマーカーとなるメモタグを付与して探索するというのは、ちょっとがんのPET検査に似ていますね。
freeeのUIから取引IDを確認する裏技
ここまで苦労して取引オブジェクトを取得してきましたが、実はfreeeのUIから取引IDを確認する裏技があります。
freeeのいつもの操作画面で、取引IDを確認したい取引を開いて仕訳帳をクリックすると該当の取引の仕訳帳のページに飛びます。
仕訳帳のページを開いた時にURLが表示されるブラウザのアドレスバーを確認すると、そこに?deal_id=xxxxxxxxxxという表示がありこの数値の部分が取引IDなのです。
取引IDがわかれば、そのIDから街頭の取引オブジェクトを取得することができますので、今回の記事のような探索を行う必要はありません。
GAS x freeeAPIライブラリを使って、取引IDから取引オブジェクトを簡単に取得することもできます。
function getSampleDeal_03() {
const accessToken = getService().getAccessToken(); // アクセストークンを取得
const company_id = freeeAPI.myCompanies(accessToken).getMyCompanyId('開発用テスト事業所');
const deal_freeeAPI = freeeAPI.deal(accessToken, company_id); //freeeAPIライブラリのdeal操作オブジェクトを作成
const deal_id = 1288629768; // 取得したい取引のID
const targetDeal = deal_freeeAPI.getDeal(deal_id); // 指定したIDの取引を取得するメソッド
console.log(targetDeal);
}
注意していただきたい点は、取引の登録や更新、または個別取引の取得等の機能は、GAS x freeeAPIライブラリでは、dealsクラスではなくdealクラスを別に作成してクラスを分けています。
- 取引全体をガバっと取得するのが dealsクラス
- 個別取引の操作が dealクラス
というイメージです。
今回の指定したIDの取引を取得するgetDeal(deal_id)メソッドは、dealクラスのメンバーとなるメソッドです。
シリーズ目次
- GAS x freeeAPIライブラリのトリセツ「定期的に届くメールからfreeeの取引を作成しよう!」その1 – 対象メールの絞り込み
- GAS x freeeAPIライブラリのトリセツ「定期的に届くメールからfreeeの取引を作成しよう!」その2 – POST用の情報を抜粋する
- GAS x freeeAPIライブラリのトリセツ「定期的に届くメールからfreeeの取引を作成しよう!」その3 – 雛形オブジェクトをGETしよう
- GAS x freeeAPIライブラリのトリセツ「定期的に届くメールからfreeeの取引を作成しよう!」その4 – 雛形上書きしてPOSTしよう
Amazon欲しい物リスト公開しています。
開発者のモチベーションアップのためにAmazon欲しい物リストを公開しております。役に立ったよ!という方の感謝の気持ちで何かいただけるのであれば嬉しいです笑