【Salesforce】【Apex】メール承認をApexで申請するときの注意点

メールドラフト機能をONにして、メールメッセージの承認プロセスを使用している組織で
Apexから申請を出すときの注意点です。
見事にハマったのと検索しても出ないエラーなので書き残しておきます。

#大前提
- メール-to-ケースの有効化

- メールドラフトの有効化

メールドラフトはメール-to-ケースのメールをすぐに送信せず下書きに残して
上長などの承認が得られた際に送信できる機能です。
それぞれの設定方法については以下の記事をご参考ください。

[【Salesforce】メール-to-ケースを設定してみた](https://qiita.com/piepie1231/items/d032ccc9d194baca8ed5)
[【Salesforce】メールドラフトを設定してみた](https://qiita.com/piepie1231/items/163eb8ae733ea724e556)


#Apexで申請を出す
メールドラフトを使用するために、メールメッセージの承認プロセスを作成しました。
今回は画面からではなく、Apexで申請を出そうとしました。

仕様：ケース情報でメールメッセージを作成し、メールドラフトの申請を出す

```Apex:
public class MailDraftApprovalLogic {
    public static boolean Submit(Case ca) {
        EmailMessage em = new EmailMessage(
            ParentId = ca.Id,
            ToAddress = ca.SuppliedEmail,
            Subject = '[' + ca.CaseNumber + ']' + ca.Subject,
            TextBody = 'お問い合わせありがとうございます。'
        );
        insert em;
               
        Approval.ProcessSubmitRequest submit =  new Approval.ProcessSubmitRequest();
        submit.setObjectId(em.id);
        submit.setComments('メールドラフト自動生成');
        submit.setProcessDefinitionNameOrId('MailDraftApproval');
        Approval.ProcessResult result = Approval.process(submit);
        return result.isSuccess();
    }
}
```
とまあ、こんな感じで
テストクラスは普通にSubmit()呼んでやります。

```Apex:
@isTest
private class MailDraftApprovalLogicTest {
    @isTest
    private static void SubmitTest(){
        Case ca = new Case(
            Origin = 'Web',
            Subject = 'テストケース',
            SuppliedName = 'ぴえ太郎',
            SuppliedPhone = '090-1234-5678',
            SuppliedEmail = 'test@piepie.co.jp'
        );
        insert ca;
        
        Test.startTest();
        system.assert(MailDraftApprovalLogic.Submit(ca));
        Test.stopTest();
    }
}
```
いざ実行！、、

#発生したエラー
(´・ω・｀)ﾁｰﾝ

`System.DmlException: Process failed. First exception on row 0; first error: INVALID_OPERATION, Submit for approval not allowed.: []
`

`Class.MailDraftApprovalLogic.Submit: line 15, column 1
Class.MailDraftApprovalLogicTest.SubmitTest: line 15, column 1
`
#原因はStatusでした
もうわかったのでアッサリ書きますが
どうやらメールメッセージのステータスを指定していないと3（送信済み）になってしまうようです。
↓は[公式リファレンス](https://developer.salesforce.com/docs/atlas.ja-jp.218.0.object_reference.meta/object_reference/sforce_api_objects_emailmessage.htm)から失敬したキャプチャ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/72b91d7a-1ea1-79eb-7e91-6fb4641e92d5.png)
「参照のみ」なんて書いてあるもんだから代入できないと思って、ずっと違うとこ調べていました。

```Apex:
public class MailDraftApprovalLogic {
    public static boolean Submit(Case ca) {
        EmailMessage em = new EmailMessage(
            ParentId = ca.Id,
            Status = '5',
            ToAddress = ca.SuppliedEmail,
            Subject = '[' + ca.CaseNumber + ']' + ca.Subject,
            TextBody = 'お問い合わせありがとうございます。'
        );
        insert em;
               
        Approval.ProcessSubmitRequest submit =  new Approval.ProcessSubmitRequest();
        submit.setObjectId(em.id);
        submit.setComments('メールドラフト自動生成');
        submit.setProcessDefinitionNameOrId('MailDraftApproval');
        Approval.ProcessResult result = Approval.process(submit);
        return result.isSuccess();
    }
}
```
ドラフトなのでStatusに'5'を代入してあげればOKです((+_+))
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/840f10fe-4c8e-0cdf-c203-8ae33172bc83.png)
テストも成功です～

#参考
[承認プロセス](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_process.htm)
[メールメッセージ](https://developer.salesforce.com/docs/atlas.ja-jp.208.0.object_reference.meta/object_reference/sforce_api_objects_emailmessage.htm)