public with sharing class DropboxFeature extends CloudStorageBase { private static final String DROPBOX_API_URL = 'https://api.dropboxapi.com/2'; private static final String DROPBOX_API_2_URL = 'https://content.dropboxapi.com/2/files'; private static String externalStorage = 'DropBox'; public override OperationResult listFiles(Map params) { List> resultFiles = new List>(); // String accessToken; Map accessTokenMap = new Map(); OperationResult result; List fileIdList = new list(); try { Boolean isServiceMode = (Boolean) params.get('isServiceMode'); Boolean myDrive = (Boolean) params.get('myDrive'); Boolean isRootFolder = (Boolean) params.get('isRootFolder'); String folderId = (String) params.get('folderId'); String accessToken = (String) params.get('accessToken'); String level = (String) params.get('level'); System.debug('isServiceMode ' + isServiceMode); System.debug('accessToken ' + accessToken); String endpoint; String body; Map header = new Map{ 'Authorization' => 'Bearer ' + accessToken, 'Content-Type' => 'application/json' }; System.debug('--Folder ID-- '+folderId); if( (folderId == null || folderId =='') && isRootFolder){ System.debug('Root Folder'); String rootFolderEndpoint = DROPBOX_API_URL + '/files/list_folder'; endpoint=rootFolderEndpoint; body = '{ "path": ""}'; } else{ String rootFolderEndpoint = DROPBOX_API_URL + '/files/list_folder'; endpoint=rootFolderEndpoint; body = '{ "path":"' + folderId + '"}'; } System.debug('endpoint='+endpoint ); HttpResponse res = CloudStorageUtlilty.makeCallout(body, endpoint, header, 'POST'); String newAccessToken; System.debug('ENDPOINT:->' + endpoint); System.debug('BODY:-> ' + res.getBody()); System.debug('API STATUS --> '+ res.getStatusCode()); // --------------------- // if(res.getStatusCode() != 200){ // DropboxAuth auth = new DropboxAuth(); // newAccessToken = auth.refreshAccessToken(refreshToken); // CloudStorageUtlilty.updateAccessToken(isServiceMode, userId, newAccessToken, externalStorage); // System.debug('New Access token:'+newAccessToken); // if(newAccessToken != null) { // // req.setHeader('Authorization', 'Bearer ' + newAccessToken); // header = new Map { // 'Authorization' => 'Bearer ' + newAccessToken // }; // HttpResponse res2 = CloudStorageUtlilty.makeCallout(body, endpoint, header, 'POST'); // if(res2.getStatusCode() != 200){ // result = OperationResult.error('Could not refresh access token'); // return result; // } // } // } // --------------------- if (res.getStatusCode() == 200) { String responseBody = res.getBody(); System.debug('responseBody '+res.getBody()); Map resultMap = (Map) JSON.deserializeUntyped(responseBody); List files = (List) resultMap.get('entries'); // 'entries' is files and folders System.debug('>>>>files='+files); //Loop to get the fileid to find out tag data for (Object file : files) { Map fileDetails = (Map) file; fileIdList.add((String) fileDetails.get('id')); } Map> fileIdVsTagListMap = new map>(); for(HIC_FilesME__Tags_Data__c tag :[select id,HIC_FilesME__Tags__c,HIC_FilesME__FileId__c from HIC_FilesME__Tags_Data__c where HIC_FilesME__FileId__c in:fileIdList AND HIC_FilesME__Tags__c != null]){ for(String tagValue : tag.HIC_FilesME__Tags__c.split(';')){ if(fileIdVsTagListMap.containsKey(tag.HIC_FilesME__FileId__c)){ List taglist = fileIdVsTagListMap.get(tag.HIC_FilesME__FileId__c); taglist.add(tagValue); fileIdVsTagListMap.put(tag.HIC_FilesME__FileId__c,taglist); }else{ List taglist = new list(); taglist.add(tagValue); fileIdVsTagListMap.put(tag.HIC_FilesME__FileId__c,taglist); } } } for (Object file : files) { Map fileDetails = (Map) file; Map fileData = new Map(); String fileId = (String) fileDetails.get('id'); fileData.put('id', (String) fileDetails.get('id')); fileData.put('name', (String) fileDetails.get('name')); if(fileDetails.containsKey('server_modified')){ String server_modified = (String) fileDetails.get('server_modified'); if(server_modified != ''){ fileData.put('createdTime', server_modified); } else{ fileData.put('createdTime', '-'); } } // fileData.put('createdTime', (String) fileDetails.get('createdTime')); // Not Available in dropbox API response if(fileDetails.containsKey('parents')){ List parents = (List) fileDetails.get('parents'); if(!parents.isEmpty()){ fileData.put('parents', (String) parents[0]); } else{ fileData.put('parents', (String) ''); } } String type = (String) fileDetails.get('.tag'); String path_display = (String) fileDetails.get('path_display'); System.debug('PATH_DISPLAY:- '+path_display); fileData.put('mimeType', type); fileData.put('path_display', path_display); if(fileDetails.containsKey('owners')){ List owners = (List) fileDetails.get('owners'); if (!owners.isEmpty()) { Map owner = (Map) owners[0]; fileData.put('createdBy', (String) owner.get('displayName')); } } if(fileDetails.containsKey('size')) { fileData.put('size', fileDetails.get('size')+''); } if (path_display != null) { fileData.put('url', 'https://www.dropbox.com/home' + path_display); } fileData.put('iconName', getFileType( (String) fileDetails.get('name') )); fileData.put('mimeType', getFileType( (String) fileDetails.get('name') )); if (type == 'folder') { fileData.put('mimeType', 'doctype:folder'); fileData.put('iconName', 'doctype:folder'); } // Now putting assigned tags data on that file if(fileIdVsTagListMap.containsKey(fileId)){ fileData.put('tagData',fileIdVsTagListMap.get(fileId)); }else{ fileData.put('tagData',new list()); } resultFiles.add(fileData); } System.debug('>>>>resultFiles='+resultFiles); result = OperationResult.success(resultFiles); // return result; } else { return OperationResult.error('Failed to list files.'); } return result; } catch (Exception e) { System.debug('Error occoured:-> ' + e.getMessage()); FME_Logger.error('Error in listing files: ' + e.getMessage(),'DropboxFeature','listFiles'); } return result; } // private method to get file type supported in salesforce private static String getFileType(String fileName) { if (fileName.endsWithIgnoreCase('.jpg') || fileName.endsWithIgnoreCase('.jpeg') ) { return 'doctype:image'; } if (fileName.endsWithIgnoreCase('.png') || fileName.endsWithIgnoreCase('.svg') || fileName.endsWithIgnoreCase('.bmp') ) { return 'doctype:image'; } if (fileName.endsWithIgnoreCase('.mp4') || fileName.endsWithIgnoreCase('.mkv') || fileName.endsWithIgnoreCase('.gif') || fileName.endsWithIgnoreCase('.ogg') ) { return 'doctype:video'; } if (fileName.endsWithIgnoreCase('.mp3') || fileName.endsWithIgnoreCase('.wav') ) { return 'doctype:audio'; } if (fileName.endsWithIgnoreCase('.docx') || fileName.endsWithIgnoreCase('.doc') || fileName.endsWithIgnoreCase('.word') ) { return 'doctype:document'; } if (fileName.endsWithIgnoreCase('.pdf') ) { return 'doctype:pdf'; } if (fileName.endsWithIgnoreCase('.txt') ) { return 'doctype:txt'; } if (fileName.endsWithIgnoreCase('.csv') ) { return 'doctype:csv'; } if (fileName.endsWithIgnoreCase('.ppt') || fileName.endsWithIgnoreCase('.pptx') ) { return 'doctype:ppt'; } return 'doctype:unknown'; } //To create a folder public override OperationResult createFolder(Map params) { OperationResult result; Map resultMap=new Map(); try{ String parentFolderId = (String) params.get('parentFolderId'); Boolean isServiceMode = (Boolean) params.get('isServiceMode'); String folderName = (String) params.get('folderName'); String userId = (String) SalesforceEnvironmentUtil.getUserId(); String accessToken = (String) params.get('accessToken'); System.debug('isServiceMode ' + isServiceMode); System.debug('accessToken ' + accessToken); Map headers = new Map{ 'Authorization' => 'Bearer ' + accessToken, 'Content-Type' => 'application/json' }; String pathString = (String.isBlank(parentFolderId))? '' : getPathString(parentFolderId, headers); System.debug('pathString ' + pathString); String folderMetadata = '{' + '"path": "'+ pathString +'/'+ folderName +'",' + '"autorename": true' + '}'; String endpoint = DROPBOX_API_URL + '/files/create_folder_v2'; HttpResponse res = CloudStorageUtlilty.makeCallout(folderMetadata, endpoint, headers, 'POST'); String responseBody = res.getBody(); System.debug('Body of create folder api response-> '+ responseBody); if(res.getStatusCode() == 200){ resultMap = (Map) JSON.deserializeUntyped(responseBody); resultMap.put('code', '200'); result = OperationResult.success(resultMap); System.debug('Created successfully-> '+ result); return result; } else { System.debug('Create folder failed [Attempt 2]'); result = OperationResult.error('Create folder failed: ' + res.getStatus()); return result; } } catch (Exception e) { System.debug('>>>error='+e.getMessage()); throw new AuraHandledException(e.getMessage()); } } // method to get path from metadata tobe used in folder creation (can not use id as path there) private String getPathString(String parentId, Map headers) { try { parentId = (String.isBlank(parentId))? 'id:root' : parentId; System.debug('ParentId:-> '+ parentId); String path = ''; String body = '{"path": "'+parentId+'"}'; String endpoint = DROPBOX_API_URL + '/files/get_metadata'; HttpResponse res = CloudStorageUtlilty.makeCallout(body, endpoint, headers, 'POST'); System.debug('Header-> '+ headers); System.debug('Body-> '+ body); if(res.getStatusCode() == 200) { Map response = (Map) JSON.deserializeUntyped(res.getBody()); path = (String) response.get('path_lower'); return path; } else { System.debug('Could not get path from metadata api'); return path; } } catch (Exception e) { System.debug('>>>error getting metadata-> '+e.getMessage()); throw new AuraHandledException(e.getMessage()); } } public override OperationResult renameFile(Map params) { OperationResult result; try { String fileId = (String) params.get('fileId'); Boolean isServiceMode = (Boolean) params.get('isServiceMode'); String newFileName = (String) params.get('newFileName'); String accessToken = (String) params.get('accessToken'); Map headers = new Map(); headers.put('Authorization', 'Bearer ' + accessToken); headers.put('Content-Type', 'application/json'); String pathString = getPathString(fileId, headers); String parentPath = pathString.substring(0, pathString.lastIndexOf('/')); String endpoint = DROPBOX_API_URL + '/files/move_v2'; System.debug('endpoint == ' + endpoint); System.debug('newFileName == ' + newFileName); String body = '{"from_path": "' + fileId + '",' + '"to_path": "' + parentPath +'/'+ newFileName +'",' + '"autorename": ' + true + '}'; System.debug('body == ' + body); HttpResponse res = CloudStorageUtlilty.makeCallout(body, endpoint, headers, 'POST'); if (res.getStatusCode() == 200) { System.debug('>>>> ' + res.getBody()); System.debug('File renamed successfully.'); result= OperationResult.success(res.getBody()); // Add audit log // String userName = UserInfo.getName(); // String logMsg = userName + ' renamed file with Id ' + fileId + ' to "' + newFileName + '"'; // FME_Logger.audit('Rename', logMsg, 'DropboxFeature', 'renameFile'); } else { System.debug('Failed to rename file: ' + res.getBody()); result= OperationResult.error(res.getBody()); } } catch (Exception e) { FME_Logger.error(e.getMessage(), 'DropboxFeature' + e.getLineNumber(), 'renameFile'); } return result; } public override OperationResult moveFileAndFolder(Map params) { OperationResult result; Boolean accessTokenNeedUpdate = false; try { String fileId = (String) params.get('fileId'); Boolean isServiceMode = (Boolean) params.get('isServiceMode'); String newFolderId = (String) params.get('newFolderId'); String oldFolderId = (String) params.get('oldFolderId'); String accessToken = (String) params.get('accessToken'); String userId = (String) SalesforceEnvironmentUtil.getUserId(); Map headers = new Map(); headers.put('Authorization', 'Bearer ' + accessToken); headers.put('Content-Type', 'application/json'); // String pathString = getPathString(fileId, headers); // String parentPath = pathString.substring(0, pathString.lastIndexOf('/')); String endpoint = DROPBOX_API_URL + '/files/move_v2'; System.debug('endpoint == ' + endpoint); String body = '{"from_path": "' + oldFolderId + '",' + '"to_path": "' + newFolderId +'",' + '"autorename": ' + true + '}'; System.debug('body == ' + body); HttpResponse res = CloudStorageUtlilty.makeCallout(body, endpoint, headers, 'POST'); String responseBody = res.getBody(); if(res.getStatusCode() == 200 ){ System.debug('>>>> ' + responseBody); System.debug('File moved successfully'); result = OperationResult.success(responseBody); } else { System.debug('Failed to move file: ' + responseBody); result = OperationResult.error(responseBody); } // Add audit log // String userName = UserInfo.getName(); // String logMsg = userName + ' renamed file with Id ' + fileId + ' to "' + newFileName + '"'; // FME_Logger.audit('Rename', logMsg, 'DropboxFeature', 'moveFileAndFolder'); } catch (Exception e) { FME_Logger.error(e.getMessage(), 'DropboxFeature' + e.getLineNumber(), 'moveFileAndFolder'); } return result; } // private static String getSizeString(String fileSizeStr){ // Decimal fileSize = Decimal.valueOf(fileSizeStr); // String size; // if (fileSize < 1024 * 1000 && fileSize > 0) { // size = String.valueOf(fileSize / 1024) + ' KB'; // } else if (fileSize < 1024 * 1024 * 1000 && fileSize > 1024 * 1000) { // size = String.valueOf(fileSize / (1024 * 1024)) + ' MB'; // } else if (fileSize >= 1024 * 1024 * 1000) { // size = String.valueOf(fileSize / (1024 * 1024 * 1024)) + ' GB'; // } else { // size = fileSizeStr + ' bytes'; // } // return size; // } // public override OperationResult deleteFile(String fileId, Boolean isServiceMode, String userId) { // Map accessTokenMap = new Map(); // String refreshToken; // try { // System.debug('>>>fileId=' + fileId + ' >>>userId=' + userId + ' >>>isServiceMode=' + isServiceMode); // String ACCESS_TOKEN; // // Get tokens // accessTokenMap = CloudStorageUtlilty.getAccessToken(isServiceMode, userId); // ACCESS_TOKEN = (String) accessTokenMap.get('ACCESS_TOKEN'); // refreshToken = (String) accessTokenMap.get('REFRESH_TOKEN'); // // Endpoint // String endpoint = 'https://www.googleapis.com/drive/v2/files/' + fileId; // System.debug('endpoint=' + endpoint); // // Callout // Map headers = new Map(); // headers.put('Authorization', 'Bearer ' + ACCESS_TOKEN); // HttpResponse res = CloudStorageUtlilty.makeCallout(null, endpoint, headers, 'DELETE'); // System.debug('>>>res=' + res.getBody()); // System.debug('>>>res.getStatusCode()=' + res.getStatusCode()); // // Handle response // if (res.getStatusCode() == 204) { // // String userName = UserInfo.getName(); // // String logMsg = userName + ' deleted file with Id "' + fileId + '"'; // // FME_Logger.audit('Delete', logMsg, 'GoogleDriveFeature', 'deleteFile'); // return OperationResult.success(res.getBody()); // } else { // return OperationResult.error(res.getBody()); // } // } catch (Exception e) { // FME_Logger.error(e.getMessage(), 'GoogleDriveFeature' + e.getLineNumber(), 'deleteFile'); // return OperationResult.error('Error deleting file: ' + e.getMessage()); // } // } public override OperationResult deleteFile(Map params) { try { String fileId = (String) params.get('fileId'); Boolean isServiceMode = (Boolean) params.get('isServiceMode'); String accessToken = (String) params.get('accessToken'); String userId = SalesforceEnvironmentUtil.getUserId(); System.debug('>>> fileId=' + fileId + ' >>> userId=' + userId + ' >>> isServiceMode=' + isServiceMode); // Dropbox delete endpoint String endpoint = 'https://api.dropboxapi.com/2/files/delete_v2'; System.debug('endpoint=' + endpoint); // Dropbox expects the file/folder path (not just ID) String body = JSON.serialize(new Map{ 'path' => fileId }); System.debug('Request body=' + body); // Headers Map headers = new Map(); headers.put('Authorization', 'Bearer ' + accessToken); headers.put('Content-Type', 'application/json'); // Make HTTP callout HttpResponse res = CloudStorageUtlilty.makeCallout(body, endpoint, headers, 'POST'); System.debug('>>> res.getStatusCode()=' + res.getStatusCode()); System.debug('>>> res.getBody()=' + res.getBody()); // Dropbox returns 200 OK for successful deletions if (res.getStatusCode() == 200) { // Log deletion String logMsg = 'Deleted file/folder with path "' + fileId + '" from Dropbox.'; FME_Logger.audit('Delete', logMsg, 'DropBoxFeature', 'deleteFile'); return OperationResult.success('File deleted successfully.'); } else { System.debug('Delete failed: ' + res.getBody()); return OperationResult.error('Failed to delete file: ' + res.getBody()); } } catch (Exception e) { FME_Logger.error(e.getMessage(), 'DropBoxFeature Line: ' + e.getLineNumber(), 'deleteFile'); return OperationResult.error('Error deleting file: ' + e.getMessage()); } } //add public static Blob fetchFileFromDropbox(Map params) { Blob fileBlob; try { Boolean isServiceMode = (Boolean) params.get('isServiceMode'); String fileId = (String) params.get('fileId'); String accessToken = (String) params.get('accessToken'); String userId = (String) SalesforceEnvironmentUtil.getUserId(); String downloadUrl = 'https://content.dropboxapi.com/2/files/download'; Map headers = new Map{ 'Authorization' => 'Bearer ' + accessToken, 'Dropbox-API-Arg' => JSON.serialize(new Map{ 'path' => fileId // fileId = Dropbox file path or id }) }; HttpResponse res = CloudStorageUtlilty.makeCallout(null, downloadUrl, headers, 'POST'); if (res.getStatusCode() == 200) { fileBlob = res.getBodyAsBlob(); } else { System.debug('Dropbox download failed: ' + res.getStatusCode() + ' | ' + res.getBody()); } } catch (Exception e) { System.debug('Error in fetchFileFromDropbox: ' +e.getMessage() + ' | Line: ' + e.getLineNumber()); FME_Logger.error(e.getMessage(),'DropboxFeature' + e.getLineNumber(),'fetchFileFromDropbox'); } return fileBlob; } public override OperationResult downloadFile(Map params) { System.debug('DropboxFeature.downloadFile'); OperationResult result; try { Blob fileBlob = fetchFileFromDropbox(params); if (fileBlob != null) { result = OperationResult.success(EncodingUtil.base64Encode(fileBlob)); System.debug('Dropbox file downloaded successfully.'); } else { result = OperationResult.error('Failed to download Dropbox file'); } } catch (Exception e) { result = OperationResult.error('Error downloading Dropbox file: ' + e.getMessage()); FME_Logger.error( e.getMessage(),'DropboxFeature' + e.getLineNumber(),'downloadFile'); } System.debug('result before return-> '+ result.data); return result; } public override OperationResult emailFile(Map params) { OperationResult result; try { //maildetails Map mailDetails =(Map) JSON.deserializeUntyped(JSON.serialize(params.get('mailDetails'))); String fileId = (String) params.get('fileId'); String fileName = (String) params.get('fileName'); String mimeType = (String) params.get('toSendFileNameMimeType'); String senderId = (String) mailDetails.get('fromUser'); String toUser = (String) mailDetails.get('toUser'); String ccUser = (String) mailDetails.get('ccUser'); String bccUser = (String) mailDetails.get('bccUser'); String subject = (String) mailDetails.get('subject'); String body = (String) mailDetails.get('body'); Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); // Required mail.setToAddresses(new List{ toUser }); // Optional if (String.isNotBlank(ccUser)) mail.setCcAddresses(new List{ ccUser }); if (String.isNotBlank(bccUser)) mail.setBccAddresses(new List{ bccUser }); mail.setSubject(subject); // Remove HTML tags safely mail.setPlainTextBody(body != null ? body.replaceAll('<[^>]+>', '') : ''); if (String.isNotBlank(senderId) && senderId.startsWith('0D2')) { mail.setOrgWideEmailAddressId(senderId); } Map downloadParams = new Map(params); downloadParams.put('fileId', fileId); downloadParams.put('fileName', fileName); OperationResult op = downloadFile(downloadParams); if (op != null && op.data != null) { Blob fileBlob = EncodingUtil.base64Decode((String) op.data); Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment(); attachment.setFileName(fileName); attachment.setBody(fileBlob); attachment.setContentType(String.isNotBlank(mimeType) ? mimeType: 'application/octet-stream'); mail.setFileAttachments(new List{ attachment }); } Messaging.SendEmailResult[] results = Messaging.sendEmail( new List{ mail }); if (!results.isEmpty() && results[0].isSuccess()) { result = OperationResult.success(null); System.debug(' Email sent successfully'); } else { String errMsg = (!results.isEmpty() && results[0].getErrors().size() > 0)? results[0].getErrors()[0].getMessage(): 'Unknown send failure'; result = OperationResult.error(errMsg); } } catch (Exception e) { FME_Logger.error(e.getMessage(),'EmailFeature ' + e.getLineNumber(),'emailFile'); result = OperationResult.error('Error sending email: ' + e.getMessage()); } System.debug('result:' + result); return result; } // public override OperationResult linkFiles(String recordId) { // List> resultFiles = new List>(); // OperationResult result; // try { // List recordFiles = [SELECT Id,CreatedDate,CreatedBy.Name,HIC_FilesME__Linked_Entity_Id__c,HIC_FilesME__Linked_Entity_Name__c,HIC_FilesME__Linked_Mimetype__c,HIC_FilesME__Linked_Record_Id__c,HIC_FilesME__Linked_Storage_Type__c FROM HIC_FilesME__File_Link__c WHERE HIC_FilesME__Linked_Record_Id__c = :recordId]; // for (HIC_FilesME__File_Link__c file : recordFiles) { // String createDate = String.valueOf(file.CreatedDate); // Map fileData = new Map(); // fileData.put('id', (String) file.HIC_FilesME__Linked_Entity_Id__c); // fileData.put('recordId', (String) file.Id); // fileData.put('name', (String) file.HIC_FilesME__Linked_Entity_Name__c); // fileData.put('mimeType', (String) file.HIC_FilesME__Linked_Mimetype__c); // fileData.put('externalStorageType', (String) file.HIC_FilesME__Linked_Storage_Type__c); // fileData.put('createdTime', createDate); // fileData.put('createdBy', (String) file.CreatedBy.Name); // fileData.put('url', 'https://drive.google.com/file/d/' + fileData.get('id') + '/view'); // resultFiles.add(fileData); // } // return OperationResult.success(resultFiles); // } catch (Exception e) { // FME_Logger.error(e.getMessage(), 'GoogleDriveFeature' + e.getLineNumber(), 'linkFiles'); // return OperationResult.error('Failed to fetch linked files. ' + e.getMessage()); // } // } // public override OperationResult toLinkFiles(String recordId, String filesDetails, String providerType) { // OperationResult result; // try { // Map filesMap = (Map) JSON.deserializeUntyped(filesDetails); // System.debug('filesMap >>>> ' + filesMap); // HIC_FilesME__File_Link__c fileLink = new HIC_FilesME__File_Link__c(); // fileLink.HIC_FilesME__Linked_Record_Id__c = recordId; // fileLink.HIC_FilesME__Linked_Entity_Id__c = (String) filesMap.get('id'); // fileLink.HIC_FilesME__Linked_Entity_Name__c = (String) filesMap.get('name'); // fileLink.HIC_FilesME__Linked_Mimetype__c = (String) filesMap.get('mimetype'); // fileLink.HIC_FilesME__Linked_Storage_Type__c = providerType; // insert fileLink; // result = OperationResult.success(fileLink); // } catch (Exception e) { // result = OperationResult.error('Error linking file: ' + e.getMessage()); // FME_Logger.error(e.getMessage(), 'GoogleDriveFeature' + e.getLineNumber(), 'toLinkFiles'); // } // return result; // } // public override OperationResult unlinkFiles(String recordId, String filesId, Boolean deleteFromDrive) { // OperationResult result; // try { // List fileLinks = [SELECT Id FROM HIC_FilesME__File_Link__c WHERE HIC_FilesME__Linked_Record_Id__c = :recordId AND HIC_FilesME__Linked_Entity_Id__c = :filesId]; // if (fileLinks.size() > 0) { // delete fileLinks; // if (deleteFromDrive) { // deleteFile(filesId, true, null); // } // result = OperationResult.success(null); // } else { // result = OperationResult.error('No record found'); // } // } catch (Exception e) { // result = OperationResult.error('Error unlinking file: ' + e.getMessage()); // FME_Logger.error(e.getMessage(), 'GoogleDriveFeature' + e.getLineNumber(), 'unlinkFiles'); // } // return result; // } public override OperationResult unlinkFiles(String recordId, String filesId, Boolean deleteFromDrive) { System.debug('recordId >>>> ' + recordId); System.debug('filesId >>>> ' + filesId); System.debug('deleteFromDrive >>>> ' + deleteFromDrive); OperationResult result; try { List fileLinks = [SELECT Id FROM HIC_FilesME__Linked_Folder__c WHERE HIC_FilesME__Linked_Record__c = :recordId AND HIC_FilesME__External_Folder_ID__c = :filesId]; if (fileLinks.size() > 0) { delete fileLinks; // if (deleteFromDrive) { // deleteFile(filesId, true, null); // } result = OperationResult.success(null); } else { result = OperationResult.error('No record found'); } } catch (Exception e) { result = OperationResult.error('Error unlinking file: ' + e.getMessage()); FME_Logger.error(e.getMessage(), 'GoogleDriveFeature' + e.getLineNumber(), 'unlinkFiles'); } return result; } // change custom object -- linkedFolder public override OperationResult linkFiles(String recordId) { List> resultFolders = new List>(); try { List linkedFolders = [ SELECT Id,Name,CreatedDate,CreatedBy.Name,HIC_FilesME__External_Folder_ID__c, HIC_FilesME__Folder_Name__c, HIC_FilesME__Folder_URL__c, HIC_FilesME__Storage_Provider__c, HIC_FilesME__Access_Level__c FROM HIC_FilesME__Linked_Folder__c WHERE HIC_FilesME__Linked_Record__c = :recordId AND HIC_FilesME__Is_Active__c = true ]; for (HIC_FilesME__Linked_Folder__c folder : linkedFolders) { Map folderData = new Map(); folderData.put('id', folder.HIC_FilesME__External_Folder_ID__c); folderData.put('recordId', folder.Id); folderData.put('name', folder.HIC_FilesME__Folder_Name__c); folderData.put('externalStorageType', folder.HIC_FilesME__Storage_Provider__c); folderData.put('accessLevel', folder.HIC_FilesME__Access_Level__c); folderData.put('createdTime', String.valueOf(folder.CreatedDate)); folderData.put('createdBy', folder.CreatedBy != null ? folder.CreatedBy.Name : '-'); folderData.put('url', folder.HIC_FilesME__Folder_URL__c); resultFolders.add(folderData); } System.debug('resultFolders >>>> ' + resultFolders); return OperationResult.success(resultFolders); } catch (Exception e) {FME_Logger.error(e.getMessage(),'LinkedFolderFeature' + e.getLineNumber(),'linkFiles'); return OperationResult.error('Failed to fetch linked folders. ' + e.getMessage()); } } // change custom object -- linkedFolder public override OperationResult toLinkFiles(String recordId,String folderDetails,String providerType) { try { System.debug('providerType >>>> ' + providerType); System.debug('recordId >>>> ' + recordId); System.debug('JSON.deserializeUntyped folderDetails >>>> ' + JSON.deserializeUntyped(folderDetails)); Map folderMap = (Map) JSON.deserializeUntyped(folderDetails); HIC_FilesME__Linked_Folder__c linkedFolder = new HIC_FilesME__Linked_Folder__c(); linkedFolder.HIC_FilesME__Linked_Record__c = recordId; linkedFolder.HIC_FilesME__External_Folder_ID__c = (String) folderMap.get('id'); linkedFolder.HIC_FilesME__Folder_Name__c = (String) folderMap.get('name'); //add linkedFolder.HIC_FilesME__Created__c = UserInfo.getUserId(); linkedFolder.HIC_FilesME__Created_Date__c = System.now(); linkedFolder.HIC_FilesME__Folder_URL__c = (String) folderMap.get('url'); linkedFolder.HIC_FilesME__Storage_Provider__c = providerType; // linkedFolder.HIC_FilesME__Access_Level__c = (String) folderMap.get('accessLevel'); linkedFolder.HIC_FilesME__Is_Active__c = true; String key = providerType +' '+ recordId +' '+ (String) folderMap.get('id'); linkedFolder.HIC_FilesME__Key__c = key; upsert linkedFolder HIC_FilesME__Key__c; // insert linkedFolder; System.debug('linkedFolder >>>> ' + linkedFolder); return OperationResult.success(linkedFolder); } catch (Exception e) { FME_Logger.error(e.getMessage(),'LinkedFolderFeature' + e.getLineNumber(),'toLinkFiles' ); return OperationResult.error('Error linking folder: ' + e.getMessage()); } } }