После первой публикации в блоге статьи про работу Synapse с SMTP не только в комментариях к статье, но и на почту получил ряд вопросов и предложений рассмотреть работу с почтой gmail.com от Google. Честно сказать, я не знаю в чем заключается проблема отправки писем с использованием smtp.gmail.com, но всё же рассмотрю пример работы с этим почтовым сервисом. Лишней, думаю, информация не будет.
Итак, в начале рассмотрим, что такого особенного в работе Gmail.com. Во-первых, в вашем аккаунте по умолчанию отключен протокол POP3. Его необходимо включать самому в настройках. Во-вторых, сервер исходящей почты (smtp) использует SSL (порт 495). Вроде бы больше отличий никаких не обнаружилось. Что ж, воспользуемся заготовкой приложения, которую мы использовали при отправке писем с вложениями.
Так как в работе используется ssl, то обязательно в uses необходимо подключить модуль ssl_openssl. Если этого не сделать, то при работе программы никаких исключений не будет, но и письмо мы отправить не сможем. Такая вот особенность Synapse. Кстати, этот же модуль необходимо подключать при работе с https.
Итак, модуль подключен. Осталась мелочь — правильно указать логин и пароль и отправить письмо. Может быть здесь у кого-то возникали проблемы? Дело в том, что логин должен содержать @gmail.com. Например, я регистрировал аккаунт Google, используя адрес email с mail.ru, но после того как завел аккаунт в GMail, то основным адресом почты в аккаунте стал v…3@gmail.com — это и есть мой логин для smtp.gmail.com. Соответственно пароль тот же, что и у аккаунта Google.
На всякий случай, приведу полный листинг процедуры отправки письма с gmail.com:
Procedure SendMail (pHost, pSubject, pTo, pFrom , pTextBody, pHTMLBody : string); var tmpMsg : TMimeMess; tmpStringList : TStringList; tmpMIMEPart : TMimePart; begin tmpMsg := TMimeMess.Create; tmpStringList := TStringList.Create; try // Headers tmpMsg.Header.Subject := pSubject; tmpMsg.Header.From := pFrom; tmpMsg.Header.ToList.Add(pTo); // MIMe Parts tmpMIMEPart := tmpMsg.AddPartMultipart('alternate',nil); if length(pTextBody)>0 then begin tmpStringList.Text := pTextBody; tmpMsg.AddPartText(tmpStringList, tmpMIMEPart); end else begin tmpStringList.Text := pHTMLBody; tmpMsg.AddPartHTML(tmpStringList, tmpMIMEPart); end; //прицепляем к письму файл if Form1.Edit1.Text<>'' then tmpMsg.AddPartBinaryFromFile(Form1.Edit1.Text,tmpMIMEPart) // Encode and send tmpMsg.EncodeMessage; smtpsend.SendToRaw(pFrom, pTo, pHost, tmpMsg.Lines, 'LOGIN@gmail.com', 'PASSWORD'); finally tmpMsg.Free; tmpStringList.Free; end; end;
Пробуем отправить письмо, например, на yandex.ru. Письмо приходит с небольшой задержкой, но тем не менее вот результат:
Теперь попробуем отправить письмо НА gmail.com, используя ту же процедуру отправки:
Письмо пришло практически моментально. Таким образом, можно сказать, что работа с сервером smtp.gmail.com в Synapse практически ничем не отличается от работы с аналогичными серверами. Единственный момент — это необходимость подключения модуля ssl_openssl в uses.
UPDATE: Последние изменения компонента для отправки писем с GMail выложены в нашем репозитории. Последняя информация по работе с GMAil и Synapse — в этом посте.
Все работает, только в качестве параметра хост надо через двоеточие указать порт. У меня кстати на 495 порт почему-то не отправляет, а на порт 587 без проблем.
smtpsend.SendToRaw(pFrom, pTo, ‘smtp.gmail.com:587’, tmpMsg.Lines, ‘LOGIN@gmail.com’, ‘PASSWORD’);
я, когда пост писал, никаких портов не указывал. Все как в посте сказано — так и делал…не думаю, что это от версии Delphi зависит…
Интересно узнать, а как приделать progressbar к этой программе, чтобы как в настоящих клиентах он закрашивался по мере передачи сообщения. Так же не понятно как указывать кодировку отправляемого письма (юникод, вин1251, кои8р)
Спасибо за статью.
А как по поводу работы через proxy?
Ну так Synapse с proxy дружит :)
Енто так и было задумано испоганить нормальый код вполне независмиой процедуры?
Добавлением строчек:
//прицепляем к письму файл
if Form1.Edit1.Text» then
tmpMsg.AddPartBinaryFromFile(Form1.Edit1.Text,tmpMIMEPart)
Логичнее на вход добавить: AttFiles: String или AttFiles: TStrings (смотря как вам удобнее парсить внутри функции).
Тоже самое касется забитых ‘LOGIN@gmail.com’, ‘PASSWORD’ прямо в текст. Лучше через параметры на вход передавать.
Так же имеет смысл перестроить порядок параметров и части параметров присвоить значения по умолчанию. :)
Мы у себя накатали подобную функцию, вынесли её в отдельный модуль, и там где надо легко цепляем в проектах, очень удобно.
Очень за вас рад, продолжайте в том же духе
А можете выложить плз исходник рабочей версии программы етого примера а то мой чтото не работает. спасибо.
Для тех у кого не отправляются письма.
Необходимо иметь библиотеки (ssleay32.dll, libeay32.dll) в директории программы.
Взять можно http://indy.fulgan.com/SSL/Archive/indy_openssl096.zip
2fank, а при чем тут Indy? )
Добавь для TGMailSMTP в Destroy «FMsg.Free;», а то утечка памяти
destructor TGMailSMTP.Destroy;
begin
FFiles.Free;
FRecipients.Free;
FMsg.Free;
inherited;
end;
SergeyRock, спасибо. Поправил. Обновленный модуль находится здесь:
http://github.com/googleapi/googleapi/tree/master/packages/gmail_pack/
совсем для чайников объясните, плиз, как в uses подключить модуль ssl_openssl ?
Алексей…я как бы в тупике…но всё-таки попробую объяснить. находите раздел uses в модуле, ставите запятую перед знаком ; и сразу же пишите ssl_openssl. Должно получиться как-то так: uses …., sslopen_ssl; вместо троеточия — куча всяких других модулей.
Странно, но когда я отсылаю почту с gmail на mail, то письмо приходит на оба ящика.
Проверяйте правильность заполнения поля получателя
А может стоит в GMailSMTP.pas объединить Login и FromEmail, так как авторизоваться можно и по FromMail. Или я ошибаюсь и где-то действительно нужен параметр FromMail?
авторизуетесь с ящика накоторый отсылаете письмо — получить два письма на оба ящика :)
Огромное спасибо за полезную информацию. Долго бегал с бубном вокруг IdSMTP. А тут все и сразу получилось, нарадоваться не могу. Еще есть вопрос, а как отправить скрытую копию письма через Synapse
var
mm: TMimemess;
..
begin
…
mm := TMimemess.create;
mm.Header.CCList.Add(copymail);;
У меня соединение устанавливается,но ничего не передается(
Большое спасибо за статью — столько искал, работающий код нашёл только у вас
Спасибо, все работает как часы :) Нашел маленький минус — после использования метода Clear, перестает посылать тело письма. Лечится добавлением в метод Clear строки:
FMIMEPart:=FMsg.AddPartMultipart(‘alternate’,nil);
[…] параметр HOSTED, то можно привести пример с тем же GMail. Имея бесплатный почтовый аккаунт Вы можете без […]
Здравствуйте.
Сегодня яндекс ввел шифрование ssl для работы с почтой. Надеялся, что приведенный пример мне поможет, но на моменте SMTP.Login в методе SendToRaw у меня происходит залипон секунд на 10 и логин не проходит.
Входные параметры в процедуру указывал
SendMail(‘smtp.yandex.ru:495’, ‘проверка отправки’, ‘PBednyagin@mail.ru’, ‘softerium@yandex.ru’, ‘Проверка тела письма’, »);
dll-ки копировал, порт 587 менять пробовал, не помогло :(
Кто-нибудь уже эксперементировал с яндексом?
FSMTP.TargetHost:= smtp_url;
FSMTP.TargetPort:= smtp_port;
FSMTP.UserName:= smtp_username;
FSMTP.Password:= smtp_pass;
FSMTP.FullSSL:= True;
Result:= FSMTP.Login and FSMTP.AuthDone;
//——
но при этом не забудь подключить в uses ssl_openssl; и к exe’шнику в папку бросить две dll’ки ssleay32.dll и libeay32.dll
Например у меня работает так:
SMTPClient.TargetHost:=’smtp.yandex.ru’;
SMTPClient.TargetPort:=25;
SMTPClient.UserName:=edUser.Text;
SMTPClient.Password:=edPassword.Text;
SMTPClient.AutoTLS:=true;
В uses ssl_openssl + библиотеки в папке программы. Все работает на ура.