Отправка сообщение на email

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Отправка сообщение на email

Сообщение san7667 » 14.07.2023 22:18:36

Добрый день, подскажите пожалуйста кто знает, живой действующий пример отправки сообщения на почту email самый простой..
какой-нибудь алгоритм или процедуру.
В интернете нашел https://www.cyberforum.ru/delphi-networks/thread1495940.html?ysclid=lk2vlk79vb340417620, но он давно не работает...
san7667
новенький
 
Сообщения: 42
Зарегистрирован: 18.06.2023 17:57:37

Re: Отправка сообщение на email

Сообщение Sharfik » 15.07.2023 03:29:35

С примером не помогу. Пробовал сам отправлять и по разному, кое какие способы работали. Но во всех случаях нужно учитывать один момент - сейчас почтовый сервера mail.ru, yandex и т.п. не позволяют по простому через них отправлять почту. Либо срабатывает отправка пары писем, а потом бан.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 791
Зарегистрирован: 20.07.2013 01:04:30

Re: Отправка сообщение на email

Сообщение Alex2013 » 15.07.2023 13:13:11

С почтой все хорошо в Инди (Indy10 ) https://www.indyproject.org
( в Лазарусе проще всего ставить через "Сетевой диспетчер пакетов" )
Есть и примеры http://digital-flame.ru/2015/09/22/delp ... lozheniya/
+ Нужно кинуть на форму IdPop3 и idSMTP
Зы
Можно и по другому но это реально вариант из серии "проще не бывает".
Зы Зы
Тоже с шифрованием SSL
https://psvlab.blogspot.com/2010/04/ssl ... n-ssl.html
https://www.cyberforum.ru/lazarus/thread1064373.html
Alex2013
долгожитель
 
Сообщения: 3048
Зарегистрирован: 03.04.2013 11:59:44

Re: Отправка сообщение на email

Сообщение Снег Север » 15.07.2023 14:03:53

У меня на работе инди под делфи великолепно отправляли тысячи писем через гугл и через почту служебного IIS сервера. Тысячи - это не фигура речи, отправка использовалась в продаваемых программах телемаркетинга у многих десятков клиентов. По ссылкам в предыдущем сообщении, примерно то же, что у меня было.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3038
Зарегистрирован: 27.11.2007 16:14:47

Re: Отправка сообщение на email

Сообщение san7667 » 15.07.2023 14:23:40

Вопрос такой, если собирать из под линукса, это реально сделать?
Я так понял множество примеров для win...
san7667
новенький
 
Сообщения: 42
Зарегистрирован: 18.06.2023 17:57:37

Re: Отправка сообщение на email

Сообщение Снег Север » 15.07.2023 14:53:13

Под линухом может быть только проблема с библиотеками openssl - они в каждой сборке именются по-разному, надо лезть в исходники инди и смотреть названия подключаемых файлов. Всё остальное - так же точно, как в винде.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3038
Зарегистрирован: 27.11.2007 16:14:47

Re: Отправка сообщение на email

Сообщение Ichthyander » 15.07.2023 15:09:51

https://github.com/risoflora/brookfreep ... ns/xmailer
Отправляет одной функцией
Код: Выделить всё
program demo;

{$mode objfpc}{$H+}

uses
  XMailer, SysUtils;

begin
  try
    SendMail('from="Your Name <test@host.com>" to=dest1@host.com;dest2@host.com ' +
      'subject="Your subject." message="Your message." user=user@host.com ' +
      'password=abc123 host=smtp.host.com:465 ssl=true tls=true');
    Write('E-mail sent successfully!');
  except
    on E: Exception do
      Write(E.Message);
  end;
end.
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 685
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Отправка сообщение на email

Сообщение Alex2013 » 15.07.2023 16:01:56

Ichthyander писал(а):https://github.com/risoflora/brookfreepascal/tree/main/plugins/xmailer
Отправляет одной функцией

И что это реально надежно ? Бо мучают меня смутные сомнения....
Alex2013
долгожитель
 
Сообщения: 3048
Зарегистрирован: 03.04.2013 11:59:44

Re: Отправка сообщение на email

Сообщение Ichthyander » 15.07.2023 17:48:21

Alex2013 писал(а):И что это реально надежно ? Бо мучают меня смутные сомнения....

Ну не знаю. Работает у меня на веб-сервере. Тестил на Windows. Что может быть проблемного-то?
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 685
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Отправка сообщение на email

Сообщение san7667 » 15.07.2023 19:14:44

Ichthyander писал(а):https://github.com/risoflora/brookfreepascal/tree/main/plugins/xmailer
Отправляет одной функцией
Код: Выделить всё
program demo;

{$mode objfpc}{$H+}

uses
  XMailer, SysUtils;

begin
  try
    SendMail('from="Your Name <test@host.com>" to=dest1@host.com;dest2@host.com ' +
      'subject="Your subject." message="Your message." user=user@host.com ' +
      'password=abc123 host=smtp.host.com:465 ssl=true tls=true');
    Write('E-mail sent successfully!');
  except
    on E: Exception do
      Write(E.Message);
  end;
end.



Не совсем понял куда это пихать)))
На гит хабе ничего не пойму что с этим делать..
Если не сложно, разжуйте для особо одаренных ))
san7667
новенький
 
Сообщения: 42
Зарегистрирован: 18.06.2023 17:57:37

Re: Отправка сообщение на email

Сообщение Ichthyander » 15.07.2023 23:26:19

1) Получить либу локально.
  • Если есть git, то
    Код: Выделить всё
    git clone https://github.com/risoflora/brookfreepascal.git
    ,
  • либо скачать через Open Package Manager (он там тоже есть),
  • либо скачать непосредственно с сайта GitHub: Кнопка Code - далее download zip.
2) Далее в папке plugins/xmailer/pkg находим файл xmailerpkg.lpk и добавляем в зависимости вашего проекта.
3) Добавляем модуль Xmailer в блок Uses вашего модуля Unit

P.S. В зависимости от ОС и установленных либ может потребоваться добавить библиотеки OpenSSL в папку программу (для работы защищенных протоколов). Или просто установить в систему
Аватара пользователя
Ichthyander
энтузиаст
 
Сообщения: 685
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань

Re: Отправка сообщение на email

Сообщение Alex2013 » 16.07.2023 02:14:14

Ichthyander писал(а):
Alex2013 писал(а):И что это реально надежно ? Бо мучают меня смутные сомнения....

Ну не знаю. Работает у меня на веб-сервере. Тестил на Windows. Что может быть проблемного-то?

Например кодировки и шифрование . :idea:
Alex2013
долгожитель
 
Сообщения: 3048
Зарегистрирован: 03.04.2013 11:59:44

Re: Отправка сообщение на email

Сообщение *Rik* » 17.07.2023 09:30:30

Я использую Synapse, работает под Windows и Linux, любые варианты работы с почтой smtp, imap, pop3 и вообще с сетью TCP, HTTP, FTP. Для работы с SSL нужно в раздел uses в своей программе добавить модуль из поставки synapse в котором прописана поддержка SSL нужной версии и собрать с ними свой проект, я использую 1.1.1, пробовал 3.0, не все сайты поддерживают, откатился на 1.1.1
Для Windows OpenSSL брать тут:
https://slproweb.com/products/Win32OpenSSL.html
можно установить в системный каталог, либо взять 2 файла libcrypto-1_1-x64.dll и libssl-1_1-x64.dll и положить рядом со своей программой.

Для Linux поставить нужную версию из репозитория.

Здесь исчерпывающие сведения об использовании библиотеки на все случаи жизни.
https://webdelphi.ru/category/kniga-synaose/
Аватара пользователя
*Rik*
постоялец
 
Сообщения: 451
Зарегистрирован: 19.04.2011 12:18:51
Откуда: Урал

Re: Отправка сообщение на email

Сообщение san7667 » 19.07.2023 07:19:22

Снег Север писал(а):Под линухом может быть только проблема с библиотеками openssl - они в каждой сборке именются по-разному, надо лезть в исходники инди и смотреть названия подключаемых файлов. Всё остальное - так же точно, как в винде.


Нашел библиотеки для линукса:

Код: Выделить всё
wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2u.tar.gz
tar -xf openssl-1.0.2u.tar.gz
cd openssl-1.0.2u
./config shared
make
cp *.so /путь к проекту


Все, что остается - показать Indy, где искать эти библиотеки:
Код: Выделить всё
IdOpenSSLSetLibPath(ExtractFilePath(ParamStr(0)));


Но у меня не находит компонент IdOpenSSLSetLibPath..

Как показать indy что библиотеки лежат в папке с проектом???

Добавлено спустя 1 час 15 минут 27 секунд:
Разобрался.
Что бы увидел функцию IdOpenSSLSetLibPath нужно подключить модуль:

Код: Выделить всё
uses IdSSLOpenSSLHeaders;
san7667
новенький
 
Сообщения: 42
Зарегистрирован: 18.06.2023 17:57:37

Re: Отправка сообщение на email

Сообщение delphius » 22.07.2023 01:44:08

san7667 писал(а):Добрый день, подскажите пожалуйста кто знает, живой действующий пример отправки сообщения на почту email самый простой..
какой-нибудь алгоритм или процедуру.

Неожиданно для себя тоже не нашел в интернете актуальных примеров на free pascal отправки простого почтового сообщения по smtp без использования TLS.

Написал простой кроссплатформенный пример на чистом fcl (без использования Indy, Synapse и тп.), так как все необходимое есть и хорошо работает очень давно.
Компилировал и проверял под Windows 10 и под Linux Mint (Ubuntu).
Код: Выделить всё
program socketmail;

{$mode objfpc}{$H+}

uses
  sockets, // работа с Sockets
  resolve, // Преобразование доменных имен в IP адреса и обратно с помощью DNS
  base64; // base64 кодирование/декодирование

function SendMail(const SmtpServer, SenderEmail, Password, RecipientEmail, MailSubject, MailBody: string; SmtpPort: Integer): Boolean;
var
  CSocket: TSocket;
  Address: TInetSockAddr;
  Buffer: array[0..1023] of Char;
  BytesRead: Integer;
  IPAddr: string;
  MailContent, Base64Encoded: string;
  hrs: THostResolver;

  procedure SendCommand(Socket: TSocket; const Command: string);
  begin
    WriteLn('Client: ', Command);
    fpsend(Socket, PChar(Command + #13#10), longword(Length(Command) + 2), 0);
    BytesRead := fprecv(Socket, @Buffer[0], SizeOf(Buffer), 0);
    Buffer[BytesRead] := #0;
    WriteLn('Server: ', Buffer);
  end;

begin
  Result := False; // По умолчанию считаем, что отправка не удалась

  // Создание сокета
  CSocket := fpsocket(AF_INET, SOCK_STREAM, 0);
  if CSocket = -1 then
  begin
    WriteLn('Error creating socket.');
    Exit;
  end;

  // Преобразование доменного имени SMTP сервера в IP адрес
  hrs := THostResolver.Create(nil);
  if hrs.NameLookup(SmtpServer) then
  begin
    IPAddr := hrs.AddressAsString;
    WriteLn('Resolved IP Address: ', IPAddr);
  end
  else
  begin
    WriteLn('Failed to resolve the hostname: ', SmtpServer);
    Exit;
  end;

  // Подключение к SMTP серверу
  with Address do
   begin
      sin_family := AF_INET; //TCP/IP
      sin_port:= htons(word(SmtpPort)); //Порт
      sin_addr:=StrToNetAddr(hrs.AddressAsString); // IP адрес
   end;

  hrs.Free; // Освобождаем переменную

  if fpconnect(CSocket, @Address, SizeOf(Address)) < 0 then
  begin
    WriteLn('Error connecting to SMTP server.');
    Exit;
  end;

  // Отправка команды EHLO
  SendCommand(CSocket, 'EHLO client');

  // Производим аутентификацию, отправляя команды AUTH LOGIN
  SendCommand(CSocket, 'AUTH LOGIN');

  // Отправка логина (email отправителя) в формате Base64
  Base64Encoded := EncodeStringBase64(SenderEmail);
  if Base64Encoded = '' then
  begin
    WriteLn('Error encoding login.');
    Exit;
  end;
  SendCommand(CSocket, Base64Encoded);

  // Отправка пароля в формате Base64
  Base64Encoded := EncodeStringBase64(Password);
  if Base64Encoded = '' then
  begin
    WriteLn('Error encoding password.');
    Exit;
  end;
  SendCommand(CSocket, Base64Encoded);

  // Отправка команды MAIL FROM
  MailContent := 'MAIL FROM: <' + SenderEmail + '>';
  SendCommand(CSocket, MailContent);

  // Отправка команды RCPT TO
  MailContent := 'RCPT TO: <' + RecipientEmail + '>';
  SendCommand(CSocket, MailContent);

  // Отправка команды DATA
  SendCommand(CSocket, 'DATA');

  // Отправка данных письма
  MailContent :=
    'Subject: ' + MailSubject + #13#10 +
    'From: <' + SenderEmail + '>' + #13#10 +
    'To: <' + RecipientEmail + '>' + #13#10 +
    #13#10 +
    MailBody + #13#10 +
    '.';

  SendCommand(CSocket, MailContent);

  // Отправка команды QUIT
  SendCommand(CSocket, 'QUIT');

  // Закрытие сокета
  CloseSocket(CSocket);

  Result := True; // Отправка прошла успешно
end;

begin
  if SendMail('smtp.rambler.ru', 'yourlogin@rambler.ru', 'yourpassword', 'adressto@mail.com', 'Test Mail', 'This is a test email sent using sockets.', 25) then
    WriteLn('Mail sent successfully.')
  else
    WriteLn('Error sending mail.');
end.


а также пример на чистом fcl под windows с помощью WinSock2:
Код: Выделить всё
program socketmail;

{$mode objfpc}{$H+}

uses
  WinSock, // WinSock2 Socket Library for Win32
  base64; // base64 encoder & decoder

function SendMail(const SmtpServer, SenderEmail, Password, RecipientEmail, MailSubject, MailBody: string; SmtpPort: Integer): Boolean;
var
  CSocket: TSocket;
  Address: TSockAddrIn;
  Buffer: array[0..1023] of Char;
  BytesRead: Integer;
  IPAddr: string;
  HostEnt: PHostEnt;
  Addr: TInAddr;
  WSAData: TWSAData;
  MailContent, Base64Encoded: string;

  procedure SendCommand(Socket: TSocket; const Command: string);
  begin
    WriteLn('Client: ', Command);
    Send(Socket, PChar(Command + #13#10), Length(Command) + 2, 0);
    BytesRead := Recv(Socket, Buffer[0], SizeOf(Buffer), 0);
    Buffer[BytesRead] := #0;
    WriteLn('Server: ', Buffer);
  end;

begin
  Result := False; // По умолчанию считаем, что отправка не удалась

  // Инициализация WinSock
  if WSAStartup($202, WSAData) <> 0 then
  begin
    WriteLn('Error initializing WinSock.');
    Exit;
  end;

  // Создание сокета
  CSocket := Socket(AF_INET, SOCK_STREAM, 0);
  if CSocket = INVALID_SOCKET then
  begin
    WriteLn('Error creating socket.');
    Exit;
  end;

  // Преобразование доменного имени SMTP сервера в IP адрес
  HostEnt := gethostbyname(PChar(SmtpServer));
  if HostEnt <> nil then
  begin
    Addr := PInAddr(HostEnt^.h_addr_list^)^;
    IPAddr := inet_ntoa(Addr);
  end
  else
  begin
    WriteLn('Host not found: ' + SmtpServer);
    Exit;
  end;

  // Подключение к SMTP серверу
  Address.sin_family := AF_INET;
  Address.sin_port := htons(u_short(SmtpPort));
  Address.sin_addr.s_addr := inet_addr(PChar(IPAddr));

  if connect(CSocket, Address, SizeOf(Address)) < 0 then
  begin
    WriteLn('Error connecting to SMTP server.');
    Exit;
  end;

  // Отправка команды EHLO
  SendCommand(CSocket, 'EHLO client');

  // Производим аутентификацию, отправляя команды AUTH LOGIN
  SendCommand(CSocket, 'AUTH LOGIN');

  // Отправка логина (email отправителя) в формате Base64
  Base64Encoded := EncodeStringBase64(SenderEmail);
  if Base64Encoded = '' then
  begin
    WriteLn('Error encoding login.');
    Exit;
  end;
  SendCommand(CSocket, Base64Encoded);

  // Отправка пароля в формате Base64
  Base64Encoded := EncodeStringBase64(Password);
  if Base64Encoded = '' then
  begin
    WriteLn('Error encoding password.');
    Exit;
  end;
  SendCommand(CSocket, Base64Encoded);

  // Отправка команды MAIL FROM
  MailContent := 'MAIL FROM: <' + SenderEmail + '>';
  SendCommand(CSocket, MailContent);

  // Отправка команды RCPT TO
  MailContent := 'RCPT TO: <' + RecipientEmail + '>';
  SendCommand(CSocket, MailContent);

  // Отправка команды DATA
  SendCommand(CSocket, 'DATA');

  // Отправка данных письма
  MailContent :=
    'Subject: ' + MailSubject + #13#10 +
    'From: <' + SenderEmail + '>' + #13#10 +
    'To: <' + RecipientEmail + '>' + #13#10 +
    #13#10 +
    MailBody + #13#10 +
    '.';

  SendCommand(CSocket, MailContent);

  // Отправка команды QUIT
  SendCommand(CSocket, 'QUIT');

  // Закрытие сокета
  CloseSocket(CSocket);

  // Очистка WinSock
  WSACleanup;

  Result := True; // Отправка прошла успешно
end;

begin
  if SendMail('smtp.rambler.ru', 'yourlogin@rambler.ru', 'yourpassword', 'adressto@mail.com', 'Test Mail', 'This is a test email sent using sockets.', 25) then
    WriteLn('Mail sent successfully.')
  else
    WriteLn('Error sending mail.');
end.


Оба примера отлично отправляют сообщения на любые адреса через почту Rambler.

По поводу мнений о том, что все крупные почтовые сервисы требуют безопасного подключения по smtp, зарегистрировал бесплатный ящик на Rambler, в помощи написано, что подключение по smtp может осуществляться на smtp.rambler.ru в том числе без шифрования. Главное, не забыть включить в настройках почты переключатель "Доступ к почтовому ящику с помощью почтовых клиентов."

Тестовые сообщения успешно отправляются на любые адреса.
Понятно, что это просто пример, но он позволяет понять "кухню" изнутри...

При необходимости, можно расширить для отправки вложений и т.п., добавить обработку ответов с сервера.

Если нужен позарез TLS, то можно конечно заморочиться с Schannel (MS SSPI SSL), но OpenSSL будет гораздо проще, ценой двух dll в папке с программой.

Приведенные примеры сделаны в процедурном стиле с помощью модуля sockets из состава rtl, если требуется объектно-ориентрованный подход, то можно использовать надстройку над sockets (для windows она использует winsock) из состава fpc-net модуль sscockets.

Модуль "sockets" из состава RTL (Run-Time Library) и модуль "ssockets" из состава FCL-Net (Free Component Library for Network) предоставляют функциональность для работы с сокетами. Однако есть некоторые различия между ними:

1. Модуль "sockets" из состава RTL:
- Этот модуль предоставляет базовые функции для работы с сокетами, которые являются стандартными для языка Free Pascal.
- Включает простые процедуры и функции для создания, связывания, прослушивания и подключения сокетов.
- Модуль "sockets" предоставляет сокеты на низком уровне, что означает, что вам придется самостоятельно управлять деталями работы с сокетами, такими как настройка соединения и обработка данных.
2. Модуль "ssockets" из состава FCL-Net:
- Этот модуль также предоставляет функции для работы с сокетами, но на более высоком уровне абстракции.
- Включает классы и компоненты для работы с сетевыми протоколами, такими как TCP и UDP, а также предоставляет удобные методы для обмена данными.
- Модуль "ssockets" предоставляет более удобный и объектно-ориентированный интерфейс, что делает код более читаемым и позволяет сосредотачиваться на бизнес-логике, а не на низкоуровневых деталях работы с сокетами.

Основное различие между модулем "sockets" из RTL и модулем "ssockets" из FCL-Net заключается в уровне абстракции и удобстве использования. Модуль "sockets" предоставляет базовую функциональность на низком уровне, в то время как модуль "ssockets" абстрагирует сложности работы с сокетами и предоставляет более удобный интерфейс для программистов, что облегчает создание сетевых приложений на Free Pascal.


В ходе изысканий использовал smtp4dev - фейковый smtp email server для разработки и тестирования
Наткнулся на интересный набор маленьких утилит для отправки почты, в том числе из консоли
И попалась интересная программа Stunnel - прокси, предназначенная для добавления функциональности TLS кодирования для существующих клиентов и серверов, без изменения их кода.
Ну и как еще одно решение - использование smtp релея, своего или стороннего.
Последний раз редактировалось delphius 26.07.2023 20:47:07, всего редактировалось 4 раз(а).
delphius
постоялец
 
Сообщения: 129
Зарегистрирован: 18.03.2020 13:40:11

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

Рейтинг@Mail.ru