在 C# 中为 Gmail API 创建消息

Posted

技术标签:

【中文标题】在 C# 中为 Gmail API 创建消息【英文标题】:Creating a Message for Gmail API in C# 【发布时间】:2014-09-03 21:54:12 【问题描述】:

我正在研究在我正在开发的应用程序中使用 Gmail API。但是,我不确定如何将他们的 Java 或 Python 示例更改为 C#。现有样本究竟如何变化?

Sample found here.

【问题讨论】:

Java 与 C# 非常接近,您肯定已经尝试过转换它并且失败了?也许发布您尝试转换的内容将是人们帮助您解决错误的一个良好开端 嗯,我正在寻找 MimeMessageProperties 等的等价物,但快速谷歌搜索并没有帮助。 Google API 都是 REST API。文档告诉您 REST API 调用需要哪些参数。 【参考方案1】:

这似乎不是 Gmail API 的真正问题。您应该寻找的是“c# create email”(可能添加“RFC 2822”,因为这是定义这些电子邮件格式的 RFC)。一旦你有了这样一个有效的“电子邮件”(你可以使用 SMTP 或 IMAP 等的真实的、完整的电子邮件内容),那么将它与 Gmail API 一起使用应该是非常简单的。

【讨论】:

你是对的。我在 Gmail API 下发帖认为有人可能以前遇到过这个问题并得到了答案,但我应该将它更多地指向 C#。谢谢。 @rar 你有什么发现吗?试图解决同样的问题。 很遗憾没有。我们不得不放弃 Gmail API,因为它不起作用,而且当我们可以使用更简单的电子邮件发件人时,我们没有太多时间花在它上面。谷歌真的可以改进他们在这方面的文档...... @rar 感谢您的回复。我终于能够使用 nuget 包 AE.Net.Mail - github.com/andyedinborough/aenetmail 获得原始 RFC 2822 消息字节。我知道您对 Gmail API 的意思——花了我一整天才终于让它发送消息。 rar/pettys: 究竟是什么问题您无法弄清楚,或者如何更好地改进文档? IMO 最困难的部分似乎是创建电子邮件消息,这并不是真正特定于 API,无论您使用 SMTP、API 还是 IMAP,您都需要这样做。一旦你有了电子邮件字符串,只需对它进行 base64url 编码并将其发布到正确的 URL 就非常简单了,并且有很好的 java 代码显示它。【参考方案2】:

这是一个很难解决的问题,但我最终得到了它。我使用 NuGet 包 AE.Net.Mail 来获取 RFC 2822 位。

using System.IO;
using System.Net.Mail;
using Google.Apis.Gmail.v1;
using Google.Apis.Gmail.v1.Data;

public class TestEmail 

  public void SendIt() 
    var msg = new AE.Net.Mail.MailMessage 
      Subject = "Your Subject",
      Body = "Hello, World, from Gmail API!",
      From = new MailAddress("[you]@gmail.com")
    ;
    msg.To.Add(new MailAddress("yourbuddy@gmail.com"));
    msg.ReplyTo.Add(msg.From); // Bounces without this!!
    var msgStr = new StringWriter();
    msg.Save(msgStr);

    var gmail = new GmailService(MyOwnGoogleOAuthInitializer);
    var result = gmail.Users.Messages.Send(new Message 
      Raw = Base64UrlEncode(msgStr.ToString())
    , "me").Execute();
    Console.WriteLine("Message ID 0 sent.", result.Id);
  

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

这里发布了相同的代码,并进行了一些进一步的分析和原因: http://jason.pettys.name/2014/10/27/sending-email-with-the-gmail-api-in-net-c/

【讨论】:

我尝试使用您的代码,但是我收到错误错误 CS0103:在 Context.GoogleOAuthInitializer 上的当前上下文中不存在名称“上下文”。你从哪里得到上下文? @Rossini 很抱歉造成混乱 - 这是对我自己的代码的引用,该代码返回一个 Google.Apis.Services.BaseClientService.Initializer,该代码设置为将 OAuth2 Bearer 令牌添加到每个请求.您也许可以只使用默认的 GmailService() 构造函数——取决于您的 GmailService 的身份验证方式。我将更新我的代码以使其更清晰。 此代码适用于纯文本电子邮件。但不适用于 html 电子邮件 + 附件。 对于将来查看此内容的任何人,请确保您使用的是 AE.Net.Mail Nuget 包 (nuget.org/packages/AE.Net.Mail) 而不是 System.Net.Mail (msdn.microsoft.com/en-us/library/system.net.mail(v=vs.110).aspx)。它们非常相似,但工作方式略有不同(例如System.Net.Mail.MailMessage 没有Save 方法)【参考方案3】:

这是我能够使用MimeKit 完成的工作。

public void SendEmail(MyInternalSystemEmailMessage email)

    var mailMessage = new System.Net.Mail.MailMessage();
    mailMessage.From = new System.Net.Mail.MailAddress(email.FromAddress);
    mailMessage.To.Add(email.ToRecipients);
    mailMessage.ReplyToList.Add(email.FromAddress);
    mailMessage.Subject = email.Subject;
    mailMessage.Body = email.Body;
    mailMessage.IsBodyHtml = email.IsHtml;

    foreach (System.Net.Mail.Attachment attachment in email.Attachments)
    
        mailMessage.Attachments.Add(attachment);
    

    var mimeMessage = MimeKit.MimeMessage.CreateFromMailMessage(mailMessage);

    var gmailMessage = new Google.Apis.Gmail.v1.Data.Message 
        Raw = Encode(mimeMessage)
    ;

    Google.Apis.Gmail.v1.UsersResource.MessagesResource.SendRequest request = service.Users.Messages.Send(gmailMessage, ServiceEmail);

    request.Execute();


public static string Encode(MimeMessage mimeMessage)

    using (MemoryStream ms = new MemoryStream())
    
        mimeMessage.WriteTo(ms);
        return Convert.ToBase64String(ms.GetBuffer())
            .TrimEnd('=')
            .Replace('+', '-')
            .Replace('/', '_');
    

注意:如果您收到电子邮件退回问题,很可能是由于未设置 ReplyToList 字段。见:GMail API Emails Bouncing

【讨论】:

我认为你不应该使用mimeMessage.ToString()。根据namespace MimeKit中的备注:In general, the string returned from this method SHOULD NOT be used for serializing the message to disk. It is recommended that you use MimeKit.MimeMessage.WriteTo(System.IO.Stream,System.Threading.CancellationToken) instead. @DoanVanThang 是的,这是可能的。它可能在过去五年中发生了变化,或者它可能一直都是这样。感谢您的提示! 我遇到了 mimeMessage.ToString() 的问题。字符ãçãá..不会正确。我在以下位置找到了解决方案:***.com/questions/55402719/… 我可以确认,就像 07/2021 一样,使用最新版本的 MimeKit 和 Gmail API SDK,mimeMessage.ToString() 方法根本不起作用(API 返回“需要收件人地址”错误)。 @ChrCury78 (***.com/questions/55402719/…) 发布的链接具有有效的解决方案(将MimeMessage 写入流而不是使用ToString())。应使用提供的代码更新此答案。我花了几个小时才弄清楚。 @thankyoussd 答案确实列出了带有该问题链接的更新,并且 cmets 提到了它。抱歉,花了你几个小时,但我认为阅读整个答案会有所帮助。

以上是关于在 C# 中为 Gmail API 创建消息的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中使用 GMail API 创建过滤器 [重复]

如何创建 Gmail API 消息

Gmail API 创建和发送电子邮件 .NET C#

在 c# 中使用 gmail API 修改消息标签时权限不足 [403] 错误

使用 Gmail API 创建的草稿邮件中未呈现图像

使用 Gmail API 阅读其他用户的电子邮件