We’re aware of an issue causing slower load times on the Dropbox Community forum. It should be resolved soon. Thanks for your patience! 

Forum Discussion

gauravpant's avatar
gauravpant
New member | Level 1
9 months ago

How can I create Dropbox autosync feature for my app ?

Hello everyone, 
I want to create an Autosync like feature in my app where a user connects his dropbox account, I get his refresh token. Then, using the dropbox sdk , I want to autosync all his pdfs from his account.

I've read in the documentation that it can be done using webhooks . I've managed to setup this much code so far. 

```

from flask import Blueprint, request, Response, abort

from hashlib import sha256

import hmac

import threading

import json

from dropbox import Dropbox

from dropbox.files import DeletedMetadata, FolderMetadata, WriteMode

import os

from markdown import markdown

from src.db import db

 

# Create a blueprint for user-related routes

dropbox_bp = Blueprint('dropbox', __name__)

 

users_collection = db['users']

 

dbox__bp.route('/webhook', methods=['GET'])

def verify():

    '''Respond to the webhook verification (GET request) by echoing back the challenge parameter.'''

 

    resp = Response(request.args.get('challenge'))

    resp.headers['Content-Type'] = 'text/plain'

    resp.headers['X-Content-Type-Options'] = 'nosniff'

 

    return resp

 

def process_user(account):

    '''Call /files/list_folder for the given user ID and process any changes.'''

    print("account id of user :",account)

    # Fetch user document based on Dropbox account_id

    user = users_collection.find_one({"dropbox_data.account_id": account})

    print("user logged :",user)

    if not user or "dropbox_data" not in user:

        print(f"No Dropbox data found for account ID: {account}")

        return

       

    dropbox_data = user["dropbox_data"]

    print("dropbox data :",dropbox_data)

    token = dropbox_data.get("refresh_token")  # Get refresh token

    cursor = dropbox_data.get("cursor")  # Get cursor

    print("token :",token)

    print("cursor :",cursor)

    dbx = Dropbox(oauth2_refresh_token=token,app_key=os.getenv("DROPBOX_CLIENT_ID"),app_secret=os.getenv("DROPBOX_CLIENT_SECRET"))

    has_more = True

 

    while has_more:

        if cursor is None:

            result = dbx.files_list_folder(path='')

        else:

            result = dbx.files_list_folder_continue(cursor)

 

        print("the result of list files api :",result.entries)

 

        for entry in result.entries:

            # Ignore deleted files, folders, and non-markdown files

            if (isinstance(entry, DeletedMetadata) or

                isinstance(entry, FolderMetadata) or

                not entry.path_lower.endswith('.md')):

                continue

 

            # Convert to Markdown and store as <basename>.html

            _, resp = dbx.files_download(entry.path_lower)

            print("the response of download api :",resp.content)

            html = markdown(resp.content)

            print("the html content :",html)

            dbx.files_upload(html.encode('utf-8'), entry.path_lower[:-3] + '.html', mode=WriteMode('overwrite'))

 

        # Update cursor in the database

        users_collection.update_one({"dropbox_data.account_id": account}, {"$set": {"dropbox_data.cursor": result.cursor}})

 

        # Repeat only if there's more to do

        has_more = result.has_more

 

dbox__bp.route('/webhook', methods=['POST'])

def webhook():

    '''Receive a list of changed user IDs from Dropbox and process each.'''

    # Make sure this is a valid request from Dropbox

    signature = request.headers.get('X-Dropbox-Signature')

    # if not hmac.compare_digest(signature, hmac.new(os.getenv("DROPBOX_CLIENT_SECRET"), request.data, sha256).hexdigest()):

    #     abort(403)

 

    for account in json.loads(request.data)['list_folder']['accounts']:

        # We need to respond quickly to the webhook request, so we do the

        # actual work in a separate thread. For more robustness, it's a

        # good idea to add the work to a reliable queue and process the queue

        # in a worker process.

        threading.Thread(target=process_user, args=(account,)).start()

    return ''
```


what I need to do after this is unclear to me ?
Any help will be appreciated , thanks !

3 Replies

  • DB-Des's avatar
    DB-Des
    Icon for Dropbox Community Moderator rankDropbox Community Moderator
    9 months ago

    Hi gauravpant,

    To clarify, webhooks are a way for web apps to get real-time notifications when users' files change in Dropbox. Once a webhook URI is registered, Dropbox will send an HTTP request to that URI every time there's a change in any of the accounts connected to your app. Feel free to review the documentation on webhooks for more information: https://www.dropbox.com/developers/reference/webhooks.

    Additionally, the code snippet you provided, also appears to be listing a user's files and folders, downloading files, and also uploading files. Could you clarify what exactly is not clear? Are you seeing errors? What are you expecting the app to do that it is not doing?

  • gauravpant's avatar
    gauravpant
    New member | Level 1
    9 months ago

    Hi DB-Des , I will explain my usecase . 

    In my app , a user connects his Dropbox account , his refresh token is stored in the application database. 

    Now, I want to have an autosync like functionality where as soon as the user has connected his dropbox account, my app autosyncs all the pdf files to my application server that this user has stored in his dropbox account.

    Now, to implement such a functionality , I would need to have the total number of files that will be synced by Autosync .

    I will store this variable in my database , I've a GET api that is used to get the total number of files that are being synced , I show it in frontend of my application. 

    I also have a variable 'syncedFileCount' , which gets incremented everytime a file is downloaded to my application server . 

    How can I develop this 'process_user' function that you can see in the code that I've shared above ?

  • DB-Des's avatar
    DB-Des
    Icon for Dropbox Community Moderator rankDropbox Community Moderator
    9 months ago

    gauravpant,

    Dropbox sends webhook notifications only when users' files change, not for login activity.

    If you’re looking to trigger autosync functionality when a user logs into their Dropbox account, you would need to implement a solution on your end to initiate the sync process accordingly. 

    That said, the logic you shared for retrieving user files, filtering through them, and uploading them appears accurate. If you notice any unexpected behavior from the API or encounter any errors, feel free to let us know.

About Dropbox API Support & Feedback

Node avatar for Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.

The Dropbox Community team is active from Monday to Friday. We try to respond to you as soon as we can, usually within 2 hours.

If you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X, Facebook or Instagram.

For more info on available support options for your Dropbox plan, see this article.

If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!