【Drupal】メール送信機能を実装してみた

こちらのサイトではDRUPAL10に関連する記事を掲載しています。

はじめに

Drupalのディベロッパー認定試験を二ヶ月後に受験することになったので、最近はDrupalをいろいろ触っています。

それとは別に開発案件で急遽Drupalにメールを実装する必要が出てきたので、ベストプラクティスを調べてみました。

以前はレンタルサーバーのSMTPを利用してメールを送信することがほとんどでしたが、今回はできるだけメール未到達のリスクの少ない方法をとることにしました。そこで、料金も比較的やすければ扱いやすいSENDGRIDを利用することにしました。

DRUPALでSENDGRIDを利用してメールを配信すると言ってもAPIかSMTPかまたどんなモジュールを使ってどうやって送るのかと言ったところはまだ決めていないのでこの機会にいろいろ調べた結果を記事にしました。

SENDGRIDについて

SendGridは全世界で利用されているメール配信サービスで、クラウドサービスのためアカウントを作成するだけですぐにメールを配信できます。また一般的なSMTPサーバーを利用したものだけでなくAPIを利用することも利用できます。

SENDGRIDのサイトを見てみると以下のような説明が載っていました。

Web APIかSMTPリレーか: どうやってメールを送ればいいの? | SendGridブログ
この記事は Web API or SMTP Relay: How Should You Send Your Email? の抄訳です。SendGrid経由でメールを送信したり、SendGridとシステムをインテグレートするときは、Web APIやSMTPリレーを用います。これら2つの手法の違いは、荷物を配達する方法の違...

Web API

SendGridのWeb APIではHTTP経由でメールを送信します。SendGridにメールの送信リクエストを投げて、HTTP応答コード200が返ってきたら、そのメッセージはSendGridに受理されたということです。一方、400や500などが返ってきたら、何か異常が起きてSendGrid側でリクエストを処理できなくなったことを意味します。

SMTP リレー

SMTPリレーでメールを送るためには、Web APIに比べて、より多くのメッセージのやり取りが必要になります。配達のたとえ話で言えば、SMTPリレーは荷物を自分自身で運ぶ方法に近いでしょう。なぜなら、荷物を届けるためには、ポストに投函するよりも更にいろいろなことをやらなければならないからです。送信者がSMTPを利用してSendGridに接続する場合は、SendGridから受信側のISPにメッセージを送る前に、送信者とSendGridの間で個別の情報を複数やりとりしなければなりません。

APIではSMTPで必要なDNS認証手続きなど不要なやり取りがいらないそうなのでAPIが利用できるのであればAPIのほうがメリットがありそうです。

SENDGRID 利用料金

次に、SENDGRIDの料金を調べてみました。

SENDGRID サイトより引用
Billing | SendGrid Docs | Twilio
Manage your SendGrid billing settings

無料プランでは上限が100通/一日に限定されているようです!

お試しでWEB APIを使ってみたかったのですが、いくら利用者が少ないとはいえこれでは少なすぎます。

かといって有料プランに入るほどの利用者もいないので、他で使用しているSMTPサーバーを使ってメールを送信することにしました。

ということで、Drupalの実装方法を検討しています。

DrupalでSENDGRID実装方法の比較検討

しばらくDrupalでSENDGRIDを実装する方法をググっているといろんなコントリビュートモジュールを使った方法が紹介されていました。どれを使ってもメールが送信できればよいのですが、いろいろあるので決めあぐねていると、今度はSENDGRIDの英語のブログ記事にいくつかのモジュールの比較記事がありました。

Drupal | SendGrid Docs | Twilio
Set up SendGrid for Drupal using modules like SendGrid Integration, SMTP Authentication Support, Swift Mailer, or PHPMailer SMTP. Achieve optimized email servic...

おー、まさに知りたかったのはこれです!

SendGrid を使用して Drupal から電子メールを送信するには、ニーズに応じて 以下のモジュールが使用できるそうです。

  • SendGrid Integration モジュール
  • SMTP Authentication Support モジュール、
  • Swift Mailer モジュール
  • PHPMailer SMTP モジュール

この記事はそれぞれのモジュールを使用した場合のメリットデメリットや設定方法がかなり詳細に記載されています。すべてのモジュールを試してみることはできませんでしたが、とても有用な記事なので翻訳して紹介します。

SendGrid Integration モジュール

SendGrid 統合モジュールは、SendGrid API Web サービスを使用して電子メールを送信します。 SMTP は使用しません。 Web サイトのワークロードによっては、これがパフォーマンスにメリットをもたらす可能性があります。 このモジュールは、人口統計のレポート用のグラフも提供します。 このモジュールをインストールしてセットアップするには、Drupal に関する高度な知識が必要です。 ドラッシュの使用が必要です。

ダウンロードしてインストールし Drupal.org からSendGrid 統合モジュールを、Composer Manager を使用して Drush 経由で更新を実行します。

インストール後のアクセス admin/config/services/sendgridAPI 認証情報を構成します。

詳細な手順については、 モジュールのドキュメントを参照してください。

403 Forbidden.

SMTP Authentication Support モジュール

で SendGrid を使用するには DrupalSMTP 認証サポート モジュールを使用します。 Drupal のバージョンと互換性のあるこのモジュールのバージョンをインストールします。

モジュール ページを開き、SMTP モジュールを見つけて、次の設定を使用して構成します。

  • SMTP サーバー– smtp.sendgrid.net
  • SMTP ポート– 587
  • 暗号化プロトコルを使用– いいえ。暗号化が必要な場合は、「SSL を使用」を選択し、SMTP ポートを 465 に設定します。
  • ユーザー名– SendGrid ユーザー名: “apikey”
  • パスワード– SendGrid API キー

Swift Mailer モジュール

を使用するには Swift Mailer モジュール、Drupal のバージョンと互換性のあるこのモジュールのバージョンをインストールします。

このモジュールの構成は上記とほぼ同じです。

PHPMailer SMTP モジュール

PHPMailer SMTP は、最新の PHPMailer ライブラリを使用して SMTP 経由で電子メールを送信し、RFC に準拠しています。 モジュールが必要です メール システム。 ご覧ください。 プロジェクトページを 詳細については

Composer を使用してインストールし、有効にします。

composer require drupal/phpmailer_smtp

インストール後のアクセス admin/config/system/phpmailer-smtpモジュールを設定します。

  • プライマリ SMTP サーバー– smtp.sendgrid.net
  • SMTP ポート– 587
  • 安全なプロトコルの使用– TLS

[SMTP 認証]、ユーザー名とパスワード (API キー) を設定します。

  • ユーザー名– SendGrid ユーザー名: “apikey”
  • パスワード– SendGrid API キー

結局どれを使うか

SMTPを利用するので選択肢がおおくて迷いますが、Drupal (Symphony)はSwift Mailをサポートしています。Swift Mailerライブラリを使うと、基本的なHTMLメールは簡単に送ることができます。

そこでSwift mailerを利用したSwift mailerモジュールを使うことにしました。こちらは別案件で採用して実績もあります。

Swift Mailerライブラリの公式サイトはこちらです。

Swift Mailer: A feature-rich PHP Mailer – Documentation – Swift Mailer

実際に使ってみる

Swift Mailer モジュールのインストールと設定

インストールは簡単です。

以下のDrupal.orgで公開されているSwift Mailerモジュールをダウンロードしてコントリビュートモジュール用のディレクトリ配下に置くかまたはComposerコマンドを実行してモジュールをインストールします。

Access to this page has been denied.

Compserを利用する場合は以下のコマンドをターミナル画面で実行してください。

composer require 'drupal/swiftmailer:^2.4'

インストールを完了するには必ず管理画面の機能拡張から対象モジュールを有効化してください。

インストールが正常に完了したら、管理画面から環境設定->システム->Swift Mailerを選択して設定画面を表示します。

メール送信方式をSMTPに設定し、必要なサーバー情報を入力すると設定は完了です。

テスト送信機能がありますので、送信先を指定してメールが正しく受信できることを確認します。

【注意事項】
正しく設定したつもりでもテスト送信するとメールが届かない場合は、CoreモジュールのMail Systemの設定を確認してみてください。デフォルトで使用するメーラーがSwiftMailerになっていない可能性があります。

バックエンドからメールを送信する

少し難易度は高くなりますが、ここからプログラムでメールを送信する方法を紹介します。

実装方法としては、Drupalのメールフック機能でメールのテンプレートを登録し、同じくDrupal Coreのメールプラグインを利用してメールを配信します。

今回やりたいことはあるコンテンツタイプのコンテンツが追加や変更されたときに対象のユーザにメールを送信するというものですが、またこちらも英文ですがとても参考になるサイトを見つけたので翻訳してご紹介します。

How to send mail programmatically in Drupal 8
How to send mail programmatically in Drupal 8||How we can use Mail API in Drupal 8 programmatically for sending emails.

Drupal で電子メールを送信するには、次の 2 つの手順を実行します。

  • 適切なhook_mail()実装で電子メールのプロパティ(件名、本文、ヘッダーなど)を定義します。
  • 電子メールを送信するには、メール マネージャーを使用します。

今回説明するプログラムは、Drupalのフック機能を使用しています。またフック機能を実装するため、モジュールを追加して拡張子が.moduleのフック用ファイルを作成する必要がありますが、その説明はここでは省略しています。

hook_mailを作成(Mailテンプレートを作る)

メールを送信する場合 プログラムで電子メール、hook_mail() を実装するモジュール名を指定する必要があります。

では、それをどのように実装するかを見てみましょう。

これは、test_message ($key) として識別される 1 つのテンプレートを定義する単純な実装です。 他の 2 つの関数引数は次のとおりです。

$message:参照によって渡され、その中にメールに関する定型文を必要なだけ追加します。

$params:電子メールに含める必要があり、電子メールの送信時にメール マネージャーから渡される追加データの配列

以上がhook_mail()の実装です。

<?php

/**
* Implements hook_mail().
*/
function <module_name>_mail($key, &$message, $params) {
 $options = array(
   'langcode' => $message['langcode'],
 );

 switch ($key) {
   case 'create_article':
     $message['from'] = \Drupal::config('system.site')->get('mail');
     $message['subject'] = t('Article created: @title', array('@title' => $params['node_title']), $options);
     $message['body'][] = $params['message'];
     break;
 }
}

?>

hook_entity_insertの作成(記事作成時にメールを配信する)

記事が作成されるたびに呼び出される部分のコードです。

記事が作成されると、Drupal Mail マネージャー サービスをロードし、電子メールの値の設定を開始します。 次の情報が必要です。

  • $module :hook_mail()を実装し、テンプレートを定義するモジュール名
  • $key : テンプレートID
  • $to :受信者の電子メール アドレス (現在のユーザー アカウントで見つかったもの)
  • $langcode : $params 配列内に含まれ、件名メッセージの翻訳に使用される言語
  • $params[‘件名’] : メールの件名
  • $params[‘message’] メール本文
  • $send : 電子メールを実際に送信する必要があるかどうかを示すブール値

次に、これらすべての値をメール マネージャーの mail() メソッドに渡します。 この中で先に説明したhook_mail()を呼び出します。

最終的に現在インストールされているMail Systemに連携して、メールが配信されます。
以上がDrupal を使用してプログラムで電子メールを送信する方法です。

<?php
/**
* Implements hook_entity_insert().
*/
function <module_name>_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {

 if ($entity->getEntityTypeId() !== 'node' || ($entity->getEntityTypeId() === 'node' && $entity->bundle() !== 'article')) {
   return;
 }
 $mailManager = \Drupal::service('plugin.manager.mail');
 $module = ‘<module_name>’;
 $key = 'create_article';
 $to = \Drupal::currentUser()->getEmail();
 $params['message'] = $entity->get('body')->value;
 $params['node_title'] = $entity->label();
 $langcode = \Drupal::currentUser()->getPreferredLangcode();
 $send = true;

 $result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
 if ($result['result'] !== true) {
   drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error');
 }
 else {
   drupal_set_message(t('Your message has been sent.'));
 }

}
?>

さいごに

いかがだったでしょうか。モジュールの設定からコードの実装までかけ足で説明しました。実際にやってみるとつまずくポイントはいろいろあります。特に後半のコードの作成はコードに馴染みのない方には少し難しいと思いますが、参考記事があまりないのでご紹介しました。

あと、Email送信機能を実際に使ってみたい場合や勉強したい場合は、Example For Developmentモジュールをインストールして実際に動きを追っかけるのが一番だと思います。

次回は、Example For DevelopmentモジュールのEmail送信機能を使ったハンズオン的な記事をご紹介できたらと思います。

Examples for Developersはこちらです。

Access to this page has been denied.
このサイトに関するご意見・ご質問はこちらまで

この記事またはDrupalに関するご質問がございましたら、お気軽にお問い合わせください。

タイトルとURLをコピーしました