带有.Net CLient库的Gmail API:缺少草稿消息[400]

时间:2014-07-09 14:54:19

标签: c# .net google-api gmail-api

我正在尝试使用.Net客户端库在Gmail中创建草稿。我可以成功登录并检索草稿列表,以便身份验证和api正常工作。现在我需要创建Draft类的实例并将其发送到API。但草案信息需要看起来像什么?我在https://developers.google.com/gmail/api/v1/reference/users/drafts/create填写API资源管理器并不重要,我的草稿总是空的。 另外,当我从C#代码中执行此操作时,我需要将draft.Message.Raw字段设置为其他内容我收到错误:

Missing draft message [400] 

3 个答案:

答案 0 :(得分:3)

使用客户端库,您可以将base64编码的电子邮件设置为Message的raw属性,然后将该Message用作Draft的message属性。

更一般地说: 消息草稿由id和消息资源组成 https://developers.google.com/gmail/api/v1/reference/users/drafts

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

消息资源的“raw”字段应设置为base64编码的RCF 2822格式字符串。

例如:

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

email body

作为base64编码的字符串是:

ZnJvbTogbWVAZW1haWwuY29tDQp0bzogeW91QGVtYWlsLmNvbQ0Kc3ViamVjdDogdGVzdCBlbWFpbA0KDQplbWFpbCBib2R5

因此draft.create的请求主体应该类似于:

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

答案 1 :(得分:2)

直到今天,我一直在努力解决这个问题。

我所做的是在此链接上调整解决方案以进行草稿。 http://jason.pettys.name/2014/10/27/sending-email-with-the-gmail-api-in-net-c/

Jason使用名为AE.Net.Mail的nuget将邮件对象序列化为RFC 2822。

我做的是我安装了两个nugets

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

之后我创建了两个方法

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

在我的Main方法中,我设计了这样的

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

答案 2 :(得分:0)

message > raw应该是完整的SMTP邮件。

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

或者,您也可以在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"
           }
       }
    }
}