Skip to content

Instantly share code, notes, and snippets.

@catdance124
Created June 11, 2023 02:52
Show Gist options
  • Save catdance124/b39a62dd056a5bdb882634d855379edb to your computer and use it in GitHub Desktop.
Save catdance124/b39a62dd056a5bdb882634d855379edb to your computer and use it in GitHub Desktop.
au PAY カード利用金額の管理
const LINE_ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty('LINE_ACCESS_TOKEN');
const LINE_GROUP_ID = PropertiesService.getScriptProperties().getProperty('LINE_GROUP_ID');
function postMessage(message){
const options = {
'method' : 'post',
'headers': {
"Content-Type": "application/json",
'Authorization': 'Bearer ' + LINE_ACCESS_TOKEN
},
'payload' : JSON.stringify({
"to": LINE_GROUP_ID,
"messages": [{
"type": "text",
"text": message,
}],
})
};
const response = UrlFetchApp.fetch('https://api.line.me/v2/bot/message/push', options);
Logger.log(response.getContentText());
}
// TODO:メールタイトルを追加
const SEARCH_QUERY = 'subject:(au PAY カード) subject:(ご利用速報 OR ) -label:starred '
const CREDIT_CARD_CLOSING_DAY = 15;
function main() {
// 未処理のスレッドを取得
const threads = GmailApp.search(SEARCH_QUERY);
threads.forEach(function(thread) {
// スレッド内メール一覧を取得
const messages = thread.getMessages();
messages.forEach(function(message) {
// 処理済みの場合はスキップ
if (message.isStarred()){
return;
}
const subject = message.getSubject();
let reportBody = '';
if (subject.match(/ご利用速報/)) {
reportBody = processCreditCardUsageReport(message);
message.star();
} else if (true) {
// TODO:処理を追加
return;
}
console.log(reportBody);
postMessage(reportBody);
// message.star();
});
});
}
// ################################################################################
// ## 【ご利用速報】 を処理する
// ################################################################################
function processCreditCardUsageReport(message){
// タイトル/本文取得
const subject = message.getSubject();
const plainBody = message.getPlainBody();
const title = subject.match(/【(.*)】/)[0];
const creditCardReport = extractCreditCardUsageReport(plainBody);
const summedAmount = outputCreditCardUsageReport(creditCardReport);
const reportBody = [
title,
'日時',
' ' + creditCardReport.date,
'内容',
' ' + creditCardReport.content,
'金額',
' ' + creditCardReport.amount,
'合計金額(推定)',
' ' + summedAmount,
].join("\n");
return reportBody;
}
function extractCreditCardUsageReport(body) {
let usageDate = "";
let usageContent = "";
let usageAmount = "";
const lines = body.split('\n');
for (let i = 0; i < lines.length; i++) {
if (lines[i].indexOf("▼ご利用日時") !== -1) {
usageDate = lines[i + 1].trim();
} else if (lines[i].indexOf("▼ご利用内容") !== -1) {
usageContent = lines[i + 1].trim();
} else if (lines[i].indexOf("▼ご利用金額") !== -1) {
usageAmount = lines[i + 1].trim();
}
}
return {
date: usageDate,
content: usageContent,
amount: usageAmount
};
}
function outputCreditCardUsageReport(creditCardReport) {
// 支払日を計算
let paymentDate = new Date(creditCardReport.date);
let creditCardClosingDate = new Date(creditCardReport.date);
creditCardClosingDate.setDate(CREDIT_CARD_CLOSING_DAY);
// 締め日を過ぎていれば支払いは翌翌月扱いとする
if (creditCardClosingDate < paymentDate){
paymentDate.setMonth(paymentDate.getMonth()+2);
} else {
paymentDate.setMonth(paymentDate.getMonth()+1);
}
const yyyy_MM = Utilities.formatDate(paymentDate, "JST", "yyyy/MM");
const sheet = setSheet(yyyy_MM);
const lastRow = sheet.getLastRow() + 1;
sheet.getRange(lastRow, 1).setValue(creditCardReport.date);
sheet.getRange(lastRow, 2).setValue(creditCardReport.content);
sheet.getRange(lastRow, 3).setValue(convertYenStrToNum(creditCardReport.amount));
const summedAmount = sheet.getRange("E1").getValue();
return formatNumberWithCommas(summedAmount) + "円";
}
function setSheet(name){
// ref: https://qiita.com/crawd4274/items/13120429cb3328e8ace2
//同じ名前のシートがなければ作成
let sheet = SpreadsheetApp.getActive().getSheetByName(name)
if(sheet)
return sheet
sheet=SpreadsheetApp.getActiveSpreadsheet().insertSheet();
sheet.setName(name);
sheet.getRange("A1:E1").setValues([[
"利用日時",
"利用内容",
"利用金額",
"合計金額(推定)",
"=SUM(C2:C1000)"
]]);
return sheet;
}
function convertYenStrToNum(yenStr) {
let yenNum = yenStr.match(/(\d{1,3}(,\d{3})*)円/)[1].replace(/,/g, "");
if (yenStr.indexOf("取消") !== -1) {
yenNum *= -1;
}
return yenNum
}
function formatNumberWithCommas(number) {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment