我正在尝试将iCal格式的日历邀请添加到通过MailGun API发送的电子邮件中。这就是我到目前为止所做的:
var request = new RestRequest();
request.AddParameter("domain", this.domain, ParameterType.UrlSegment);
request.Resource = "{domain}/messages";
request.AddParameter("from", contactDetails.SenderAddress);
request.AddParameter("to", contactDetails.RecipientAddress);
request.AddParameter("subject", message.Subject);
request.AddParameter("text", message.TextBody);
request.AddParameter("html", message.HtmlBody);
if (!string.IsNullOrWhiteSpace(message.IcalAttachment))
{
request.AddFileBytes("attachment",
Encoding.UTF8.GetBytes(message.IcalAttachment),
"invite.ics",
"text/calendar");
}
request.Method = Method.POST;
return request;
这导致日历作为附件包含在电子邮件中,不是电子邮件的替代视图。附件在gmail中正常工作,但在Outlook中它显示为必须首先单击的附件文件,然后同意将日历添加到Outlook日历。有没有其他方法可以使用REST api,以便正确发送日历邀请,作为备用电子邮件视图?
要明确的是,这是我使用.Net SmtpClient
发送日历邀请的方式:
var contentType = new ContentType("text/calendar");
if (contentType.Parameters != null)
{
contentType.Parameters.Add("method", "REQUEST");
contentType.CharSet = "UTF-8";
}
// this is the same way you add a html view to the message
request.AlternateViews.Add(
AlternateView.CreateAlternateViewFromString(
message.IcalAttachment,
contentType));
答案 0 :(得分:5)
特别感谢Mailgun支持我指出正确的方向。相关部分或他们的回应是:
您可以使用/message.mime端点构建日历邀请的MIME: https://documentation.mailgun.com/api-sending.html#sending
创建mime消息并不像简单地使用他们的/消息端点那样容易,但有几个.net库可用于执行此操作。我在这个例子中使用了MimeKit。
var request = new RestRequest();
request.AddParameter("domain", this.domain, ParameterType.UrlSegment);
request.Resource = "{domain}/messages.mime";
request.AddParameter("to", contactDetails.RecipientAddress);
request.AddFile(
"message",
Encoding.UTF8.GetBytes(BuildMimeContent(message)),
"message.mime");
request.Method = Method.POST;
return request;
我想创建的mime内容将包含一个multipart / mixed body,它将包含multipart / alternative以及每个附件。日历邀请实际上将附加两次,作为替代视图和附件。这有助于在不同的电子邮件客户端之间实现兼容。
BuildMimeContent(message)
的实现如下所示:
// create the alternative views
var textBody = new TextPart("plain") { Text = message.TextBody };
var htmlBody = new TextPart("html") { Text = message.HtmlBody };
// add views to the multipart/alternative
var alternative = new Multipart("alternative");
alternative.Add(textBody);
alternative.Add(htmlBody);
if (!string.IsNullOrWhiteSpace(message.CalendarInvite))
{
// also add the calendar as an alternative view
// encoded as base64, but 7bit will also work
var calendarBody = new TextPart("calendar")
{
Text = message.CalendarInvite,
ContentTransferEncoding = ContentEncoding.Base64
};
// most clients wont recognise the alternative view without the
// method=REQUEST header
calendarBody.ContentType.Parameters.Add("method", "REQUEST");
alternative.Add(calendarBody);
}
// create the multipart/mixed that will contain the multipart/alternative
// and all attachments
var multiPart = new Multipart("mixed") { alternative };
if (!string.IsNullOrWhiteSpace(message.CalendarInvite))
{
// add the calendar as an attachment
var calAttachment = new MimePart("application", "ics")
{
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Base64,
FileName = "invite.ics",
ContentObject = new ContentObject(GenerateStreamFromString(message.CalendarInvite))
};
multiPart.Add(calAttachment);
}
// TODO: Add any other attachements to 'multipart' here.
// build final mime message
var mimeMessage = new MimeMessage();
mimeMessage.From.Add(GetMimeAddress(message.MessageInfo.SenderName, message.MessageInfo.SenderAddress));
mimeMessage.To.Add(GetMimeAddress(message.MessageInfo.RecipientName, message.MessageInfo.RecipientAddress));
mimeMessage.Subject = message.Subject;
mimeMessage.Body = multiPart;
// parse and return mime message
return mimeMessage.ToString();
Office365在验证日历邀请方面非常挑剔。为了不收到如下所示的消息,您需要确保vCal的organizer
电子邮件地址与电子邮件的from
地址相匹配。如果您使用的是mailgun的沙盒测试环境,则无法进行此操作。