前回のおさらい
前々回と前回はslackとchatworkという2つのチャットツールに通知メッセージを投稿できるようにしました。
それぞれ、slackAPI、chatworkAPIを利用する関数をつくって、本体のプログラムから呼び出すようにしました。
sendSlack関数 ※slackにメッセージを投稿する関数
const sendSlack = chatMessage => {
const endpoint = 'https://slack.com/api/chat.postMessage'
const token = 'トークンが入ります'
const channel = 'チャンネルIDが入ります'
const text = chatMessage
const payload = {
token, channel, text
}
const options = {
method: 'POST',
payload,
}
const response = UrlFetchApp.fetch(endpoint, options)
console.log(response.getResponseCode())
}
sendChatwork関数 ※chatworkにメッセージを投稿する関数
const sendChatwork = chatMessage => {
// endpointの定義
const roomId = 'ルームIDが入ります'
const endpoint = `https://api.chatwork.com/v2/rooms/${roomId}/messages`
// APIトークン
const token = 'APIトークンが入ります'
// リクエストボディ
const message = chatMessage
// リクエストボディにはメッセージのみを格納
const payload = {
body: message,
}
// ヘッダーにトークンをセット
const headers = {
'x-chatworktoken': token,
}
// optionsにheaderとpayload(リクエストボディ)をセット
const options = {
headers, payload
}
const response = UrlFetchApp.fetch(endpoint, options)
console.log(response.getResponseCode())
}
今回は経理からの要望を受けまして、税抜請求額と税込請求額をスプレッドシートに転記します。
手作業ですと必ずいつかは忘れてしまいます。
そこでGASにやらせてしまおうといった魂胆でございます。
転記用のスプレッドシートを作成する
まずは転記用のスプレッドシートを作成します。
Googleドライブの任意のフォルダをひらきます。(ここでは請求書フォルダ)
右クリックでメニューをひらいてGoogleスプレッドシートを選択

すると無題のスプレッドシートがつくられます

スプレッドシートの名前を変更して、年月、税抜請求額、税込請求額と記入

シート名は「請求額」としておきます。

Googleドライブでこのようになっていればオッケー

これで準備完了です。
次にスプレッドシートに転記するための関数をつくって、請求月、税抜請求額、税込請求額をわたしましょう
転記するための関数をつくって請求月、税抜請求額、税込請求額をわたす
searchGmail関数はこんなふうになっています。
const searchGmail = () => {
const gmail = GmailApp
const searchedMail = gmail.search('from:株式会社 インボイス送信元 subject: 【請求書】送付のご案内 is:unread')
const messages = searchedMail.map(thread => {
return thread.getMessages()
})
const message = messages[0][0]
// 本文から税抜請求額と税込請求額を取得
const messageBody = message.getPlainBody()
const taxNotIncluded = messageBody.match(/税抜請求額.*$/m)[0]
const taxIncluded = messageBody.match(/税込請求額.*$/m)[0]
// 添付ファイルの取得とドライブへの保存
const attachments = message.getAttachments()
const drive = DriveApp
const folder = drive.getFolderById('フォルダIDが入ります')
const invoiceFile = folder.createFile(attachments[0])
// チャット通知用メッセージの材料を集める
const fromName = message.getFrom()
const companyName = fromName.match(/"([^"]*)"/)[1]
const invoiceUrl = invoiceFile.getDownloadUrl()
// PDFからOCRでテキストを取り出す
const document = Drive.Files.copy({ title: 'テスト' }, invoiceFile.getId(), { ocr: true })
const documentApp = DocumentApp
const documentFile = documentApp.openById(document.id)
const documentBody = documentFile.getBody()
const text = documentBody.getText()
const invoiceDate = text.match(/(\d{4}年\d{1,2}月分)/)[1]
invoiceFile.setName(`${invoiceDate} ${companyName} 請求書`)
// 通知用のメッセージをつくる ※位置を上から移動
const chatMessage = `${companyName}の${invoiceDate}請求書が届きました。\n${taxNotIncluded} ${taxIncluded}\n以下のURLからダウンロードしてください。\n${invoiceUrl}`
// 不要なGoogleドキュメントファイルを削除する
const removingFile = drive.getFileById(document.id)
removingFile.setTrashed(true)
sendChatwork(chatMessage)
sendSlack(chatMessage)
}
上のsearchGmail関数の中のtaxNotIncluded、taxIncluded、invoiceDateがそれぞれ税抜請求額、税込請求額、請求月にあたります。
せっかく取得したのでスプレッドシートに転記するための関数にわたします。
転記するための関数には請求月、税抜請求額、税込請求額を受け取れるように引数を3つ設定します。
const insertBillingAccount = (invoiceDate, taxNotIncluded, taxIncluded) => {
// 日付は「分」を削除、税抜請求額、税込請求額は数字のみ抜き出す
const date = invoiceDate.replace('分', '')
const taxNotIncludedInt = taxNotIncluded.replace('税抜請求額 ', '').replace('円', '')
const taxIncludedInt = taxIncluded.replace('税込請求額 ', '').replace('円', '')
console.log(date, taxNotIncludedInt, taxIncludedInt)
}
invoiceDateは「2024年3月分」となっていまして、「分」が余計なのでreplaceメソッドを使って削除します。
同様にtaxNotIncludedもtaxIncludedも数字の部分だけ抜き出したいのでreplaceメソッドを使います。
では、ためしに実行してみます。
実行結果

ちゃんとできていますね。
では、さっきつくったスプレッドシートの書き込むセルを指定します。
スプレッドシートの書き込むセルを指定
GASでスプレッドシートを扱うためにスプレッドシートアプリをつくります。
const spreadSheetApp = SpreadsheetApp
スプレッドシートアプリからスプレッドシートのオブジェクトをつくります。
const spreadSheet = spreadSheetApp.openById('スプレッドシートIDが入ります')
スプレッドシートIDは下の赤枠内の文字列です ※下の画像ではマスクしています

ちなみにオブジェクトってのはデータとメソッド(命令)がワンセットになった便利なやつです。
概念図

次にスプレッドシートオブジェクトからシートオブジェクトを作ります。
const sheet = spreadSheet.getSheetByName('請求額')
シート名を「請求額」としましたので、getSheetByNameメソッドにわたすのは’請求額’です。
さらに書き込む範囲(セル)を指定します。
年月は1列目、税抜請求額は2列目、税込請求額は3列目です。
で、それぞれの最初の空白行に書き込むようにすれば良いというわけです。
const row = sheet.getLastRow() + 1
const dateRange = sheet.getRange(row, 1) // 日付を記入するセルを指定
const notIncludedRange = sheet.getRange(row, 2) // 税抜請求額を記入するセルを指定
const includedRange = sheet.getRange(row, 3) // 税込請求額を記入するセルを指定
getLastRowメソッドはシート中のデータのある最終行を取得するのでこの場合は1を値として取得できます。(なぜなら1行目にしかデータがないので)
最終行の次の行が空白なので、+1をしているんですね。
const row = sheet.getLastRow() + 1
ここまででセルの指定が完了しました。
セルの指定方法は↓でもう少し詳しく説明しています。
セルに値を記入する
さて、つくったスプレッドシートに請求月、税抜請求額、税込請求額を書き込んでいきます。
dateRange.setValue(date)
notIncludedRange.setValue(taxNotIncludedInt)
includedRange.setValue(taxIncludedInt)
これで大丈夫じゃないかと思います。
スプレッドシートに転記するための関数はこうなっています。
const insertBillingAccount = (invoiceDate, taxNotIncluded, taxIncluded) => {
// 日付は「分」を削除、税抜請求額、税込請求額は数字のみ抜き出す
const date = invoiceDate.replace('分', '')
const taxNotIncludedInt = taxNotIncluded.replace('税抜請求額 ', '').replace('円', '')
const taxIncludedInt = taxIncluded.replace('税込請求額 ', '').replace('円', '')
console.log(date, taxNotIncludedInt, taxIncludedInt)
// 転記するセルを指定する
const spreadSheetApp = SpreadsheetApp
const spreadSheet = spreadSheetApp.openById('スプレッドシートIDが入ります')
const sheet = spreadSheet.getSheetByName('請求額')
const row = sheet.getLastRow() + 1
const dateRange = sheet.getRange(row, 1) // 日付を記入するセルを指定
const notIncludedRange = sheet.getRange(row, 2) // 税抜請求額を記入するセルを指定
const includedRange = sheet.getRange(row, 3) // 税込請求額を記入するセルを指定
// 日付を記入する
dateRange.setValue(date)
// 税抜請求額を記入する
notIncludedRange.setValue(taxNotIncludedInt)
// 税込請求額を記入する
includedRange.setValue(taxIncludedInt)
}
つくったinsertBillingAccount関数を、searchGmail関数から呼び出してあげます。
const searchGmail = () => {
// 中略
// 通知用のメッセージをつくる ※位置を上から移動
const chatMessage = `${companyName}の${invoiceDate}請求書が届きました。\n${taxNotIncluded} ${taxIncluded}\n以下のURLからダウンロードしてください。\n${invoiceUrl}`
// 不要なGoogleドキュメントファイルを削除する
const removingFile = drive.getFileById(document.id)
removingFile.setTrashed(true)
sendChatwork(chatMessage)
sendSlack(chatMessage)
// スプレッドシートに転記する
insertBillingAcount(invoiceDate, taxNotIncluded, taxIncluded)
}
実行結果

このようにスプレッドシートにデータが書き込まれてます。(slackとchatworkにもメッセージが投稿されました)
翌月以降は次の行に書き込まれていきますので、これで転記する必要はなくなります。
最後にもうひと仕上げ。
処理した請求書メールを既読にしておかないとメールの内容を読みにいってしまいます。
また、請求書メールが届いていなかったりするとプログラムがエラーで終了してしまいます。
次回はそれらを解決し、安心の自動化を実現します。
アンニョン
