Каков самый простой способ отправить электронную почту?

Я хотел бы отправить простое электронное сообщение из моей программы Delphi. Более конкретно, если моя программа встречает исключение, я хочу предоставить возможность отправить сообщение об ошибке через любой указанный адрес электронной почты, который предоставляет пользователь, конечно, мог бы отправить электронную почту для любой ситуации сам по себе. Возможность отправки вложений - это бонус, но не требуется.

Я пробовал много примеров, найденных в Интернете, но большинство из них, похоже, не работают. Некоторые из них требуют таких параметров, как SMTP-сервер и т.д., Но как моя программа может определить это, если мой пользователь может свободно ввести там собственный адрес электронной почты? Кроме того, у меня нет клиента электронной почты по умолчанию, установленного на моем ПК, поэтому, если я не могу отправить электронное письмо из своей программы, то я уверен, что кто-то, кто использует мою программу, будет иметь одинаковую проблему.

Итак, в основном я спрашиваю:

  • Как отправить электронное письмо
  • Вложения не требуются, но будут иметь свои преимущества.
  • Как обрабатывать такие вещи, как SMTP-сервер, номера портов и т.д.
  • Если почтовый клиент по умолчанию не установлен, как справиться с этим

Я надеюсь, что мой пост легко понять.

Спасибо

Ответ 1

Я начну с возможных решений, а затем объясню, почему альтернативы в лучшем случае проблематичны:

Возможные решения

  • Не отправляйте электронную почту с клиентского компьютера, используйте веб-службу для передачи сообщений. Независимо от того, какая технология управляет вашим веб-сайтом, он может обрабатывать размещенные формы и отправлять электронную почту. Просто отправьте свой запрос пользователю на свой веб-сервис и отправьте его веб-службой с помощью электронной почты или сохраните его в базе данных. Если пользователь считает, что он подключен к Интернету, он, вероятно, скажет так, потому что работает его браузер, но работает только HTTP: SMTP может быть заблокирован брандмауэром компании или интернет-провайдером. Это мое предпочтительное решение.
  • Отправьте eMail с помощью SMTP-сервера и ваших учетных данных. Отправка электронной почты с адреса пользователя крайне ненадежна. Вы можете указать свой адрес электронной почты пользователя в заголовке "ОТВЕТ" или просто поместить его в тело сообщения. Вы можете сделать это с помощью компонентов Indy, и поскольку это ваш SMTP-сервер и ваши учетные данные, вы знаете все подробности. Как упоминалось в предыдущем выпуске, это может завершиться неудачно, поскольку SMTP может быть заблокирован брандмауэром пользователя или брандмауэром ISP.

О SMTP

Прежде всего несколько слов о самом SMTP-протоколе, потому что все остальное основано на этом:

  • SMTP - это протокол для отправки электронной почты. Существуют другие протоколы, специфичные для реализации, но все серверы eMail необходимы для реализации SMTP.
  • SMTP был разработан до SPAM. Он позволяет любому компьютеру отправлять электронную почту на любой сервер. Абсолютно никакой аутентификации (теоретически) не требуется для отправки сообщения электронной почты, а адрес сервера SMTP сервера хранится в DNS как запись MX.
  • SMTP сам по себе не имеет абсолютно никакого способа аутентификации отправителя, не предпринимается попытка проверить, действительно ли пользователь находится в поле "От".

Какая проблема с отправкой электронной почты с адреса электронной почты пользователя

Первый вариант при отправке электронной почты с пользовательского адреса - это использование локально установленного клиента и автоматизация, поэтому им предоставляется готовая форма электронной почты Outlook (или Firefox или что-то еще), и нужно просто нажать "Отправить". Но вы говорите, что хотите, чтобы ваше решение работало даже при отсутствии локальной электронной почты, поэтому это не вариант.

Вы упомянули, что надеетесь достичь этого, попросив пользователя только ее адрес электронной почты, никаких сведений о сервере, и я не предполагаю, что у вас нет имени пользователя и пароля. Протокол SMTP фактически позволяет это, потому что у него нет встроенного механизма для аутентификации отправителя. СПАМЫ используют это преимущество, и это называется "спуфинг адреса отправителя". Чтобы защитить это, произошли две вещи:

  • SMTP-хосты больше не принимают электронную почту от кого-либо, они пытаются как-то аутентифицировать отправляющий SMTP-сервер. Другими словами, ваш SMTP-сервер отклонит фальшивую электронную почту, которую вы отправляете себе! Предлагаемое исправление заключается в использовании реле SMTP. Но тогда...
  • Реле SMTP больше не ретранслируют электронную почту от неизвестных пользователей! Сам SMTP не предлагает какой-либо механизм проверки подлинности, но обычным обходным решением является первое чтение электронной почты (поскольку эта часть требует аутентификации), а затем отправлять электронную почту. Это делается автоматически с помощью отправляющего SMTP-компонента, который вы используете, но тем не менее для этого требуется имя пользователя и пароль.

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

Ответ 2

Если вы хотите, чтобы программа отправила вам электронное письмо при возникновении исключения, вы должны проверить MadExcept. Он автоматически сделает это и включит полную трассировку стека и другую полезную информацию об отладке.

Ответ 3

Единица JclMapi в JEDI Code Library содержит два простых метода с использованием установленного клиента MAPI:

function JclSimpleSendMail(const Recipient, Name, Subject, Body: AnsiString;
  const Attachment: TFileName = ''; ShowDialog: Boolean = True; ParentWND: THandle = 0;
  const ProfileName: AnsiString = ''; const Password: AnsiString = ''): Boolean;

и

function JclSimpleBringUpSendMailDialog(const Subject, Body: AnsiString;
  const Attachment: TFileName = ''; ParentWND: THandle = 0;
  const ProfileName: AnsiString = ''; const Password: AnsiString = ''): Boolean;

Не нужно настраивать сервер и т.д. в Delphi - будут использоваться настройки установленного клиента.

Это простое решение, однако, не работает, если почтовый клиент не установлен. Извините за ответ слишком быстро.

Другой вариант - предоставить общедоступный веб-сервер (я сделал это с помощью Google App Engine), который можно использовать из приложения Delphi в качестве почтового шлюза, отправив HTTP-запрос. Это можно сделать с помощью Indy, и поскольку клиенты, имеющие доступ к Интернету, обычно могут выполнять HTTP-запросы, не требуют особых конфигураций, поскольку клиентам SMTP не всегда разрешено проходить через корпоративный брандмауэр.

Библиотека madExcept предоставляет один и тот же способ передачи (отправка по HTTP), так как ему нужен только адрес сервера как константа, определенная в приложении.

Ответ 4

Если у вас есть и знаете имя хоста электронной почты, используйте компонент TidSMTP. Часть клиентов indy.

Затем назовите это заполнением своей информацией

Email.QuickSend('mail.YourEmailHost.com','Title','Addressed To',
                '[email protected]','EmailText');

Ответ 5

Я думаю, что самый простой способ отправить электронную почту - это Windows Collaboration Data Objects (CDO). Альтернативный способ - использовать компонент Indy, но мне не нравится огромный размер двоичного файла.

Прежде чем использовать CDO, импортируйте библиотеку типов из c:\windows\system32\cdosys.dll. В следующем примере показано, как использовать CDO для отправки электронной почты:

uses CDO_TLB;

var M: IMessage;
    s: string;
begin
  M := CoMessage.Create;
  M.From := '[email protected]';
  M.To_ := '[email protected]';
  M.Subject := 'This is subject';
  M.TextBody := 'This is text body';

  s := 'http://schemas.microsoft.com/cdo/configuration/';
  with M.Configuration.Fields do begin
    Item[s + 'sendusing'].Value := cdoPostUsingPort;
    Item[s + 'smtpserver'].Value := 'smtp.host.com';
    Item[s + 'smtpauthenticate'].Value := cdoBasic;
    Item[s + 'sendusername'].Value := 'user_name';
    Item[s + 'sendpassword'].Value := 'password';
    Item[s + 'smtpserverport'].Value := 587;
    Item[s + 'smtpusessl'].Value := False;
    Item[s + 'smtpconnectiontimeout'].Value := 5;  // default is 30 seconds
    Update;
  end;

  try
    M.Send;
    // success
  except
    // fail
    on E: Exception do
      ShowMessage(E.Message);
  end;
end;