Search code examples
pythonflaskdropboxdropbox-api

Flask app for Dropbox webhook, notifications not working


I created a Flask app with endpoints ready for Dropbox webhooks. A Dropbox webhook is a service that calls our defined API endpoint when some event happens in our dropbox folder (like uploading a file). The configuration for my app is like shown in next image, clearly showing that the webhook URI has been enabled, i.e. challenge URI for Dropbox webhook works correctly (API_KEY, API_SECRET, and app.secret_key are hidden here).

Congiguration set up for my Dropbox app

Next, you can see the code of my flask app. The problem is that I am expecting the /webhook POST call to be triggered everytime I upload a file to my Dropbox folder, but it never happens. Do you know the correct way to fix this? Thank you.

# App key and secret from the App console (dropbox.com/developers/apps)
    APP_KEY = "XXXXXXXXXXXXX"
    APP_SECRET = "YYYYYYYYYYYYY"

    app = Flask(__name__)
    app.debug = True

    # A random secret used by Flask to encrypt session data cookies
    app.secret_key = "zzzzzzzzzzzzz"


    def process_user(account):

        print("Yeahhhhh")


    @app.route('/webhook', methods=['GET'])
    def challenge():
        '''Respond to the webhook challenge (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

    @app.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').encode("utf-8")
        if not hmac.compare_digest(signature, hmac.new(APP_SECRET, request.data, sha256).hexdigest()):
            abort(403)

        for account in json.loads(request.data)['list_folder']['accounts']:
            threading.Thread(target=process_user, args=(account,)).start()
        return ''

    if __name__=='__main__':
        app.run(host='0.0.0.0')

Solution

  • There are a few things to check if you're not receiving the expected webhook notification requests from Dropbox. Make sure you have:

    • the correct app: if you may have registered multiple apps, ensure that you added the webhook URI to the right one
    • the correct webhook URI: ensure you have the right host/port/path registered in your webook URI. (The dropbox_hook project can be useful for easily simulating webhook notification requests.)
    • changes in the correct account: ensure that you're making changes in the right account. Dropbox webhook notifications will only be sent for changes in an account that is currently connected to the API app (e.g., authorized by the OAuth app authorization flow, or by generating an access token on the App Console).
    • changes in the correct folder, if using the "app folder" permission: for apps using the "app folder" permission, such as yours, webhook notifications will only be sent for changes inside the special app folder created in connected users' accounts (by default at /Apps/APP_FOLDER_NAME for accounts using English), and not anywhere else in the accounts.