Skip to main content

Command Palette

Search for a command to run...

JSON Serialization of Emoji in Go

Updated
β€’1 min read
S

I have been working at the rapid changing software development field over 19 years as a software engineer, architect, devops. I am an expert in designing and implementing scalable architectures to deal with large transactions and massive requests on e-commerce and messaging services. I am skillful at using opensource technologies like Node.js, Nginx, Redis, Cassandra, ELK and Kafka to secure site reliability. I also have proficiency in C#, Java, Javascript, Python and Go.

I recently found Golang suffers JSON serialization for emoji like πŸ˜€. The main reason was QuoteToASCII() method converted emoji into utf16 representation like U+00000000 which could not be serialized in JSON. The solution is dividing emoji into high and low runes and modifies them into \u0000 forms then concats them again.

package main

import (
    "encoding/json"
    "fmt"
    "strconv"
    "strings"
    "unicode/utf16"
)

func convertToSafeString(s string) string {
    ns := ""
    for _, char := range s {
        h, l := utf16.EncodeRune(char)
        if h != '\uFFFD' && l != '\uFFFD' {
            safe := strings.ReplaceAll(fmt.Sprintf("%U%U", h, l), "U+", "\\u")
            ns += strings.ToLower(safe)
        } else {
            qs := strconv.QuoteToASCII(string(char))
            ns += qs[1 : len(qs)-1] // remove quotes surrounding string
        }
    }
    return ns
}

func main() {

    s := "πŸ˜€πŸ˜€μ•ˆλ…• hiπŸ˜€πŸŽ…πŸŽ…πŸ€ΆπŸ€ΆπŸŽ†πŸŽ‡πŸŽ‡"
    ns := convertToSafeString(s)

    println(s, ns)

    var msg map[string]interface{}
    m := fmt.Sprintf(`{"message":"Success %s","ok":true}`, ns)
    json.Unmarshal([]byte(m), &msg)
    fmt.Println(msg)
}

Reference

  • https://dev.to/matthewdale/sending-in-go-46bf