こんにちは、まえしまです。
GAS x マネーフォワードクラウドのAPIによる請求書作成の自動化について、この記事が最後になります。
前回の振り返りと今回やっていくこと
前回までで、請求書の作成ができました。
前回の記事を確認したい方はこちら
https://maeshiiii.com/posts/automated-billing-4
今回の記事では、この請求書作成処理を自動で定期的に実行する方法を見ていきます。毎月1日に前月の稼動時間を元に請求書を作成するようにしたいので、毎月1日に実行されるように設定していきましょう!
今回やっていくこと
今回の記事でやっていくことは、以下です。
- 毎月1日に請求書を作成する処理が実行されるように定期実行の設定を行う。
トリガーを追加する
決まったタイミングで定期実行をさせるには、GASのトリガー機能を利用します。
以下の手順でトリガーを設定しましょう。
- 画面左側の「トリガー」をクリックする。
- 画面右下にある「トリガーを追加」をクリックする。
- イベントのソースの選択で「時間主導型」を選択する。
- 時間ベースのトリガーのタイプの選択で「月ベースのタイマー」を選択する。
- 日を選択で「1日」を選択する。
- 時刻を選択は好きな時間帯で問題ありません。
- 最後に「保存」をクリックする。
これで毎月1日に自動で請求書が作成されるようになります。
ここまでお疲れ様でした!
これまでの全てのコード
請求書の作成までの全てのコードを最後に載せておきます。
最終的にこのようにコードが書けていればOKです。
function start() {
try {
auth_();
const lastMonth = getLastMonth_();
const billingId = createNewBilling_(lastMonth);
const items = getSpreadsheet_(lastMonth);
addBillingItems_(billingId, items); // 追加箇所
} catch (error) {
logError('請求書の自動作成にエラーが発生しました。:', error);
}
}
function auth_() {
try {
Logger.log(getService_().getAuthorizationUrl());
} catch (error) {
logError('Error in auth_ function', error);
throw error;
}
}
function getService_() {
try {
const PROPERTIES = getScriptProperties_();
return OAuth2.createService('moneyforward')
.setAuthorizationBaseUrl('https://api.biz.moneyforward.com/authorize')
.setTokenUrl('https://api.biz.moneyforward.com/token')
.setClientId(PROPERTIES.CLIENT_ID)
.setClientSecret(PROPERTIES.CLIENT_SECRET)
.setCallbackFunction('callback_')
.setPropertyStore(PropertiesService.getUserProperties())
.setScope('mfc/invoice/data.write');
} catch (error) {
logError('Error in getService_ function', error);
throw error;
}
}
function callback_(request) {
try {
return HtmlService.createHtmlOutput(getService_().handleCallback(request) ?
'認証OK!このタブを閉じてください。' : '認証NG!原因を調査してください。このタブを閉じてください。');
} catch (error) {
logError('Error in callback_ function', error);
}
}
function getScriptProperties_() {
const PROPERTIES = PropertiesService.getScriptProperties();
return {
CLIENT_ID: PROPERTIES.getProperty('CLIENT_ID'),
CLIENT_SECRET: PROPERTIES.getProperty('CLIENT_SECRET'),
DEPARTMENT_ID: PROPERTIES.getProperty('DEPARTMENT_ID'),
ITEM_ID_PRODUCTION: PROPERTIES.getProperty('ITEM_ID'), // 追加箇所
};
}
function getLastMonth_() {
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth();
const lastMonthDate = new Date(year, month - 1, 1);
const lastMonthYear = lastMonthDate.getFullYear();
const lastMonth = lastMonthDate.getMonth() + 1;
return `${lastMonthYear}年${lastMonth}月`;
}
function createNewBilling_(lastMonth) {
try {
const PROPERTIES = getScriptProperties_();
const url = 'https://invoice.moneyforward.com/api/v3/billings';
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: 'Bearer ' + getService_().getAccessToken()
},
payload: JSON.stringify({
department_id: PROPERTIES.DEPARTMENT_ID,
title: '業務委託 請求書(' + lastMonth + ')',
billing_date: Utilities.formatDate(new Date(), 'JST', 'yyyy-MM-dd'),
due_date: Utilities.formatDate((d => {
d.setMonth(d.getMonth() + 1);
d.setDate(0);
return d;
})(new Date()), 'JST', 'yyyy-MM-dd')
})
};
const response = UrlFetchApp.fetch(url, options);
const billingData = JSON.parse(response.getContentText());
Logger.log(billingData);
return billingData.id;
} catch (error) {
Logger.log('Error in createNewBilling_ function: ' + error.message);
throw error;
}
}
function getSpreadsheet_(lastMonth) {
const PROPERTIES = getScriptProperties_();
const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadSheet.getSheetByName(lastMonth);
const items = [
{
itemId: PROPERTIES.ITEM_ID,
quantity: sheet.getRange('B1').getValue().toFixed(2)
}
];
return items;
}
function addBillingItems_(billingId, items) {
try {
const url = 'https://invoice.moneyforward.com/api/v3/billings/' + billingId + '/items';
items.forEach(function(item) {
Logger.log(item);
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + getService_().getAccessToken()
},
payload: JSON.stringify({
item_id: item.itemId,
quantity: item.quantity
})
};
UrlFetchApp.fetch(url, options);
});
} catch (error) {
Logger.log('Error in addBillingItems_ function: ' + error.message);
throw error;
}
}
おわりに
フリーランスとして働いていると、日々業務が忙しくなってしまい、どうしても請求書発行などの事務タスクが疎かになってしまうこともあると思います。
今回の自動化によって、皆さんの事務タスクの負荷を減らすことができたら嬉しいです。
ここまで読んでいただき、ありがとうございました。