22
15

More than 3 years have passed since last update.

Apexでメールを送信する

Last updated at Posted at 2020-08-21

Apexでのメール送信の流れ

  1. 単一メールクラスまたは一括メールクラスのインスタンスを作成する。
  2. 送信先、件名、本文などを設定する。
  3. 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.getEmailInvocationsTest.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」

メールテンプレートに差し込み項目を反映させるwhatIdtargetObjectIdに取引先責任者を設定したときのみ使用可能です。
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実行者のプロファイルを送信元アドレスの使用許可に選択します。

参考

22
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
15