表情符号不会在Gmail主题中呈现 [英] Emoji is not rendered in the subject of gmail

查看:13
本文介绍了表情符号不会在Gmail主题中呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Gmail API从NodeJS API发送电子邮件。我正在使用以下实用程序函数渲染原始正文

message += '[DEFAULT EMOJI 😆]'
  
const str = [
    'Content-Type: text/html; charset="UTF-8"
',
    'MIME-Version: 1.0
',
    'Content-Transfer-Encoding: 7bit
',
    'to: ',
    to,
    '
',
    'from: ',
    from.name,
    ' <',
    from.address,
    '>',
    '
',
    'subject: ',
    subject + '[DEFAULT EMOJI 😆]',
    '

',
    message
  ].join('');

  return Buffer.alloc(str.length, str).toString('base64').replace(/+/g, '-').replace(///g, '_');

我用来发送电子邮件的代码是

const r = await gmail.users.messages.send({
    auth,
    userId: "me",
    requestBody: {
        raw: makeEmailBody(
            thread.send_to,
            {
                address: user.from_email,
                name: user.from_name,
            },
            campaign.subject,
            campaign.template,
            thread.id
        ),
    },
});

表情符号在主体中呈现,但在主体中不起作用。见下图

左侧来自桌面上Google Chrome中的Gmail,右侧来自手机中的Gmail App

推荐答案

您的实用程序可能会从几个改进中受益(我们将讨论表情符号问题):

  1. 首先,使用CRLF( )分隔行,使其符合RFC822
  2. 注意Content-Transfer-Encoding标头,将其设置为7bit最简单,但可能不够通用(quoted-printable可能是更好的选项)。

现在来看表情符号问题:

您需要确保主题与正文分开正确编码,才能传递表情符号。根据RFC13420,您可以在主题上使用Base64或引号可打印编码来创建编码单词,如下所示:

&Q;=&Q;??&Q;字符集&Q;??&Q;编码&Q;??&Q;编码文本

其中,对于引用的可打印编码,编码为Q;对于Base64编码,编码为B

请注意,生成的编码主题字符串的长度不得超过76个字符,这将为该字符串保留75个字符,为分隔符保留1(要使用多个单词,请使用空格或换行符[CRLF]分隔它们)。

因此,将您的字符集设置为utf-8,将编码设置为Q,使用如下1对实际主题进行编码,您就完成了一半:

/**
 * @summary RFC 1342 header encoding
 * @see {@link https://www.rfc-editor.org/rfc/rfc1342}
 */
class HeaderEncoder {

  /**
   * @summary encode using Q encoding
   */
  static quotedPrintable(str: string, encoding = "utf-8") {
    let encoded = "";

    for (const char of str) {
      const cp = char.codePointAt(0);
      encoded += `=${cp.toString(16)}`;
    }

    return `=?${encoding}?Q?${encoded}?=`;
  }
}

现在,有趣的部分来了。我当时在做一个GAS项目,它必须直接利用Gmail API(毕竟,这就是客户端库在幕后做的事情)。即使使用正确的编码,尝试传递类似"Beep! u{1F697}"的内容也会导致主题解析错误。

结果是您需要利用fromCodePoint对原始字符串中的字节数组或缓冲区进行操作。此代码段应该足够了(不要忘记仅适用于多字节字符):

const escape = (u: string) => String.fromCodePoint(...Buffer.from(u));

0这是初始RFC,参考RFC 2047会更合适。此外,请参阅RFC 2231以在标题中包含区域设置信息(以及一些更模糊的扩展名)。
1如果字符落在printable US-ASCII范围内,则可以保持原样,但由于一组广泛的规则,我建议坚持使用48-57(数字)、65-90(大写)和97-122(小写)范围。

这篇关于表情符号不会在Gmail主题中呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆