Domain üzerinden E-posta gönderme

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Domain üzerinden E-posta gönderme

Mesaj gönderen mmg »

Merhaba,

Aşağıda ki kodu kullanarak e-posta gönderimi yamak istiyorum. Kendim yandex mail kullanıyorum ve aşağıda görülen gerekli bilgileri yerlerine girince e-posta gönderimi yapabiliyorum. Fakat e-postalarını içeride kendi bünyesinde kendi domain server'ında tutan ortamda e-posta gönderemiyorum, "SSL Negotiation failed" hatasını veriyor. Kullandığım kodu olduğu gibi paylaşıyorum. Bu konuda yardımlarınızı rica ediyorum.

Kod: Tümünü seç

var
  Attachmentfile: TIdAttachmentFile;
begin

  if MessageBox(Handle, PChar(TrimLeft(TrimRight(T_SIPARISYETKILI_ADI.Value))+' yetkilisi '+TrimLeft(TrimRight(T_SIPARISE_POSTA.Value))+' adresine e-posta gönderilecektir, devam etmek istiyor musunuz ?'),'Uyarı',mb_YESNO)= id_No then
     exit;

  // IO HANDLER SETTINGS //
  With IdSSLIOHandlerSocketOpenSSL1 do
  begin
    Destination := T_SISTEMSMTP_HOST.Value;
    Host := T_SISTEMSMTP_HOST.Value;
    MaxLineAction := maException;
    Port := T_SISTEMSMTP_PORT.Value;
    SSLOptions.Method := sslvTLSv1;
    SSLOptions.Mode := sslmUnassigned;
    SSLOptions.VerifyMode := [];
    SSLOptions.VerifyDepth := 0;
  end;

  // SETTING SMTP COMPONENT DATA //
  SMTP.Host := T_SISTEMSMTP_HOST.Value;          //.. smtp.yandex.com.tr;
  SMTP.Port := T_SISTEMSMTP_PORT.Value;          //.. 587; -->yandex giden posta için bu port numarasını kabul ediyor.
  SMTP.Username := T_SISTEMSMTP_USERNAME.Value;  //.. emailadresin@domainadi.com
  SMTP.Password := T_SISTEMSMTP_PASSWORD.Value;  //.. Kullanıcı şifresi;
  SMTP.IOHandler:= IdSSLIOHandlerSocketOpenSSL1;
  SMTP.AuthType := satDefault;
  SMTP.UseTLS := utUseExplicitTLS;

  //.. FASTREPORT İLE PDF FİLE OLUŞTURUYOR.
  try
    if not DirectoryExists('C:\Temp') Then // Klasör yoksa
       If not CreateDir('C:\Temp') Then // Oluştur
       begin
         showmessage('C:\Temp klasörü oluşturulamadı.');
         Exit;
       end;
    if not DirectoryExists('C:\Temp') Then // Klasör yoksa
       If not CreateDir('C:\Temp') Then // Oluştur
       begin
         showmessage('C:\Temp klasörü oluşturulamadı.');
         Exit;
       end;

    frxSIPARIS_RPT.Report.LoadFromFile(ExtractFilePath(ParamStr(0))+'Rapor\SIPARIS_RPT.fr3');

    frxSIPARIS_RPT.PrintOptions.ShowDialog := False;
    frxSIPARIS_RPT.PreviewOptions.AllowEdit:= False;
    frxSIPARIS_RPT.ShowProgress:= false;
    frxSIPARIS_RPT.EngineOptions.SilentMode:= True;
    frxSIPARIS_RPT.EngineOptions.EnableThreadSafe := True;
    frxSIPARIS_RPT.EngineOptions.DestroyForms := False;
    frxSIPARIS_RPT.EngineOptions.UseGlobalDataSetList:= False;

    frxPDFExport1.Background:= True;
    frxPDFExport1.ShowProgress:= False;
    frxPDFExport1.ShowDialog:= False;
    frxPDFExport1.DefaultPath:= '';

    if length(T_SISTEMLOGO.Value)>0 then
      (frxSIPARIS_RPT.FindObject('LOGO') as Tfrxpictureview).picture.LoadFromFile(ExtractFilePath(ParamStr(0))+T_SISTEMLOGO.Value)
    else
      (frxSIPARIS_RPT.FindObject('LOGO') as Tfrxpictureview).Visible:= false;
    (frxSIPARIS_RPT.FindObject('BELGE_NO') as Tfrxmemoview).Memo.Text:= T_SIPARISSERI.Value+'-'+IntToStr(T_SIPARISFIS_NO.Value);
    (frxSIPARIS_RPT.FindObject('BELGE_TAR') as Tfrxmemoview).Memo.Text:= DateToStr(date());
    (frxSIPARIS_RPT.FindObject('HESAP_ADI') as Tfrxmemoview).Memo.Text:= T_SIPARISHESAP_ADI.Value;

    frxSIPARIS_RPT.PrepareReport();
    frxPDFExport1.FileName := 'C:\Temp\'+TrimLeft(TrimRight(T_SIPARISFIS_NO.Value))+'.pdf';
    frxSIPARIS_RPT.Export(frxPDFExport1);

  except on e:Exception do
    begin
      ShowMessage(e.Message);
      exit;
    end;
  end;

  // mail gönderiliyor //
  MailMessage.Clear;
  MailMessage.CharSet:= 'utf-8';

  // alıcılar listesi //
  with MailMessage.Recipients.Add do
  begin
    Name := TrimLeft(TrimRight(T_SIPARISE_POSTA.Value));    //.. alıcı adı
    Address := TrimLeft(TrimRight(T_SIPARISE_POSTA.Value)); //.. alıcı@email.com
  end;

  // CC listesi //
  with MailMessage.CCList.Add do
  begin
    Name := '';     //.. CC alıcı adı
    Address := '';  //.. CCalıcı@email.com
  end;

  // e-postaya dosya ekleme //
  Attachmentfile := TIdAttachmentFile.Create(MailMessage.MessageParts,'C:\Temp\'+TrimLeft(TrimRight(T_SIPARISFIS_NO.Value))+'.pdf');

  MailMessage.From.Address :=  T_SISTEMSMTP_USERNAME.Value; //.. emailadresin@domainadi.com
  MailMessage.Subject := 'SİPARİŞ E-POSTA TEST';
  MailMessage.Body.Text := 'BU E-MAIL ULAŞTIYSA ARAYABİLİR MİSİN ?';

  MailMessage.Priority := mpHigh;
  TRY
    SMTP.Connect();
    SMTP.Send(MailMessage);
    ShowMessage('E-Posta gönderildi.');
    SMTP.Disconnect();
  except on e:Exception do
    begin
      ShowMessage(e.Message);
      SMTP.Disconnect();
    end;
  END;
  AttachmentFile.Free;
ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen ertank »

Merhaba,

Kullandığınız Indy sürümünü bildirmemişsiniz. Bazı sistemlerde çok eski olabiliyor. Indy v10.6.2.0 (Delphi 10.4.2 ile gelen) sürüm ile sorunsuz SMTP iletişimi kullanıldığını biliyorum.

Aldığınız hata mesajını tam olarak paylaşmamışsınız. Bazı konularda varsayımda bulunmak gerekecek.

Aşağıdaki maddeleri kontrol etmenizde fayda var.
1- Ham hata mesajının tamamını kontrol edin. Mail göndermek istediğiniz sunucu "ImplicitTLS" istiyor olabilir. Eğer gelen hata mesajı içinde STARTTLS kelimesi var ise istiyordur.
2- IdSSLIOHandlerSocketOpenSSL1 nesnesini oluşturmanız yeterli. Parametrelerini çoğu zaman değiştirmenize gerek yok. Aşağıdaki koda benzer şekilde kullanmanız genelde yeterlidir.

Kod: Tümünü seç

    MySMTP := TIdSMTP.Create(nil);
    if SecureConnection then
    begin
      IdSSLIOHandlerSocket := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
      MySMTP.IOHandler := IdSSLIOHandlerSocket;
    end;
3- TLS v1 oldukça eski ve artık terk edilmekte olan bir protokoldür. Sunucunuz eğer TLS v1.2 zorunlu kılıyor ise bu şekilde bağlantı sağlayamazsınız. IdSSLIOHandlerSocketOpenSSL1 oluşturulduğunda standart olarak sadece TLSv1.0 kullanır. Günümüzde IdSSLIOHandlerSocketOpenSSL1 için tek satırlık parametre düzenlemesi yapmanızda fayda var.

Kod: Tümünü seç

  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
Bunun dışında with ile başlayan IdSSLIOHandlerSocketOpenSSL1 ile ilgili diğer tüm satırları kodunuzdan kaldırabilirsiniz.

E-maili nereden gönderdiğinizin önemi yok. Hedef SMTP sunucu iletişim gerekliliklerini bilip ona uygun bağlantı kurmaya çalışmalısınız.
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen mmg »

ertank merhaba,

Yardımınız için çok teşekkür ediyorum, kodu aşağıda ki blok hariç belirttiğiniz şekilde düzenlemeye çalıştım fakat bazı noktaları belirtmek ve sormak istiyorum. Kendi bilgisayarım haricinde çalışma anında hala hata veriyor ve verdiği hata "SSL Negotiation failed" şeklinde ne bir harf fazla ne bir harf eksik. Çok açıklayıcı değil biliyorum fakat başka bir mesaj çıkmıyor. Bu arada şöyle bir deneme yaptım, e-posta gönderemedim ve belirttiğim hatayı aldığım bilgisayarda kendi e-posta bilgilerimi girerek mail atmaya çalıştığımda da aynı hatayı verdi. Kendi bilgisayarımda Delphi 10.2 kurulu acaba karşı tarafta eksik olan bir dll yada kurulumdan dolayı bu hatayı veriyor olabilir mi ? Sonuç olarak kendi bilgisayarımda e-posta gönderirken bu kod çalışıyor fakat farklı bir bilgisayarda çalışmıyor. Delphi 10.2 kullanıyorum ve dışarıdan hiç bir yükleme yapmadım her şey üzerinde geldiği gibi.

Birde;

Aşağıda ki kodda "SecureConnection" ve "IdSSLIOHandlerSocket" için derleme anında bilinmeyen nesne hatası veriyor.

MySMTP := TIdSMTP.Create(nil);
if SecureConnection then
begin
IdSSLIOHandlerSocket := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
MySMTP.IOHandler := IdSSLIOHandlerSocket;
end;

Yardımlarınız için çok teşekkür ediyorum.
ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen ertank »

Merhaba,

IdSSLIOHandlerSocket benim size kullanım örneği için verdiğim bir kod parçası idi. Sizin direk alıp kullanabileceğiniz bir örnek kod değildi.

Kendi bilgisayarınızdaki ve hata aldığınız bilgisayardaki EXE dosyanız ile aynı dizindeki "ssleay32.dll" ve "libeay32.dll" sürümlerini kontrol edin. Hata alınan bilgisayardaki daha eski ise güncellemek gerekiyor olabilir. EXE dosyanızın yanında bu dosyalar yok ise ihtimal C:\Windows dizininde olabilir.

Aldığınız hata öncesinde oluşan hatalar olup siz nihai en son hata mesajını görüyor olabilirsiniz. Dolayısıyla hata alabilecek yerler için try..except bloklarını kullanarak hata mesajını log dosyasına yazdırmanızda fayda var.
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen mmg »

Merhaba,

IdSSLIOHandlerSocket ile ilgili sorum için çok özür dilerim, hataya odaklanmamdan dolayı gözden kaçırmışım. Söylediğiniz 2 dll dosyasını hata aldığım bilgisayarda bulamadım. Kendi bilgisayarımdan "C:\Program Files (x86)\Embarcadero\Studio\19.0\bin\subversion" klasöründen alarak hata veren bilgisayarda exe dosyasının olduğu yere kopyaladım ve hata vermedi fakat e-postayı da göndermiyor. Neden göndermiyor olabilir acaba ?
ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen ertank »

Merhaba,

Sorunuzun birçok farklı sebebi olabilir. Bunu daha önce de bahsettiğim log benzeri bir işlem yapmadan öğrenmeniz oldukça zor. TIdSMTP bileşeninin Onstatus olayı vardır. Başlangıç olarak bunu kullanarak olay içinde gelen AStatusText değerini kayıt ederek başlayabilirsiniz. Aşağıdakine benzer kayıtlar olacaktır. Bunlardan başlayarak sorunun nerede olduğunu anlamaya çalışabilirsiniz.

Kod: Tümünü seç

Connecting to 1.1.1.1
Connected.
Encoding text
Disconnecting.
Disconnected.
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen mmg »

ertank merhaba,

Sorun çözüldü, yardımlarınız için çok teşekkür ediyorum. mail gönderme çalışıyor. Aslında belirttiğiniz 2 dll dosyasını uygulamanın olduğu klasöre kopyalayınca sorun çözülmüş. SMTP.Host alanına kayıtlı IP numarasını hatalı yazdığımız için göndermediğini anladık. IP numarasını düzelttik ve şu an mail gidiyor, yukarıda ki kod çalışıyor. Tabii 2 dll dosyasının uygulamanın olduğu yere kopyalanması gerekiyor.
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen mmg »

Yine geldim, ilerleyen süreçte şöyle bir sorun ile karşılaştım. Uygulamanın kurulu olduğu sanal sunucuda mail atma sorunsuz çalışıyor fakat terminallerde "Error: authentication failed: UGFzc3dvcmQ6" hatası veriyor. Server üzerinde ki kullanıcı bilgileri ile terminallerde deneme yapıyorum fakat bir şey değişmiyor. Bu problem ile ilgili yardımcı olabilir misiniz ? Google'da hatayı aradım fakat net bir yanıt bulamadım.
ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen ertank »

mmg yazdı: 17 Kas 2022 09:17 Tabii 2 dll dosyasının uygulamanın olduğu yere kopyalanması gerekiyor.
Terminallerdeki DLL sürümlerinin doğru olduğunu kontrol ettiniz mi?
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen mmg »

Merhaba,

Terminallerde uygulamanın yüklü olduğu bir klasör yok server'a kısa yol ile bağlanarak çalışıyor uygulama bende terminallerdeki windows ve windows\system32 klasörlerinin her ikisinede serverda uygulamanın olduğu dizindeki bu 2 dll dosyasını kopyaladım. Serverda çalışıyorsa terminallerde de çalışması gerekirdi diye düşünmüştüm, yanlış mı düşünüyorum acaba ? Birde bu 2 dll doğru sürüm olduğunu nasıl kontrol edebilirim ?
ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: Domain üzerinden E-posta gönderme

Mesaj gönderen ertank »

Sanal sunucudaki ile Terminallerdeki EXE'nin kesinlikle aynı olduğuna emin misiniz?
Hata mesajındaki okunamaz veri kısmına bakınca sanki deşifre edilmemiş veya hatalı deşifre edilmiş veri ile erişim sağlamaya çalışıyorsunuz gibi gözüküyor.

https://www.gezginler.net/indir/hashtab.html

Bu uygulamayı terminale kurun. EXE için SHA hash değeri hesaplatın. (Uygulama Dosya özellikleri kısmında TAB olarak gözükür)
Aynı Hash hesabını sanal sunucuda da yaptırın. Aynı dosyalar olduğuna emin olun.

Aynı dosylar ise log dosyasına kullanıcı adı ve şifre bilgilerini de yazdıran yeni bir sürüm hazırlayın. Bununla sanal sucunu denemesi ve terminal bağlantı denemesi yapın.

Aynı EXE kullanılıyor ise parametre tanımları terminale özel değil ve global tek ise her iki şekilde de çalışmasını beklerim.

Ancak, daha önce Administator kullanıcı yetkisine sahip olmadan RDP kullanan kullanıcılarda değişik kısıtlamalar olduğunu biliyorum. Bunu da kontrol etmenizde fayda var.

Bu noktadan sonrası artık kodlama dışına çıkıyor gibi maalesef.
Cevapla