動画で学ぶ freee会計 API × Google Apps Script 連携

このページでは、初学者向けに、freee会計APIと「 Google Apps Script」を連携して、Google スプレッドシートにデータを出力するまでを動画を使いながら学びます。

※本動画およびサンプルコードは、自習のためのサンプル動画・コードとなり、サポート対象外となります。動画・コードに対するご質問へのご回答・サポートは行なっておりませんので、ご了承ください。

再生リスト

準備するもの

Googleスプレッドシートを使うためのGoogleアカウントをご準備ください。

1. Googleスプレッドシートの動作確認

この動画では、freee会計 API と連携するための Googleスプレッドシートを準備し、Google Apps Scriptが動作するかどうかを確認します。

この動画内で利用しているコードは以下です。

freeeを試すコード.gs

function myFunction() {
  Logger.log("今からメッセージを出力します");
  Browser.msgBox("I’m freee");
  Logger.log("メッセージを出力しました");
  const Sheet = SpreadsheetApp.getActiveSheet();
  Sheet.getRange(1,2).setValue("ここに値を表示");
}

2. Google OAuth 2.0 クライアントIDの登録

この動画では、freee会計 API の操作に必要な認可手順「OAuth 2.0」を使えるようにするための設定を行います。

動画内に表示される「OAuth2ライブラリ」のスクリプトIDは以下となります。

1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF

コールバックURIの文字列は以下となります。

https://script.google.com/macros/d/{SCRIPT ID}/usercallback

URI中の {SCRIPT ID}は、Sclipt IDは、Googe Apps Scriptのエディタ画面で確認できます。スプレッドシート上部のメニューから [ツール]→[スクリプトエディタ]からエディタ画面を開き、左メニューから[プロジェクトの設定]→[ID]→[スクリプトID]の順に確認してください。

3. Google スプレッドシートの動作確認

この動画では、Google スプレッドシートとfreee会計APIを連携し、事業所のIDを取得するまでを行います。

この動画内で利用しているコードは以下です。

freee_GoogleAppsScript3.gs

const Client_ID = '「Client ID」';
const Client_Secret = '「Client Secret」';

function alertAuth() {
  var service = getService();
  var authorizationUrl = service.getAuthorizationUrl();
  Logger.log(authorizationUrl);
}
function getService() {
  return OAuth2.createService('freee')
  .setAuthorizationBaseUrl('https://accounts.secure.freee.co.jp/public_api/authorize')
  .setTokenUrl('https://accounts.secure.freee.co.jp/public_api/token')
  .setClientId(Client_ID)
  .setClientSecret(Client_Secret)
  .setCallbackFunction('authCallback')
  .setPropertyStore(PropertiesService.getUserProperties())
}
function authCallback(request) {
  var service = getService();
  var isAuthorized = service.handleCallback(request);
  if (isAuthorized){
    return HtmlService.createHtmlOutput('認証が成功したのでタブを閉じてください');
  } else {
    return HtmlService.createHtmlOutput('認証に失敗しています');
  }
}
function getJigyousho() {
  const accessToken = getService().getAccessToken();
  const requestUrl = 'https://api.freee.co.jp/api/1/companies';
  const params = {
    method: 'get',
    headers:{'Authorization':'Bearer ' + accessToken}
  };
  const response = UrlFetchApp.fetch(requestUrl, params);
  Logger.log(response);
  const Sheets = SpreadsheetApp.getActiveSheet();
  Sheets.getRange(1,2).setValue(JSON.parse(response).companies[0].id);
}

4. 取引先の取得

この動画では、取引先データを取得するまでを行います。

この動画内で利用しているコードは以下です。

freee_GoogleAppsScript4.gs

const Client_ID2 = '「Client ID」';
const Client_Secret2 = '「Client Secret」';

//認証のエンドポイント
function alertAuth2() {
  const service = getService2();
  const authorizationUrl = service.getAuthorizationUrl();
  Logger.log(authorizationUrl);//認証用URLがログ出力される
}
 
//freeeAPIのサービスを取得
function getService2() {
  return OAuth2.createService('freee')
  .setAuthorizationBaseUrl('https://accounts.secure.freee.co.jp/public_api/authorize')
  .setTokenUrl('https://accounts.secure.freee.co.jp/public_api/token')
  .setClientId(Client_ID2)
  .setClientSecret(Client_Secret2)
  .setCallbackFunction('authCallback')
  .setPropertyStore(PropertiesService.getUserProperties())
}
 
 
//認証コールバック関数
function authCallback(request) {
  const service = getService2();
  const isAuthorized = service.handleCallback(request);
  if (isAuthorized) {
    return HtmlService.createHtmlOutput('認証に成功しました。タブを閉じてください。');
  } else {
    return HtmlService.createHtmlOutput('認証に失敗しました。');
  }
}

//取引先を取得
function getTorihikisaki() {
    const Sheets = SpreadsheetApp.getActiveSheet();
    const accessToken = getService2().getAccessToken();
    const requestUrl = 'https://api.freee.co.jp/api/1/partners?company_id=' + Sheets.getRange(1,2).getValue();

    const params = {
      method: 'get',
      headers:{'Authorization':'Bearer ' + accessToken}
    };

    const response = UrlFetchApp.fetch(requestUrl, params);

    Logger.log(response);
    for(let i = 0; i < JSON.parse(response).partners.length; i++) {
      Sheets.getRange(i + 5,2).setValue(JSON.parse(response).partners[i].id);
      Sheets.getRange(i + 5,3).setValue(JSON.parse(response).partners[i].name);
    }
  }

  //取引先の詳細を取得
  function getTorihikisakiDetail() {
    const Sheets = SpreadsheetApp.getActiveSheet();
    const accessToken = getService2().getAccessToken();
    const requestUrl = 'https://api.freee.co.jp/api/1/partners/' + Sheets.getRange(5,2).getValue() + '?company_id=' + Sheets.getRange(1,2).getValue();

    const params = {
      method: 'get',
      headers:{'Authorization':'Bearer ' + accessToken}
    };

    const response = UrlFetchApp.fetch(requestUrl, params);

    Logger.log(response);
    Logger.log(JSON.parse(response).partner.id.name);
    if (JSON.parse(response).partner.name) {
      Sheets.getRange(5,4).setValue(JSON.parse(response).partner.long_name);
      Sheets.getRange(5,5).setValue(JSON.parse(response).partner.name_kana);
      Sheets.getRange(5,6).setValue(JSON.parse(response).partner.address_attributes.street_name1);
      Sheets.getRange(5,7).setValue(JSON.parse(response).partner.email);
      Sheets.getRange(5,8).setValue(JSON.parse(response).partner.phone);
    }
  }

5. 取引先の追加

この動画では、取引先データをfreee会計に追加するまでを行います。

この動画内で利用しているコードは以下です。

freee_GoogleAppsScript5.gs

const Client_ID3 = '「Client ID」';
const Client_Secret3 = '「Client Secret」';

//認証のエンドポイント
function alertAuth3() {
  const service = getService3();
  const authorizationUrl = service.getAuthorizationUrl();
  Logger.log(authorizationUrl);//認証用URLがログ出力される
}
 
//freeeAPIのサービスを取得
function getService3() {
  return OAuth2.createService('freee')
  .setAuthorizationBaseUrl('https://accounts.secure.freee.co.jp/public_api/authorize')
  .setTokenUrl('https://accounts.secure.freee.co.jp/public_api/token')
  .setClientId(Client_ID3)
  .setClientSecret(Client_Secret3)
  .setCallbackFunction('authCallback')
  .setPropertyStore(PropertiesService.getUserProperties())
}
 
 
//認証コールバック関数
function authCallback(request) {
  var service = getService3();
  var isAuthorized = service.handleCallback(request);
  if (isAuthorized) {
    return HtmlService.createHtmlOutput('認証に成功しました。タブを閉じてください。');
  } else {
    return HtmlService.createHtmlOutput('認証に失敗しました。');
  }
}

//取引先を追加
function postTorihikisaki() {
    const Sheets = SpreadsheetApp.getActiveSheet();
    const accessToken = getService3().getAccessToken();
    const requestUrl = 'https://api.freee.co.jp/api/1/partners';

    const body = {
      'company_id': parseInt(Sheets.getRange(1,2).getValue(), 10),
      'name': Sheets.getRange(3,3).getValue(),
      'long_name': Sheets.getRange(3,4).getValue(),
      'name_kana': Sheets.getRange(3,5).getValue(),
      'address_attributes': {
        'street_name1': Sheets.getRange(3,6).getValue()
      },
      'email': Sheets.getRange(3,7).getValue(),
      'phone': Sheets.getRange(3,8).getValue()
    };
    const params = {
      method: 'post',
      headers: {
        'Authorization':'Bearer ' + accessToken,
      },
      'contentType': 'application/json',
      payload: JSON.stringify(body)
    };

    const response = UrlFetchApp.fetch(requestUrl, params);

    Logger.log(response);
  }

6. 取引先情報の編集

この動画では、freee会計の取引先情報の編集を行います。

この動画内で利用しているコードは以下です。

freee_GoogleAppsScript6.gs

  const Client_ID4 = '「Client ID」';
  const Client_Secret4 = '「Client Secret」';

  //「認証のエンドポイント」関数を貼り付け
  function showAuth4() {
    const service = getService4();
    const authorizationUrl = service.getAuthorizationUrl();
    Logger.log(authorizationUrl);
  }

  //freeeAPIのサービスを取得
  function getService4() {
    return OAuth2.createService('freee')
    .setAuthorizationBaseUrl('https://accounts.secure.freee.co.jp/public_api/authorize')
    .setTokenUrl('https://accounts.secure.freee.co.jp/public_api/token')
    .setClientId(Client_ID4)
    .setClientSecret(Client_Secret4)
    .setCallbackFunction('authCallback')
    .setPropertyStore(PropertiesService.getUserProperties())
  }

  //認証コールバック関数
  function authCallback(request) {
    const service = getService4();
    const isAuthorized = service.handleCallback(request);
    if (isAuthorized){
      return HtmlService.createHtmlOutput('認証が成功したのでタブを閉じてください');
    } else {
      return HtmlService.createHtmlOutput('認証に失敗しています');
    }
  }

  //取引先を取得
  function getTorihikisaki2() {
    const Sheets = SpreadsheetApp.getActiveSheet();
    const accessToken = getService4().getAccessToken();
    const requestUrl = 'https://api.freee.co.jp/api/1/partners?company_id=' + Sheets.getRange(1,2).getValue();

    const params = {
      method: 'get',
      headers:{'Authorization':'Bearer ' + accessToken}
    };

    const response = UrlFetchApp.fetch(requestUrl, params);

    // Logger.log(response);
    for(let i = 0; i < JSON.parse(response).partners.length; i++) {
      Sheets.getRange(i + 5,2).setValue(JSON.parse(response).partners[i].id);
      Sheets.getRange(i + 5,3).setValue(JSON.parse(response).partners[i].name);
    }
  }

  //取引先の詳細を取得
  function getTorihikisakiDetail2() {
    const Sheets = SpreadsheetApp.getActiveSheet();
    const accessToken = getService4().getAccessToken();
    const requestUrl = 'https://api.freee.co.jp/api/1/partners/' + Sheets.getRange(5,2).getValue() + '?company_id=' + Sheets.getRange(1,2).getValue();

    const params = {
      method: 'get',
      headers:{'Authorization':'Bearer ' + accessToken}
    };

    const response = UrlFetchApp.fetch(requestUrl, params);

    Logger.log(response);
    Logger.log(JSON.parse(response).partner.id.name);
    if (JSON.parse(response).partner.name) {
      Sheets.getRange(5,4).setValue(JSON.parse(response).partner.long_name);
      Sheets.getRange(5,5).setValue(JSON.parse(response).partner.name_kana);
      Sheets.getRange(5,6).setValue(JSON.parse(response).partner.address_attributes.street_name1);
      Sheets.getRange(5,7).setValue(JSON.parse(response).partner.email);
      Sheets.getRange(5,8).setValue(JSON.parse(response).partner.phone);
    }
  }
  
  //取引先の編集&更新
  function putTorihikisaki() {
    const Sheets = SpreadsheetApp.getActiveSheet();
    const accessToken = getService4().getAccessToken();
    const requestUrl = 'https://api.freee.co.jp/api/1/partners/' + Sheets.getRange(5,2).getValue();

    const body = {
      'company_id': parseInt(Sheets.getRange(1,2).getValue(), 10),
      'name': Sheets.getRange(5,3).getValue(),
      'long_name': Sheets.getRange(5,4).getValue(),
      'name_kana': Sheets.getRange(5,5).getValue(),
      'address_attributes': {
        'street_name1': Sheets.getRange(5,6).getValue()
      },
      'email': Sheets.getRange(5,7).getValue(),
      'phone': Sheets.getRange(5,8).getValue()
    };
    const params = {
      method: 'put',
      headers: {
        'Authorization':'Bearer ' + accessToken,
      },
      'contentType': 'application/json',
      payload: JSON.stringify(body)
    };

    const response = UrlFetchApp.fetch(requestUrl, params);

    Logger.log(response);
  }

7. 税区分、勘定科目の取得

この動画では、freee会計から税区分と勘定科目を取得しています。

この動画内で利用している動画は以下です。

freee_GoogleAppsScript7.gs

const Client_ID5 = '[Client_ID]';
const Client_Secret5 = '[Client_Secret]';

//認証のエンドポイント
function showAuth5() {
  const service = getService5();
  const authorizationUrl = service.getAuthorizationUrl();
  Logger.log(authorizationUrl);//認証用URLがログ出力される
}
 
 //freeeAPIのサービスを取得
function getService5() {
  return OAuth2.createService('freee')
  .setAuthorizationBaseUrl('https://accounts.secure.freee.co.jp/public_api/authorize')
  .setTokenUrl('https://accounts.secure.freee.co.jp/public_api/token')
  .setClientId(Client_ID5)
  .setClientSecret(Client_Secret5)
  .setCallbackFunction('authCallback')
  .setPropertyStore(PropertiesService.getUserProperties())
}

//認証コールバック関数
function authCallback(request) {
  const service = getService5();
  const isAuthorized = service.handleCallback(request);
  if (isAuthorized) {
    return HtmlService.createHtmlOutput('認証に成功しました。タブを閉じてください。');
  } else {
    return HtmlService.createHtmlOutput('認証に失敗しました。');
  }
}

//税区分を取得
function getZeikubun() {
    const Sheets = SpreadsheetApp.getActiveSheet();
    const accessToken = getService2().getAccessToken();
    const requestUrl = 'https://api.freee.co.jp/api/1/taxes/codes?company_id=' + Sheets.getRange(1,2).getValue();

    const params = {
      method: 'get',
      headers:{'Authorization':'Bearer ' + accessToken}
    };

    const response = UrlFetchApp.fetch(requestUrl, params);

    Logger.log(response);
    for(let i = 0; i < JSON.parse(response).taxes.length; i++) {
      Sheets.getRange(i + 3,2).setValue(JSON.parse(response).taxes[i].code);
      Sheets.getRange(i + 3,3).setValue(JSON.parse(response).taxes[i].name);
      Sheets.getRange(i + 3,4).setValue(JSON.parse(response).taxes[i].name_ja);
    }
  }

  //勘定科目を取得
function getKanjoukamoku() {
    const Sheets = SpreadsheetApp.getActiveSheet();
    const accessToken = getService2().getAccessToken();
    const requestUrl = 'https://api.freee.co.jp/api/1/account_items/?company_id=' + Sheets.getRange(1,2).getValue();

    const params = {
      method: 'get',
      headers:{'Authorization':'Bearer ' + accessToken}
    };

    const response = UrlFetchApp.fetch(requestUrl, params);

    Logger.log(response);
    for(let i = 0; i < JSON.parse(response).account_items.length; i++) {
      Sheets.getRange(i + 3,5).setValue(JSON.parse(response).account_items[i].id);
      Sheets.getRange(i + 3,6).setValue(JSON.parse(response).account_items[i].name);
      Sheets.getRange(i + 3,7).setValue(JSON.parse(response).account_items[i].shortcut);
    }
  }

   //勘定科目の詳細を取得
  function getKanjoukamokuDetail() {
    const Sheets = SpreadsheetApp.getActiveSheet();
    const accessToken = getService2().getAccessToken();
    const requestUrl = 'https://api.freee.co.jp/api/1/account_items/' + '?company_id=' + Sheets.getRange(1,2).getValue();

    const params = {
      method: 'get',
      headers:{'Authorization':'Bearer ' + accessToken}
    };

    const response = UrlFetchApp.fetch(requestUrl, params);
    Logger.log(response);
    for(let i = 0; i < JSON.parse(response).account_items.length; i++) {
      Sheets.getRange(i + 3,8).setValue(JSON.parse(response).account_items[i].account_category);
      Sheets.getRange(i + 3,9).setValue(JSON.parse(response).account_items[i].corresponding_income_name);
    }
  }