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 !