You might see that the Dropbox Community team have been busy working on some major updates to the Community itself! So, here is some info on what’s changed, what’s staying the same and what you can expect from the Dropbox Community overall.

Forum Discussion

af11's avatar
af11
Explorer | Level 4
3 years ago

dropbox.exceptions.AuthError: AuthError('adf0b24714c641a5b3dfcd68573db5e4', AuthError('invalid_acces

I am working on a notification app linked to a business account via a webhook to get notified when any of the team members edit files in certain folders.  Attached below is the code, deployed on Heroku

 

 

import os
from dotenv import load_dotenv
from dropbox import Dropbox
from flask import Flask, render_template, session, Response, request, abort
import hmac
from hashlib import sha256
import json
import threading
import sendgrid
from sendgrid.helpers.mail import *
import redis
from dropbox.files import DeletedMetadata, FolderMetadata, WriteMode, FileMetadata
from dropbox.users import FullAccount

load_dotenv()

ACCESS_TOKEN = os.environ.get('ACCESS_TOKEN')
APP_KEY = os.environ.get('APP_KEY')
APP_SECRET = os.environ.get('APP_SECRET')
EMAIL_USERNAME = os.environ.get('EMAIL_USERNAME')
redis_url = os.environ.get('REDISTOGO_URL')
redis_client = redis.from_url(redis_url, decode_responses=True)
main_folder = 'Career Consulting Real'
subfolder_list = ['eng101', "mat101"]

app = Flask(__name__)
app.secret_key = os.environ.get('FLASK_SECRET_KEY')

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/login')
def login():
    return render_template('done.html')

@app.route('/webhook', methods=['GET'])
def challenge():
    resp = Response(request.args.get('challenge'))
    resp.headers['Content-Type'] = 'text/plain'
    resp.headers['X-Content-Type-Options'] = 'nosniff'
    print(resp)
    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')
    key = bytes(APP_SECRET, encoding="ascii")
    if not hmac.compare_digest(signature, hmac.new(key, request.data, sha256).hexdigest()):
        abort(403)

    #print(json.loads(request.data))
    #print(json.loads(request.data)['delta']['teams']['dbtid:AAB_JmVTCr29MzCFLUPWLOP3ch-RdRv3Quo'])
    for account in json.loads(request.data)['delta']['teams']['dbtid:AAB_JmVTCr29MzCFLUPWLOP3ch-RdRv3Quo']:
        # 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 ''

def filter_notifications(entry):
    file_path_split = entry.path_display.replace(' ', '').lower().split('/')
    if file_path_split[1] == main_folder.replace(' ', '').lower():
        for subfolder in subfolder_list:
            if subfolder in file_path_split[2]:
                return True

def send_notification(message):

    send_grid_key = os.environ.get('SEND_GRID')
    sg = sendgrid.SendGridAPIClient(api_key=send_grid_key)
    from_email = Email(EMAIL_USERNAME)
    to_email = To("cdropboxchanges@gmail.com")
    subject = "A change has been made"
    content = Content("text/plain", message)
    mail = Mail(from_email, to_email, subject, content)
    response = sg.client.mail.send.post(request_body=mail.get())

def process_user(account):

    # cursor for the user (None the first time)
    cursor = redis_client.hget('cursors', account)

    dbx = Dropbox(ACCESS_TOKEN)

    has_more = True

    while has_more:
        if cursor is None:
            result = dbx.files_list_folder(path='', recursive=True, include_non_downloadable_files=True)
        else:
            result = dbx.files_list_folder_continue(cursor)

        for entry in result.entries:
            if filter_notifications(entry):
                if isinstance(entry, FileMetadata):
                    send_notification('File Metadat')
                elif isinstance(entry, DeletedMetadata):
                    send_notification('DeletedMetadata')
                elif isinstance(entry, FolderMetadata):
                    send_notification('Folder Metadata')
                else:
                    send_notification('Something happened, not sure what...')

        # Update cursor
        cursor = result.cursor
        redis_client.hset('cursors', account, cursor)

        # Repeat only if there's more to do
        has_more = result.has_more


if __name__ == '__main__':
    app.run(debug=True)

 

 

When I run the code, I get the following error: 

 dropbox.exceptions.AuthError: AuthError('adf0b24714c641a5b3dfcd68573db5e4', AuthError('invalid_access_token', None))

However, the access token I am passing in is straight from the app on Dropbox.

Can you please advise what could be the problem that is causing this error?

Thank you

About Dropbox API Support & Feedback

Node avatar for Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.5,918 PostsLatest Activity: 2 days ago
334 Following

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 or Facebook.

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!