Gmail草稿(带附件的HTML),带有MimeKit、C#Winforms和谷歌API

Gmail草稿(带附件的HTML),带有MimeKit、C#Winforms和谷歌API,c#,winforms,google-api,gmail,mimekit,C#,Winforms,Google Api,Gmail,Mimekit,我正在尝试使用C#在winforms应用程序中生成Gmail草稿消息。邮件草稿需要为HTML格式,并且能够包含附件 我能够使用AE.Net.Mail生成带有附件的草稿,但草稿邮件是纯文本的(我不知道如何编写AE.Net.Mail来生成HTML Gmail草稿邮件) 为了将消息转换成HTML格式,我使用MimeKit获取System.Net.Mail消息,并将其转换为MimeMessage消息。但是,我不知道如何按照Gmail草案规范的要求将MIME消息放入RFC2822格式和URL安全的base

我正在尝试使用C#在winforms应用程序中生成Gmail草稿消息。邮件草稿需要为HTML格式,并且能够包含附件

我能够使用
AE.Net.Mail
生成带有附件的草稿,但草稿邮件是纯文本的(我不知道如何编写
AE.Net.Mail
来生成HTML Gmail草稿邮件)

为了将消息转换成HTML格式,我使用MimeKit获取
System.Net.Mail
消息,并将其转换为
MimeMessage
消息。但是,我不知道如何按照Gmail草案规范的要求将MIME消息放入RFC2822格式和URL安全的base64编码字符串中

以下是MimeKit转换尝试的代码:

var service = new GmailService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = ApplicationName,
});

MailMessage msg = new MailMessage(); //System.Net.Mail
msg.IsBodyHtml = true;
msg.Subject = "HTML Email";
msg.Body = "<a href = 'http://www.yahoo.com/'>Enjoy Yahoo!</a>";
msg.Attachments.Add(file);

MimeMessage message = MimeMessage.CreateFromMailMessage(msg); //MimeKit conversion

//At this point I cannot figure out how to get the MIME message into 
//an RFC 2822 formatted and URL-safe base64 encoded string
//as required by the Gmail draft specification
//See working code below for how this works in AE.Net.Mail

有没有办法将MimeKit的
MimeMessage
消息转换成RFC 2822格式和URL安全的base64编码字符串,以便生成Gmail草稿?如果做不到这一点,有没有办法在编码之前以HTML格式创建
AE.Net.Mail
消息?非常感谢您的帮助。

做您想做的事情的最简单方法如下:

static string Base64UrlEncode (MimeMessage message)
{
    using (var stream = new MemoryStream ()) {
        message.WriteTo (stream);

        return Convert.ToBase64String (stream.GetBuffer (), 0, (int) stream.Length)
            .Replace ('+', '-')
            .Replace ('/', '_')
            .Replace ("=", "");
    }
}
static string Base64UrlEncode (MimeMessage message)
{
    using (var stream = new MemoryStream ()) {
        using (var filtered = new FilteredStream (stream)) {
            filtered.Add (EncoderFilter.Create (ContentEncoding.Base64));
            filtered.Add (new UrlEncodeFilter ());

            message.WriteTo (filtered);
            filtered.Flush ();
        }

        return Encoding.ASCII.GetString (stream.GetBuffer (), 0, (int) stream.Length);
    }
}
但更有效的方法是实现我们自己的UrlEncoderFilter来替换您的“.replace(…)”逻辑:

如果做不到这一点,是否有办法在编码之前以HTML格式创建AE.Net.Mail消息

你可以试试

msg.ContentType = "text/html"; 
在你的AE.Net.Mail.MailMessage中,这里是我用来创建带有附件的gmail草稿的C代码

using System;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Gmail.v1;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System.IO;
using System.Threading;
using System.Net.Mail;

namespace SendStatusReportsAddin1
{
    class Program
    {
        // If modifying these scopes, delete your previously saved credentials
        // at ~/.credentials/gmail-dotnet-quickstart.json
        //static string[] Scopes = { GmailService.Scope.GmailReadonly };
        static string[] Scopes = { GmailService.Scope.MailGoogleCom };
        static string ApplicationName = "Gmail API .NET Quickstart";

        static void Main(string[] args)
        {
            //Authorization
              UserCredential credential;

              using (var stream =
                  new FileStream("client_secret2.json", FileMode.Open, FileAccess.Read))
              {
                  string credPath = System.Environment.GetFolderPath(
                      System.Environment.SpecialFolder.Personal);
                  credPath = Path.Combine(credPath, ".credentials3/gmail-dotnet.json");

                  credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                      GoogleClientSecrets.Load(stream).Secrets,
                      Scopes,
                      "user",
                      CancellationToken.None,
                      new FileDataStore(credPath, true)).Result;
                  Console.WriteLine("Credential file saved to: " + credPath);
              }

            //Create Gmail API service.
              var service = new GmailService(new BaseClientService.Initializer()
              {
                  HttpClientInitializer = credential,
                  ApplicationName = ApplicationName,
              });

            //Create mail message
              MailMessage mailmsg = new MailMessage();
              {
                  mailmsg.Subject = "My test subject";
                  mailmsg.Body = "<b>My smart message </b>";
                  mailmsg.From = new MailAddress("joe.blow@hotmail.com");
                  mailmsg.To.Add(new MailAddress("jeff.jones@gmail.com"));
                  mailmsg.IsBodyHtml = true;
              }

            //add attachment
              string statusreportfile =
                        @"C:\Users\ey96a\Google Drive\10 Status-Vacation-Expense\Status Reports\UUM RewriteStatus Report.pdf";

              Attachment data = new Attachment(statusreportfile);
              mailmsg.Attachments.Add(data);

            //Make mail message a Mime message
              MimeKit.MimeMessage mimemessage = MimeKit.MimeMessage.CreateFromMailMessage(mailmsg);

            //Use Base64URLEncode to encode the Mime message
              Google.Apis.Gmail.v1.Data.Message finalmessage = new Google.Apis.Gmail.v1.Data.Message();
              finalmessage.Raw = Base64UrlEncode(mimemessage.ToString());

            //Create the draft email
              var mydraft = new Google.Apis.Gmail.v1.Data.Draft();
              mydraft.Message = finalmessage;

              var resultdraft = service.Users.Drafts.Create(mydraft, "me").Execute();

            //Send the email (instead of creating a draft)
              var resultsend = service.Users.Messages.Send(finalmessage, "me").Execute();

            //Open the SendStatusReports form
              aOpenForm.myForm1();

        }  //end of Main

        //Base64 URL encode
        public static string Base64UrlEncode(string input)
        {
            var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
            // Special "url-safe" base64 encode.

            return System.Convert.ToBase64String(inputBytes)
                .Replace('+', '-')
                .Replace('/', '_')
                .Replace("=", "");
        }

    } //end of class Program

}
使用系统;
使用Google.api.Auth.OAuth2;
使用Google.api.Gmail.v1;
使用Google.api.Services;
使用Google.api.Util.Store;
使用System.IO;
使用系统线程;
使用System.Net.Mail;
命名空间SendStatusReportsAddin1
{
班级计划
{
//如果修改这些作用域,请删除以前保存的凭据
//位于~/.credentials/gmail-dotnet-quickstart.json
//静态字符串[]范围={GmailService.Scope.GmailReadonly};
静态字符串[]Scopes={GmailService.Scope.MailGoogleCom};
静态字符串ApplicationName=“Gmail API.NET快速启动”;
静态void Main(字符串[]参数)
{
//授权书
用户凭证;
使用(var)流=
新的文件流(“client_secret2.json”、FileMode.Open、FileAccess.Read))
{
字符串credPath=System.Environment.GetFolderPath(
系统、环境、专用文件夹、个人);
credPath=Path.Combine(credPath,“.credentials3/gmail dotnet.json”);
凭证=GoogleWebAuthorizationBroker.AuthorizationAsync(
GoogleClientSecrets.Load(stream.Secrets),
范围,
“用户”,
取消令牌。无,
新文件数据存储(credPath,true))。结果;
Console.WriteLine(“凭证文件保存到:”+credPath);
}
//创建Gmail API服务。
var service=new-GmailService(new-BaseClientService.Initializer()
{
HttpClientInitializer=凭证,
ApplicationName=ApplicationName,
});
//创建邮件消息
MailMessage mailmsg=新邮件();
{
mailmsg.Subject=“我的测试对象”;
mailmsg.Body=“我的智能消息”;
mailmsg.From=新邮件地址(“joe。blow@hotmail.com");
mailmsg.To.Add(新邮件地址(“jeff。jones@gmail.com"));
mailmsg.IsBodyHtml=true;
}
//添加附件
字符串状态报告文件=
@“C:\Users\ey96a\Google Drive\10状态度假费用\Status Reports\UUM RewriteStatus Report.pdf”;
附件数据=新附件(statusreportfile);
mailmsg.Attachments.Add(数据);
//将邮件消息设置为Mime消息
MimeKit.MimeMessage MimeMessage=MimeKit.MimeMessage.CreateFromMailMessage(mailmsg);
//使用Base64URLEncode对Mime消息进行编码
Google.api.Gmail.v1.Data.Message finalmessage=new Google.api.Gmail.v1.Data.Message();
finalmessage.Raw=Base64UrlEncode(mimessage.ToString());
//创建草稿电子邮件
var mydraft=new Google.api.Gmail.v1.Data.Draft();
mydraft.Message=最终消息;
var resultdraft=service.Users.Drafts.Create(mydraft,“me”).Execute();
//发送电子邮件(而不是创建草稿)
var resultsend=service.Users.Messages.Send(finalmessage,“me”).Execute();
//打开SendStatusReports表单
aOpenForm.myForm1();
}//主管道末端
//Base64 URL编码
公共静态字符串Base64UrlEncode(字符串输入)
{
var inputBytes=System.Text.Encoding.UTF8.GetBytes(输入);
//特殊的“url安全”base64编码。
返回System.Convert.ToBase64String(inputBytes)
.替换(“+”、“-”)
.替换(“/”,“"”)
.替换(“=”,”);
}
}//课程结束
}

谢谢!传递
MimeMessage
并将其写入流非常有意义。我最终使用了我的“替换”逻辑,因为我无法使
UrlEncoderFilter
工作。我试图放在电子邮件正文中的所有HTML都没有正确编码,被放在gobbledygook字符串中。如果时间允许,我会在这方面做更多的工作,看看我是否能找出哪里出了问题。非常感谢您的帮助,感谢您创建MimeKit!你有几篇关于草稿的帖子
msg.ContentType = "text/html"; 
using System;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Gmail.v1;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System.IO;
using System.Threading;
using System.Net.Mail;

namespace SendStatusReportsAddin1
{
    class Program
    {
        // If modifying these scopes, delete your previously saved credentials
        // at ~/.credentials/gmail-dotnet-quickstart.json
        //static string[] Scopes = { GmailService.Scope.GmailReadonly };
        static string[] Scopes = { GmailService.Scope.MailGoogleCom };
        static string ApplicationName = "Gmail API .NET Quickstart";

        static void Main(string[] args)
        {
            //Authorization
              UserCredential credential;

              using (var stream =
                  new FileStream("client_secret2.json", FileMode.Open, FileAccess.Read))
              {
                  string credPath = System.Environment.GetFolderPath(
                      System.Environment.SpecialFolder.Personal);
                  credPath = Path.Combine(credPath, ".credentials3/gmail-dotnet.json");

                  credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                      GoogleClientSecrets.Load(stream).Secrets,
                      Scopes,
                      "user",
                      CancellationToken.None,
                      new FileDataStore(credPath, true)).Result;
                  Console.WriteLine("Credential file saved to: " + credPath);
              }

            //Create Gmail API service.
              var service = new GmailService(new BaseClientService.Initializer()
              {
                  HttpClientInitializer = credential,
                  ApplicationName = ApplicationName,
              });

            //Create mail message
              MailMessage mailmsg = new MailMessage();
              {
                  mailmsg.Subject = "My test subject";
                  mailmsg.Body = "<b>My smart message </b>";
                  mailmsg.From = new MailAddress("joe.blow@hotmail.com");
                  mailmsg.To.Add(new MailAddress("jeff.jones@gmail.com"));
                  mailmsg.IsBodyHtml = true;
              }

            //add attachment
              string statusreportfile =
                        @"C:\Users\ey96a\Google Drive\10 Status-Vacation-Expense\Status Reports\UUM RewriteStatus Report.pdf";

              Attachment data = new Attachment(statusreportfile);
              mailmsg.Attachments.Add(data);

            //Make mail message a Mime message
              MimeKit.MimeMessage mimemessage = MimeKit.MimeMessage.CreateFromMailMessage(mailmsg);

            //Use Base64URLEncode to encode the Mime message
              Google.Apis.Gmail.v1.Data.Message finalmessage = new Google.Apis.Gmail.v1.Data.Message();
              finalmessage.Raw = Base64UrlEncode(mimemessage.ToString());

            //Create the draft email
              var mydraft = new Google.Apis.Gmail.v1.Data.Draft();
              mydraft.Message = finalmessage;

              var resultdraft = service.Users.Drafts.Create(mydraft, "me").Execute();

            //Send the email (instead of creating a draft)
              var resultsend = service.Users.Messages.Send(finalmessage, "me").Execute();

            //Open the SendStatusReports form
              aOpenForm.myForm1();

        }  //end of Main

        //Base64 URL encode
        public static string Base64UrlEncode(string input)
        {
            var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
            // Special "url-safe" base64 encode.

            return System.Convert.ToBase64String(inputBytes)
                .Replace('+', '-')
                .Replace('/', '_')
                .Replace("=", "");
        }

    } //end of class Program

}