Help us understand the problem. What is going on with this article?

Go言語 Gmailのsubjectの日本語文字化けに対応する

More than 3 years have passed since last update.

はじめに

GoでGmail APIを触っていた際に、「本文」は正しく日本語が表示されるのに「件名(subject)」が文字化けする事象に遭遇しました。

Gmail APIには、base64urlにエンコードしたstringを渡します。
下記のようなコードだと、件名の部分で 文字化け が発生します。

package main

import (
    "encoding/base64"
    ...
    "google.golang.org/api/gmail/v1"
)

func main() {
    ...
    msgStr := "to: hoge@gmail.com\n" + "subject: 件名\n\n" + "message: 本文"
    msg := []byte(msgStr)
    message := gmail.Message{}
    message.Raw = base64.URLEncoding.EncodeToString(msg)
    ...
}

ハマりどころ

メールのヘッダー部分(subjectを含む)は、「7ビットアスキーコード」でなければなりません。
参考:http://hogem.hatenablog.com/entry/20100122/1264169093

Goの文字エンコーディングはUTF-8であり、1ビットが破棄され日本語文字化けを引き起こしていました。

対処法

下記の流れで変換してあげました。

UTF-8(Go文字列でのデフォ) -> ISO-2022-JP -> (byteスライス) -> base64urlString
package main

import (
    "encoding/base64"
    "io/ioutil"
    "strings"
    "golang.org/x/text/encoding/japanese"
    "golang.org/x/text/transform"
    ...
    "google.golang.org/api/gmail/v1"
)

// Convert UTF-8 to ISO2022JP
func toISO2022JP(str string) ([]byte, error) {
    reader := strings.NewReader(str)
    transformer := japanese.ISO2022JP.NewEncoder()

    return ioutil.ReadAll(transform.NewReader(reader, transformer))
}

func main() {
    ...
    msgStr := "to: hoge@gmail.com\n" + "subject: 件名\n\n" + "message: 本文"
    // ISO-2022-JP(JISコード) へ一度変換する
    msgISO2022JP, _ := toISO2022JP(msgStr)
    msg := []byte(msgISO2022JP)
    message := gmail.Message{}
    message.Raw = base64.URLEncoding.EncodeToString(msg)
    ...
}

参考:http://qiita.com/spiegel-im-spiegel/items/2e475b48226330aa5570

おまけ

下記のレポジトリで実際に使っています。
https://github.com/yyoshiki41/go-gmail-drafts

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away