Apexでのメール送信の流れ
- 単一メールクラスまたは一括メールクラスのインスタンスを作成する。
- 送信先、件名、本文などを設定する。
- MessagingクラスのsendEmailメソッドを使用してメールを送信する。
Apexのトランザクションがコミットされるまでメールは送信されません。
単一メールと一括メールの違い
単一メールクラスを使用したとしても、複数のメールを一度に送信することができます。
単一メールクラスでメールテンプレートを使用する場合、差し込まれるオブジェクト・送信先を個別に指定する必要があります。
一括メールクラスを使用すると、メールテンプレートで差し込まれるオブジェクト・送信先をリストで指定することができます。
その他、下記のような違いがあります。
- 単一メール
- 件名・本文は、メールテンプレートの他、個別に指定できます。
- メールテンプレートにテキスト、HTML、Visualforceが使用できます。
- 送信先をオブジェクトIDで指定できる他、StringでEmailアドレスを指定できます。
- 送信元に組織のメールアドレスを使用できます。
- 一括メール送信
- 件名・本文はメールテンプレートで指定します。
- Visualforceメールテンプレートを使用することができません。
- 送信先はオブジェクトIDで指定します。
- 送信元はApex実行者となります。
単一メール(SingleEmailMessage)でメールを送信する
① メールテンプレートを使用せずにメールを送信する
-
setTargetObjectId
で取引先責任者、リード、ユーザを送信先に設定することができます。ユーザを設定した場合はmsgObj.setSaveAsActivity(false);
を設定する必要があります。指定したユーザが無効ユーザでもメールが送信されます。 - 送信メールを活動レコードに保存する場合は、
setTargetObjectId(recordId)
で取引先責任者ID、リードIDを指定します。
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(toAddresses); // 送信先(String[])
mail.setCcAddresses(ccAddresses); // CC送信先(String[])
mail.setBccAddresses(bccAddresses); // BCC送信先(String[])
mail.setSubject(subject); // 件名(String)
mail.setPlainTextBody(body); // 本文(String)
mail.setEntityAttachments(ids); // 添付ファイル(Document、ContentVersion、AttachmentのIDのリスト)
mail.setOrgWideEmailAddressId(emailAddressId); // 送信元に設定する組織のアドレスID(設定しない場合はApexの実行者が設定される)
// mail.setSenderDisplayName(displayName); // 送信者表示名。組織のメールアドレス使用時は設定不可。
mail.setUseSignature(false); // 著名の有無。デフォルトはtrue。
mail.setBccSender(true); // 送信者をBCCに追加
mail.setReplyTo(replyAddress); // 返信先メールアドレス(String)
Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{mail});
② メールテンプレートを使用してメールを送信する
// whoId: メール送信先オブジェクト
// whatId: メールテンプレート差し込み用オブジェクト
Messaging.SingleEmailMessage mail= Messaging.renderStoredEmailTemplate(templateId, whoId, whatId);
mail.setSaveAsActivity(false); // 送信メールを活動に保存する。デフォルトはtrue。
Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{mail});
一括メール(MassEmailMessage)でメールを送信する
-
targetObjectIds
(送信先)に指定できるオブジェクトは取引先責任者、リード、ユーザのみです。 -
targetObjectIds
(送信先)のIDはすべて同じオブジェクトのレコードIDである必要があります。 -
whatIds
(差し込み用オブジェクト)を指定できるのはtargetObjectIds
(送信先)に取引先責任者のIDのリストを設定したときのみです。 -
whatIds
に指定できるオブジェクトは取引先責任者、ケース、商談、商品のみです。 -
whatIds
を指定する場合は、targetObjectId
ごとに1つずつ指定します。
Messaging.MassEmailMessage mail = new Messaging.MassEmailMessage();
mail.setTemplateId(templateId); // メールテンプレートId
mail.setTargetObjectIds(targetObjectIds); // 送信先(取引先責任者、リード、ユーザのIDのリスト)。
mail.setWhatIds(whatIds); // メールテンプレート差し込み用オブジェクト
mail.setReplyTo(replyAddress); // 返信先メールアドレス(String)
mail.setSenderDisplayName(displayName); // 送信者表示名。
mail.setSaveAsActivity(false); // 送信メールを活動に保存する。デフォルトはtrue。
mail.setUseSignature(false); // 著名の有無。デフォルトはtrue。
Massaging.SendEmail(new List<Messaging.MassEmailMessage>{mail});
テスト
メールが送信されるかを検証する場合、System.assertEquals(1, Limits.getEmailInvocations());
を使用することができます。
ただし、Limits.getEmailInvocations
はTest.startTest()
と同時に使用できないため、非同期処理のメール送信を検証することはできません。
非同期の処理とメール送信の処理は個別にテストする必要があります。
@isTest static void sendEmailTest() {
EmailService.sendEmail('テスト'); // メール送信を行う同期処理
System.assertEquals(1, Limits.getEmailInvocations());
}
@isTest static void futureTest() {
Test.startTest();
EmailService.sendEmailFuture('テスト');
Test.stopTest();
System.assertEquals(1, Limits.getFutureCalls());
}
メール送信の制限
- トランザクションあたり
sendEmail
を10回まで使用できます。 - 単一メールは1日に最大5,000個の外部メールアドレスに送信できます。
- アドレスが一意であるかどうかは考慮されません。
- 組織の内部ユーザ(ポータルユーザを含む)に送信できるメールには制限はありません。
- 一括メールは1日に最大5,000この外部メールアドレスに送信できます。
- アドレスが一意であるかどうかは考慮されません。
- 組織の内部ユーザ(ポータルユーザを含む)に送信できるメールには制限はありません。
グリニッジ標準時 (GMT) に基づき、各組織は 1 日に最大 5,000 個の外部メールアドレスに単一メールを送信できます。Spring '19 よりも前に作成された組織では、この日次制限は、Apex と Salesforce API (REST API を除く) を介して送信されたメールに対してのみ適用されます。Spring '19 以降に作成された組織では、この日次制限はメールアラート、単純なメールアクション、フロー内の [メールを送信] アクション、および REST API にも適用されます。組織がこの制限に達したため新しくカウントされたいずれかのメールを送信できない場合、通知のメールがユーザに送信され、エントリがデバッグログに追加されます。Salesforce の Email Author やコンポーザを使用して送信した単一メールは、この制限に含まれません。取引先、取引先責任者、リード、商談、ケース、キャンペーン、カスタムオブジェクトの各ページから、組織の取引先責任者、リード、個人取引先、ユーザに単一メールを直接送信する場合は、制限はありません。
単一メールを送信する場合は、次の点に注意してください。
各 SingleEmailMessage では、To、CC、および BCC の各項目全体で最大 150 名の受信者を指定できます。また、各項目は、4,000 バイトに制限されています。
SingleEmailMessage を使用して組織の内部ユーザにメールを送信するときに setTargetObjectId でユーザ ID を指定すると、メールが 1 日あたりの制限値にカウントされません。ただし、setToAddresses で内部ユーザのメールアドレスを指定すると、制限値にカウントされます。
メールテンプレート
-
{!User.xxx}
はApex実行ユーザが設定されます。受信ユーザを設定する場合は{!Receiving_User.xxx}
を使います。
エラー (例外)
■ INVALID_SAVE_AS_ACTIVITY_FLAG
「INVALID_SAVE_AS_ACTIVITY_FLAG, saveAsActivity must be false when sending mail to users」
targetObjectId
またはtargetObjectIds
が設定されていると、EmailオブジェクトのプロパティsaveAsActivity
がデフォルトでtrueが設定されます。この値がtrueで設定されているとメールが活動として保存されます。
しかし、targetObjectId
またはtargetObjectIds
にユーザIDを設定しているとこの機能がサポートされていません。そのため、上記のエラーが発生します。
対応
setSaveAsActivity(false)
でSaveAsActivityをfalseに設定します。
■ INVALID_ID_FIELD
「INVALID_ID_FIELD, WhatId is not available for sending emails to UserIds」
メールテンプレートに差し込み項目を反映させるwhatId
はtargetObjectId
に取引先責任者を設定したときのみ使用可能です。
targetObjectId
にユーザIDを設定すると上記のエラーが発生します。
対応
Messaging.renderStoredEmailTemplate(templateId, whoId, whatId)
を使用します。
■ DUPLICATE_SENDER_DISPLAY_NAME
setOrgWideEmailAddressId
(送信元に組織のメールアドレスを設定)とetSenderDisplayName
(送信者表示名)を同時に使用すると上記のエラーが発生します。
エラー (送信エラー)
Messaging.sendEmail(mails)
でメールが送信できなかった際のエラーは例外ではなく、Messaging.SendEmailResult
で扱います。
エラーとなるのは送信時のエラーで、送信先に到達したか否かは関係ありません。
/** エラーハンドリング例 */
List<Messaging.SendEmailResult> results = Messaging.sendEmail(mails, false);
for (Messaging.SendEmailResult result : results) {
if (!result.isSuccess()) {
System.debug(LoggingLevel.ERROR, result.getErrors()[0]);
}
}
■ Organization-Wide Email Address has not be verified for use.
送信元に未検証の組織のメールを指定してsendMailメソッドをコールしたときに上記のエラーが発生します。SendEmailResultのgetErrorsメソッドでエラー内容を取得します。
対応
[設定]-[組織のアドレス]から組織のメールの検証メールを再送し、メールアドレスを検証します。
■ Not profiled to access this Org-wide Email Address
送信元に設定した組織のメールアドレスが、Apex実行者のプロファイルでの使用が許可されていません。
対応
[設定]-[組織のアドレス]から組織のメールを編集し、Apex実行者のプロファイルを送信元アドレスの使用許可に選択します。