уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Сегодня решил немного поэкспериментировать с библиотекой Synapse и научиться отправлять письма, используя протокол SMTP (Simple Mail Transfer Protocol — протокол передачи почты). Тема эта достаточно интересная и полезная. Дело даже не в том, чтобы написать для себя почтовый клиент, коих миллионы. Подобные навыки работы с бибилиотекой могут потребоваться, например, если Вы захотитенаписать своего клиента для отправки сообщений в свой блог на ЖЖ, Blogger или LiveInternet — эти блог сервисы поддерживают публикацию новых постов по e-mail. Так что, полученные сегодня навыки несомнено должы принести Вам (мне точно) определенную пользу. Для работы с протоколом SMTP в Synapse можно использовать следующие модули библиотеки:

  1. smtpsend — содержит объект Tsmtpsend и ключевые методы для отправки электронных писем.
  2. mimemess — содержит объекты TMessHeader — заголовки сообщения; TMimeMess — сообщение;
  3. mimepart — содержит объект TMimePart для работы с частями сообщения, которые можно использовать для отправки по почте файлов.

Сегодня сосредоточимся на основной задаче — отправке текста. Так как именно для этого в свое время и был создан SMTP, а пересылкой файлов (аттачей) занимается не протокол, а расширение к протоколу —  MIME (Multupurpose Internet Mail Extentions, RFC-1521). Расширениями займемся позднее.

Итак, сегодня в наши задачи входит:

  1. Составить правильный заголовок сообщения
  2. Добавить в сообщение текст (plain text) или html-код
  3. Оправить сообщение на постовый ящик, используя заданый smtp-сервер.

1. Подготавливаемся к работе с SMTP в Delphi. Загоовка приложения.

Открываем Delphi, создаем новое приложение и на главной форме размещаем компоненты как показано на рисунке:

Как вы знаете, SMTP-серверы почтовых служб таких как mail.ru требуют обязательной авторизации, поэтому на форме нашего будущего приложения предусмотрены два поля: «Логин пользователя» и «Пароль пользователя» — туда будем записывать данные для авторизации на SMTP-сервере.

Поле «Хост» должно содержать хост smtp-сервера, например, smtp.mail.ru или smtp.yandex.ru и т.д., смотря от чьего имени вы будете слать письма. Поле «Адрес e-mail» для отправителя должен содержать правильный адрес, т.е. применительно к mal.ru, если ваш логин «blogger», то ящик должен быть «blogger@mail.ru», а хост «smtp.mail.ru».

С формой приложения и назначением элементов главной формы, думаю, разобрались. Переходим ко второму пункту нашей работы — создадим правильное сообщение.

2. Формируем сообщение e-mail, используя Synapse

Итак, в заголовки сообщения нам необходимо включить:

  1. Имя отправителя
  2. Адрес отправителя
  3. Список получателей (в нашем случае получатель будет один)

Подключаем к проекту модули mimemess, mimepart, smtpsend.  Создаем процедуру с названием, например SendMail:

Procedure SendMail (Host, Subject, pTo, From , TextBody, HTMLBody, login,password : string);
var Msg : TMimeMess; //собщение
    StringList : TStringList; //содержимое письма
    MIMEPart : TMimePart; //части сообщения (на будущее)
begin
  Msg := TMimeMess.Create; //создаем новое сообщение
  StringList := TStringList.Create;
  try
// Добавляем заголовки
    Msg.Header.Subject := Subject;//тема сообщения
    Msg.Header.From := From; //имя и адрес отправителя
    Msg.Header.ToList.Add(pTo); //имя и адрес получателя
// создаем корневой элемент
    MIMEPart := Msg.AddPartMultipart('alternative', nil);
    if length(TextBody)>0 then
      begin
        StringList.Text := TextBody;
        Msg.AddPartText(StringList, MIMEPart);
      end
    else
      begin
        StringList.Text := HTMLBody;
        Msg.AddPartHTML(StringList, MIMEPart);
      end;
// Кодируем и отправляем
    Msg.EncodeMessage;
    smtpsend.SendToRaw(From, pTo, Host, Msg.Lines, login, password);
 finally
   Msg.Free;
   StringList.Free;
 end;
end;

Разберем по частям, что к чему. В начале создаем новое сообщение, используя объект TMimeMess (сообщение) из модуля Synapse mimemess.

Далее добавляем в сообщение все необходимые заголовки. Создаем объект TMimePart. Так как создается корневой элемент MIME, то вторым параметром, согласно условиям работы с Synapse, ставится nil. Если мы отправляем простой текст, то используем метод AddPartText, где вторым параметром выступает как раз созданные нами корневой элемент, иначе, если текстовое содержимое не отсылается, то принимаем, что отсылается HTML-код и используем соответственно метод AddPartHTML. Также Вы можете добавить в сообщение:

  • Текст из файла, используя метод AddPartTextFromFile.
  • HTML-код из файла, используя метод AddPartHTMLFromFile
  • Бинарный файл, загрузив данные в поток TStream и указав его в параметрах метода AddPartBinary

Есть ещё ряд других методов, расширяющих возможности объекта TMimePart, разобраться с работой которых, думаю, будет достаточно просто.

После того, как сообщение собрано, мы его кодируем, используя метод EncodeMessage, в котором собираются правильные, согласно RFC заголовки, «склеиваются» все части  и т.д. И, наконец, отправляется письмо, используя метод SendToRaw из модуля Synapse httpsend.

Теперь, когда основная процедура отправки готова. Дописываем приложение.

3. Дорабатываем приложение для отправки почты.

В обработчике onClick кнопки пишем:

procedure TForm5.Button1Click(Sender: TObject);
begin
if RadioButton1.Checked then
  SendMail(Edit1.Text,
    'Test Message',
    '"' + Edit4.Text + '" <' + Edit5.Text + '>',
    '"' + Edit2.Text + '" <' + Edit3.Text + '>',
    Memo1.Text,
    '',
    Edit6.Text, Edit7.text)
else
  SendMail(Edit1.Text,
    'Test Message',
    '"' + Edit4.Text + '" <' + Edit5.Text + '>',
    '"' + Edit2.Text + '" <' + Edit3.Text + '>',
    '',
    Memo1.Text,
    Edit6.Text, Edit7.text)
end;

Теперь можете проверить работу приложения. Например я отправил себе на второй ящик письмо:

И спустя буквально пару секунд получил новое письмо на свой ящик:

Теперь можете потренироваться с приложением, добавить возможность отправки файлов по электронной почте и т.д. Как видите, с Synapse не только просто работать с HTTP и HTTPS-протоколами, но и не менее просто отправлять электронную почту.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
110 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
alex
alex
25/12/2011 13:51

так что насчет отправки почты через прокси? возможно ли ?

alex
alex
25/12/2011 13:57

«используя метод SendToRaw из модуля Synapse httpsend.»
это я так полагаю ошибка, в коде используется модуль smtpsend который может отправлять  похоже только через сокс5 прокси? возможно ли через http прокси отправлять почту?

Elena
Elena
05/02/2012 20:41

Дай исходник темы.

Elena
Elena
07/02/2012 05:09

Пишу здесь, значит этой «Synapse. Отправка писем, используя SMTP.».

fedos
fedos
21/02/2012 22:04

на некоторых компах под Windows 7 не работает отправка сообщения. Файервол и антивирус отключены и ошибок никаких не возникает ни на стадии компиляции, ни в процессе работы. Может быть какая-нибудь служба блокирует отправку?

Юрий Загорянский

Все работает и исходник изменил, всем огромное спасибо, вот только при приеме Батом в html вылазит бяка в начале текста стоит символ верхней точки… , даже если пустое письмо в html отправляешь…так и не разобрался как убрать (((

Павел
Павел
29/07/2012 00:45

Ребята, не могу понять в чем дело.
Код целиком стащил, ничего не менял. Была ошибка с > прочел что это < , изменил. Все скомпилилось, запустилось. Но ничего не отправляется. Очень нужно решить эту проблему.

Pavel
Pavel
29/07/2012 02:05

Здравствуйте. Очень рад, что наткнулся на эту статью. Скопировал себе полностью код, ничего не меняя. Компиляция прошла успешно, на письмо не доходит. Отправляю с mail.ru на mail.ru Не пойму, в чем дело. Может может кто помочь? Я могу выслать исходники. Очень нужно разрешить данный вопрос.
Благодарю за помощь

Александр
Александр
02/11/2012 18:34

Здравствуйте. У меня вопрос по поводу запроса о получении (доставке). Отправляю письма на mail и yandex c заголовками :
// запрос о прочтении
X-Confirm-Reading-To: отправитель@мейл.ру
Disposition-Notification-To: отправитель@мейл.ру
// запрос о получении
Return-Receipt-To:отправитель@мейл.ру
mail реагирует ТОЛЬКО на запрос О ПРОЧТЕНИИ
yandex же вообще ни как не реагирует
в чем может быть проблема или есть другие способы получить отчет о получении?

Александр
Александр
02/11/2012 18:49

Vlad, спасибо за столь оперативный ответ) Если сам догадаюсь дам знать

Павел
Павел
13/11/2012 16:43

Влад, привет. Объясни, пожалуйста, как добиться прихода ответной квитанции о доставке сообщения с помощью synapse? Писал в службу mail и yandex. Говорят, они такую информацию не предоставляют. Как-то это сделано в outlook, значит принципиально возможно. Перепробовал все что написано выше-не работает.

Александр
Александр
15/11/2012 19:20

Vlad, решил я вопрос с доставкой :) пришлось прочитать пару иностранных источников по SMTP протоколу, потом тестировать через Telnet, и как всегда все самое сложно пишется в одну строчку :) Сразу скажу что получение отчета о доставке зависит от возможностей smtp сервера, а точнее его возможность поддерживать DSN (Delivery Status notification — уведомлений о состоянии доставки). Из известных это yandex ( даже не gmail :) ), ну или Ваш если поддерживает, как это узнать могу Вам написать куда-нибудь. А само решение такое: нужно подправить исходник synapse, а точнее smtpsend.pas в нем в функции function TSMTPSend.MailTo(const Value: string): Boolean; строку FSock.SendString(‘RCPT… Подробнее »

Александр
Александр
15/11/2012 22:10

Vlad, можно так: ( пример для yandex )
1.Открываем командную строку ( Выполнить => cmd )
2.набираем «telnet smtp.yandex.ru 25″ ( все дальше без кавычек ) ждем ответа от сервера
3.»EHLO ip» (ваш ip — это у яндекса, у меня на работе например логин от мыла, тот что до @, на mail.ru вообще любая строка подходит, т.е. в зависимости от сервера)
4.Сервер выдает нам список поддерживаемых команд, и если там есть DSN — значит поддерживает.

vorvv
vorvv
22/11/2012 23:18

Как отправить нескольким получателям используя smtp.MailData?
Спасибо

Игорь
Игорь
21/02/2013 15:46

Все замечательно отправляется и работает, НО! Работаешь в слепую: не выводится ни одной ошибки, мало того, нет возможности их вывести. Все что ты можешь это узнать отвправлена почта или нет. А Почему — нет ответа. Хотя в Smtpsend.pas есть интересный код: function TSMTPSend.EnhCodeString: string; var s, t: string; begin s := IntToStr(FEnhCode2) + '.' + IntToStr(FEnhCode3); t := ''; if s = '0.0' then t := 'Other undefined Status'; if s = '1.0' then t := 'Other address status'; if s = '1.1' then t := 'Bad destination mailbox address'; if s = '1.2' then t := 'Bad destination system… Подробнее »

sergej
sergej
13/03/2013 01:49

Пытаюь отправить письма при помощи synapse с уведомлением и ни фига… Выше написано:
»
А само решение такое: нужно подправить исходник synapse, а точнее smtpsend.pas в нем в функции function TSMTPSend.MailTo(const Value: string): Boolean; строку
FSock.SendString(‘RCPT TO:’ + CRLF); заменить на :
FSock.SendString(‘RCPT TO:’ + ‘ NOTIFY=SUCCESS’ + CRLF);
»
но в функции TSMTPSend.MailTo нет такой строки… там есть
FSock.SendString(‘RCPT TO:’ + CRLF);
и если ее поменять по аналогии, то функция отправки фозвращает false и письма вообще не отправляются… Не подскажите куда покопать?

sergej
sergej
13/03/2013 12:27
Ответить на  Vlad

Спасибо за ответ. Только не очень понял… Или я плохо пояснил. После правки функция
smtpsend.SendToRaw(pFrom, pTo, pHost, tmpMsg.Lines, plogin, ppassword) возвращает false и письмо не отправляется. Как только правку убираю — все ок, письмо приходит. Слал письмо на mail.ru, а он вроде все поддерживает. Да и опять же, даже если DSN не пддерживается, то письмо-то доходить до адресата вроде должно…

Александр
Александр
14/03/2013 15:39
Ответить на  sergej

sergej, mail.ru не поддерживает DSN. Пробуйте yandex

Александр
Александр
14/03/2013 15:55

Вы пишите: «но в функции TSMTPSend.MailTo нет такой строки… там есть
FSock.SendString(‘RCPT TO:’ + CRLF);» наверное FSock.SendString(‘RCPT TO:’ + CRLF); ??? ее и нужно заменить на
FSock.SendString(‘RCPT TO:’ + ‘ NOTIFY=SUCCESS’ + CRLF);

Александр
Александр
14/03/2013 15:56

сори вот это верно
Вы пишите: «но в функции TSMTPSend.MailTo нет такой строки… там есть
FSock.SendString(‘RCPT TO:’ + CRLF);» наверное FSock.SendString(‘RCPT TO’ + CRLF); ??? ее и нужно заменить на
FSock.SendString(‘RCPT TO:’ + ‘ NOTIFY=SUCCESS’ + CRLF);;

Александр
Александр
14/03/2013 15:59

не знаю что с моим компьютером….сори за кучу сообщений
RCPT TO:’ + ‘ NOTIFY=SUCCESS’ + CRLF // Value не забыть между RCPT TO: и NOTIFY=SUCCESS

sergej
sergej
14/03/2013 19:49

Александр, спасибо за ответ. Прошу прощения я неверно привел пример строки. В общем вот эта функция целиком

function TSMTPSend.MailTo(const Value: string): Boolean;
begin
FSock.SendString('RCPT TO:' + CRLF);
Result := ReadResult = 250;
end;

я пробовал менять вот так

FSock.SendString('RCPT TO: NOTIFY=SUCCESS'+CRLF);

про яндекс.ру спасибо — попробую.

sergej
sergej
14/03/2013 19:51

сорри, не так скопировал…
менял вот так

FSock.SendString('RCPT TO: NOTIFY=SUCCESS'+CRLF);

sergej
sergej
14/03/2013 19:55

ууууууууу,как тут все запущено однако… я думал, что это я ошибаюсь, а оказывается тутошний движок мягко говоря мудрит… выбрасывает куски текста… че за бред…

куда девается контекст «+ value +»

пробую еще раз привесты примеры….

function TSMTPSend.MailTo(const Value: string): Boolean;
begin
FSock.SendString(‘RCPT TO:’ + CRLF);
// FSock.SendString(‘RCPT TO: NOTIFY=SUCCESS’+CRLF);
Result := ReadResult = 250;
end;

sergej
sergej
14/03/2013 19:57

да это полный бред… ваш движок творит «чудеса» Вставляешь одно, а он вставляет другое…

sergej
sergej
15/03/2013 02:17
Ответить на  Vlad

Огромное спасибо за проделанную работу! Теперь надо только все это понять и освоить (усвоить).

Nikolay
Nikolay
03/08/2013 03:24

Можно получить исход? уже 3,5 часа вожусь c smtp а письмо так и не смог отправить(

Sasha
Sasha
12/10/2013 05:03

Подскажите в ХЕ5 перестал отправлять письма. Изначально ругался TimeSeparator заменил на FormatSettings.TimeSeparator
так же ругался на
CustomMonthNames[n] := ShortMonthNames[n];
MyMonthNames[0, n] := ShortMonthNames[n];

изменил на
FormatSettings.ShortMonthNames[n]
FormatSettings.ShortMonthNames[n]
но письма не отправляются

Sasha
Sasha
12/10/2013 15:53

Относительно предыдущего вопроса
Релиз Release 40 2012-04-23 отправка почты не работает
а вот старый который использую
Release 39 2009-10-08 все гуд работает и на xe5

Agent00007
04/02/2015 15:39
Ответить на  Sasha

А как сделать так чтобы отправлялась без libeay32.dll,ssleay32.dll, может какой-нить модуль к проекту надо подключить, или скомпилировать сразу проект с этими длл??

trackback

[…] прошлой статье про использование Synapse для отправки писем мы разработали простенькое приложение для отправки […]

trackback
Пишем спам-бот. Часть 1: Отправка письма. | Coding PWCode
09/01/2015 22:05

[…] Если либа Synaps’а у тебя ещё не установлена, по каким-то причинам, или же ты не знаешь как ей пользоваться — то рекомендую следующие мануалы и ресурсы: скачать Synapse, установка Synapse, установка в картинких и мануал по адаптации к новым версиям Delphi (XE+), отправка smtp-писем, используя Synapse. […]

loginza23Vepwvof80U9RD35FS89c

здраствуйте,использую делфи 2010,полностью скопировал ваш код,но выдает ошибку [DCC Error] Unit1.pas(50): E2012 Type of expression must be BOOLEAN ,в строке if length(TextBody)>0 then

vorvv
vorvv
08/04/2015 23:12

Привет всем!!!
Наберусь смелости задать вопрос!

Заголовки письма
TMimeMess
From: «=?ISO-8859-5?Q?=C0=DE=D1=…
To: «=?ISO-8859-5?Q?=…
Subject: =?ISO-8859-5?Q?=BB=DE=D3_…

Для кодировки символов работает
Msg.Header.CharsetCode:=CP1251 или UTF_8
IdealCharsets:=[UTF_8];

Как в !!!!!!!!!!!заголовке!!!!!!!!!!!!! указать свои ME_7BIT, ME_8BIT, ME_QUOTED_PRINTABLE and ME_BASE64
вместо ME_QUOTED_PRINTABLE

Напимер:
AddPartTextEx(StringList, MIMEPart, CP1251, True, ME_BASE64);
Это работает но для текста письма.

Спасибо!!!