✉️

GASで請求書更新リマインドからメール送信まで自動化させる方法

2023/05/31に公開

概要

毎月月末に請求書を出している方へ。
毎月毎月請求書作成して、PDFにして、メール添付して、、、と面倒だなと感じていませんか?
また、「あっ月末だったの忘れてた!」とかで月初に「すみません…」みたいな文入れて遅れて出すことないですか?
そんなあなたへ朗報です。
この記事では
・毎月の月初に請求書更新の予定を月末前日にGoogleカレンダーへ自動で入れてくれる
・月末になると請求書をPDFにして、請求書先のメールアドレスに自動で添付して送ってくれる
処理をGoogle App Scriptで作る方法を紹介します。
請求書フォーマットからコードまでコピペで作成できるので是非利用してください。

環境

・Googleアカウント
・請求書:スプレッドシート

請求書フォーマット作成

特に指定はないですが、独自のものを使用されてる場合はコードも読み替えて作成してください。
一応この記事では以下のフォーマットをベースに紹介していきたいと思います。
https://docs.google.com/spreadsheets/d/1tURBc4vRoN_95C4s1rXqgKuofUJkjG_jmPnTGoRgsi8/edit?usp=sharing

開きましたらファイルよりコピーを作成を選択して自分のドライブ環境にコピーするなりして編集できるようにしてください。
編集できるようになりましたら名前や住所をよしなに修正してください。
フォーマット作成は以上です。

Googleカレンダーに自動で予定を入れる

続いてGoogle App ScriptにてGoogleカレンダーに予定を入れる処理を書いていきます。
拡張機能のAppScriptを選択することでエディタが立ち上がります。

デフォルトでは以下のコードが生成されています。

function myFunction() {
  
}

myFunctionを以下に書き換えます。

function setReminder() {
  // 今月の最後の日を取得
  var lastDay = new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0);
  
  // 最後の日から1日前の日付を取得
  var reminderDate = new Date(lastDay.getFullYear(), lastDay.getMonth(), lastDay.getDate() - 1);
  
  // リマインダーを設定する日時を設定
  var reminderTime = new Date(reminderDate.getFullYear(), reminderDate.getMonth(), reminderDate.getDate(), 9, 0, 0); // 9:00AMに設定
  
  // リマインダーのタイトルを設定
  var reminderTitle = "リマインダー: 今月の終わりが近づいています。請求書を更新してください。";
  
  // カレンダーから請求書のスプレッドシートへ飛べるように設定
  var options = {
    description: "ここにスプレッドシートのURLを貼り付けてください"
  };
  
  // リマインダーを作成
  var reminder = CalendarApp.getDefaultCalendar().createEvent(reminderTitle, reminderTime, reminderTime, options);
  
  Logger.log("リマインダーが設定されました。");
};

以上です。
ここまで出来たら一旦デバッグして確認をしてみましょう。
デバッグはエディタの上部にあります。

初めてデバックする場合は承認などのポップアップが出るかもしれませんが、許可してください。
※Scriptは保存していないとデバッグできないので以下の状態の方はまずプロジェクト名を適当に入力して保存してください。

成功するとコンソールに実行完了が出力され、カレンダーにて確認する事ができます。

これで請求書フォーマットを更新する予定をカレンダーに追加する処理は書けたのでこのsetReminderを自動で叩くように設定します。

設定はサイドメニューにあるトリガーを使用します。

右下にトリガー追加ボタンがあるのでそこからトリガーの設定を行います。

設定はキャプチャ通りに設定すると毎月1日になると自動でカレンダーにsetReminderを叩いて、月末前日に請求書フォーマットを更新する予定を追加してくれます。

請求書をPDFで発行し、メールに添付して送る

setReminderの下にgeneratePDFを追加します。
各処理はコメントに記載しているのでそちらを見てください。
コードは以下コピペで使用できますがメールアドレスが入っている場合は生成したPDFを添付して送る処理も含まれていますのでメール文はよしなに修正してください。

function generatePDF() {
    // アクティブなシートを取得
  var sheet = SpreadsheetApp.getActiveSheet();

  // 今日の日付を取得
  var today = new Date();
  
  // 来月の最終日を取得
  var nextMonthEnd = new Date(today.getFullYear(), today.getMonth() + 2, 0);
  
  // 日付フォーマットを定義
  var format = Utilities.formatDate;
  var timezone = Session.getScriptTimeZone();
  
  // 日付をフォーマットに合わせて変換
  var formattedToday = format(today, timezone, 'yyyy/MM/dd');
  var formattedNextMonthEnd = format(nextMonthEnd, timezone, 'yyyy/MM/dd');

  // 指定したセルに日付をセット
  sheet.getRange('E11').setValue(formattedToday);
  sheet.getRange('E12').setValue(formattedNextMonthEnd);


  // H3以降の行に何かしらの値が入っているかチェック
  var data = sheet.getRange("H3:H").getValues();
  var lastRow = data.filter(String).length;
  if (lastRow < 1) {
    return;
  }
 
 for(let i = 1; i <= lastRow; i++) {
  var setRange = i + 2;
  Logger.log(setRange);
    // B9:C9にH3の値を代入
  var company = sheet.getRange(setRange, 8).getValue();
  Logger.log(company);
  sheet.getRange(9, 2).setValue(company);
  Logger.log(sheet.getRange(9, 2).getValue());
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheetName = '雛型';
  const ssId = ss.getId();
  const sheetId = ss.getSheetByName(sheetName).getSheetId();
  // スプレッドシートをPDF出力するためのURL
  const url = 'https://docs.google.com/spreadsheets/d/' + ssId + '/export?'

  // PDF出力のオプションを設定
  const options = 'exportFormat=pdf&format=pdf'
  + '&gid=' + sheetId  //PDFにするシートの「シートID」
  + '&portrait=true'  //true(縦) or false(横)
  + '&size=A4'         //印刷サイズ
  + '&fitw=true'       //true(幅を用紙に合わせる) or false(原寸大)
  + '&gridlines=false' //グリッドラインの表示有無
  + '&range=A1%3AF43'   //★POINT★セル範囲を指定
  // %3A はコロン(:)を表す

  const requestUrl = url + options;
  
  //API使用のためのOAuth認証
  const token = ScriptApp.getOAuthToken();
  
  const params = {
    'headers' : {'Authorization':'Bearer ' + token},
    'muteHttpExceptions' : true
  };
  
  const response = UrlFetchApp.fetch(requestUrl, params);
  
  //Blobオブジェクトを作成
  var fileName = "請求書" + formattedToday + company + "御中";
  const blob = response.getBlob();
  blob.setName(fileName + '.pdf'); //PDFファイル名を設定
  
  //このスプレッドシートが存在するフォルダにPDFファイルを作成
  const parentFolders = DriveApp.getFileById(ss.getId()).getParents();
  const folderId = parentFolders.next().getId();
  const folder = DriveApp.getFolderById(folderId);
  folder.createFile(blob);
  
  // メールアドレスが入っている場合、PDFを添付してメール送信
  var email = sheet.getRange(setRange, 13).getValue();
  if (email) {
    var subject = "請求書";
    var body = 
    `${company} 御中
    お世話になります。
    今月分の請求書を送らせていただきます。

    ------------------------------
    ここに署名書く
    名前
    Tel: 
    Mail: 
    ------------------------------
    `;
    MailApp.sendEmail(email, subject, body, {attachments: [blob]});
  }
 }
};

これでPDF生成及び、メールアドレスがスプレッドシートの連絡先列に入力されていたら自動的にメールが生成されて、PDFを添付して送ってくれます。
保存して実行するとこんな感じで送られてくることが確認できます。

最後にこちらもトリガーを追加して月末に実行するにセットすれば
・毎月の月初に請求書更新の予定を月末前日にGoogleカレンダーへ自動で入れてくれる
・月末になると請求書をPDFにして、請求書先のメールアドレスに自動で添付して送ってくれる
ことを自動で行ってくれます。

まとめ

これで月末前日にカレンダーからスプレッドシートを立ち上げて、時間や金額などの一覧を修正するだけで自動的に各請求先に請求書を送ってくれるので今まで手作業でしていた方はすごく楽になると思います!
もっと他にいい方法があれば是非教えてください!

追伸

あくまでサンプルコードなので一企業に対して一内容しか反映できなかったりしますが、そこはよしなに修正していただければと思います!
もちろん自分で修正できないけど請求書発行自動化したい!という方はTwitterのDMよりお仕事依頼としてご連絡ください!

Discussion