MetadataServiceを使ってリストビューを操作する

\:cloud: Metadata API

# MetadataServiceを使ってリストビューを作成する

```
public with sharing class Matadata_sample01 {
    
    public class MetadataServiceExamplesException extends Exception { }    
      
    /**
     * Example helper method to interpret a SaveResult, throws an exception if errors are found
     **/
    public static void handleSaveResults(MetadataService.SaveResult saveResult) {
        // Nothing to see?
        if(saveResult==null || saveResult.success)
            return;
        // Construct error message and throw an exception
        if(saveResult.errors!=null)
        {
            List<String> messages = new List<String>();
            messages.add(
                (saveResult.errors.size()==1 ? 'Error ' : 'Errors ') +
                    'occured processing component ' + saveResult.fullName + '.');
            for(MetadataService.Error error : saveResult.errors)
                messages.add(
                    error.message + ' (' + error.statusCode + ').' +
                    ( error.fields!=null && error.fields.size()>0 ?
                        ' Fields ' + String.join(error.fields, ',') + '.' : '' ) );
            if(messages.size()>0)
                throw new MetadataServiceExamplesException(String.join(messages, ' '));
        }
        if(!saveResult.success)
            throw new MetadataServiceExamplesException('Request failed with no specified error.');
    }
    
    @AuraEnabled
    //これはエラーになる
    public static ResponseDto createListView() {
        try{
            //MetadataService.MetadataPort service = createService();
            updateInFuture();
            
            ResponseDto res = new ResponseDto(true, '');
            //res.values.put('Id', myProperty.Id);
            return res;
        }catch(Exception e){
            ResponseDto res = new ResponseDto(false,'システムエラーが発生しました：'+e.getMessage());
            return res;
        }
        
    }
        
    public static void updateInFuture() {
        updateInFuture(UserInfo.getSessionId());
    }
    
    @future(callout=true)    
    private static void updateInFuture(String sessionId) {
        MetadataService.MetadataPort service = new MetadataService.MetadataPort();
        service.SessionHeader = new MetadataService.SessionHeader_element();
        service.SessionHeader.sessionId = sessionId;
                
        MetadataService.ListView listView = new MetadataService.ListView();
        listView.fullName = 'test2__c.MyListView';
        listView.label = 'My List View';
        listView.filterScope = 'Everything';
        listView.columns = new List<String> { 'NAME' };
            List<MetadataService.SaveResult> results =
            service.createMetadata(
                new MetadataService.Metadata[] { listView });
        handleSaveResults(results[0]);

    }

    public class ResponseDto{
    	@AuraEnabled public Boolean isSuccess{get;set;}
        @AuraEnabled public String message {get;set;}
        @AuraEnabled public Map<Object,Object> values {get;set;}
        public ResponseDto(Boolean isSuccess, String msg){
        	this.isSuccess  =isSuccess;
            this.message = msg;
            this.values = new Map<Object, Object>();
        }
    }
    
}
```

listView.fullName = 'test2__c.MyListView';
のとことのtest2__cを目的のオブジェクトに変更して下さい。

匿名 Apex コードの実行で Matadata_sample01.updateInFuture();してちゃんとリストビューが作成できました。
Lightningの画面からボタンの操作をすると何故かエラーになります。

**INVALID_SESSION_ID: This session is not valid for use with the API #138**
https://github.com/financialforcedev/apex-mdapi/issues/138

これによると、

これは、Aura Enabledリクエストでは、セッションIDがAPI呼び出しを行うことができないためです。そのセキュリティ制限。ここで説明する回避策がありますが、このアプローチに関するSalesforceの公式の見解はわかりません。

何だ?、半日悩んだ。

# 参考
https://trailblazers.salesforce.com/answers?id=9064S000000DHrsQAG