拡張メモの内容を取引先オブジェクトに更新する

Update Account fields when Enhanced Note is created/edited
I'll preface this with saying I'm in no way a developer and only have minimal experience with Apex code. I have a business requirement to update the following 2 Account custom fields whenever a new Enhanced Note is created or edited.

https://trailblazers.salesforce.com/answers?id=9064S000000DnzNQAS

という質問がありましたので、腕試しにApexトリガーを書いてみました....

まずはオブジェクトのデータモデルを確認します。
ふむふむ、拡張メモ(Lightningのメモ)は　ContentNoteオブジェクトだな、取引先とはContentDocumentLinkを介して参照関係にあるようです。
そうであれば、ContentDocumentLinkのトリガー(after insert)の処理でよさそうです。

というように基本方針が決まればあとは書くだけだ。

```
trigger NoteToAccount on ContentDocumentLink (after insert) {

    Map<Id,Id> AccountIdMap = new Map<Id,Id>();
    for(ContentDocumentLink cdl : Trigger.New){
        String s = cdl.LinkedEntityId;
        if (s.left(3)  == '001') {
            //Account Only
            AccountIdMap.put(cdl.ContentDocumentid,cdl.LinkedEntityId);
        }
    }//end of for
      
    
    List<ContentNote> ContentNoteList = [SELECT Id,Title,TextPreview,CreatedDate,Content FROM ContentNote WHERE ID =: AccountIdMap.keySet()];
    System.debug('##############################' + ContentNoteList.size());
    Set<Id> ContentNoteIdSet = new Set<Id>();
    for (ContentNote cn : ContentNoteList){
        ContentNoteIdSet.Add(cn.Id);
    }
    
    List<ContentVersion> cvList = [SELECT Id,Title,TextPreview,ContentDocumentId,VersionData FROM ContentVersion WHERE ContentDocumentId =:ContentNoteIdSet];
    Map<Id,ContentVersion> cvMap = new Map<Id,ContentVersion>();
    for (ContentVersion cv : cvList){
		cvMap.put(cv.ContentDocumentId,cv);        
    }
    
    List<Account> updateAccountList = new List<Account>();
    for (ContentNote cn : ContentNoteList){
    	Account acc = new Account();
        Id accId = (Id)AccountIdMap.get(cn.Id);
        if (accId != null) {
            acc.Id = accId;
            //acc.TextPreview__c = cn.TextPreview;
            //System.debug('##############################' + cn.TextPreview);// NG null
            acc.TextPreview__c = cn.Content.toString();
            System.debug('##############################' + cn.Content.toString());// NG null
            //ContentVersion cv = (ContentVersion)cvMap.get(cn.Id);
            //if (cv != null ) acc.TextPreview__c = cv.TextPreview;
            //System.debug('##############################' + cv.TextPreview);//NG null 
            //if (cv != null ) acc.TextPreview__c = cv.VersionData.toString();
            //System.debug('##############################' + cv.VersionData.toString().escapeHtml4());
            //System.debug('##############################' + EncodingUtil.base64Decode(cv.VersionData.toString().escapeHtml4()) );
            acc.LastModifiedDate__c = cn.CreatedDate;
            updateAccountList.add(acc);
        }
    }
    
    if (updateAccountList.size() > 0) update updateAccountList;
    
}
```

トリガー自体はものの30分くらいで完成。はい動作確認....


あれ！　何故かTextPreviewから値が取れていない。
しかし、SOQLをたたいてみると　TextPreviewに値はあるんですねぇ。
何で？


もしかして、TextPreviewは特殊なフィールドか。
しかたないので、ContentVersionからTextPreviewを参照してみる。
結果は変わらず。


それじゃぁ、大元のVersionDataを使ってみる。これってBlob型でややこしい。
何だこれ、<p></p>しかない。データがない。


どうなっているんでしょうねぇ。

色々探すと気になる投稿がでてきました。

ContentDocumentIDは、ContentVersionが挿入された直後は使用できませんが、soqlクエリの後で使用できます
https://salesforce.stackexchange.com/questions/229335/contentdocumentid-is-not-available-just-after-contentversion-getting-inserted-bu