В качестве небольшого бонуса своим читателям, которые заинтересовались работой с почтой GMail из Delphi, написал небольшой компонент для отправки писем через аккаунт GMail. В принципе, сам по себе этот компонент может использоваться для работы и с другими smtp-серверами, например, с mail.ru, но обо всем по порядку.
Во-первых, сразу предупреждаю, что для работы компонента необходимо иметь под рукой библиотеку Synapse. Так уж сложилось, что с ней мне работать намного удобнее, чем с Indy.
Во-вторых, скачать компонент, а также его исходники Вы можете со страницы нашего общего проекта на Google Code.
Теперь, непосредственно по работе с компонентом. У компонента TGmailSMTP определены следующие публичные свойства:
Login: string — логин для smtp-сервера. У Gmail совпадает с адресом электронной почты
Password: string — пароль для smtp-сервера. Совпадает с парольем к аккаунту
Host: string — хост smtp-сервера. По умолчанию smtp.gmail.com
FromEmail: string — адрес email с которого отправляется письмо
FromName: string — имя отправителя
Port: integer — порт. По умолчанию 587. Если значение равно 0, то используется порт по умолчанию для smtp
AttachFiles: TStrings — список файлов для отправки
Recipients: TStrings — список адресов получателей
А также для свойства для работы непосредственно с объектами Synapse:
property GMessage:TMimeMess read FMsg write FMsg; property MIMEPart:TMimePart read FMIMEPart write FMIMEPart;
Для отправки письма всем получателям используется метод:
function SendMessage(const aSubject:string; aClear:boolean=true):boolean;
Параметры метода:
aSubject:string — тема отправляемого письма
aClear:boolean — определяет будут ли очищены все поля сообщения после отправки.
В целом, работа с компонентом проста как три копейки:
1. Кидаете компонент на форму
2. Заполняете поля. При этом поле FromName может оставаться пустым
3. Вызываете метод SendMessage
Компонент протестирован на Delphi 2010, письма отправлялись с gmail.com на mail.ru и yandex.ru, а также наоборот — с mail.ru на gmail.com. При отправки письма не с gmail свойство port должно быть равно 0 или содержать номер пора по умолчанию.
Демо по работе с компонентом также находится на странице загрузок нашего проекта.
UPDATE: Tсли компонент не отправляет письма — читайте этот пост. Вполне возможно, что проблема в отсутствии необходимых DLL
Хорошо бы ещё указать, чем это отличается от стандартного компонента SMTP.
Да практически ни чем :) Просто использует пару модулей Synapse. Был где-то вопрос по поводу smtp не то в почте не то в блоге — как установить для заголовка письма одну кодировку, а для тела — другую. Хз зачем это надо, но ради интереса добавлю в компонент эту возможность
В чем может быть проблема:
хочу отправить с mail.ru — ввожу Login, Password, Host(smtp.mail.ru) — не отправляет
хочу отправить с gmail.com — ввожу Login, Password, Host(smtp.gmail.com) — не отправляет
хочу отправить с rambler.ru — ввожу Login, Password, Host(smtp.rambler.ru) — Отправляет !!!
Так… с mail.ru проблема была на моей стороне)
А с gmail.com всё равно не отправляет(
на gmail.com логин к smtp как записываете? c @gmail.com? Порт 587? Проверил работу на 2-х разных ящиках gmail — все отправляется без проблем.
Стилистические замечания к коду в GMailSMTP.pas:
property GMessage:TMimeMess read FMsg write FMsg;
property MIMEPart:TMimePart read FMIMEPart write FMIMEPart;
совсем не понимаю, зачем в описании свойств указана write-часть? имхо, такие свойства обычно делаются read-only, чтобы не дать возможность пользователям переписать переменную и допустить утечку памяти!
Gmail исползует ssl шифрование
поэтому и прицепляем в проект модуль ssl_openssl, а в Indy dll-ки храним с проектом :)
а на gmail не отправляет потому что в компоненте запускается функция smtpsend.SendToRaw в которой по умолчанию закомментированы
SMTP.AutoTLS := True; и //SMTP.FullSSL := True;
а gmail требует или ту или другую в зависимости от порта (465 или 587).
У меня никак не хочет отправляться, SendToRaw всегда вовзращает False. Менять AutoTLS и FullSSL пробовал.
Keeper, то что тут написано смотрел? Модуль модуль ssl_openssl подключен? протокол POP3 включен в настройках? Порт указан 495? Проверил у себя уже раз 100 — отправляется все :) Глянь в настройках gmail — мож чего забыл включить.
Да и ещё один момент — если пароль содержит спецсимволы, то можно попробовать его передать его в параметры в закодированном виде, т.е. как-то так
EncodeURL(password)
Смотрел.
ssl_openssl есть, есть POP3, спец. символов в пароле нет. POP3 включается странно: ставлю 1 или второй радиобаттон, жму сохранить, а в настройках по-прежнему ничего не выделено, но написано » Состояние: POP включен для всех писем, полученных с 13 июля.».
Порт указываю 587 (так рекомендовано в настройках + telnet соединяется по нему, по 495 не хочет).
Код:
[code]
...
Msg.Header.ToList.Add(ATo); //имя и адрес получателя
// создаем корневой элемент
MIMEPart := Msg.AddPartMultipart('alternative', nil);
Msg.AddPartHTML(AHTMLBody, MIMEPart);
// Кодируем и отправляем
Msg.EncodeMessage;
Result := smtpsend.SendToRaw(AFrom, ATo, AHost, Msg.Lines,
ALogin, APassword);
end;
[/code]
Ок, Keeper, сегодня уже врядли чего путнего скажу, т.к. у меня время позднее — спать пора, горшок звенит и всё такое :) Завтра первым делом разберусь с gmail. Если получиться слишком много объеснений — запостю пост, а так — откомментируюсь тута.
Ок, спасибо )
Начал разбираться со gmail ещё раз. Обнаружил на тестовом акке следующую проблему — Synapse вупор не хочет выполнять SSLC0nnect — выдает ошибку 10091. Подозреваю, что проблема с Синапсом…Буду разбираться дальше
Пока не поставил Microsoft Visual C++ Runtime Library
почта «тихо» не уходила…Ошибок не выдавала.
Добрый день, пробую ваш компонент, все работает. Решил добавить ProgressBar чтобы видеть как идет закачивание на сервер. [code] procedure TForm2.GMailSMTP1Status(Sender: TObject; Reason: THookSocketReason; const Value: string); begin Application.ProcessMessages; StatusBar1.Panels[0].Text:=GetEnumName(TypeInfo(THookSocketReason),ord(Reason))+ ' '+Value; if Reason=HR_WriteCount then begin Download:=Download+StrToInt(value); end; end; [/code] Размер письма по этому методу получается больше где-то в полтора раза больше размера вложений. Я прекрасно понимаю, что это нормально и что это и служебные запросы и сам формат письма для smtp перекодируется. Из-за этого растет размер. Вопрос же в следующем, как можно адекватно узнать размер отправляемого письма? Ведь по спецификации, как я… Подробнее »
Извините, но установить ваш компанент не получается….
Андрей, а по-конкретнее? Synapse есть? Какая версия Delphi? Почему не получается установить?
Установить получилось только пришлось ручками чуть чуть подправить. Delphi 7. 1. При установке компилятор выдал ошибку на первую строчку, там кракозябры были какето перед фигурной скобкой где идёт описание Убрал. 2. Дальше выдал ошибки на строки {REGION {ENDREGION Закоментил 3. Закинул необходимы файлы *.pas от Synapse которых рядом с компонентам не было. В туже папку с компанентом 4. Пришлось редактировать файл *.dpk (или какое там расширение не помню) в самом конце изменил путь к файлам *.pas и только после этого всё установилось. Не знаю мб криво чтото встало, но отправить почтку с gmail получилось с первого раза. Отдельно хочу сказать… Подробнее »
Привет! Нет возможности скачать компонент: 404 ошибка
Влад, проблемка одна возникла. Отправляю письма из базы, один клиент = одно письмо. Получается что письмо с прикреплёными файлами уходит только первому клиенту, а все остальные письма без прикреплённых файлов!!! ДАже если создать новую рассылку! Вообще получается что рассылка происходит только один раз при запуске проги, а дальше шиш! Мб подскажите почему так?
Dozent, интересный вопрос :) Ок, гляну. А как письма отправляются: каждый раз создается новый объект или просто в поле отправителя вбивается список адресов получателей?
ну процесс отправки примерно следующий, взяли первого из списка рассылки, получили адрес эл. почты, вписали его в Recipients, получили список путей к файлам для данной рассылки, добавили в AttachFiles, отправка! Потом берём следующего и так до конца списка… Мб в коде будит понятнее with fmDM.ESEND do begin First; fmDM.GMail.AttachFiles.Clear; //очищаем список файлов While not EOF do begin if (FieldbyName(‘STATUS’).AsInteger=0) and (FieldbyName(‘E_MAIL’).AsString») then begin fmDM.GMail.FromEmail:=’mail@gmail.com’; fmDM.GMail.FromName:=’Компания’; fmDM.GMail.Login:=’mail@gmail.com’; fmDM.GMail.Password:=’password’; fmDM.GMail.Recipients.Add(FieldbyName(‘E_MAIL’).AsString); //Добавление аттачей with fmDM.IBATT do begin SQL.Text:=’select * from EATTACH where id_mail= :id’; ParamByName(‘id’).AsInteger:=fmDM.ESEND.FieldByName(‘id_mail’).AsInteger; Open; First; While not EOF do begin fmDM.GMail.AttachFiles.Add(FieldByName(‘PATH’).AsString); Next; end; Close; Transaction.Active:=false; end; ShowMessage(fmDM.GMail.Recipients.Text); ShowMessage(fmDM.GMail.AttachFiles.Text); fmDM.GMail.SendMessage(‘Компания’, true); //… Подробнее »
[…] написания статьи я решил использовать тему с форума и один из последних комментариев в статье, посвященной использованию Synapse для работы с […]
Вот только поставил компонент на Delphi 2010. Почту отправляет, но может я чего то недосмотрел или не дочитал, когда я специально ввожу не существующий почтовый адрес, то «сообщение отправляется», а на адрес отправителя приходит сообщение о несуществующем адресе. Хотелось бы перед отправкой сообщения как то проверить наличие существования адресата получателя. Как то так.