【问题标题】:Invalid value for ByteString error when calling gmail send API with base64 encoded < or >使用 base64 编码 < 或 > 调用 gmail 发送 API 时 ByteString 错误值无效
【发布时间】:2014-12-27 02:46:46
【问题描述】:

真的坚持这个,把我的头发拉出来试图弄清楚该怎么做,到处搜索并尝试了所有方法,但仍然卡住了。非常感谢任何帮助。

所以我正在调用 Gmail 发送消息 API:

https://www.googleapis.com/gmail/v1/users/me/messages/send

我传入以下 base64 编码的原始消息:

VG86IGVjaG9zaWduLnNmZGMucWFAZ21haWwuY29tDQpTdWJqZWN0OiBSZTogd2UgaGF2ZSBhIGNvb2wgcHJvZHVjdA0KSW4tUmVwbHktVG86IDxDQUFMRnBBSmc1aTJlQ1p4T2dQWlhUdnNaN0J5M0gzNlRCMkNQYTdoVEtzTXh2bXZfT3dAbWFpbC5nbWFpbC5jb20 + DQpSZWZlcmVuY2VzOiA8Q0FBTEZwQUpnNWkyZUNaeE9nUFpYVHZzWjdCeTNIMzZUQjJDUGE3aFRLc014dm12X093QG1haWwuZ21haWwuY29tPg0KDQoxMTozNg == P>

解码为:

To: echosign.sfdc.qa@gmail.com
Subject: Re: we have a cool product
In-Reply-To: <CAALFpAJg5i2eCZxOgPZXTvsZ7By3H36TB2CPa7hTKsMxvmv_Ow@mail.gmail.com>
References: <CAALFpAJg5i2eCZxOgPZXTvsZ7By3H36TB2CPa7hTKsMxvmv_Ow@mail.gmail.com>

11:36

我得到错误:

状态代码:400 和状态:错误请求和响应:{“错误”:{“错误”:[{“域”:“全局”,“原因”:“无效”,“消息”:“无效值对于字节串

问题在于 In-Reply-To 和 References 标头中的小于 &lt; 和大于 &gt; 的符号。我需要这些标题,因为我试图让电子邮件作为线程的回复。我试图省略 &lt;&gt; 但回复没有线程。

谢谢

【问题讨论】:

  • 它是 url 安全的 base64 编码吗?
  • 我尝试使用 UTF-8 将电子邮件编码为 URL 安全,但没有帮助。你知道我应该用什么替换 以使它穿过电线吗?
  • 实际上只是再次尝试了它,如果编码然后它确实发送了,但是回复没有显示为回复,不包括以前的对话。这看起来正确吗?收件人:echosign.sfdc.qa@gmail.com 主题:回复:我们有一个很酷的产品回复:%3C089e01538a1223ee380506ab2157%40google.com%3E 参考:%3C089e01538a1223ee380506ab2157%40google.com%3E 你好

标签: gmail


【解决方案1】:

来自 Google 的 gmail rest api(发送消息):

“RFC 2822 格式和 base64url 编码字符串中的整个电子邮件消息。在提供 format=RAW 参数时在 messages.get 和 drafts.get 响应中返回。”

base64url编码与base64编码不同。

在 python 中,base64 库提供 b64encode() 和 urlsafe_b64encode()。如果你不使用 urlsafe_b64encode(),你会得到那个错误,而不是一直这样,所以它可能会通过一个简单的单元测试,但很快就会失败。

【讨论】:

  • 对于 Java 8:Base64.getUrlEncoder().encodeToString(bytes)
【解决方案2】:

如果您使用的是 PHP,请尝试此操作(否则请尝试将其转换为您使用的任何语言)

在将 mime 消息设置为原始属性之前调用以下函数。

private function base64url_encode($mime) {
    return rtrim(strtr(base64_encode($mime), '+/', '-_'), '=');
}

【讨论】:

  • 这拯救了我的一天!非常感谢!
  • 在 golang 中执行此操作的一种快速而肮脏的方法(cmets 不会让我格式化为代码): b64 := base64.StdEncoding.EncodeToString(msg) b64 = strings.Replace(b64, " +", "-", -1) b64 = strings.Replace(b64, "-", "_", -1) message.Raw = strings.TrimRightFunc(b64, unicode.IsSpace)
  • 其实所有golang需要RawURLEncoding而不是StdEncoding: message.Raw:= base64.RawURLEncoding.EncodeToString(msg)
【解决方案3】:

在 Google Apps 脚本中,以下修复了该问题

var draftBody = Utilities.base64EncodeWebSafe(raw);

不要使用 var draftBody = Utilities.base64Encode(raw);

【讨论】:

    【解决方案4】:

    Google API 使用urlsafe_b64decode 进行解码。尝试使用 urlsafe_b64encode(使用 URL 安全字母编码字符串,在标准 Base64 字母中使用 - 代替 +_ 代替 /。)

    在您的示例中,我看到一个 +,这意味着您使用了标准 Base64。

    【讨论】:

      【解决方案5】:

      之后你通过base64Encode编码你的消息内容,就像这里(假设谷歌脚本):

      var draftBody =  Utilities.base64Encode(message_content_string);
      

      您必须转换所有 不是“网络安全”'/''+' 字符,并且会产生 “字节字符串的值无效” 错误。你可以这样做:

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

      然后您将其作为原始数据提交。显然这里的消息内容没有失真。

      【讨论】:

        猜你喜欢
        • 2016-12-31
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 2017-11-06
        • 2017-02-07
        • 2021-01-27
        • 2017-12-03
        • 1970-01-01
        相关资源
        最近更新 更多