понедельник, 17 мая 2021 г.

Проблема с IP*Works

Заметил, что при скачивании вложенных файлов из письма (которое в моем сервисе реализовано через Ip*Works, версия 20.0.7447) иногда имя вложенного файла определяется неверно. Каждый раз как "xls". Если смотреть содержимое письма в Outlooke, то там указано другое имя вложения.
Исследование под дебагером подтвердило, что проблема в стороннем софте, т.е. в компоненте Ip*Works
Далее я экспортировал письмо из Аутлука в файл и открыл его в HEX-редакторе.
В текстовой части (справа) мне удалось найти заголовки вложения. Они были закодированы по BASE-64. Когда я их раскодировал, оказалось, что это и было необходимое мне имя вложения.
Написав в тех. поддержку, я стал обдумывать как обойти эту проблему. Первая мысль была самостоятельно парсить заголовки и вместо "name" брать "filename". Но тут подоспел ответ от тех. поддержки Ip*Works, предлагали добавить магическую строчку ".Config('UseAttachmentNameParam=false');"

Таким образом, демонстрационный пример для скачивания вложений в письме с помощью Ip*Works выглядит так:

program Demo;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  ipwCore,
  ipwIMAP,
  ipwtypes,
  System.SysUtils;


var
  ImapHandle:  TipwIMAP;

procedure InitImap();
begin
  ImapHandle.MailServer := 
  ImapHandle.MailPort   := 
  ImapHandle.User       := 
  ImapHandle.Password   := 
  ImapHandle.SSLEnabled := False;
  ImapHandle.AutoDecodeParts := True;
  ImapHandle.Config('UseAttachmentNameParam=false');
end;

begin
  ImapHandle := TipwIMAP.Create(nil);
  try
    try
      InitImap();
      ImapHandle.Connect();
      ImapHandle.Mailbox := 'INBOX';
      ImapHandle.SelectMailbox();

      for var I := ImapHandle.MessageCount - 1 downto ImapHandle.MessageCount - 1 do
      begin
        ImapHandle.MessageSet := i.ToString();
        ImapHandle.FetchMessageInfo();

        WriteLn('Id         : ' + ImapHandle.MessageId);
        WriteLn('From       : ' + ImapHandle.MessageFrom);
        WriteLn('Subject    : ' + ImapHandle.MessageSubject);
        WriteLn('Flags      : ' + ImapHandle.MessageFlags);
        WriteLn('ContentType: ' + ImapHandle.MessageContentType);
        WriteLn('Size       : ' + ImapHandle.MessageSize.ToString);
        WriteLn('');

        for var j := 0 to ImapHandle.MessageParts.Count - 1 do
        begin
          if ImapHandle.MessageParts[j].Filename <> '' then
          begin
            WriteLn('    Id          : ' + ImapHandle.MessageParts[j].Id);
            WriteLn('    ContentId   : ' + ImapHandle.MessageParts[j].ContentId);
            WriteLn('    Filename    : ' + ImapHandle.MessageParts[j].Filename);
            WriteLn('    ContentType : ' + ImapHandle.MessageParts[j].ContentType);
            WriteLn('    Size        : ' + ImapHandle.MessageParts[j].Size.ToString);
            WriteLn('');
          end
        end
      end;

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

  finally
    FreeAndNil(ImapHandle);
  end;

  Write(#13#10 + 'press any key to continue...');
  ReadLn;
end.

Комментариев нет:

Отправить комментарий