Кодировка indy10 под Linux

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

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

Re: Кодировка indy10 под Linux

Сообщение san7667 » 27.07.2023 11:33:11

delphius писал(а):Чудо произошло?


Пока еще нет)
Буду вечером дома пробовать ваш вариант)
san7667
новенький
 
Сообщения: 42
Зарегистрирован: 18.06.2023 17:57:37

Re: Кодировка indy10 под Linux

Сообщение san7667 » 29.07.2023 19:50:39

delphius писал(а):Чудо произошло?

Поправьте что не так?...

Код: Выделить всё
GIdDefaultTextEncoding := encUTF8;
       IdMessage1.Clear();
       IdMessage1.From.Address:=tmp_email;
       IdMessage1.Recipients.EMailAddresses := tmp_email;
       IdMessage1.From.Name:='Запрос на ТХП';
       //IdMessage1.Subject := utf8encode('Тест');
       IdMessage1.Subject :='';
       IdMessage1.ExtraHeaders.Add('Subject: '+EncodeSubj('Тема письма на русском или английском языке'));
       IdMessage1.Body.Text := memo1.Text;
       IdMessage1.ContentTransferEncoding := 'base64';
       IdMessage1.Date := Now();   


Письмо так же приходит "без темы"
san7667
новенький
 
Сообщения: 42
Зарегистрирован: 18.06.2023 17:57:37

Re: Кодировка indy10 под Linux

Сообщение delphius » 29.07.2023 20:44:36

san7667 писал(а):Поправьте что не так?...

Есть ли возможность поработать со всей структурой кода, конкретнее, с ее полной частью, отвечающей за отправку письма?
Отправка на яндекс из линукс?
delphius
постоялец
 
Сообщения: 122
Зарегистрирован: 18.03.2020 13:40:11

Re: Кодировка indy10 под Linux

Сообщение san7667 » 30.07.2023 09:06:19

delphius писал(а):Есть ли возможность поработать со всей структурой кода, конкретнее, с ее полной частью, отвечающей за отправку письма?
Отправка на яндекс из линукс?

Отправка идет с линукса на mail.ru.

Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
  // imgpart : TIdAttachmentFile;
  txtpart, htmpart : TIdText;
  tmp_email:string;
begin
  TRY

  if ComboKomu.Text='' then begin
    ComboKomu.SetFocus;
    ShowMessage('Укажите адресата!');
    Exit;
  end;

  Screen.Cursor:=crSQLWait;
  IdSMTP1.Host := 'smtp.mail.ru'; // проверял через gmail
  IdSMTP1.Port := 25;
  IdSMTP1.Username := 'вашящик@mail.ru'; // тут - полный username (у меня - включая @gmail.com)
  IdSMTP1.Password := 'вашпароль'; // тут - пароль
  IdSMTP1.UseTLS := utUseImplicitTLS;
  IdSMTP1.AuthType:=satDefault;



  IdSSLIOHandlerSocketOpenSSL1.Destination := IdSMTP1.Host+':'+IntToStr(IdSMTP1.Port);
  IdSSLIOHandlerSocketOpenSSL1.Host := IdSMTP1.Host;
  IdSSLIOHandlerSocketOpenSSL1.Port := IdSMTP1.Port;
  IdSSLIOHandlerSocketOpenSSL1.DefaultPort := 0;
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions:=[sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2,sslvSSLv3];
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Mode := sslmUnassigned;
  IdSMTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
  IdSMTP1.UseTLS := utUseImplicitTLS;

       GIdDefaultTextEncoding := encUTF8;
       IdMessage1.Clear();
       IdMessage1.From.Address:='вашящик';
       IdMessage1.Recipients.EMailAddresses := 'ящик получателя';
       IdMessage1.From.Name:='Запрос на ТХП';
       IdMessage1.Subject :='ТЕСТ';
       IdMessage1.ExtraHeaders.Add('Subject: '+EncodeSubj('Тема письма на русском или английском языке'));
       IdMessage1.Body.Text := memo1.Text;
       IdMessage1.ContentTransferEncoding := 'base64';
       IdMessage1.Date := Now();


  if edit1.Text<>'' then TIdAttachmentFile.Create(idMessage1.MessageParts, Edit1.Text);

  IdSMTP1.Connect();
  IdSMTP1.Send(Form1.IdMessage1);
  IdSMTP1.Disconnect();
  Screen.Cursor:=crDefault;
  ShowMessage('Сообщение отправлено!');
  except
    on e:Exception do begin
       Screen.Cursor:=crDefault;
      ShowMessage('Ошибка отправка почты!'+#13+E.Message);
    end;
  end;
  Screen.Cursor:=crDefault;
end;
san7667
новенький
 
Сообщения: 42
Зарегистрирован: 18.06.2023 17:57:37

Re: Кодировка indy10 под Linux

Сообщение delphius » 30.07.2023 20:04:02

san7667 писал(а):Отправка идет с линукса на mail.ru.

Пока не проверял ваш код, но проверил свой код, который успешно работает как под Windows, так и под Ubuntu, собрав и используя напрямую через IdOpenSSLSetLibPath библиотеки OpenSSL v.1.0.2u из вашего сообщения для чистоты эксперимента.

Из под обеих систем сообщения через smtp mail.ru успешно доставляются на yandex.ru и mail.ru, все параметры присутствуют и видны правильно.

Вот кроссплатформенный код, который отправляет письма из под Windows и из под Linux в правильной кодировке:
Код: Выделить всё
program sendmail;

{$mode delphi}{$H+}

uses classes, sysutils, base64, IdMessage, IdSMTP, IdLogEvent,
IdSSLOpenSSL, IdSSLOpenSSLHeaders, IdExplicitTLSClientServerBase;

// Объект заглушка для обработки событий
type
  TLogEventHandlers = class
    procedure LogReceived(ASender: TComponent; const AText, AData: string);
    procedure LogSent(ASender: TComponent; const AText, AData: string);
    procedure LogStatus(ASender: TComponent; const AText: string);
  end;

procedure TLogEventHandlers.LogReceived(ASender: TComponent; const AText, AData: string);
begin
  WriteLn('<--- ' + AData);
end;

procedure TLogEventHandlers.LogSent(ASender: TComponent; const AText, AData: string);
begin
WriteLn('---> ' + AData);
end;

procedure TLogEventHandlers.LogStatus(ASender: TComponent; const AText: string);
begin
  WriteLn('Status: ' + AText);
end;

// Параметры для отправки письма
    const
      SmtpServer = 'smtp.mail.ru';
      SmtpPort = 465;
      SmtpLogin = '***@mail.ru';
      SmtpPassword = '***';
      FromAddress = '***@mail.ru';
      FromName = 'Отправитель Sender';
      ToAddress = '***@yandex.ru';
      Subject = 'Тема письма. Mail Subject';
      BodyText = 'Привет! Это тестовое письмо. Hello! This is a test message.';

procedure SendEmail(
    aSmtpServer: string;
    aSmtpPort: integer;
    aSmtpLogin: string;
    aSmtpPassword: string;
    aFromAddress: string;
    aFromName: string;
    aToAddress: string;
    aMessageSubject: string;
    aMessageText: string;
    aUseSSL: boolean = false
    );
var
  lMessage : TIDMessage;
  lSMTP    : TIdSMTP;
  lLogEvent: TIdLogEvent;
  lHandlers: TLogEventHandlers;
  sslHandler: TIdSSLIOHandlerSocketOpenSSL;

begin
  IdOpenSSLSetLibPath(ExtractFilePath(ParamStr(0))); // Указание использовать библиотеки из папки программы
  lLogEvent := TIdLogEvent.Create(nil);
  lHandlers := TLogEventHandlers.Create;
  lMessage:= TIDMessage.Create(nil);
  lSmtp:= TIDSmtp.Create(nil);
  sslHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(nil);

  try
    // Подключение обработчиков событий к объекту TIdLogEvent
    lLogEvent.OnReceived := lHandlers.LogReceived;
    lLogEvent.OnSent := lHandlers.LogSent;
    lLogEvent.OnStatus := lHandlers.LogStatus;
   
    // Установка параметров отправки
    lSMTP.AuthType := satDefault;
    lSMTP.Host     := aSmtpServer;   //Хост
    lSMTP.Port     := aSmtpPort;     //Порт
    lSMTP.Username := aSmtpLogin;    //Логин
    lSMTP.Password := aSmtpPassword; //Пароль

    //-- отправляем почту через SSL, если надо
    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;
   
    lSMTP.Intercept := lLogEvent; // Установка перехватчика событий SMTP
    lLogEvent.Active := True; // Активация логирования
   
    lMessage.NoEncode := True; // Отключение кодирования заголовков и тела письма при отправке средствами Indy

    // Принудительное кодирование и установка необходимых заголовков письма
    lMessage.Headers.AddValue('Subject', '=?UTF-8?B?' + EncodeStringBase64(aMessageSubject) + '?=');
    lMessage.Headers.AddValue('From', '=?UTF-8?B?' + EncodeStringBase64(aFromName) + '?=' + ' <' + aFromAddress + '>');
    lMessage.Headers.AddValue('Content-Type', 'text/plain; charset=utf-8');
    lMessage.Headers.AddValue('Content-Transfer-Encoding', 'base64');
    lMessage.ProcessHeaders; // Установленные через AddValue заголовки парсятся в соответствующие им поля TIdMessage
    // Если установить значение адреса получателя до ProcessHeaders, то оно сбросится,
    // так как не было установлено через AddValue
    lMessage.Recipients.EMailAddresses:= aToAddress;

    lMessage.Body.Text := EncodeStringBase64(aMessageText);
   
    //-- собственно отправка
    lSMTP.Connect;
    try
      lSMTP.Send(lMessage);
    finally
      lSMTP.Disconnect;
    end;

  finally
    lHandlers.Free;
    lLogEvent.Free;
    sslHandler.Free;
    lMessage.Free;
    lSmtp.Free;
  end;
end;

begin 
  try
    // Отправка письма
    SendEmail(
      SmtpServer,
      SmtpPort,
      SmtpLogin,
      SmtpPassword,
      FromAddress,
      FromName,
      ToAddress,
      Subject,
      BodyText,
      true
    );

    Writeln('The email has been sent successfully.');
  except
    on E: Exception do
      Writeln('Error when sending an email: ' + E.Message);
  end;
end.

Все ухищрения и способы, которые были рекомендованы в сети не сработали, пришлось выдумывать свой, путем курения перевода книги и официальной документации Indy 9 и Indy 10, ну и само собой, копания в исходниках этой "чудесной" библиотеки :mrgreen:

Не получилось победить встроенные функции Indy :cry: , поэтому пришлось отказаться от кодирования заголовков в quoted-printable, а добавить и обработать их принудительно в кодировку base64 нативной функцией из fcl модуля base64, что так же отлично воспринимается большинством почтовых сервисов и программ.

Upd. 2.08.2023
Добавил встроенный в Indy логгер, чтобы можно было смотреть в консоли за событиями отправки письма.
Большая просьба проверить :!:
Последний раз редактировалось delphius 02.08.2023 11:42:02, всего редактировалось 24 раз(а).
delphius
постоялец
 
Сообщения: 122
Зарегистрирован: 18.03.2020 13:40:11

Re: Кодировка indy10 под Linux

Сообщение delphius » 01.08.2023 04:00:08

Не получилось победить встроенные функции Indy :cry: , пришлось отказаться от кодирования заголовков в quoted-printable, добавить и обработать их принудительно в кодировку base64 нативной функцией из fcl модуля base64, сейчас все работает кроссплатформенно и приходит в utf-8, как и требуется.
delphius
постоялец
 
Сообщения: 122
Зарегистрирован: 18.03.2020 13:40:11

Пред.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru