PDFを作成し、Salesforceメールテンプレートに添付する方法

以下のような質問があったので、詳しく調べてみると
やり方を説明しているサイトがいくつかありました。

質問
dynamic attachments help needed
https://trailblazers.salesforce.com/answers?id=9064S000000D5RCQA0


やり方を紹介しているサイト
Attach a Dynamic PDF Message to a Salesforce Email Template
https://apexdevforce.com/apex/attach-a-dynamic-pdf-message-to-a-salesforce-email-template/

How to Attach a Dynamic PDF to a Salesforce Messaging Email Template
https://www.codeproject.com/Tips/1129916/How-to-Attach-a-Dynamic-PDF-to-a-Salesforce-Messag

どちらも同じような感じです。

テンプレートの他に以下の4つを作成する必要がありそうです。
・PDFとして表示されるVisualforceページ(Receipt.page)
・上記のVFページのApexコントローラクラス。(ReceiptController.class)
・Visualforceメールテンプレートによって参照されるVFコンポーネント。（ReceiptAttachment.component）
・上記のVFコンポーネントのApexコントローラクラス。（ReceiptAttachmentController.class）

質問を勘違いして、動的にPDFを作るようなことを考えてました。
でも、上記２つのやり方ではうまくいかなかったです。
何故か、動かない。

さて、質問の答え

#添付ファイル、メモをリンクとしてメールテンプレートに表示する方法


普段はVFは全く書かないので、かなり時間が掛かってしまいました。


```メールテンプレート
<messaging:emailTemplate subject="CSF processing request for: {!relatedTo.name}" recipientType="Contact" relatedToType="Opportunity">
<messaging:htmlEmailBody >       
    <html>
        <body>
        <STYLE type="text/css">
               TH {font-size: 11px; font-face: arial;background: #CCCCCC; border-width: 1;  text-align: center }
               TD  {font-size: 11px; font-face: verdana }
               TABLE {border: solid #CCCCCC; border-width: 1}
               TR {border: solid #CCCCCC; border-width: 1}
        </STYLE>
        <font face="arial" size="2">
        <p>CSF PROCESSING REQUEST</p>
        <p>Please find attached the detailed CSF for:</p>
        <p> Opportunity:<b> {!relatedTo.name}</b>
        <br/>Account: <i><b> {!relatedTo.Account.name}</b>  </i>         
        <br/>Opp ID:<b> {!relatedTo.Opp_ID__c} </b>
        <br/>Opportunity Owner: <b>{!relatedTo.owner.name}</b>
        <br/>Operating Region: <b> {!relatedTo.xxxxxx_Operating_Region2__c}</b> 
        </p>
        </font>
        </body>
        
        <c:ReceiptAttachment opportunityId="{!relatedTo.Id}"/>
    </html>
</messaging:htmlEmailBody>       
</messaging:emailTemplate>
```

メールテンプレートで参照しているコンポーネント

```
<apex:component controller="ReceiptAttachmentController" access="global" >
    <apex:attribute name="opportunityId" description="Opportunity Id" assignTo="{!OpportunityObjectId}" type="Id" />       
    
    <apex:repeat value="{!myCombinedAttachments}" var="a">        
        <p><a href="{!baseUrl}/lightning/r/ContentDocument/{!a.Id}/view"  target="_blank" styleClass="btn">{!a.Title}</a>({!a.ContentSize} B)</p>
    </apex:repeat>
    
    <apex:repeat value="{!myContentNote}" var="a">       
        <p><a href="{!baseUrl}/lightning/r/ContentNote/{!a.Id}/view"  target="_blank" styleClass="btn">{!a.Title}</a>({!a.ContentSize} B)</p>
    </apex:repeat>
    

</apex:component>
```

上記のコントローラ

```
global class ReceiptAttachmentController {
    
    global String OpportunityObjectId{ 
        get;
        set {
            UpdateContents2(value);
        } 
    }
    
    global String baseUrl{ get; set; }
    
    global List<CombinedAttachment> myCombinedAttachments{ get; set; }
    
    global List<ContentNote> myContentNote{ get; set; }
    
    public void UpdateContents2(String OpportunityObjectId) {
        
        baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
        
        if (OpportunityObjectId != null) {
            List<Opportunity> oppList = [SELECT Id,( SELECT Id, Title, ContentSize FROM CombinedAttachments ) FROM Opportunity WHERE Id =:OpportunityObjectId];
            if (oppList.size() > 0) {
                myCombinedAttachments = (List<CombinedAttachment>)oppList[0].CombinedAttachments;
            }
            
            List<ContentDocumentLink> ListContentNote = [select ContentDocumentId from ContentDocumentLink where LinkedEntityId =:OpportunityObjectId];
            if (ListContentNote.size() > 0) {
                set<Id> setContentNoteId = new set<Id>();
                for (ContentDocumentLink myCN :ListContentNote){
                    setContentNoteId.add(myCN.ContentDocumentId);
                }        
                myContentNote = [select Id,title,ContentSize,TextPreview from ContentNote where Id=:setContentNoteId];
            }
        }
    
}
```

上記が回答になると思う質問
[How to add a URL of Opportunity page to the body of the email template?](https://trailblazers.salesforce.com/answers?id=9064S000000D8yOQAS)

[how to get the record url in visualforce emil template](https://trailblazers.salesforce.com/answers?id=9064S000000DBlwQAG)

もっと簡単な方法がありそうです。
[Visualforce Email-Template with link to record](https://trailblazers.salesforce.com/answers?id=9063A0000019fzKQAQ)
[How to add hyper link in pdf attachment in vf page](https://developer.salesforce.com/forums/?id=9062I000000DIxZQAW)

# その他の関連資料

+ [Attach Dynamic Attachment to Salesforce Email Template](https://www.biswajeetsamal.com/blog/tag/attachment/)
+ [Attach a Dynamic PDF Message to a Salesforce Email Template](https://apexdevforce.com/apex/attach-a-dynamic-pdf-message-to-a-salesforce-email-template/)
+ [How to Attach a Dynamic PDF to a Salesforce Messaging Email Template](https://www.codeproject.com/Tips/1129916/How-to-Attach-a-Dynamic-PDF-to-a-Salesforce-Messag)