見出し画像

AppleギフトカードをGASで管理しよう!



みなさん、こんにちは!前回の記事「Apple領収書を回収しよう!〜GASで自動化&ノーストレスな管理術〜」が好評で、とても嬉しかったです!ありがとうございます😊

本当は前回お伝えしていた「PDFの内容を文字起こしするシステム」について解説する予定だったのですが、少し設定が複雑で初心者の方にはハードルが高いかもしれないと思い、今回は別のテーマをお届けすることにしました。

タイミング的にも楽天マラソンが開催されている今、
AppleギフトカードをGASで効率的に管理する方法」を先に紹介します!

Appleギフトカードを楽天などで購入すると、ギフトコードが記載されたメールが届きますよね。これまでは、そのメールからコードをコピーしてスプレッドシートに貼り付けて管理していた方も多いのではないでしょうか。

そこで今回は、この作業の負担を減らすことできるシステムを作成しました!

自動化の流れは、たったこれだけ

  1. ギフトコードが記載された部分をスクリーンショットで保存

  2. 指定したGoogleドライブのフォルダにアップロード

簡単ですよね? あとはGAS(Google Apps Script)がコードと金額をスプレッドシートに自動で記載してくれます!

実際の記載された内容がこちら👇


準備するもの

このシステムを実行するには、以下の準備が必要です:

  1. Googleスプレッドシート:データを記録するためのスプレッドシートを1つ用意します。

  2. スクショ保存用フォルダ:ギフトカードのスクショを保存するフォルダです。

  3. 処理済みフォルダ:処理が完了したスクショを移動するためのフォルダです。

  4. 重複用フォルダ:重複したスクショを分けるためのフォルダです。

これらの準備ができたら、下のソフトに必要な情報を入力するだけで、あなただけの専用GASコードが生成されます。

そのコードをスプレッドシートに貼り付けるだけで、自動化が始まります!

⬇️ Difyアプリはこちら
GAS自動作成アプリ

動画で設定の解説してます。(音声なしです)

コードの例も載せておきます

function processAndTranscribeImages() {
  // フォルダとスプレッドシートの設定
  const SOURCE_FOLDER_ID = '1eSHeh49RBreAJ1110fBXUiZ1fK9VQMDJ'; 
  const PROCESSED_FOLDER_ID = '1DZxiMR2nNe111pxdmqvpIzuR1kfj7coX'; 
  const DUPLICATE_FOLDER_ID = '1pCkmjn5hJoODu5111Tk7NwAF4-LFlKLD'; 
  const SPREADSHEET_ID = '1lMajaSD2JU6EByfffB0Sg4111jTk8xsjyaLRdovIME'; 

  const sourceFolder = DriveApp.getFolderById(SOURCE_FOLDER_ID);
  const processedFolder = DriveApp.getFolderById(PROCESSED_FOLDER_ID);
  const duplicateFolder = DriveApp.getFolderById(DUPLICATE_FOLDER_ID);
  const ss = SpreadsheetApp.openById(SPREADSHEET_ID);
  const sheet = ss.getSheetByName('シート1');
  let duplicateSheet = ss.getSheetByName('重複ファイル');

  // メインシートヘッダー行を確認または作成
  if (sheet.getLastRow() === 0) {
    sheet.appendRow(['日付', 'コード', '金額', '元のファイル名', 'ファイルリンク', '変更後のファイル名', '作成日時']);
  }

  // 重複シートの確認または作成
  if (!duplicateSheet) {
    duplicateSheet = ss.insertSheet('重複ファイル');
    duplicateSheet.appendRow(['元のファイル名', 'ファイルリンク', '検出日時']);
  }

  // スプレッドシートから既存のコードと金額の組み合わせを取得
  const lastRow = sheet.getLastRow();
  let existingRecords = new Set();

  if (lastRow > 1) { // データが存在する場合のみ取得
    const existingData = sheet.getRange(2, 2, lastRow - 1, 2).getValues();
    existingRecords = new Set(existingData.map(row => row.join('-')));
  }

  const files = sourceFolder.getFiles();

  while (files.hasNext()) {
    const file = files.next();
    const originalFileName = file.getName();
    const fileLink = `https://drive.google.com/file/d/${file.getId()}/view?usp=sharing`;
    const mimeType = file.getMimeType();

    // 画像ファイル(JPEG、PNG)のみ処理
    if (mimeType === 'image/jpeg' || mimeType === 'image/png') {
      Logger.log('処理開始: ' + originalFileName);

      try {
        // Google Docsに変換してOCR
        const docFile = Drive.Files.insert({
          title: 'OCR_' + originalFileName,
          mimeType: 'application/vnd.google-apps.document'
        }, file.getBlob());

        // OCR処理の完了を待つ
        Utilities.sleep(3000);

        // テキストを取得
        const doc = DocumentApp.openById(docFile.id);
        const extractedText = doc.getBody().getText();

        // 日付、コード、金額を抽出
        const extractedDate = extractDateFromText(extractedText);
        const extractedCode = extractCodeFromText(extractedText);
        const extractedAmount = extractAmountFollowingGiftCard(extractedText);

        // 一時ドキュメントを削除
        Drive.Files.remove(docFile.id);

        // 抽出されたコードと金額が存在する場合
        if (extractedCode && extractedAmount) {
          // 重複チェック
          const recordKey = `${extractedCode}-${extractedAmount}`;

          if (existingRecords.has(recordKey)) {
            Logger.log(`重複ファイル: ${originalFileName}`);
            const now = new Date();
            const dateStr = Utilities.formatDate(now, Session.getScriptTimeZone(), 'yyyy/MM/dd HH:mm:ss');

            // 重複ファイルを記録
            duplicateSheet.appendRow([originalFileName, fileLink, dateStr]);

            // 重複フォルダに移動
            file.moveTo(duplicateFolder);
            continue;
          }

          // 変更後のファイル名を作成
          const newFileName = `${extractedCode}-${extractedAmount}`;
          file.setName(newFileName);

          // 作成日時を取得
          const now = new Date();
          const dateStr = Utilities.formatDate(now, Session.getScriptTimeZone(), 'yyyy/MM/dd HH:mm:ss');

          // スプレッドシートに記載
          sheet.appendRow([
            extractedDate || '',
            extractedCode,
            extractedAmount,
            originalFileName,
            fileLink,
            newFileName,
            dateStr
          ]);

          existingRecords.add(recordKey);
        }

        // 処理済みファイルを移動
        file.moveTo(processedFolder);

      } catch (error) {
        Logger.log('エラー発生: ' + error.toString());
        continue;
      }
    }
  }
}

// 日付抽出関数
function extractDateFromText(text) {
  const dateRegexes = [
    /(20\d{2})[\/\-\.](0[1-9]|1[0-2])[\/\-\.](0[1-9]|[12][0-9]|3[01])/, // yyyy/mm/dd
    /(令和)(\d{1,2})年(0[1-9]|1[0-2])月(0[1-9]|[12][0-9]|3[01])日/, // 令和形式
    /(0[1-9]|1[0-2])月(0[1-9]|[12][0-9]|3[01])日/ // mm月dd日
  ];

  for (let regex of dateRegexes) {
    const match = text.match(regex);
    if (match) {
      if (regex === dateRegexes[0]) { // yyyy/mm/dd
        return `${match[1]}/${match[2]}/${match[3]}`;
      } else if (regex === dateRegexes[1]) { // 令和形式
        const year = 2018 + parseInt(match[2]); // 令和元年は2019年
        return `${year}/${match[3]}/${match[4]}`;
      } else if (regex === dateRegexes[2]) { // mm月dd日
        const year = new Date().getFullYear(); // 年が指定されていない場合は現在の年を使用
        return `${year}/${match[1]}/${match[2]}`;
      }
    }
  }

  return ''; // 日付が見つからない場合
}

// コード抽出関数
function extractCodeFromText(text) {
  const codeRegex = /[A-Z0-9]{15,20}/g;
  const matches = text.match(codeRegex);

  if (matches && matches.length > 0) {
    return matches[0];
  }

  return '';
}

// 金額抽出関数
function extractAmountFollowingGiftCard(text) {
  const amountRegex = /金額\s*[::]?\s*([0-9]{1,3}(,?[0-9]{3})*(\.?\d{2})?)/;
  const match = text.match(amountRegex);

  if (match && match.length > 1) {
    return match[1].replace(/[¥¥,]/g, '');
  }

  return ''; // 金額が見つからない場合
}

GASの設定方法(重要ポイント)

コードをスプレッドシートに貼り付けた後、以下の設定を行ってください:

  1. GASエディター画面の左側にある「サービス」をクリック

  2. 「+ボタン」を押して、サービスを追加

  3. 上から8番目にある「ドライブAPI」を選択して追加

  4. ⚠️Ver.2を必ず選ぶ(Ver.3だとエラーが出ました)

これで準備完了です! あとはスクリプトを実行するだけで、指定したフォルダ内のスクショを読み取り、コードと金額をスプレッドシートに記載してくれます。

ちなみに、ファイル名は自動で「コード+金額」に命名変更する機能と、同じコードをフォルダに入れた場合は自動で重複フォルダとシートに移動する機能も付いています✌🏻


注意点

  • システムは100%正確ではなく、たまに日付を読み取れなかったりコードを間違える場合があります。

  • スプレッドシートにはスクショのリンクも記載されるので、目視で確認してください。


まとめ

これでAppleギフトカードのコード管理が一気にラクになります!無料で構築できるシステムですので、ぜひ試してみてください。

もし少しでも役に立ったら寄付していただけると嬉しいな😊 #GAS #GoogleAppsScript #自動化 #Apple #ギフトカード #楽天マラソン #楽天 #お買い物 #時短術 #生産性向上

ここから先は

19字

¥ 100

PayPay
PayPayで支払うと抽選でお得

この記事が気に入ったらチップで応援してみませんか?