トップへ(mam-mam.net/)

Windows用Sendmail.exeを作る ~Delphiソースコード集

検索:

Windows用Sendmail.exeを作る ~Delphiソースコード集

1.OpenSSL系のDLLファイルをダウンロードして展開しパスの通った場所に設定する

https://indy.fulgan.com/SSL/
からOpenSSLをダウンロードし、解凍します。
libeay32.dll
ssleay32.dll
ファイルをパスの通った場所(c:\windowsフォルダや、これから作成する実行ファイルMamSendMail.exeと同じ位置等)に配置します。

2.Iniファイルを作成して設定する

これから作成するプログラムは、同一パスにあるMamSendMail.iniファイルを参照して設定を読み込みます。
MamSendMail.iniファイルの内容は以下を参考にテキストエディタで作成します。
[sendmail]
;SMTPサーバーのIP又はドメイン
smtp_server=smtp.gmail.com

;SMTPサーバーのポート。SslTlsを使わない場合は25、使う場合は456が多い。
smtp_port=465

;メールの送信に認証が不要な場合は0、必要な場合は1
auth=1

;認証ユーザー名。送信元メールアドレスを設定することが多い
auth_username=メールアドレス名@gmail.com
;認証パスワード
auth_password=認証パスワードを記述

;SslTlsを使う場合は1、使わない場合は0を設定
use_ssltls=1

3.Delphiを起動してファイル⇒新規作成⇒その他からコンソールアプリケーションを選択する

以下ソースコードを記述する
program MamSendMail;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,System.Classes,System.IniFiles,
  System.StrUtils ,System.NetEncoding,
  UMamSendMail in 'UMamSendMail.pas',
  IdSSLOpenSSL,IdSMTP,IdGlobal,IdExplicitTLSClientServerBase;
var
  i:integer;
  st:string;
  path:string;    //パスを取得して入れる
  stl:TStringList;//標準入力の値を入れる
  stlRCPT,stlLog:TStringList;//送信先、エラーログ用
  ffrom:string;
  ini:TIniFile;
  smtp_server:String;
  smtp_port:Word;
  auth:integer;        //1で認証あり
  auth_username:string;
  auth_password:string;
  use_ssltls:integer;  //1でSslTlsを使う

  smtp:Tidsmtp;
  ssl:TIdSSLIOHandlerSocketOpenSSL;

  rs,rc:integer;
const
  fini:string='MamSendMail.ini';
  flog:string='MamSendMail.log';
begin
  try
    {パスの取得}
    path:=ExtractFilePath(ParamStr(0));
    {iniファイルがなかったら終了する}
    if not FileExists(path+fini) then
    begin
      stlLog:=TStringList.Create;
      try
        stlLog.Add(fini+'ファイルを実行ファイルと同じパスに作成してください。');
        stlLog.SaveToFile(path+flog);
      finally
        stlLog.Free;
      end;
      exit;
    end;

    stl:=TStringList.Create;
    stlRCPT:=TStringList.Create;
    smtp:=TIdSMTP.Create();
    ssl:=TIdSSLIOHandlerSocketOpenSSL.Create();
    try
      {標準入力から読み取る}
      while not eof(input) do
      begin
        readln(input,st);
        stl.Add(st);
      end;
      //From:から始まる行を取り出す
      getMail(stl,stlRCPT,'From:',rs,rc);
      if stlRCPT.Count>0 then ffrom:=stlRCPT[0];
      stlRCPT.Clear;

      //To,Cc,Bccを取り出す
      getMail(stl,stlRCPT,'To:',rs,rc);
      getMail(stl,stlRCPT,'Cc:',rs,rc);
      getMail(stl,stlRCPT,'Bcc:',rs,rc);

      //標準入力からBCCを消す
      while rc>0 do
      begin
        stl.Delete(rs);
        dec(rc);
      end;

      //iniファイルの読み込み
      ini:=TIniFile.Create(path+fini);
      try
        smtp_server:=ini.ReadString('sendmail','smtp_server','');
        smtp_port:=ini.ReadInteger('sendmail','smtp_port',25);
        auth:=ini.ReadInteger('sendmail','auth',0);
        auth_username:=ini.ReadString('sendmail','auth_username','');
        auth_password:=ini.ReadString('sendmail','auth_password','');
        use_ssltls:=ini.ReadInteger('sendmail','use_ssltls',0);
      finally
        ini.Free;
      end;

      smtp.ConnectTimeout:=10000;
      smtp.ReadTimeout:=10000;
      smtp.Host:=smtp_server;
      smtp.Port:=smtp_port;
      smtp.Username:=auth_username;
      smtp.Password:=auth_password;
      smtp.HeloName:='SmtpClient';
      if use_ssltls=1 then
      begin
        ssl.Host:=smtp.Host;
        ssl.Port:=smtp.Port;
        ssl.Destination:=ssl.Host+':'+IntToStr(ssl.Port);
        smtp.IOHandler:=ssl;
        // utUseImplicitTLSはSSL/TLS通信指定、
        // utUseExplicitTLSはStartTLS(途中からSSL/TLS切り替え)通信指定で
        //   smtp.UseEhlo=True;も指定する(サーバーがStartTLSをサポートしているかTIdSMTPが検出)
        smtp.UseTLS:=TIdUseTLS.utUseImplicitTLS;
      end;

      smtp.Connect;
      if auth=1 then
      begin
        smtp.SendCmd('auth LOGIN',334);
        smtp.SendCmd(TNetEncoding.Base64.Encode(auth_username),334);
        smtp.SendCmd(TNetEncoding.Base64.Encode(auth_password),235);
      end;
      smtp.SendCmd('MAIL FROM: <'+ffrom+'>',250);
      for i := 0 to stlRCPT.Count-1 do
      begin
        smtp.SendCmd('RCPT TO: <'+stlRCPT[i]+'>',[250,251]);
      end;
      smtp.SendCmd('DATA',354);
      smtp.SendCmd(stl.Text+#13#10+'.',250);
      smtp.SendCmd('RSET',250);
      smtp.SendCmd('QUIT',221);
      smtp.Disconnect();

    finally
      if assigned(ssl) then ssl.Free;
      smtp.Free;
      stlRCPT.Free;
      stl.Free;
    end;
  except
    on E: Exception do
    begin
      Writeln(E.ClassName, ': ', E.Message);
      stlLog:=TStringList.Create;
      try
        stlLog.Add(E.ClassName+': '+E.Message);
        stlLog.SaveToFile(path+flog);
      finally
        stlLog.Free;
      end;
    end;
  end;
end.

4.ファイル⇒新規作成⇒ユニットをクリックし以下プログラムを記述する

unit UMamSendMail;

interface
uses system.sysutils,system.classes,system.strutils;

//hd:"From:" "To:" "Cc:" "Bcc:"を渡す           CCを消すため見つかった行と行数
procedure getMail(stl:TStringList;stlm:TStringList;hd:String;out rs,rc:integer);
// ltからgtまでを取得。(<>は含まない)
function getLtGt(st:string):string;

implementation

procedure getMail(stl:TStringList;stlm:TStringList;hd:String;out rs,rc:integer);
var i,j:integer;
    st:string;
    sp:TArray<String>;
begin
  st:='';
  rs:=0;
  rc:=0;
  for i := 0 to stl.Count-1 do
  begin
    if (pos(UpperCase(hd),UpperCase(stl[i]))=1) then
    begin
      rs:=i;
      rc:=1;
      st:=Trim(stl[i]);
      j:=i+1;
      //行数未満、空行ではない、コロン":"を含まない
      while (j<stl.Count) and (trim(stl[j])<>'') and (pos(':',stl[j])=0) do
      begin
        st:=st+trim(stl[j]);
        inc(rc);
        inc(j);
      end;
      st:=trim(StringReplace(st,hd,'',[rfIgnoreCase,rfReplaceAll]));
      //カンマで分割する
      sp:=st.Split([',']);
      for j := 0 to length(sp)-1 do
      begin
        st:=getLtGt(sp[j]);
        stlm.Add(st);
      end;
      break;
    end;
  end;
end;

// ltからgtまでを取得。(<>は含まない)
function getLtGt(st:string):string;
var l,g:integer;
begin
  st:=trim(st);
  l:=pos('<',st);
  g:=pos('>',st);
  if (l>0) and (g>0) and (l<g) then
  begin
    st:=leftstr(st,g-1);
    st:=rightstr(st,length(st)-l);
    result:=st;
  end
  else
  begin
    result:=st;
  end;
end;

end.

5.PHPの設定を行う

(1)c:\MamSendMail のフォルダに以下ファイルを配置する
libeay32.dll
ssleay32.dll
MamSendMail.ini
MamSendMail.exe

(2)php.iniに以下の設定を追加してapacheの再起動を行う
sendmail_path ="C:\MamSendMail\MamSendMail.exe"

(3)phpソースコードに以下を入力してブラウザからURL(http://localhost/mail.php等)を入力して又は、コマンドプロンプトからphp -f mail.phpで実行する
mail.php
mail(
"<toメールアドレス>"	,
'subject'		,
'body1'."\r\n"."body2"	,
"From: fromアドレス"
);
参考 mail2.php (UTF-8で記述する)
mb_send_mail(
'送信先1アドレス,'.mb_encode_mimeheader("次郎様")."<送信先2メールアドレス>,送信先3メールアドレス",
'ここにメールの件名を入れる',
'メールの本文1行目、\r\nメールの本文2行目\r\n",
"From: ".mb_encode_mimeheader("送信太郎")."<fromアドレス>"."\r\n".
"Return-Path: return-pathアドレス"."\r\n".
"Cc: Cc1アドレス,".mb_encode_mimeheader("太郎様")."<Cc2アドレス>"."\r\n".
"Bcc: Bcc1アドレス,".mb_encode_mimeheader("三郎様")."<Bcc2アドレス".",Bcc3アドレス"."\r\n"
);

参考:SMTPが使えるようにGMailの設定を行うには

外部のメーラーを使えるようにGMailの設定を行います

1-(1)ギアマークをクリックし、設定をクリックします。

1-(2)メール転送とPOP/IMAPをクリックします。
●すべてのメールでPOPを有効にする を選択します
●IMAPを有効にする を選択します。
変更を保存する をクリックします。

1-(3)Googleアカウントをクリックします。

1-(4)アカウントにアクセスできるアプリをクリックします。

1-(5)安全性の低いアプリの許可を有効にします。