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
3 years agoExplorer | Level 4
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
- Greg-DBDropbox StaffBy default, Dropbox API access tokens for your app(s) don't become invalid and yield 'invalid_access_token' by themselves, but there a number of different ways that a Dropbox API access token can become invalid, including:
- the user or team admin can revoke all access tokens for an app by unlinking it on any of the following Dropbox web pages:
- the Connected apps page
- the Security checkup page
- the Team apps page on the Settings section of Business Admin console
- the team member’s page on the Members section of the Business Admin console
- any client with the access token can revoke the access token by calling /2/auth/token/revoke
- the GitHub-Dropbox token scanning partnership can revoke access tokens found publicly posted on GitHub
- if the app uses the "app folder" access type, the access token can effectively be disabled by deleting the app folder itself in the Dropbox account, via the Dropbox website or any client
- the app can be disabled
- the account that owns the app can be disabled
- the connected account/team can be disabled
Please review the above possibilities for information on why the access token may be invalid. If the Dropbox API isn't behaving as expected, feel free to contact support by opening an API ticket.
About Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.5,918 PostsLatest Activity: 2 days ago
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!