メール送信(Ver.6)

はじめに

メールはサーバーで送ります。送信方法は、PHPのmail関数を使う方法なので、UNIX系ならsendmailコマンドをたたく方法になります。一方、これだとSMTPサーバーへの転送ができないので、swiftmailerも組み込みました。Windowsの場合はmail関数がすでにSMTPですので、php.iniにサーバー情報などを書くことで対処できます。(設定のリファレンスは本ページの末尾にあります。)

定義ファイルでの指定例を以下に示します。なお、Ver.5の動作とVer.6の動作の兼ね合いがあるので、後半の記事もご覧ください。

IM_Entry(
        array(   // Contexts
            array(
                'name' => 'request',
                'send-mail' => array(
                    'create' => array(
                        'from-constant' => 'info@msyk.net',
                        'to' => 'email',
                        'cc-constant' => 'msyk@me.com',
                        'subject-constant' => 'ビジネスマッチング申し込み',
                        'body-constant' => '受け付けました。\n本当です。',
                        'f-option' => true,
                        'body-wrap' => 68,
                    )
                )
             )
        ),
        array(   // Options
            'formatter' => array(...),
            'smtp' => array(
                'server' => 'mysmtp.msyk.net',
                'port' => 587,
                'username' => 'msyktest@msyk.net',
                'password' => 'oshienai',
            )
        ),
        array('db-class' => 'PDO'),
        false
    );

メールを送信するタイミングの指定

'send-mail'キーの配列の次のレベルのキーとして、'read' 'update' 'create'のいずれかを指定できます。それぞれ、データベースからの読み込み時、更新時、新規レコード作成時を意味し、コンテキストに対するそれぞれのタイミングでメールを送信します。いずれも、データベース処理が終了してからメールの送信にかかります。上記の例では、新規レコード作成時に、メールが送信されます。

宛先や送信者の指定

宛先の指定は、'to'ないしは'to-constant'キーに指定します。もし、宛先が一定のものであれば、'to-constant'キーに指定をしてください。'to'キーにはフィールド名を指定します。データベース処理の結果、たとえば新規レコードの場合には新しいレコードが1つ作成されて、そのレコードの内容から'to'キーに指定したフィールドより宛先のデータが取り出されます。編集も原則は1レコードです。一方、読み出しの場合は1レコードにならないかもしれませんが、その場合は最初のレコードから取り出します。むしろ、1レコードに絞り込むコンテキストにするのがメールを送る場合には妥当だと考えられます。

メールアドレスは「名前 <アドレス>」ないしは「アドレス」の2つの形式のみのサポートになります。'to-constant'キーに対する値、あるいは'to'キーで指定されるフィールドの値は、このどちらかの形式にしてください。

cc、bccについてもまったく同様のルールです。'to'と'to-constant'の両方の指定があれば、'to-constant'が優先されます。cc、bccでも-constantが優先となります。

fromについても、fromとfrom-constantキーがあり、設定や動作等は同じです。ただし、UNIXでSMTPサーバーを使わない場合だと、通常はソース側のFrom:は無視されて、UNIXアカウントそのものをFrom:として設定してしまいます。ただし、サーバー側で許可されていれば「'f-option' => true」の指定を定義ファイル内に記述することで、sendmailコマンドの-fパラメータを指定して、送信者の指定が可能です。

件名と本文の指定

件名は、subjectあるいはsubject-constantのいずれかのキーに指定します。toなどと同じルールです。

メールの本文は、定義ファイル内に指定した通りに送信する'body-constant'、フィールドの内容をそのまま送信する'body'に加えて、テンプレートの処理も可能です。優先順はテンプレート、body-constant、bodyの順になりますので、不要なフィールドは消しておきましょう。

テンプレート処理をするには、テンプレートのファイル名をbody-templateキーに指定します。このとき、テンプレートのファイルは、定義ファイルのあるディレクトリを基準に検索します。つまり、定義ファイルといっしょに何らかのテキストファイルを億としたら、body-templateキーの値はファイル名だけでかまいません。

テンプレートのファイル内では、そのファイルの内容を本文にしますが、フィールドの値との置き換えも可能です。置き換えたい箇所に@@1@@、@@2@@のように、アットマーク2つに囲まれた1から始まる整数を指定します。テンプレートのファイルはUTF-8で保存します。

フィールドについては、'body-fields'キーに、半角のカンマで区切って指定します。最初が1で、順次番号が増えるようになります。例で言えば、emailフィールドの値は、テンプレート内の@@3@@と置き換わって表示されます。'body-fields'キーを省略すると、テンプレートのファイル通りにメールが送信されます。

本文は一定の長さで改行を入れます。既定値では72バイトですが、'body-wrap'キーで異なる値にできます。0に設定すると改行しません。ここで、バイト数ですが、実際のバイト数ではなく、日本語は2バイト、英語は1バイトと数えた結果で示しています。実際のエンコードはUTF-8なので、嘘と言えば嘘のカウントになりますが、おそらくこうして指定をすることに慣れている人が多いので、ここでは実態とは関係ない数値ではありますけども実用的という意味で「2バイトルール」でカウントしたものとします。

UNIXの場合のSMTPサーバーの指定

定義ファイルのIM_Entry関数の第3引数のオプション領域に'smtp'キーで配列を指定します。その他のキーは、前記の例の通りで、キーを見れば意味は分かると思います。もし、SMTP認証をしない場合は、serverとportだけを指定します。認証する場合は、server, port, username, passwordを指定します。したがって、2つないしは4つの要素があるかのどちらかになります。

SMTPサーバーの指定は、params.phpファイルでも指定が可能です。変数名として、$sendMailSMTPの定義し、値は'smtp'の右側の配列と同様に指定をします。params.phpファイルでの指定よりも、定義ファイルの指定が優先されます。どこにもSMTPサーバーの設定がない場合には、mail関数での送信になります。

Windowsの場合は、'smtp'の指定やparams.phpファイルでの指定は一般には不要ですが、もし設定すれば、mail関数ではなく、qdsmtpによるメール送信ができます。

送信されるメールの文字セット

基本的にはメールはUTF-8でエンコードして送られます。ISO-2022-JPの指定はOME.phpではできるのですが、必要なら定義ファイルでの指定ができるようにしようと思います。リクエストがなければUTF-8固定で行きます。

ヘッダについては、base64のインラインエンコードを、ASCIIコード以外の文字について行います。本文はそのままですが、ヘッダのContent-TyleのcharsetにUTF-8という文字を付けます。つまり、本文はbase64等でのエンコードは行いません。

ファイルの添付は実装する予定はありません。ファイルを送りたいのなら、そのリンクを送るようなアプリケーションの動作にしましょう。

Gmailのアカウントでメール送信する場合

"server"キーの値は、"smtp.gmail.com" としてください。"port"キーの値は、"587"としてください。さらに"encription"キーは、"tls"とします。"username"キーの値は、ユーザー名を指定しますが、メールアドレスそのものを指定します。"password"キーはパスワードそのものを指定します。params.phpファイルに指定する場合の例を示します。

$sendMailSMTP = array(
    "server" => "smtp.gmail.com",
    "port" => 587,
    "encryption" => "tls",
    "username" => "msyk.nii83@gmail.com",
    "password" => "himitsunopassword",
);

定義ファイルやparams.phpに上記の2つのSMTP送信に関するパラメータを設定するとメールが送信できますが、できない場合には、こちらの記述に従って、「安全性の低いアプリのアクセス」を有効にします。この設定が「有効」になっていないと、SMTPサーバーが受け付けません。相当以前はこれが既定値で「有効」になっていましたが、ある時期からは「無効」が既定値になっているようですので、以前は送ることができたという方も、この設定は必ず確認をしてみてください。

INTER-Mediator Ver.5とVer.6との相互運用

Ver.6の開発時に、様々な機能を追加しましたが、そのための互換性が微妙な感じになってきたので、何もしない場合はVer.5と同じ動作になることを目指し、次のようなルールでバージョン間の動作を切り分けられるようにしました。以下の方法で切り分けるのは、メールの文面を作成する動作です。メール送信は、以下の方法でVer.5の動作にしている時でも、SMTPサーバーを指定するとswiftmailerを利用するなど、送信処理はVer.6で置き換わったものになります。

まず、params.phpに$sendMailCompatibilityModeという変数を記述することができるようにしました。これがtrueならVer.5の動作、falseならVer.6の動作となります。この変数は省略した場合trueになります。しかしながら、コンテキストのsend-mailキーに、template-contextキーの値がある場合には、無条件にVer.6の動作になります。

Ver.5と6の動作の違いは以下のとおりです。

  • template-contextキーによる、メール文面をデータベースから取り出す処理はVer.6動作が必須。一方、body-template、body-fieldsによるテンプレート処理は、Ver.5互換にしないと利用できない。
  • 文字列中の@@フィールド名@@をフィールドの値に置き換える機能は、Ver.5ではsubject-constant、body-constantのみ。Ver.6では、from、to、bcc、cc、body、subjectについて置き換えが可能になった。
  • Ver.6では、from-constant、to-constant、cc-constant、bcc-constant、subject-constant、body-constantは無視するようにした。
  • HTMLの送信はVer.6のみ。

ファイルを添付する

ファイルを1つだけ追加できます。添付するには、media-root-dirキーの指定が必要です。そして、media-root-dirキーと、attachmentキーから得られるパスを繋いだ絶対パスのファイルを添付します。attachmentキーにフィールド名を指定した場合、そのフィールドは、ファイルのアップロードコンポーネントを利用してアップロードした場合に自動的に設定されるパス名であることを想定していますが、状況によってはテンプレートの仕組みでパスを合成すれば良いでしょう。

送信結果をデータベースに残す

storeキーには、同じ定義ファイル内に定義した、レコード作成可能なコンテキストを指定します。そのコンテキストに、新たにレコードを作って送信した結果を残せます。エラーがあって送れない場合でも結果を残します。なお、指定したコンテキストには、以下のフィールドがあるものとします。フィールド名は固定でカスタマイズはできません。フィールド名から、何が入力されるかは判別可能だと思います。

to_field、bcc_field、cc_field、from_field、subject、body、errors

あるテーブルの関連テーブルに送信結果を残す場合、relationキーを指定します。すると、上位のコンテキストの主キー値を自分自身の外部キーフィールドに設定できるので、作られたメール送信レコードに元のテーブルとの関連を残すことができます。ただし、operatorが=のものだけです。また、送信結果を残すコンテキストにqueryキーがあり、operatorが=のものがある場合、その値も初期値として設定されます。

データベースに入れたテンプレートにある文面でメールを作成する

メールの文面や送り先などをデータベースに入れておき、それを元にメールを作成して送付するには、template-contextキーを指定します。例えば、「mail_template@id=3」のように記述します。mail_templateは、同じ定義ファイルにある読み込み可能なコンテキストで、このコンテキストから以下のようなフィールドがあるものとします。フィールド名は固定でカスタマイズはできません。フィールド名から、何が入力されているかは判別可能だと思います。

to_field、bcc_field、cc_field、from_field、subject、body

@以降は、コンテキストの中の検索条件を指定しますが、条件そのものではなく、=の前後で分離して、WHERE id = 3 のような検索条件で検索をします。実際には最初の1つのレコードだけを利用します。そのレコードからそれぞれのフィールドを取り出しますが、値そのままの場合もありますが、@@フィールド@@を置き換えることも可能です。

HTMLメールの送信

メールの文面の最初の文字列が <html> である場合、HTMLメールトとして送信します。添付ファイルも一緒に送れますが、添付ファイルをHTMLに埋め込みたい場合、本文の文面内で##image## と記述すればOKです。ただし、画像ファイルであるという前提で文面を作成してください。

メッセージングとしてメール送信

send-mailキーはVer.6でも利用できますが、メッセージ送信機能を拡張するにあたり、send-mailキーの代わりにmessagingキーを指定することもできます。その場合は、配列にdriverキーで値がmailのエントリーを入れるか、drivierキーを省略することでも構いません。

リファレンス

[第1引数, コンテキスト定義]
メール送信

配列指定
キー インデックス 下位のキー
'send-mail'
あるいは
'messaging'
'driver' メールを送信する場合は、値は'mail'、あるいはこのエントリーごと省略する(send-mailキーの場合は記述してはいけない)
'read' コンテキストに対してレコードの取り出しを行った後にメールを送信する。
'from' 送信者名や送信者アドレスが含まれるフィールド名、あるいはアドレスの文字列。文字列内に「@@フィールド名@@」の記述があれば、フィールドのレコードに置き換わる
'to' 送信先が含まれるフィールド名、あるいはアドレスの文字列。文字列内に「@@フィールド名@@」の記述があれば、フィールドのレコードに置き換わる。複数の送信先はカンマで区切る
'cc' Cc先が含まれるフィールド名、あるいはアドレスの文字列。文字列内に「@@フィールド名@@」の記述があれば、フィールドのレコードに置き換わる。複数の送信先はカンマで区切る
'bcc' Bcc先が含まれるフィールド名、あるいはアドレスの文字列。文字列内に「@@フィールド名@@」の記述があれば、フィールドのレコードに置き換わる。複数の送信先はカンマで区切る
'subject' 件名が含まれるフィールド名、あるいは件名の文字列。文字列内に「@@フィールド名@@」の記述があれば、フィールドのレコードに置き換わる
'body' メール本文が含まれるフィールド名、あるいは本文の文字列。文字列内に「@@フィールド名@@」の記述があれば、フィールドのレコードに置き換わる
'from-constant' 送信者やアドレスを文字列で指定(Ver.5互換動作の場合のみ)
'to-constant' 送信先を文字列で指定(Ver.5互換動作の場合のみ)
'cc-constant' Cc先を文字列で指定(Ver.5互換動作の場合のみ)
'bcc-constant' Bcc先を文字列で指定(Ver.5互換動作の場合のみ)
'subject-constant' 件名を文字列で指定。文字列内に「@@フィールド名@@」の記述があれば、フィールドのレコードに置き換わる(Ver.5互換動作の場合のみ)
'body-constant' 本文を文字列で指定。文字列内に「@@フィールド名@@」の記述があれば、フィールドのレコードに置き換わる(Ver.5互換動作の場合のみ)
'body-template' 本文のテンプレートとなるファイルのファイル名(Ver.5互換動作の場合のみ)
'body-fields' テンプレートに差し込むフィールドの順序をカンマで区切る(Ver.5互換動作の場合のみ)
'f-option' UNIXでSMTPサーバを経由しない場合にtrueを指定すると、fromの指定が有効
'body-wrap' 右端の折り返しのバイト数
'template-context' メールの文面を得られるコンテキスト名と検索条件。テーブルに文面のテンプレートをセットしているものとする
'store' 送信したメールをここで指定したコンテキストに対して新規レコードを作成して保存する
'attachment' 添付するファイルへの相対パスの文字列、あるいはそれを含むフィールド名。文字列内に「@@フィールド名@@」の記述があれば、フィールドのレコードに置き換わる
'update' コンテキストに対してレコードの更新処理を行った後にメールを送信する。第3次元については、readと同様
'create' コンテキストに対して新たなレコードを作るアクションを起こした後にメールを送信する。第3次元については、readと同様

[第2引数, オプション設定]
メール送信サーバー

配列指定 params.phpで変数名
第1次元 第2次元
'smtp' 'server' メール送信時に使用するサーバのホスト $sendMailSMTP
'port' メール送信時に使用するサーバのポート
'username' メール送信時に認証で使用するユーザー名
'password' メール送信時に認証で使用するパスワード
'encryption' 通信処理の暗号化をする場合にその方法を指定する。'ssl'、あるいは'tls'を指定する