Wysłanie maila z wtopionymi obrazami

0

Cześć, męczę się z tym już drugi dzień, wertuje Internet i nadal nic.
Używam INDY 10.0.20. O ile nie mam żadnego problemu z wysłaniem zwykłego maila(plain text), nie mam też problemu z wysłaniem maila z załącznikiem, to nie mogę sobie dać rady z wysłaniem maila, w którym obrazy są wtopione w jego treść. Próbowałem już miliardy kombinacji i efekt jest taki, że na jeden serwer w ogóle mail nie dochodzi, na drugi dochodzą dziwne rzeczy.

Kod jest następujący (założenie, że jest tylko jeden obraz):

var
  SMTPServer: TIDSMTP;
  IDMsg: TIDMessage;
begin
  IDMsg:=TIDMessage.Create;
  IDMsg.ClearHeader;
  IDMsg.ContentType='multipart/mixed';

  //dodawanie załącznika
  with TIDAttachmentFile.Create(IDMsg.MessageParts, 'D:\plik.jpg') do
  begin
    ContentType='image/jpeg';
    ContentDisposition='inline';
    ContentID:='0';
  end;

  IDMsg.Subject:='Temat';
  IDMsg.Body.Text:='Treść '+#13#10+'<img src="cid:0" />';
  IDMsg.BccList.EMailAddresses:='prawdziwy_adres@mail.com';
  IDMsg.From.Name:='Juhas';
  IDMsg.From.Address:='mail@juhasa.net';
  IDMsg.ReplyTo.EmailAddresses:='mail@juhasa.net';

  SMTPServer:=TIDSMTP.Create;
  //tu wypełniam pola SMTPServer

  SMTPServer.Connect;
  SMTPServer.Send(IDMsg);
  SMTPServer.Disconnect;

end;

Już nie wiem, co mam robić. Siedzę, analizuję nagłówki, czytam w necie i niby wszystko powinno być ok, a nie jest. Treść wiadomości umieszczałem też między znacznikami: <html><body> i </body></html>
Nic to nie daje.

Zaczynam wątpić w Indy. Jeśli Wam też nie uda się wysłać takiego maila, to może znacie jakiś alternatywny sposób wysyłania maili? Jakiś komponent, biblioteka, cokolwiek. Wymaganie jest tylko takie, żeby to było darmowe(również do komercyjnego użytku) i, żeby działało na każdym komputerze z Windowsem.

Pytanie poza konkursem:
Wszędzie w necie znajduje kody z użyciem "with TIDAttachmentFile.Create". Zastanawia mnie to dość mocno. Czy to jest jakaś konkretna specyfika? Czy IDMessage potem czyści te obiekty, czy prowadzi to po prostu do memory leaków?

0

OK, pogrzebałem jeszcze trochę i coś się udało (na Indy 10.5.8 w XE2, na INDY 10.0.20 w Delphi 2005 jeszcze nie próbowałem). Ale tylko połowicznie. Problem jest taki, że wszystko działa ok i jest ładnie pokazywane w Microsoft Outlook. Natomiast w klientach pocztowych internetowych(np. gmail), obrazek nie jest pokazywany. Zamiast niego jest kwadracik. Dlaczego?

Oto mój kod:

var
  SMTPServer: TIDSMTP;
  IDMsg: TIDMessage;
  IDTextHTML: TIDText;
begin
  IDMsg:=TIDMessage.Create;
  IDMsg.ClearHeader;


  with TIDText.Create(IDMsg.MessageParts) do
  begin
    ContentType:='text/html';
    Charset:='utf-8';
    Body.Text:='<html><body>Treść '+#13#10+'<img alt="Obrazek" src="cid:0"></body></html>';
  end;

    //dodawanie załącznika
  with TIDAttachmentFile.Create(IDMsg.MessageParts, 'C:\plik.jpg') do
  begin
    ContentType:='image/jpeg';
    ContentDisposition:='inline';
    ContentID:='0';
    FileName:='plik.jpg';
  end;

  IDMsg.ContentType:='multipart/related';

  IDMsg.Subject:='Temat ąśżźćńółę';
  IDMsg.BccList.EMailAddresses:='poprawny_adres_email';
  IDMsg.From.Name:='Juhas';
  IDMsg.From.Address:='poprawny_adres_email';
  IDMsg.ReplyTo.EmailAddresses:='poprawny_adres_email';

  SMTPServer:=TIDSMTP.Create;
  SMTPServer.AuthType:=satDefault;
  SMTPServer.MailAgent:='Test';
  SMTPServer.Username:='user';
  SMTPServer.Password:='pass';
  SMTPServer.Host:='serwer';
  SMTPServer.Port:=25;

  SMTPServer.Connect;
  SMTPServer.Send(IDMsg);
  SMTPServer.Disconnect;

  FreeAndNil(IDMsg);
  FreeAndNil(SMTPServer);

  showMessage('Poszło');
end;
0

Spróbuj tak:

  //ciach
  IdMessage1.Subject:= 'Jakie to Indy jest be...';
  IdMessage1.ContentType:= 'multipart/mixed';

  html:= TIdText.Create(IdMessage1.MessageParts);
  html.ContentType:= 'text/html';
  html.Body.Add('<h1>Witam</h1>');
  html.Body.Add('To jest <span style="color: #FF0000;">testowa</span> wiadomość');
  html.Body.Add('Wysłana przez <strong>IdSMTP</strong>.');
  html.Body.Add('<p><img src="cid:mojtest.jpg" /></p>');
  html.Body.Add('z osadzonym załącznikiem :)');

  attach:= TIdAttachmentFile.Create(IdMessage1.MessageParts, 'C:\mojtest.jpg');
  attach.ContentType := 'image/jpeg';
  attach.FileIsTempFile:= false; //true jak plik zalacznika ma byc usuniety po wyslanu
  attach.ContentDisposition := 'inline';
  attach.ExtraHeaders.Values['content-id'] := 'mojtest.jpg';
  attach.DisplayName := 'mojtest.jpg';
  
  IdSMTP1.Send(IdMessage1);
  //ciach

Konstrukcja with TIDAttachmentFile.Create do w przypadku TIDAttachmentFile ani TIdText nie spowoduje wycieku pamięci chyba dlatego że za ich zwolnienie odpowiedzialny jest IdMessage. Jednak ja wolę "tradycyjną" składnię ponieważ "with ... do" czasem nie działa jak trzeba (źle interpretuje gdy kilka obiektów ma tą samą właściwość). W ten sposób oczywiscie też nie trzeba zwalniać html (TIdText) ani attach (TIdAttachmentFile).

0

Nie działa ten kod niestety. Ale dzięki za wyjaśnienie co do with...

0

OK, jest krok dalej. Nie uwierzycie. Okazuje się, że Content-ID nie może być jakikolwiek. Miałem: "0" - nie działało w klientach internetowych. Zmieniłem na: "0abc" - zaczęło działać w jednym z klientów internetowych, ale gmail nadal nie pokazuje obrazka

2

OK, udało się. Content-ID musi być odpowiednio sformatowane. Przynajmniej to jest wymóg gmail'a.
Otóż, żeby gmail obsłużył dobrze, content-id musi być między znakami: < > i musi być w formie adresu serwera, np:
Content-id=losowy_ciag@test.pl

Okazuje się, że wcale nie musi być host serwera SMTP, ale myślę, że lepiej, żeby był, bo z kolei inni klienci mogą mieć jeszcze inne ograniczenia. A więc podsumowując, ustawiajcie content-id w sposób następujący:
Content-ID=losowy_ciag@serwer.pl

Jeśli wysyłamy z onetu, to: losowy_ciag@onet.pl
Wtedy wszystko powinno chodzić.

No, teraz można iść na wódkę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1