LoginSignup
19

More than 5 years have passed since last update.

JavaScriptのGmail APIでメール送信する時のBase64エンコード

Last updated at Posted at 2015-09-20

@laco0416 です。前にDartでも同じような記事書いたけどJavaScriptでも同じことしようとしたら躓いた。

日本語メールをGmail APIで送るのに必要なステップ

日本語というかマルチバイトなUTF-8文字列をGmail APIで扱えるBase64文字列に変換する。

  1. 件名(Subject)をURL-UnsafeなBase64文字列にエンコードする
  2. メール全体をURL-SafeなBase64文字列にエンコードする

Subjectに個別のエンコードが必要な理由は最初に触れたDartの方の記事で書いてるので気になる方は参照してほしい。

URL-UnsafeなBase64文字列

普通にJavaScriptでBase64に変換するとこっちになる。

日本語を含まない場合は

window.btoa(str);

でいいが、日本語が入る場合は

window.btoa(unescape(encodeURIComponent(str)));

で、非ASCII文字をエンコードした後にBase64化する必要がある

URL-SafeなBase64文字列

通常のBase64には+/が使われているが、URL-SafeなBase64ではこれらを変換する必要がある。Dartでは関数のオプションで指定できたが、JavaScriptでは専用の関数が用意されていないので自力でやる必要がある。上記のURL-UnsafeなBase64を作った後に、次の置換を入れる

str.replace(/\+/g, '-').replace(/\//g, '_');

適当なサンプル

メールの組み立てはこんな感じになる

var mail = [
        "To: $to",
        "Subject: =?utf-8?B?$subject?=",
        "MIME-Version: 1.0",
        "Content-Type: text/plain; charset=UTF-8",
        "Content-Transfer-Encoding: 7bit",
        "",
        "$body"
      ].join("\n").trim();
mail = mail
  .replace("$to", this.to)
  .replace("$subject", window.btoa(unescape(encodeURIComponent(this.subject))))
  .replace("$body", this.body);
var encoded = window.btoa(unescape(encodeURIComponent(mail)))
  .replace(/\+/g, '-').replace(/\//g, '_');
sendMail(encoded); 

Gmail APIのドキュメントが間違ってる

ところで、Gmail APIのドキュメントではmessages.sendのサンプルコードは次のようになっている

ドキュメントのサンプルコード
function sendMessage(userId, email, callback) {
  var base64EncodedEmail = btoa(email);
  var request = gapi.client.gmail.users.messages.send({
    'userId': userId,
    'message': {
      'raw': base64EncodedEmail
    }
  });
  request.execute(callback);
}

が、これはバージョンが古く、現在はmessageではなくresourceプロパティにメールの文字列を渡すようになっている。

今動くやつ
function sendMessage(userId, email, callback) {
  var base64EncodedEmail = btoa(email);
  var request = gapi.client.gmail.users.messages.send({
    'userId': userId,
    'resource': {
      'raw': base64EncodedEmail
    }
  });
  request.execute(callback);
}

フィードバックは送ったが、ドキュメントにバージョンを書くか、更新するかどっちか(できればどっちも)やってほしい。

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
19