如何发送一个带有日历请求的电子邮件(内容类型:text/calendar)

7

我尝试将icalendar代码嵌入电子邮件中,并通过indy以文本/日历内容类型发送,但在添加为附件时,它会在编码电子邮件时挂起,而只是作为附件到达,而不像其他日历请求一样提示。是否有人有如何通过indy进行日历请求的示例代码?

2个回答

5

@David,如果您将属性设置为ContentType:='text/calendar',电子邮件客户端将识别附件为日历请求,请参见iCalendar格式规范

请查看此示例代码(已在Delphi 2010上测试)

program SendMailWithCalendarRequest;
{$APPTYPE CONSOLE}


uses
  IdSMTP,
  Classes,
  DateUtils,
  IdAttachmentFile,
  IdMessage,
  SysUtils;

 procedure SendCalendarRequest;
 var
  SMTP        : TIdSMTP;
  MailMessage : TIdMessage;
  Calendar    : TStrings;
  CalendarFile: String;
  Attachment  : TIdAttachmentFile;
  SenderMail  : String;
 begin
    SenderMail:='mail@server.com';
    CalendarFile:=ExtractFilePath(ParamStr(0))+'\appmnt.vcs';
    Calendar:=TStringList.Create;
    try
        Calendar.Add('BEGIN:VCALENDAR');
        Calendar.Add('VERSION:1.0');
        Calendar.Add('BEGIN:VEVENT');
        Calendar.Add('ORGANIZER:MAILTO:'+SenderMail);
        Calendar.Add('DTStart:'+FormatDateTime('YYYY-DD-DD',Now));
        Calendar.Add('DTEnd:'+FormatDateTime('YYYY-DD-DD',  Tomorrow));
        Calendar.Add('Location;ENCODING=QUOTED-PRINTABLE: My home');
        Calendar.Add('UID:'+FormatDateTime('YYYY-DD-DD',Now)+FormatDateTime('YYYY-DD-DD',Tomorrow));
        Calendar.Add('SUMMARY:Appointment Reminder');
        Calendar.Add('DESCRIPTION:Test message');
        Calendar.Add('PRIORITY:5');
        Calendar.Add('END:VEVENT');
        Calendar.Add('END:VCALENDAR');
        Calendar.SaveToFile(CalendarFile);
    finally
    Calendar.Free;
    end;

   SMTP:= TIdSMTP.Create(nil);
   MailMessage := TIdMessage.Create(nil);
   try
     SMTP.Host := 'smtp.mailserver.com';
     SMTP.Port := 25;
     SMTP.Username:='the account';
     SMTP.Password:='the password';
     SMTP.AuthType:=satDefault;
     MailMessage.From.Address := SenderMail;
     MailMessage.Recipients.EMailAddresses := 'the Recipient';
     MailMessage.Subject   := 'Send calendar';
     MailMessage.Body.Text := '';
     Attachment:=TIdAttachmentFile.Create(MailMessage.MessageParts, CalendarFile) ;
     Attachment.ContentType:='text/calendar';//set the content type to text/calendar
     try
       try
         SMTP.Connect;
         SMTP.Send(MailMessage) ;
         Writeln('OK')
       except on E:Exception do
         Writeln(0, 'ERROR: ' + E.Message) ;
       end;
     finally
       if SMTP.Connected then SMTP.Disconnect;
     end;
   finally
    SMTP.Free;
    MailMessage.Free;
   end;

 end;

begin
  try
    SendCalendarRequest;
    readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

5
这是一个RRUZ示例的替代方案:
program SendMailWithCalendarRequest; 
{$APPTYPE CONSOLE} 

uses 
  IdSMTP, 
  Classes, 
  DateUtils, 
  IdMessage, 
  SysUtils; 

 procedure SendCalendarRequest; 
 var 
  SMTP        : TIdSMTP; 
  MailMessage : TIdMessage; 
 begin 
   SMTP:= TIdSMTP.Create(nil); 
   MailMessage := TIdMessage.Create(nil); 
   try 
     SMTP.Host := 'smtp.mailserver.com'; 
     SMTP.Port := 25; 
     SMTP.Username := 'the account'; 
     SMTP.Password := 'the password'; 
     SMTP.AuthType := satDefault; 
     MailMessage.From.Address := 'mail@server.com'; 
     MailMessage.Recipients.EMailAddresses := 'the Recipient'; 
     MailMessage.Subject := 'Send calendar'; 
     MailMessage.Body.Add('BEGIN:VCALENDAR'); 
     MailMessage.Body.Add('VERSION:1.0'); 
     MailMessage.Body.Add('BEGIN:VEVENT'); 
     MailMessage.Body.Add('ORGANIZER:MAILTO:'+SenderMail); 
     MailMessage.Body.Add('DTStart:'+FormatDateTime('YYYY-DD-DD',Now)); 
     MailMessage.Body.Add('DTEnd:'+FormatDateTime('YYYY-DD-DD',  Tomorrow)); 
     MailMessage.Body.Add('Location;ENCODING=QUOTED-PRINTABLE: My home'); 
     MailMessage.Body.Add('UID:'+FormatDateTime('YYYY-DD-DD',Now)+FormatDateTime('YYYY-DD-DD', Tomorrow)); 
     MailMessage.Body.Add('SUMMARY:Appointment Reminder'); 
     MailMessage.Body.Add('DESCRIPTION:Test message'); 
     MailMessage.Body.Add('PRIORITY:5'); 
     MailMessage.Body.Add('END:VEVENT'); 
     MailMessage.Body.Add('END:VCALENDAR'); 
     MailMessage.ContentType := 'text/calendar';
     SMTP.Connect; 
     try 
       try 
         SMTP.Send(MailMessage) ; 
         Writeln('OK') 
       except on E:Exception do 
         Writeln(0, 'ERROR: ' + E.Message) ; 
       end; 
     finally 
       SMTP.Disconnect; 
     end; 
   finally 
    SMTP.Free; 
    MailMessage.Free; 
   end; 
 end; 

begin 
  try 
    SendCalendarRequest; 
    readln; 
  except 
    on E: Exception do 
      Writeln(E.ClassName, ': ', E.Message); 
  end; 
end. 

谢谢,我运行了RRUZ程序,在Gmail中运作良好,但是在Outlook检索电子邮件时却突然终止。 更具体地说,该服务使用Indy从服务器自动发送电子邮件,每封电子邮件都有一个text/plain部分、text/html部分和可选的附件。这部分工作正常。当尝试在末尾类似于content text/calendar; method=request等示例的情况下将ical并入时,程序在为前面的部分编码后就会冻结,而在日历部分存在问题。 信息部分就像是一个带有ical tstrings的text/plain,内容如上所述。 - David Lindsey
那么您很可能没有正确填写TIdMessage,请展示您的实际代码。 - Remy Lebeau
以下是我的代码,添加的部分在附件等后面:Procedure Emailer.BuildCalendar(Msg_In : TIdMessage); var s: TStrings; const TAB = #9; begin try s:= TStringList.Create; s.Add('BEGIN:VCALENDAR'); ... 其他行在此处添加 ..... s.Add('END:VCALENDAR'); // 创建日历部分 with TIdText.Create(Msg_In.MessageParts, s) do begin
ContentType := 'text/calendar; method="REQUEST"; charset="UTF-8"'; ParentPart := 0 ; // IdText.CharSet end; finally s.free; end; end; .... 感谢您的使用
- David Lindsey
你没有展示完整的TIdMessage代码。然而,你设置了ParentPart:=0,这会将附件放在消息的错误层级上。ParentPart用于嵌套,而附件不应该被嵌套。请将ParentPart设置为-1。 - Remy Lebeau
就是这样。更改了ParentPart,现在可以工作了。多么尴尬啊。非常感谢您的协助。敬礼,大卫 - David Lindsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接