trying to send email with gmail api receive 'raw' RFC822 payload message string

自闭症网瘾萝莉.ら 提交于 2020-01-21 10:35:34

问题


I'm trying to perform a simple Reply to email with Gmail API.

I'm receiving the following error:

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

'raw' RFC822 payload message string or uploading message via /upload/* URL required [400]

Errors [

Message['raw' RFC822 payload message string or uploading message via /upload/* URL required] Location[ - ] Reason[invalidArgument] Domain[global]

my code is:

   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();

Is there a simple way to perform a reply to the original email?

Is there an example reference on how to perform this task?


回答1:


You could resort to using third party MIME library with below steps:

  1. Download the gmail message in raw format
  2. Parse the raw message using library
  3. Modify the message
  4. Output it back to raw format using library
  5. Insert back into the gmail message and then send.

Have a look at this solution on SO https://stackoverflow.com/a/26599752/2637802

Using the MimeKit library heres sample code:

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("=", "");
}



回答2:


Note that Users.messages: send method supports an /upload URI and accepts uploaded media with the following characteristics:

  • Maximum file size: 35MB
  • Accepted Media MIME types: message/rfc822

Also, you may want to check details given in Sending Email,

Emails are sent as base64url encoded strings within the raw property of a message resource. The high-level workflow to send an email is to:

  1. Create the email content in some convenient way and encode it as a base64url string.
  2. Create a new message resource and set its raw property to the base64url string you just created.
  3. Call messages.send, or, if sending a draft, drafts.send to send the message.

With these, try adding the raw parameter in your request body with value set to a base64 encoded email.

Just for additional insights (as these are not C# related), see these related SO posts

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


来源:https://stackoverflow.com/questions/44821814/trying-to-send-email-with-gmail-api-receive-raw-rfc822-payload-message-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!