LoginSignup
1
0

More than 1 year has passed since last update.

ISO-2022-JP(7bit JIS)のeml形式データをApps Scriptで解読する

Posted at

Google Driveにバックアップしておいたeml形式のメールデータをApps Scriptで読み込んでみました。文字コードがISO-2022-JP(7bit JIS)だったのですが、Apps ScriptのUtilitiesのおかげでいい感じに読めました。

ISO-2022-JPのeml形式データを読み込むには

生データにISO-2022-JPと書いてあったので、文字コードをJISに指定して読み込みます。

const driveUrl = 'https://drive.google.com/drive/folders/...';
const folderId = driveUrl.split('/')[5];
const childFolderName = 'backups'; // driveUrlの下にあるフォルダー名
const fileName = 'a.eml'; // フォルダーの下にあるファイル名 
const file = DriveApp.getFolderById(folderId).getFoldersByName(childFolderName).next().getFilesByName(fileName).next();
const eml = file.getBlob().getDataAsString('JIS');

これでメール本文は解読できたのですが、ヘッダーのSubject、From、Toなどにある日本語が読めません。

ISO-2022-JPのヘッダーを読み込むには

どれも=?ISO-2022-JP?B?と書いてあります。Bはbase64によるエンコードなので、

function decodeJis(encoded) {
  return encoded.replace(/=\?ISO-2022-JP\?B\?(.*?)\?=/ig, (a, b) => Utilities.newBlob(Utilities.base64Decode(b)).getDataAsString('JIS'));
}

という関数を作って解読しました。こんな風に使います。

function test() {
  const encoded = '=?ISO-2022-JP?B?GyRCJDMkcyRLJEEkTxsoQg==?==?ISO-2022-JP?B?GyRCJDMkcyRLJEEkTxsoQg==?=';
  const decoded = decodeJis(encoded);
  console.log(decoded);
  //こんにちはこんにちは
}

ヘッダーを解析するには

かなり力技ですが、ヘッダーを読み込んでオブジェクト形式に変換する関数も作ってみました。車輪の再発明は楽しいですね!

sepはセパレーターです。\nの場合と、\r\nの場合があります。

function parseHeaders(headers, sep='\n') {
  const set = (obj, line) => {
    const sep = ': ';
    const [key, ...values] = line.split(sep);
    const k = key.toLowerCase().replace(/-/g, '_');
    const value = values.join(sep);
    if (obj[k] && Array.isArray(obj[k])) {
      obj[k].push(value);
    } else if (obj[k]) {
      obj[k] = [obj[k], value];
    } else {
      obj[k] = value;
    }
  };
  let line = '';
  const ojb = headers.split(sep).reduce(prev, curr) => {
    if (curr.includes(': ')) {
      if (line) set(prev, line);
      line = decodeJis(curr);
      return prev;
    }
    line += decodeJis(curr);
    return prev;
  }, {});
  if (line) set(obj, line);
  return obj;
}

先ほどDriveから取得したemlからヘッダーを解析してみます。

const eml = ... // 上記
const sep = data.includes('\r\n') ? '\r\n' : '\n';
const [headersPart, ...body] = data.split(sep + sep); // 空行2つがヘッダーとボディーの切れ目
const headers = parseHeaders(headersPart, sep);
console.log(headers);
// { "subject": "...", "from": "...", "to": "...", ... }
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0