Gmail api with .Net CLient library: Missing draft message [400]

China☆狼群 提交于 2019-11-30 18:12:52

问题


I'm trying to create drafts in Gmail using the .Net Client Library. I can successfully login and retrieve a list of drafts so the authentication and api are working. Now I need to create an instance of the Draft class and send it to the API. But what does the draft message need to look like? It doesn't matter what I fill in the API explorer on https://developers.google.com/gmail/api/v1/reference/users/drafts/create, my draft is always empty. Also when doing it from my C# code I need to set the draft.Message.Raw field to something else I get an error:

Missing draft message [400] 

回答1:


Using the client library you can set the base64 encoded email to the raw property of a Message then use that Message as the message property of the Draft.

More generally: The Draft Message consists of an id and a Message Resource https://developers.google.com/gmail/api/v1/reference/users/drafts

{
  "id": string,
  "message": users.messages Resource
}

The Message Resource should have its "raw" field set to a base64 encoded RCF 2822 formatted string.

Eg:

from: me@email.com
to: you@email.com
subject: test email

email body

As a base64 encoded string is:

ZnJvbTogbWVAZW1haWwuY29tDQp0bzogeW91QGVtYWlsLmNvbQ0Kc3ViamVjdDogdGVzdCBlbWFpbA0KDQplbWFpbCBib2R5

So the request body of a draft.create should look something like:

{
  "message": {
    "raw": "ZnJvbTogbWVAZW1haWwuY29tDQp0bzogeW91QGVtYWlsLmNvbQ0Kc3ViamVjdDogdGVzdCBlbWFpbA0KDQplbWFpbCBib2R5"
  }
}



回答2:


I was struggling with this until today.

What I did was adapting the solution on this link for drafts. http://jason.pettys.name/2014/10/27/sending-email-with-the-gmail-api-in-net-c/

Jason uses a nuget called AE.Net.Mail to serialize an mail object to RFC 2822.

what I did was I installed both nugets

Install-Package Google.Apis.Gmail.v1
Install-Package AE.Net.Mail

And after that I created two methods

static GmailService Service;
    public static void CriaService(string emailaConectar)
    {
        var certificate = new X509Certificate2(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ClientCredentials.CertificatePath), ClientCredentials.ClientSecret, X509KeyStorageFlags.Exportable);

        var credential = new ServiceAccountCredential(
            new ServiceAccountCredential.Initializer(ClientCredentials.ServiceAccountEmail)
            {
                Scopes = new[] { GmailService.Scope.GmailCompose },
                User = emailaConectar
            }.FromCertificate(certificate)) { };

        Service = new GmailService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = ClientCredentials.ApplicationName,
        });
    }

    private static string Base64UrlEncode(string input)
    {
        var inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
        // Special "url-safe" base64 encode.
        return Convert.ToBase64String(inputBytes)
          .Replace('+', '-')
          .Replace('/', '_')
          .Replace("=", "");
    }

And on my Main method I designed like this

        CriaService("xpto@gmail.com");

        var msg = new AE.Net.Mail.MailMessage
        {
            Subject = "Your Subject",
            Body = "Hello, World, from Gmail API!",
            From = new MailAddress("xpto@gmail.com")
        };
        msg.To.Add(new MailAddress("someone@gmail.com"));
        msg.ReplyTo.Add(msg.From); 
        var msgStr = new StringWriter();
        msg.Save(msgStr);

        Message m = new Message();
        m.Raw = Base64UrlEncode(msgStr.ToString());

        var draft = new Draft();
        draft.Message = m;

        try
        {
            Service.Users.Drafts.Create(draft, "xpto@opportunity.com.br").Execute();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }



回答3:


message > raw is expected to be the full SMTP message.

{
    "message": {
      "raw": "From: me@example.com\nTo:you@example.com\nSubject:Ignore\n\nTest message\n"
}

Alternatively, you can also set the appropriate fields in message > payload:

{
    "message": {
      "payload": {
          "headers": {
              {"name": "From", "value": "me@example.com},
              {"name": "To", "value": "you@example.com"},
              {"name": "Subject", "value":"Ignore"}
           },
           "body": {
              "data": "Test message"
           }
       }
    }
}


来源:https://stackoverflow.com/questions/24657004/gmail-api-with-net-client-library-missing-draft-message-400

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