@laco0416 です。前にDartでも同じような記事書いたけどJavaScriptでも同じことしようとしたら躓いた。
日本語メールをGmail APIで送るのに必要なステップ
日本語というかマルチバイトなUTF-8文字列をGmail APIで扱えるBase64文字列に変換する。
- 件名(Subject)をURL-UnsafeなBase64文字列にエンコードする
- メール全体を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);
}
フィードバックは送ったが、ドキュメントにバージョンを書くか、更新するかどっちか(できればどっちも)やってほしい。