尝试使用 gmail api 发送电子邮件接收“原始”RFC822 有效负载消息字符串

Posted

技术标签:

【中文标题】尝试使用 gmail api 发送电子邮件接收“原始”RFC822 有效负载消息字符串【英文标题】:trying to send email with gmail api receive 'raw' RFC822 payload message string 【发布时间】:2017-12-02 23:00:59 【问题描述】:

我正在尝试使用 Gmail API 对电子邮件执行简单的回复。

我收到以下错误:

Google.GoogleApiException: 'Google.Apis.Requests.RequestError

'raw' RFC822 有效负载消息字符串或通过 /upload/* 上传消息 需要 URL [400]

错误 [

Message['raw' RFC822 有效负载消息字符串或通过上传消息 /upload/* URL required] Location[ - ] Reason[invalidArgument] 域[全局]

我的代码是:

   var msg = service.Users.Messages.Get("me", labelItem.Id).Execute();//the original email

                    var toReceipients = GetReceipients(msg, "TO", out int toReceipientsCount);
                    var ccReceipients = GetReceipients(msg, "CC", out int ccReceipientsCount);
                    var bccReceipients = GetReceipients(msg, "BCC", out int bccReceipientsCount);
                    toReceipients.AddRange(ccReceipients);
                    toReceipients.AddRange(bccReceipients);
                    var result = string.Join(",", toReceipients);
                    Message newMsg = new Message();
                    MessagePartHeader toAddress = msg.Payload.Headers.FirstOrDefault(g => g.Name == "To");
                    MessagePartHeader fromAddress = msg.Payload.Headers.FirstOrDefault(g => g.Name == "From");
                    fromAddress.Value = toAddress.Value;
                    fromAddress.Value = "xxxxx@gmail.com";
                    toAddress.Value = result;
                    newMsg.Raw = msg.Raw;
                    newMsg.Payload = new MessagePart();
                    newMsg.Payload.Headers = new List<MessagePartHeader>();
                    newMsg.Payload.Headers.Add(toAddress);
                    newMsg.Payload.Headers.Add(fromAddress);
                    newMsg.Payload.MimeType = "text/plain";
                    MessagePartHeader Subject = msg.Payload.Headers.FirstOrDefault(g => g.Name == "Subject");
                    newMsg.Payload.Headers.Add(Subject);
                    //MessagePartHeader References = msg.Payload.Headers.FirstOrDefault(g => g.Name == "References");
                    MessagePartHeader MessageID = msg.Payload.Headers.FirstOrDefault(g => g.Name == "Message-ID");
                    newMsg.Payload.Headers.Add(MessageID);
                    // MessagePartHeader format = msg.Payload.Headers.FirstOrDefault(g => g.Name == "format");
                    // MessagePartHeader aaa = msg.Payload.Headers.FirstOrDefault(g => g.Name == "In-Reply-To");

                    msg.Payload =  newMsg.Payload;
                    service.Users.Messages.Send(msg, "me").Execute();

有没有简单的方法来回复原始电子邮件?

是否有关于如何执行此任务的示例参考?

【问题讨论】:

【参考方案1】:

请注意,Users.messages: send 方法支持 /upload URI 并接受具有以下特征的上传媒体:

最大文件大小:35MB 接受的媒体 MIME 类型:message/rfc822

另外,您可能需要查看Sending Email 中提供的详细信息,

电子邮件在消息资源的raw 属性中作为base64url 编码字符串发送。发送电子邮件的高级工作流程是:

    以某种方便的方式创建电子邮件内容并将其编码为 base64url 字符串。 创建一个新的消息资源并将其raw 属性设置为 您刚刚创建的 base64url 字符串。 致电messages.send,或者,如果发送草稿,请drafts.send 发送消息。

使用这些,尝试在您的请求正文中添加 raw 参数,并将值设置为 base64 编码的电子邮件。

只是为了获得更多见解(因为这些与 C# 无关),请参阅这些相关的 SO 帖子

Failed sending mail through google api with javascript Sending gmail attachment using api failed

【讨论】:

【参考方案2】:

您可以通过以下步骤使用第三方 MIME 库:

    以原始格式下载 gmail 邮件 使用库解析原始消息 修改消息 使用库将其输出回原始格式 重新插入到 gmail 邮件中,然后发送。

在 SO https://***.com/a/26599752/2637802 上查看此解决方案

使用 MimeKit 库的示例代码如下:

var msgRequest = service.Users.Messages.Get("me", msg.Id);
msgRequest.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Raw;
var msgDetails = msgRequest.Execute();

using (MemoryStream rawInStream = new MemoryStream(Base64FUrlDecode(msgDetails.Raw)))
using (MemoryStream rawOutStream = new MemoryStream())

    var message = MimeKit.MimeMessage.Load(rawInStream);

    message.To.Clear();
    message.To.Add(new MimeKit.MailboxAddress("", "<email address>"));
    message.Subject = "Edited Subject";

    message.WriteTo(rawOutStream);
    msgDetails.Raw = Base64UrlEncode(rawOutStream.ToArray());


service.Users.Messages.Send(msgDetails, "me").Execute();

private static byte[] Base64FUrlDecode(string input)

    int padChars = (input.Length % 4) == 0 ? 0 : (4 - (input.Length % 4));
    StringBuilder result = new StringBuilder(input, input.Length + padChars);
    result.Append(String.Empty.PadRight(padChars, '='));
    result.Replace('-', '+');
    result.Replace('_', '/');
    return Convert.FromBase64String(result.ToString());


private static string Base64UrlEncode(byte[] input)

    // Special "url-safe" base64 encode.
    return Convert.ToBase64String(input)
      .Replace('+', '-')
      .Replace('/', '_')
      .Replace("=", "");

【讨论】:

以上是关于尝试使用 gmail api 发送电子邮件接收“原始”RFC822 有效负载消息字符串的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 Google.Apis.Gmail 从 asp.net core web api 应用程序从谷歌工作区发送电子邮件时出错

在 golang 中使用 gmail API 发送带附件的电子邮件

使用 PHP 向使用 Gmail API 发送的电子邮件添加密件抄送

退回 <nobody@gmail.com> Gmail API 发送失败

使用 Gmail api 通过 Android 应用发送邮件

当我尝试使用我的 Google 服务帐户通过 Gmail API 发送电子邮件时,“myemail@mydomain.com”的委派被拒绝