Method 1: Automating Google Sheets to Dropbox Uploads using Short-Lived Access Tokens
This method uses a short-lived Dropbox access token, which needs to be generated and replaced in the script each time it expires. While simpler to set up, it requires more frequent updates to the access token within the script.
1. Dropbox App Setup
- Sign in to Dropbox.
- Go to the Dropbox App Console
- Click "Create app".
- Set the app type to "App folder".
- Fill in the app details. Crucially, note the App key, App secret, and OAuth 2 Redirect URIs. Generate a short-lived access token. Securely store these credentials.
- Under "Permissions", select account_info.write, files.metadata.write, files.content.write, and files.content.read under Account Info and Files and Folders. Under Connect, select Profile and Email. Click "Submit". Add optional branding information and click "Save changes".
2. Google Apps Script Implementation
After setting up your Dropbox app, open your Google Sheet in Google Drive. Go to "Extensions" -> "Apps Script". Replace the placeholders in the following code with your actual credentials:
- function onEdit(e) {
- // Configuration (Use Script Properties for production)
- const ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty('DROPBOX_ACCESS_TOKEN'); // Replace with your Dropbox access token from Script Properties
- const DROPBOX_FOLDER_PATH = '/home/Google_CSV_Destination/';
- const FILE_NAME = 'data.csv';
- const SHEET_NAME = 'Form Responses 1'; // Change to your sheet name
- // Get the spreadsheet and specific sheet (by name)
- const ss = SpreadsheetApp.getActiveSpreadsheet();
- const sheet = ss.getSheetByName(SHEET_NAME);
- if (!sheet) {
- Logger.log('Sheet not found: ' + SHEET_NAME);
- return; // Exit if the sheet isn't found
- }
- // Get the sheet data as a 2D array
- const data = sheet.getDataRange().getValues();
- // Convert the 2D array to CSV format
- const csvData = data.map(row => row.map(cell => `"${cell}"`).join(',')).join('\n');
- // Dropbox API endpoint and options
- const options = {
- 'method': 'post',
- 'contentType': 'application/octet-stream',
- 'headers': {
- 'Authorization': 'Bearer ' + ACCESS_TOKEN,
- 'Dropbox-API-Arg': JSON.stringify({
- 'path': DROPBOX_FOLDER_PATH + FILE_NAME,
- 'mode': 'overwrite', // or 'add' if you want to create a new file each time
- 'autorename': false,
- 'mute': true, // Don't get notifications from Dropbox
- }),
- },
- 'payload': csvData,
- };
- // Send data to Dropbox
- try {
- UrlFetchApp.fetch('https://content.dropboxapi.com/2/files/upload', options);
- Logger.log('File uploaded to Dropbox successfully!');
- } catch (error) {
- Logger.log('Error uploading file to Dropbox: ' + error);
- }
- }
3. Securely Storing Credentials
For enhanced security, store the ACCESS_TOKEN in the Script Properties (Script Editor -> Project Settings -> Script properties). Set the property DROPBOX_ACCESS_TOKEN to your Dropbox access token. This avoids hardcoding sensitive information directly in the script.
4. Deploy the app as a web app
Go to "Deploy" > "New deployment" > choose "Web app". Set the "Who has access to the app" to "Anyone, even anonymous". In this case, choose "Only Myself".
5. Setting up Event Triggers
Go to "Edit" -> "Current project's triggers". Click "+ Add Trigger". Configure the trigger to run the onEdit function "on edit" of your spreadsheet. This will automatically upload the data whenever the spreadsheet is modified, configure more triggers as desired. You can also configure time-driven triggers for scheduled uploads.
Check the Executions page - Editor -> Executions to see the deployment status.
Method 2: Automating Google Sheets to Dropbox Uploads using Refresh Tokens
Here is the quick summary of Method 2:
- Copy and paste the code into Editor.
- Enable the OAuth2 Library.
- Go to Project Settings and set the App key and the App secret under the Script Properties.
- Deploy the script as the web app, choose "Only Myself".
- Authorize the app with Gmail account if needed, you may be prompted when you run either the printRedirectURI or the authorize function or upon deploying the script as the web app.
- Authorize with the authorize function. Copy the URL printed and paste it on the browser to authorizen - do this only once.
- Run printRedirectURI function to get the redirect URI, add it to DX under Redirect URIs.
- Set Triggers and test the code.
- You're done.
- Dropbox App Setup: Same as Method 1, but this time you need to add the redirect URI:
This method requires a properly set up of the redirect URI. To obtain the redirect URI:
- Copy the printRedirectUri() function below to the start of the script:
- function printRedirectUri() {
- const redirectUri = ScriptApp.getService().getUrl();
- // Log the redirect URI to the Apps Script logs
- Logger.log("Your Redirect URI is: " + redirectUri);
- }
- Run the function to log the redirect URI to the console.
- Copy and paste the URI to add it into the Redirect URIs section in the Dropbox app.
- Remove the printRedirectUri() function from the script.
- Copy the printRedirectUri() function below to the start of the script:
- Google Apps Script Implementation:
This method requires a more complex OAuth2 flow. Add the OAuth2 library (Script ID: 1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF). Replace placeholders with your actual Dropbox app credentials (DO NOT HARDCODE IN PRODUCTION; USE PropertiesService AS SHOWN IN THE COMMENTS).
- function authorize() {
- const CLIENT_ID = PropertiesService.getScriptProperties().getProperty('DROPBOX_APP_KEY'); // Replace with your actual key from Script Properties
- const CLIENT_SECRET = PropertiesService.getScriptProperties().getProperty('DROPBOX_APP_SECRET'); // Replace with your actual secret from Script Properties
- const REDIRECT_URI = ScriptApp.getService().getUrl();
- const authorizeUrl = `https://www.dropbox.com/oauth2/authorize?response_type=code&client_id=${CLIENT_ID}&redirect_uri=\${encodeURIComponent(REDIRECT_URI)}&token_access_type=offline`;
- Logger.log("Authorize Dropbox app: " + authorizeUrl);
- SpreadsheetApp.getActiveSpreadsheet().toast('Copy and paste the URL in the log into your browser to authorize the app','Dropbox Authorization', -1);
- }
- function doGet(e) {
- if (e && e.parameter && e.parameter.code) {
- const code = e.parameter.code;
- const CLIENT_ID = PropertiesService.getScriptProperties().getProperty('DROPBOX_APP_KEY');
- const CLIENT_SECRET = PropertiesService.getScriptProperties().getProperty('DROPBOX_APP_SECRET');
- const REDIRECT_URI = ScriptApp.getService().getUrl();
- const options = {
- 'method': 'post',
- 'contentType': 'application/x-www-form-urlencoded',
- 'payload': `grant_type=authorization_code&code=${code}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}`
- };
- const response = UrlFetchApp.fetch('https://api.dropboxapi.com/oauth2/token', options);
- const data = JSON.parse(response.getContentText());
- if (data.access_token && data.refresh_token) {
- PropertiesService.getScriptProperties().setProperty('dropboxRefreshToken', data.refresh_token);
- Logger.log('Refresh token stored successfully!');
- return HtmlService.createHtmlOutput('Authorization successful. Refresh token stored.');
- } else {
- Logger.log('Error obtaining tokens: ' + JSON.stringify(data));
- return HtmlService.createHtmlOutput('Authorization failed. Check the logs.');
- }
- } else {
- return HtmlService.createHtmlOutput('Authorization failed. Invalid redirect.');
- }
- }
- function getDropboxRefreshToken() {
- return PropertiesService.getScriptProperties().getProperty('dropboxRefreshToken');
- }
- function getAccessToken() {
- const refreshToken = getDropboxRefreshToken();
- if (!refreshToken) {
- Logger.log('Refresh token not found. Run authorize().');
- return null;
- }
- const CLIENT_ID = PropertiesService.getScriptProperties().getProperty('DROPBOX_APP_KEY');
- const CLIENT_SECRET = PropertiesService.getScriptProperties().getProperty('DROPBOX_APP_SECRET');
- const options = {
- 'method': 'post',
- 'contentType': 'application/x-www-form-urlencoded',
- 'payload': `grant_type=refresh_token&refresh_token=${refreshToken}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}`
- };
- try {
- const response = UrlFetchApp.fetch('https://api.dropboxapi.com/oauth2/token', options);
- const data = JSON.parse(response.getContentText());
- return data.access_token;
- } catch (error) {
- Logger.log('Error refreshing access token: ' + error);
- return null;
- }
- }
- function onEdit(e) {
- const DROPBOX_FOLDER_PATH = '/home/Google_CSV_Destination/';
- const FILE_NAME = 'data.csv';
- const SHEET_NAME = 'Form Responses 1';
- const ss = SpreadsheetApp.getActiveSpreadsheet();
- const sheet = ss.getSheetByName(SHEET_NAME);
- if (!sheet) {
- Logger.log('Sheet not found: ' + SHEET_NAME);
- return;
- }
- const data = sheet.getDataRange().getValues();
- const csvData = data.map(row => row.map(cell => `"${cell}"`).join(',')).join('\n');
- const accessToken = getAccessToken();
- if (!accessToken) {
- Logger.log('Failed to obtain access token.');
- return;
- }
- const options = {
- 'method': 'post',
- 'contentType': 'application/octet-stream',
- 'headers': {
- 'Authorization': 'Bearer ' + accessToken,
- 'Dropbox-API-Arg': JSON.stringify({
- 'path': DROPBOX_FOLDER_PATH + FILE_NAME,
- 'mode': 'overwrite',
- 'autorename': false,
- 'mute': true,
- }),
- },
- 'payload': csvData,
- };
- try {
- UrlFetchApp.fetch('https://content.dropboxapi.com/2/files/upload', options);
- Logger.log('File uploaded to Dropbox successfully!');
- } catch (error) {
- Logger.log('Error uploading file to Dropbox: ' + error);
- }
- }
- Securely Storing Credentials
Store DROPBOX_APP_KEY and DROPBOX_APP_SECRET in Script Properties. The refresh token will be stored automatically in Script Properties after successful authorization.
\(\\ \) - Authorization with Gmail to use the Apps Script, choose the appropriate Gmail account and Continue - there will be some warnings about safety, ignore them, choose Advanced and proceed.
- Next Authorization:
- Run the authorize() function. This will generate an authorization URL.
- Copy and paste the URL into your browser and authorize the app.
- The doGet function will handle the redirect from Dropbox and store the refresh token: Dropbox's OAuth 2.0 flow necessitates a designated endpoint within the Google Apps Script web app to process the authorization redirect. This is achieved by a doGet function, which intercepts the Dropbox redirect, retrieves the authorization code, exchanges it for access and refresh tokens, and securely stores the refresh token.
- Setting up Event Triggers: (Same as Method 1)