dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

[salesforce]Apexでのメール送信時に送信元(From)を変更する

変更する方法あるのかなと思って調べてみたら、ありました。
「組織のメールアドレス」という設定を使った方法です。

はじめに

SalesforceEmailクラス(Messaging.SingleEmailMessageMassEmailMessageの親クラス)には、メールの送信者の名前に任意の文字列をセットするsetSenderDisplayNameというメソッドがあります。

サンプル(setSenderDisplayNameを使った例)

public class SendEmail {

    private static final String SUBJECT = 'Sample Email';

    private static final String BODY = 'Hi, This is a sample email.';

    public void send(Id targetObjId) {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setSubject(SUBJECT);
        mail.setPlainTextBody(BODY);
        mail.setTargetObjectId(targetObjId);
        mail.setSaveAsActivity(true);
        // 送信者の氏名を変更する
        mail.setSenderDisplayName('hoge');

        // 送信
        Messaging.sendEmail(new List<Messaging.SingleEmailMessage> { mail });
    }
}

これによって、メールの受信者から見た送信元の名前は変更できますが、メールアドレスまで変更することはできません。

f:id:dackdive:20140710020319p:plain

setCcAddressesのようなメソッドでFromを指定することももちろんできません。

そこで登場するのが、「組織のメールアドレス」を使った方法です。

組織のメールアドレスを設定する

実際に設定してみます。

管理 > メール管理 > 組織のアドレス

を開き、「追加」をクリックします。

すると、次のような画面が表示されるので、

  • 表示名
  • メールアドレス

を指定します。

f:id:dackdive:20140710023926p:plain

「選択したプロファイルにのみ〜」を選択した場合、
わかりづらいですが反転しているプロファイルが選択された状態というように解釈されます。
(ドラッグやCtrlキー+クリックで複数選ぶ)

保存すると、入力したメールアドレス宛に確認メールが送られてくるので、
メール本文のリンクをクリックして承認します。

設定した組織のメールアドレスを使ってみる(UI)

組織のアドレスが承認済みで、かつ許可されたプロファイルのユーザが
リードや取引先責任者の「活動履歴」からメールを送信しようとすると、 下の画像のように表示されます。

f:id:dackdive:20140710021827p:plain

これで、Salesforce上で送信元を切り替えることができるようになりました。

Apexでのメール送信に組織のメールアドレスを使う

それでは、Apexでも組織のメールアドレスを使ってみましょう。
SingleEmailMessageクラスで組織のメールアドレスをセットするには
setOrgWideEmailAddressId(ID)メソッドを使います。

引数に渡すIdは、先ほど作成した組織のメールアドレスのIdなんですが
それはOrgWideEmailAddressというオブジェクトから取得します。

サンプル(組織のメールアドレスを使った例)

public class SendEmail {

    private static final String SUBJECT = 'Sample Email';

    private static final String BODY = 'Hi, This is a sample email.';

    public void send(Id targetObjId) {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setSubject(SUBJECT);
        mail.setPlainTextBody(BODY);
        mail.setTargetObjectId(targetObjId);
        mail.setSaveAsActivity(true);
        // 「組織のメールアドレス」に登録したメールアドレスを取得
        ID orgWideEmailAddressId = this.getOrgWideEmailAddress('カスタマーサポート担当');
        // 送信元になるようセット
        mail.setOrgWideEmailAddressId(orgWideEmailAddressId);

        // 送信
        Messaging.sendEmail(new List<Messaging.SingleEmailMessage> { mail });
    }

    private ID getOrgWideEmailAddress(String displayName) {
        // 表示名(DiplayName)またはメールアドレス(Address)で検索
        return [
            SELECT
                Address,
                DisplayName
            FROM
                OrgWideEmailAddress
            WHERE
                DisplayName = :displayName
            LIMIT 1
        ].id;
    }
}

サンプルを実行すると、送信されるメールの送信元のアドレスおよび表示名がどちらも変更されていることが確認できます。
(メアドはぼかしてますが)

f:id:dackdive:20140710023429p:plain

注意事項

  • setSenderDisplayNamesetOrgWideEmailAddressはどちらか一方しか指定できません
  • 組織のメールアドレスを登録する際、「表示名」は重複可能なので表示名によるクエリ結果は1件でない可能性があります

リファレンス

https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_email_outbound_base.htm#apex_classes_email_outbound_base

https://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_orgwideemailaddress.htm