При отправке писем через SMTP компоненты Indy в Delphi 7 наталкивался периодически на разные проблемы.
Варианты проблем:
- отправка писем от машин, у которых - есть русские буквы в названиях
- отправка писем через SSL
- проблемы с кодировками в теме и теле письма
В интернете общего решения не находил - только разрозненные части.
Все решения свел здесь. может кому-то пригодится
Конфигурация системы:
- Delphi 7,
- Версия компонентов Indy:10.5.9.4797 (переустанавливал вручную по статье http://conferences.embarcadero.com/article/32160 файл: Indy10_4798.zip)
- ssl - библиотеки: openssl-1.0.0d-i386-win32.zip
брал отсюда http://indy.fulgan.com/SSL/
(в директорию с exe-файлом подложил libeay32.dll и ssleay32.dll)
Ключевая процедура в коде - SendEmail
Важные места подкомментировал.
uses
...
IdCoderMIME , IdMessage, IdSMTP,
IdSSLOpenSSL , IdIOHandler, IdAttachmentFile, IdExplicitTLSClientServerBase, idCharSets, idText
...
type
//-- вспомогательный класс-заглушка для подвязки события компонента indy
Tindystub = class(tobject)
public
procedure OnInitISO(var VHeaderEncoding: Char; var VCharSet: string);
end;
procedure Tindystub.OnInitISO(var VHeaderEncoding: Char;
var VCharSet: string);
begin
VCharSet := IdCharsetNames[ idcs_UTF_8 ];
end;
procedure SendEmail(
aSmtpServer: string;
aSmtpPort: integer;
aSmtpLogin: string;
aSmtpPassword: string;
aFromAddress: string;
aFromName: string;
aToAddress: string;
aMessageSubject: string;
aMessageText: string;
aAttachmentFileFullName: string;
aUseSSL: boolean = false
);
var
lMessage : TIDMessage;
lSMTP : TIdSMTP;
attach : TIdAttachmentFile;
sslHandler: TIdSSLIOHandlerSocketOpenSSL;
lindystub: Tindystub;
idtTextPart: TIdText;
begin
lMessage:= TIDMessage.Create(nil);
lSmtp:= TIDSmtp.Create(nil);
sslHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(nil);
lindystub:= Tindystub.Create();
try
lSMTP.AuthType:= satDefault;
lSMTP.Host := aSmtpServer; //Хост
lSMTP.Port := aSmtpPort; //Порт (25 - по умолчанию)
lSMTP.Username := aSmtpLogin;
lSMTP.Password := aSmtpPassword;
//-- решаем проблему отправки писем, если у компьютера руссоке имя
lSMTP.HeloName := 'tfo';
//-- отправляем почту через SSL, если надо (пока тестировал только на ukr.net)
if (aUseSSL) then
begin
SSLHandler.Destination := aSmtpServer+':'+IntToStr(aSmtpPort);
SSLHandler.Host := aSmtpServer;
SSLHandler.Port := aSmtpPort;
SSLHandler.DefaultPort := 0;
SSLHandler.SSLOptions.Method := sslvSSLv23;
SSLHandler.SSLOptions.Mode := sslmUnassigned;
lSMTP.IOHandler := SSLHandler;
lSMTP.UseTLS := utUseImplicitTLS;
end;
//-- решаем вопрос кодировки темы письма
lMessage.OnInitializeISO := lindystub.OnInitISO;
lMessage.Subject := aMessageSubject;
lMessage.From.Address := aFromAddress;
lMessage.From.Name := aFromName;
lMessage.Recipients.EMailAddresses:= aToAddress;
//-- решаем вопрос кодировки тела письма
idtTextPart := TIdText.Create(lMessage.MessageParts, nil);
idtTextPart.ContentType := 'text/plain';
idtTextPart.CharSet := 'Windows-1251';
idtTextPart.Body.Text:= aMessageText;
//-- работа со вложенными файлами
if (aAttachmentFileFullName <> '') then
begin
attach:=TIdAttachmentFile.Create(lMessage.MessageParts, aAttachmentFileFullName); //Вложение
end;
//-- собственно отправка
lSMTP.Connect;
try
lSMTP.Send(lMessage);
finally
lSMTP.Disconnect;
end;
finally
sslHandler.Free;
lMessage.Free;
lSmtp.Free;
lindystub.Free;
end;
end;
Вопросы/пожелания/предложения оставляйте в комментариях
см. также
Обработка почты через POP3 компоненты Indy10 в Delphi 7
http://dev-doc.blogspot.com/2013/02/delphi-indy-10-pop3.html
EMAIL MESSAGES FROM DELPHI. USING INDY TO SEND E-MAILS
https://community.embarcadero.com/article/technical-articles/162-programming/5913-email-messages-from-delphi-using-indy-to-send-emails
---------------------------------
UPD
Если хотите отправить почту через ukr.net
проверьте чтобы были включен параметр "POP3 и SMTP" согласно статье
http://www.qdpro.com.ua/node/17758
(если не сделать, будет выскакивать ошибка SYSERR 417)
Вот мой кривой вариант. Вроди все нормально, только не могу отправить с mail.ru (рамблер и яндекс нормально):
ОтветитьУдалитьprocedure TMessage.sendmailmessage;
var
i:integer;
begin
////подключение
IdSMTP1.Host:='smtp.mail.ru';
IdSMTP1.Port := 25;
IdSMTP1.Username:='help';
IdSMTP1.Password:='пароль';
////тело сообщения
IdMessage1.ContentType := 'multipart/mixed';
IdMessage1.Body.Text:=Memo1.Text;
IdMessage1.From.Name := 'help';
IdMessage1.From.Text:='help@mail.ru';
IdMessage1.Recipients.Add.Text:='motoarhangel@bk.ru';
// добавляем текст
TidText.Create(IdMessage1.MessageParts, idMessage1.Body);
//добавляем файлы
if ListBox1.Items.Count > 0 then
for i := 0 to listbox1.Items.Count - 1 do
begin
if (FileExists(listbox1.Items[i])) then
begin
TIdAttachmentFile.Create(IdMessage1.MessageParts, listbox1.Items[i]);
end;
end;
// указываем тип текстового блока и его кодировку
IdMessage1.MessageParts.Items[0].ContentType := 'text/html';
IdMessage1.MessageParts.Items[0].CharSet := 'Windows-1251';
////Конект и отправка
try
try
IdSMTP1.Connect();
Application.ProcessMessages;
IdSMTP1.Send(IdMessage1);
MessageBox(0, 'Письмо успешно отправленно', 'Информация', 0);
except on E:Exception do
begin
MessageBox(0, Pwidechar('Письмо не было отправленно по причине: '+E.Message), 'Информация', 0);
end;
end;
finally
if IdSMTP1.Connected then IdSMTP1.Disconnect;
end;
IdMessage1.free;
IdSMTP1.Free;
end;
Приму все пожелания и исправления =)
На яндекс и рамблер на какой порт отправляете? если не на 25-ый, то скорее всего дело в том, что 25-ый порт у вас закрыт провайдером.
ОтветитьУдалитьдля mail.ru есть альтернаивные порты без шифрования: 587 и 2525
Ну все вроди бы разобрался.
ОтветитьУдалитьА какие настройки для укр.нет Вы используете?
ОтветитьУдалитьу меня выбивает ошибку
Socket Error # 10013 Access denied.
логин и пароль правильный
проверьте настройки здесь:
Удалитьhttp://wiki.ukr.net/%D0%94%D0%BB%D1%8F_%D0%B4%D1%80%D1%83%D0%B3%D0%B8%D1%85_%D0%BF%D0%BE%D1%87%D1%82%D0%BE%D0%B2%D1%8B%D1%85_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC_%D0%B8_%D0%BF%D0%BE%D1%87%D1%82%D0%BE%D0%B2%D1%8B%D1%85_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC_%D0%BC%D0%BE%D0%B1%D0%B8%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D1%82%D0%B5%D0%BB%D0%B5%D1%84%D0%BE%D0%BD%D0%BE%D0%B2
странно, но все вроде бы так. с другими почтовыми ящиками работает нормально.
ОтветитьУдалитьправда, должен сказать что это единственный мануал, по которому удалось решить проблеммы с кодировком письма
для укр.нет должен быть обязательно включен SSL.
Удалитьв остальном же только могу посоветовать сделать новый тестовый почтовый ящик и на нем попробовать отправку писем.
Т.к. у меня этот код рабочий и используется для отправки писем в том числе и через ящики укр. нет.
По ukr.net:
Удалитьв настройках ящика включите использование "POP3 и SMTP"
по статье http://www.qdpro.com.ua/node/17758
если не сделать, будет выскакивать ошибка SYSERR 417
Спасибо! Из всего, что было в инете на данную тему - Ваш пример реально работает
ОтветитьУдалитьСпасибо, очень помогли
ОтветитьУдалитьОтличный пример! Спасибо! Всё заработало с полу-тыка, правда на ukr.net )
ОтветитьУдалить