cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Want to learn some quick and useful tips to make your day easier? Check out how Calvin uses Replay to get feedback from other teams at Dropbox here.

Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Dropbox Python API Webhooks

Dropbox Python API Webhooks

eight-fives
Explorer | Level 3

Im currently working on a application were i need to implement webhooks from my dropbox to my local pc. Unfortunatly im having problems with getting my program to work with the webhooks.

 

My process so far has been roughly as follows.
    - Ive setup a app on the dorpbox website and given it most of the permissions.
    - Ive generated a webhook using webhook.site and put a $request.query.challenge$ in the body. Ive added it to the
    dropbox webhook list and it enables it. When I delete or add something to my dropbox it notifies an update on webhook.site so it        seems to be working on that end.
    - In my main program its a script setup in pycharm using flask which i run.

 

The main problem is that when I update my dropbox webhook.site registers the callback however the program on my pc fails to do.

Im using windows 10 and pycharm as my ide, a basic dropbox account.

Ive included my code below, any insight would be greatly appreciated!

 

from hashlib import sha256
import hmac
import threading
import json
import requests
from flask import request,  Response, app, abort, Flask
import os

app = Flask(__name__)

def auth():
    app_key =  # from app 
    app_secret =  # from app

    # build the authorization URL:
    authorization_url = "https://www.dropbox.com/oauth2/authorize?client_id=%s&response_type=code" % app_key

    # send the user to the authorization URL:
    print('Go to the following URL and allow access:')
    print(authorization_url)

    # get the authorization code from the user:
    authorization_code = input('Enter the code:\n')

    # exchange the authorization code for an access token:
    token_url = "https://api.dropboxapi.com/oauth2/token"
    params = {
        "code": authorization_code,
        "grant_type": "authorization_code",
        "client_id": app_key,
        "client_secret": app_secret
    }
    r = requests.post(token_url, data=params)
    print(r.text)

@app.route('/link to webhook.site/mywebhook', methods=['GET'])
def verify():
    print("verify")

    resp = Response(request.args.get('webhook.site challenge goes here'))
    resp.headers['Content-Type'] = 'text/plain'
    resp.headers['X-Content-Type-Options'] = 'nosniff'
    print(resp)
    return resp

@app.route('/link to webhook.site/mywebhook', methods=['POST'])
def webhook():
    print("webhook")
    app_key = # from app 
    app_secret = # from app

    # Make sure this is a valid request from Dropbox
    signature = request.headers.get('X-Dropbox-Signature')
    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 ''

def process_user(account):
    print("Hello")

if __name__ == "__main__":
    auth()
    app.run()OK

I authenticate the user, it takes me through the process of clicking on the windows to get a key which i then enter back into the console. If its important i can never find the localhost, always says its out of reach.

 

Thanks for taking the time to read my long post!

2 Replies 2

Greg-DB
Dropbox Staff

When you register a webhook URI, Dropbox will send the webhook notifications (both the verification request and the notifications requests) to the server identified by the URI you supply. In your case, you supplied a site on 'webhook.site', so those requests are sent to the servers at 'webhook.site', which are maintained by the owners of 'webhook.site'.

 

Separately, I see you're trying to run a Flask web app in your IDE. This would run locally, on your computer (i.e., on your localhost), not on the webhook.site servers. The requests sent to webhook.site aren't connected to your locally running code.

 

I also see that you are attempting to connect your webhook.site site to your own code using the '@app.route' decorator, but that would only define the routes in your own web app; it wouldn't connect it to the actual webhook.site site.

 

Dropbox webhook notifications are sent by the Dropbox servers, so they can only be sent to publicly accessible Internet addresses. Typically, when running a web app locally like you are, that web app is not publicly accessible. To be able to run your own code interactively for handling webhooks, you'd need to deploy your web app online and get a public address that you could register as your webhook URI. (Alternatively, there are some tools that would let you get an address to connect to your local app for testing, such as 'ngrok', but we can't provide support for third party tools themselves like this.)

Здравко
Legendary | Level 20

Hi @eight-fives,

If you are looking for a way to receive notifications for changes in client side application (not something residing on server), might be more convenient usage of long poll API call (or equivalent SDK implementation). Take it a look.

Good luck.

Need more support?
Who's talking

Top contributors to this post

  • User avatar
    Здравко Legendary | Level 20
  • User avatar
    Greg-DB Dropbox Staff
What do Dropbox user levels mean?