Need to see if your shared folder is taking up space on your dropbox 👨💻? Find out how to check here.
dropbox business
5 TopicsRefresh token is not included in the API call.
I am not getting the refresh token even after following the instructions on https://developers.dropbox.com/oauth-guide Note: you’ll need to include token_access_type=offline as a parameter on your Authorization URL in order to return a refresh_token inside your access token payload. It always return the access token only101Views0likes3Comments409 no_write_permission
Hi, I am using dropbox in n8n and have connected a dropbox team account. But I am getting 409 no_write_permission error. It was working fine a few days earlier but now I am getting this error for no reason. I changed nothing in n8n, nor in my dropbox settings. It was working fine a few days ago. It happened before too, and it got resolved after reconnecting and create a new node. But I am getting the same error again. Why am I getting this error and what is the fix. Please help me out! complete error: 409 - "{\"error_summary\": \"path/no_write_permission/.\", \"error\": {\".tag\": \"path\", \"reason\": {\".tag\": \"no_write_permission\"}, \"upload_session_id\": \"pid_upload_session:ABIJdIKguQwyyRnlJPP0VU6cKu7yvOT0Xo4yZCllqv3074TJtg\"}}"Solved271Views0likes5Commentsapi file request set naming convention
HI, There is currently no way to set the naming convention when creating a file request through the API. Therefore the uploader name is added to the file automatically and we have no say about it. The idea to implement the option to set the naming convention through the api https://api.dropboxapi.com/2/file_requests/create or setting a default naming convention for file request could also work. Related threads : - File Request API | The Dropbox Community - Rest API: naming conventions for new file request | The Dropbox Community142Views1like3CommentsUnable to Retrieve Dropbox "path_display" for Folders in Google Sheets Script
I'm developing a Google Sheets database that feeds an interactive map on My Maps. The script uses the Dropbox API to update folder names (in column A) and folder paths (in column F) based on metadata retrieved from Dropbox shared links. Although every folder is mounted on my account and I have full administrative rights on my Dropbox team, I'm not seeing the expected "path_display" value for my Dropbox folders. The script calls several API endpoints (such as sharing/get_shared_link_metadata, sharing/list_folders, sharing/list_mountable_folders, and sharing/get_folder_metadata) to try to obtain the complete folder path, but the path_display property remains empty in my sheet. I need to retrieve path_display because it lets me move folders in Dropbox while still keeping the most recent path in my map. The script is set to run weekly so that any folder moves are captured and my map stays up to date. Below is the complete script (with sensitive credentials, paths, and other details replaced): I tried this script in Google Apps Script: ``` // ===================================================== // CONFIGURATION & CONSTANTS // ===================================================== // Google Maps API Key (for geocoding) const API_KEY = "YOUR_GOOGLE_MAPS_API_KEY"; // OAuth2 Dropbox: Replace with your Dropbox credentials const DROPBOX_CLIENT_ID = 'YOUR_DROPBOX_CLIENT_ID'; const DROPBOX_CLIENT_SECRET = 'YOUR_DROPBOX_CLIENT_SECRET'; const DROPBOX_SCOPES = 'sharing.read files.metadata.read files.team_metadata.read team_data.member'; // Replace with your Dropbox team member ID (the member on which you want to operate) // Example: "dbmid:example_member_id" const DROPBOX_TEAM_MEMBER_ID = 'YOUR_DROPBOX_TEAM_MEMBER_ID'; const BATCH_SIZE = 100; const DELAY_BETWEEN_REQUESTS = 1000; // ===================================================== // OAUTH2 FOR DROPBOX (using the OAuth2 library) // ===================================================== function getDropboxService() { return OAuth2.createService('Dropbox') .setAuthorizationBaseUrl('https://www.dropbox.com/oauth2/authorize') .setTokenUrl('https://api.dropboxapi.com/oauth2/token') .setClientId(DROPBOX_CLIENT_ID) .setClientSecret(DROPBOX_CLIENT_SECRET) .setCallbackFunction('authCallback') .setPropertyStore(PropertiesService.getUserProperties()) .setScope(DROPBOX_SCOPES) // Request a refresh token .setParam('token_access_type', 'offline'); } function authCallback(request) { const service = getDropboxService(); const authorized = service.handleCallback(request); return HtmlService.createHtmlOutput(authorized ? 'Success! You can close this tab.' : 'Access denied.'); } function authorizeDropbox() { const service = getDropboxService(); if (!service.hasAccess()) { const authorizationUrl = service.getAuthorizationUrl(); Logger.log('Open the following URL and authorize the app, then re-run the script: %s', authorizationUrl); return authorizationUrl; } else { Logger.log('Already authorized with Dropbox.'); } } // ===================================================== // FUNCTIONS FOR UPDATING COORDINATES // ===================================================== function updateCoordinates() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const startRow = 4; const addresses = sheet.getRange(`B${startRow}:B${sheet.getLastRow()}`).getValues().flat(); const gpsData = sheet.getRange(`D${startRow}:D${sheet.getLastRow()}`).getValues().flat(); addresses.forEach((address, index) => { const gps = gpsData[index]; if (address && !gps) { const coordinates = getCoordinates(address); if (coordinates) { sheet.getRange(index + startRow, 4).setValue(coordinates); } } }); SpreadsheetApp.flush(); } function getCoordinates(address) { const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${API_KEY}`; try { const response = UrlFetchApp.fetch(url); const json = JSON.parse(response.getContentText()); if (json.status === "OK") { const latitude = json.results[0].geometry.location.lat; const longitude = json.results[0].geometry.location.lng; return `${latitude}, ${longitude}`; } else { console.error(`API error for address: ${address} - Status: ${json.status}`); return "API error"; } } catch (error) { console.error(`Error fetching coordinates: ${error.message}`); return "API error"; } } // ===================================================== // FUNCTIONS FOR UPDATING STATUS (column E) FROM PATHS (column F) // ===================================================== function updateStatusFromPaths() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const startRow = 4; const lastRow = sheet.getLastRow(); const paths = sheet.getRange(`F${startRow}:F${lastRow}`).getValues().flat(); const statuses = []; paths.forEach(path => { if (path) { if (path.includes("ActiveDeals/Active") || path.includes("C:\\Path\\To\\ActiveDeals\\Active")) { statuses.push(["Active"]); } else if (path.includes("ActiveDeals/ToWatch") || path.includes("C:\\Path\\To\\ActiveDeals\\ToWatch")) { statuses.push(["To watch"]); } else if (path.includes("Properties/Owned") || path.includes("C:\\Path\\To\\Properties\\Owned")) { statuses.push(["Owned"]); } else if (path.includes("Properties/Sold") || path.includes("C:\\Path\\To\\Properties\\Sold")) { statuses.push(["Sold"]); } else if (path.includes("DeadDeals") || path.includes("C:\\Path\\To\\DeadDeals")) { statuses.push(["Dead"]); } else { statuses.push(["Undefined"]); } } else { statuses.push([""]); } }); sheet.getRange(startRow, 5, statuses.length, 1).setValues(statuses); } // ===================================================== // FUNCTIONS FOR UPDATING DROPBOX INFORMATION // ===================================================== /** * This script updates both the folder name (column A) * and the folder path (column F) by comparing the path_display returned * by Dropbox. Any changes are logged in column H. */ function updateFolderNamesInBatches() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const startRow = 4; const lastRow = sheet.getLastRow(); const scriptProperties = PropertiesService.getScriptProperties(); let batchIndex = parseInt(scriptProperties.getProperty('batchIndexDropbox') || '0'); const totalBatches = Math.ceil((lastRow - startRow + 1) / BATCH_SIZE); // If all batches have been processed, reset and stop if (batchIndex >= totalBatches) { scriptProperties.deleteProperty('batchIndexDropbox'); Logger.log("All batches processed. Function stopped."); return; } const batchStart = startRow + (batchIndex * BATCH_SIZE); const batchEnd = Math.min(batchStart + BATCH_SIZE - 1, lastRow); // Check if the batch contains any sharing links (Column C) const linksRange = sheet.getRange(`C${batchStart}:C${batchEnd}`).getValues(); let hasLink = false; for (let i = 0; i < linksRange.length; i++) { if (linksRange[i][0].toString().trim() !== "") { hasLink = true; break; } } // If no links are found in the batch, stop processing if (!hasLink) { scriptProperties.deleteProperty('batchIndexDropbox'); Logger.log("No sharing links found in batch. Function stopped."); return; } // Clear previous statuses for the current batch (Column H) sheet.getRange(`H${batchStart}:H${batchEnd}`).clearContent(); // Process the current batch updateBatch(batchStart, batchEnd); // Update the batch index batchIndex++; scriptProperties.setProperty('batchIndexDropbox', batchIndex.toString()); // Schedule the next batch if there are more rows to process if (batchIndex < totalBatches) { ScriptApp.newTrigger('updateFolderNamesInBatches') .timeBased() .after(1000) .create(); } } /** * Processes the rows in the batch, * compares existing names/paths with those returned by Dropbox, and updates if necessary. */ function updateBatch(startRow, endRow) { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); // Read columns A (folderNames), C (sharingLinks) and F (folderPaths) const folderNames = sheet.getRange(`A${startRow}:A${endRow}`).getValues().flat(); const sharingLinks = sheet.getRange(`C${startRow}:C${endRow}`).getValues().flat(); const folderPaths = sheet.getRange(`F${startRow}:F${endRow}`).getValues().flat(); for (let index = 0; index < sharingLinks.length; index++) { const link = sharingLinks[index]; const currentRow = startRow + index; // Skip if the link is empty if (!link || link.trim() === "") { Logger.log(`Stopping at row ${currentRow}: No sharing link found.`); return; } try { const metadata = getDropboxMetadata(link); let statusMessages = []; if (metadata && metadata.name) { // Compare folder name if (folderNames[index] !== metadata.name) { sheet.getRange(currentRow, 1).setValue(metadata.name); statusMessages.push("Folder name updated"); } // Compare folder path if (metadata.path && folderPaths[index] !== metadata.path) { sheet.getRange(currentRow, 6).setValue(metadata.path); statusMessages.push("Path updated"); } if (statusMessages.length === 0) { statusMessages.push("No changes needed"); } sheet.getRange(currentRow, 8).setValue(statusMessages.join(" | ")); } else { sheet.getRange(currentRow, 8).setValue("Failed: No metadata/name"); } } catch (err) { sheet.getRange(currentRow, 8).setValue("Failed: " + err.message); } // Delay to respect rate limits Utilities.sleep(DELAY_BETWEEN_REQUESTS); } SpreadsheetApp.flush(); } /** * getDropboxMetadata retrieves the name and path_display * from the Dropbox sharing link. * * It uses multiple methods to try to obtain the full path, * handling various limitations of the Dropbox API. */ function getDropboxMetadata(sharingLink) { const service = getDropboxService(); if (!service.hasAccess()) { throw new Error("Authorization required. Run authorizeDropbox() first."); } const accessToken = service.getAccessToken(); // First call to sharing/get_shared_link_metadata let apiUrl = "https://api.dropboxapi.com/2/sharing/get_shared_link_metadata"; let payload = { url: sharingLink }; let options = { method: "post", contentType: "application/json", headers: { Authorization: "Bearer " + accessToken, "Dropbox-API-Select-User": DROPBOX_TEAM_MEMBER_ID }, payload: JSON.stringify(payload), muteHttpExceptions: true }; let response = UrlFetchApp.fetch(apiUrl, options); let responseText = response.getContentText(); Logger.log("API Response for " + sharingLink + ": " + responseText); let json; try { json = JSON.parse(responseText); } catch (e) { throw new Error("Invalid JSON response: " + responseText); } if (json.error_summary) { throw new Error("Dropbox API error: " + json.error_summary); } // For shared folders, try a different approach to get the path if (!json.path_display && json['.tag'] === 'folder' && json.id) { // Try with sharing/list_folders endpoint if it's a shared folder apiUrl = "https://api.dropboxapi.com/2/sharing/list_folders"; payload = { limit: 100 }; options.payload = JSON.stringify(payload); try { response = UrlFetchApp.fetch(apiUrl, options); responseText = response.getContentText(); Logger.log("List Folders API Response: " + responseText); const listFolders = JSON.parse(responseText); if (listFolders.entries && listFolders.entries.length > 0) { // Look for matching entry by shared_folder_id const matchingFolder = listFolders.entries.find(folder => folder.shared_folder_id === json.id.replace('id:', '') ); if (matchingFolder && matchingFolder.path_lower) { json.path_display = matchingFolder.path_lower; } } } catch (e) { Logger.log("Fallback list_folders method failed: " + e.message); } // If still no path_display, try with list_mountable_folders if (!json.path_display) { apiUrl = "https://api.dropboxapi.com/2/sharing/list_mountable_folders"; payload = { limit: 100 }; options.payload = JSON.stringify(payload); try { response = UrlFetchApp.fetch(apiUrl, options); responseText = response.getContentText(); Logger.log("List Mountable Folders API Response: " + responseText); const listFolders = JSON.parse(responseText); if (listFolders.entries && listFolders.entries.length > 0) { // Look for matching entry by shared_folder_id const matchingFolder = listFolders.entries.find(folder => folder.shared_folder_id === json.id.replace('id:', '') ); if (matchingFolder && matchingFolder.path_lower) { json.path_display = matchingFolder.path_lower; } } } catch (e) { Logger.log("Fallback list_mountable_folders method failed: " + e.message); } } // Try one more approach with sharing/get_folder_metadata if (!json.path_display) { apiUrl = "https://api.dropboxapi.com/2/sharing/get_folder_metadata"; payload = { shared_folder_id: json.id.replace('id:', '') }; options.payload = JSON.stringify(payload); try { response = UrlFetchApp.fetch(apiUrl, options); responseText = response.getContentText(); Logger.log("Get Folder Metadata API Response: " + responseText); const folderMetadata = JSON.parse(responseText); if (folderMetadata.path_lower) { json.path_display = folderMetadata.path_lower; } } catch (e) { Logger.log("Fallback get_folder_metadata method failed: " + e.message); } } } return { name: json.name || "", path: json.path_display || "" }; } function startFolderNameUpdate() { PropertiesService.getScriptProperties().setProperty("batchIndexDropbox", "0"); updateFolderNamesInBatches(); } // ===================================================== // SETUP TRIGGERS // ===================================================== function setupTriggers() { // Delete all existing triggers. ScriptApp.getProjectTriggers().forEach(function(trigger) { ScriptApp.deleteTrigger(trigger); }); // Trigger on change to update coordinates. ScriptApp.newTrigger("updateCoordinates") .forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()) .onChange() .create(); // Trigger on change to update statuses from paths. ScriptApp.newTrigger("updateStatusFromPaths") .forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()) .onChange() .create(); // Time-based trigger to update Dropbox folder names & paths in batches (every Monday at 15:00). ScriptApp.newTrigger("updateFolderNamesInBatches") .timeBased() .onWeekDay(ScriptApp.WeekDay.MONDAY) .atHour(15) .create(); Logger.log("Triggers set: onChange for updateCoordinates and updateStatusFromPaths; weekly for updateFolderNamesInBatches."); } // Function to manually reset the batch index. function resetBatchIndex() { PropertiesService.getScriptProperties().deleteProperty('batchIndexDropbox'); Logger.log("Batch index reset to start from the beginning (row 4)"); } // Function to reset old Dropbox credentials. function resetDropboxAuth() { PropertiesService.getUserProperties().deleteAllProperties(); Logger.log("Dropbox authorization reset. Re-run authorizeDropbox()."); } ``` Typical Log Output: Here are examples of the log messages I typically see when the script runs: API Response Log: `3 March 2025, 15:10:42 Info API Response for https://www.dropbox.com/scl/fo/REPLACE_URL?dl=0: {"tag": "folder", "url": "https://www.dropbox.com/scl/fo/REPLACE_URL?dl=0", "id": "id:REPLACE_ID", "name": "REPLACE_NAME", "link_permissions": { ... }, "team_member_info": { ... }}` Fallback Log: `3 March 2025, 15:10:42 Info Fallback API Response for https://www.dropbox.com/scl/fo/REPLACE_URL?dl=0: Error in call to API function "files/get_metadata": request body: unknown field 'shared_link'` In these logs, all sensitive details (such as URLs, IDs, names, and team names) have been replaced with placeholders. My question is: Why isn't the path_display property being returned by the Dropbox API, even though my account has the necessary permissions? Retrieving this property is crucial because it allows me to move folders in Dropbox and still maintain the most recent folder path in my interactive map. This is why I run weekly updates—to ensure that the map reflects any changes in folder structure. Any help or suggestions would be greatly appreciated!Solved600Views0likes1CommentApp folder to a org folder
Hello, I have a folder that stores builds from my pipeline. This folder was created by a Dropbox app I created. The folder sits under my personal folder and I want it to be a org level folder so other team members can access it. Is there a way to do that? Cheers,172Views0likes4Comments