👔

仕事がないって言われたときにぃ、じゃあAI活動できるじゃない!

に公開

この春始めたことというタイトルでコンテストを募集していたので
Copilot版ではないGASオリジナル版ハロワ就活自動メール添付セットくんを思い出した。

GoogleドライブからGASデータ引っ張り出してきてClaude(Sonet4.6)に解析させたらバグまでみつけてくれた。(元データはGemini作成)

この中でハロワからメール申し込み可能な求人がある場合、ボタン一つで
履歴書・職務経歴書・英文レジュメ・その他・紹介状は手動で

本文も万人受けのものにすれば、サクッと申し込みができる。

そんな僕は、就活を諦める4月半ばまでこのツールで10通ほど送ってみたけど
わざわざ添付したり文章を考える必要がなかったから本当に楽だった。

どうせ就活は当たるも八卦外れるも八卦なので、ちょっと変わったやり方で数をこなしたいあなたはぜひこの機械化が遅れているハロワ関連の自動化ツールを使ってみてほしい。

概要
ハローワークの求人票PDF(フォームRAF)からOCRでメールアドレスを自動抽出し、履歴書等の添付ファイルとともにGmailの下書きを自動生成するGASスクリプト。
求人票を1枚Driveの指定フォルダに置いて実行するだけで、宛先・会社名の入力なしに応募下書きが完成する。

アーキテクチャ
Driveフォルダ(指定ID)
├── 求人票PDF(ファイル名に"RAF"含む)← OCR対象
├── 履歴書.pdf
├── 職務経歴書.pdf
└── 英文Resume.pdf
↓ GAS実行
[Drive OCR] → テキスト抽出 → 正規表現でメール&会社名取得

[GmailApp] → 全ファイル添付で下書き作成 → Gmailで確認・送信

完全コード
javascriptfunction createJobDraftWithAttachments() {
const folderId = 'YOUR_FOLDER_ID';

try {
const folder = DriveApp.getFolderById(folderId);
const files = folder.getFiles();
const attachments = [];

let targetPdfBlob = null;
let targetPdfName = "";

while (files.hasNext()) {
  const file = files.next();
  const mimeType = file.getMimeType();
  const fileName = file.getName();

  if (mimeType !== MimeType.GOOGLE_APPS_SCRIPT && 
      mimeType !== "application/vnd.google-apps.folder") {
    attachments.push(file.getBlob());
  }

  if (mimeType === MimeType.PDF && fileName.includes('RAF')) {
    targetPdfBlob = file.getBlob();
    targetPdfName = fileName;
  }
}

let extractedEmail = "";
let extractedCompany = "【取得失敗_事業者名】";

if (targetPdfBlob) {
  const resource = {
    name: targetPdfName + "_OCR_Temp",
    mimeType: MimeType.GOOGLE_DOCS
  };
  
  const docFile = Drive.Files.create(resource, targetPdfBlob, { ocrLanguage: 'ja' });
  const doc = DocumentApp.openById(docFile.id);
  const extractedText = doc.getBody().getText();

  const emailMatch = extractedText.match(
    /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/
  );
  if (emailMatch) extractedEmail = emailMatch[0];

  // ★後置き形式(○○株式会社)にも対応した修正版
  const companyMatch = extractedText.match(
    /(?:[^\r\n \s]{1,30})?(?:株式会社|有限会社|合同会社|一般社団法人|財団法人)(?:[^\r\n \s]{0,30})?/
  );
  if (companyMatch) extractedCompany = companyMatch[0].trim();

  DriveApp.getFileById(docFile.id).setTrashed(true);
}

// ★空メール防止ガード
if (!extractedEmail) {
  console.log("⚠️ メールアドレスが取得できませんでした。下書きを作成しません。");
  return;
}

const subject = '【鈴木雅斗】履歴書・職務経歴書 Eng Resumeの送付(氏名:鈴木雅斗)';
const body = `${extractedCompany}

人事担当者様

お世話になっております。

貴社の求人の件で、応募書類を送付させていただきます。
ご査収のほど、よろしくお願い申し上げます。

尚、法務系の経歴も添付してあるのと同時に、AIエンジニア等の経歴は下記GitHub参照願います。

github.com/masato7suzuki

どうかよろしくお願いいたします。

連絡先
鈴木 雅斗
TEL:070-2174-4330
m7@gmail.com


To Whom It May Concern,

I hope this message finds you well.
My name is Masato Suzuki.
Having reviewed your company's job listing, I am pleased to submit my application materials for your consideration.
I would appreciate your kind review of the enclosed documents.

Sincerely,
Masato Suzuki
TEL:
m7@gmail.com`;

if (attachments.length > 0) {
  GmailApp.createDraft(extractedEmail, subject, body, {
    attachments: attachments
  });
  
  console.log("-----------------------------------------");
  console.log("✅ 下書きの作成に成功しました!");
  console.log("宛先: " + extractedEmail);
  console.log("会社名: " + extractedCompany);
  console.log("https://mail.google.com/mail/u/0/#drafts");
  console.log("-----------------------------------------");
}

} catch (e) {
console.log("❌ エラー: " + e.toString());
}
}

回帰テスト結果
オリジナルコードに含まれていたバグをNode.jsで再現・検証した。
① メールアドレス抽出:6/6 PASS ✅
✅ 標準メール(tanaka@example.co.jp)
✅ 英数字ドメイン(info@company.com)
✅ スペース入り → マッチなし(OCRノイズ耐性あり)
✅ メールなし → null(ただし後述のガード未実装時は問題)
✅ URLのみ → null
✅ 日本語ドメイン混入 → null
メール抽出の正規表現自体は適切。問題は抽出失敗時のフォールバック処理の欠落にある。

② 会社名抽出:6/7 PASS / ★重大バグあり ❌
入力パターン元コード修正後株式会社ABC(前置き)✅ 正常✅ 正常ABC株式会社(後置き)❌ "株式会社" のみ抽出✅ "ABC株式会社"東京商事有限会社❌ "有限会社" のみ抽出✅ "東京商事有限会社"山田産業株式会社❌ "株式会社" のみ抽出✅ "山田産業株式会社"
ハローワーク求人票の企業名は後置き形式(○○株式会社)が多数派。元コードのままでは宛名が"株式会社"という不完全なメールが送信されるリスクがある。
元の正規表現(バグあり):
javascript// 前置き形式しか取れない
/(?:株式会社|有限会社|...)[^\r\n]*/
修正版:
javascript// 前後どちらの形式でも対応
/(?:[^\r\n \s]{1,30})?(?:株式会社|有限会社|合同会社|一般社団法人|財団法人)(?:[^\r\n \s]{0,30})?/

③ 空メール宛先バグ:要修正 ⚠️
元コードはメールが取得できなかった場合でもGmailApp.createDraft("", subject, body, ...)を実行する。
想定される失敗ケース(全4種):
・求人票がFAX・フォームのみで掲載(メールなし)
・OCRノイズによるメール誤認識(スペース混入等)
・URLのみ記載(Webフォーム採用)
・日本語ドメイン混入による抽出失敗

現状:宛先空欄の下書きが作成される
→ 手動確認なしで送信すると不達・エラー
修正は1行のアーリーリターンで解決:
javascriptif (!extractedEmail) {
console.log("⚠️ メールアドレスが取得できませんでした。処理を中断します。");
return;
}

セットアップ手順
事前準備

Google Driveに専用フォルダを作成し、フォルダIDをコピー
フォルダ内に以下を配置:

ハローワーク求人票PDF(ファイル名にRAFを含める)
履歴書・職務経歴書等の添付ファイル群

GAS設定

script.google.com で新規プロジェクト作成
コードをペースト、folderIdを自分のものに変更
Advanced Drive APIを有効化(必須):

左サイドバー「サービス」→「Drive API」を追加

権限付与して実行

必要なOAuthスコープ(自動付与)
json{
"oauthScopes": [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/gmail.compose"
]
}

既知の制限事項
制限内容Gmail添付上限25MB。複数PDFの合計サイズに注意OCR精度手書き・低解像度PDFは誤認識率が上がる会社名精度修正版正規表現でも長い社名(30文字超)はトランケートされるフォーム採用メールアドレスが存在しない求人には本ツールは使えない1実行1社バッチ処理(複数求人の一括処理)は未実装

まとめ

元コードで動作するが、後置き形式の会社名バグと空メール宛先バグの2点は本番運用前に修正すべきである。修正版コードは上記の通り、正規表現1行とアーリーリターン1行で対応できる。
Advanced Drive APIの有効化を忘れるとDrive is not definedエラーで即落ちする点も注意。

Discussion