使用Tweepy调用create_tweet时遭遇403 Forbidden错误求助
Twitter API 403 Forbidden 错误排查与解决
问题概述
调用 twitter_client.create_tweet(text=message,user_auth=False) 时触发403 Forbidden错误,Facebook授权和发布功能正常,已尝试多种OAuth方法、刷新令牌、脱离Flask运行等方案仍未解决。
报错详情
File "C:\Users\Watch\Desktop\Line Web App\main.py", line 104, in index twitter_client.create_tweet(text=message,user_auth=False) File "C:\Users\Watch\AppData\Local\Programs\Python\Python310\lib\site-packages\tweepy\client.py", line 835, in create_tweet return self._make_request( File "C:\Users\Watch\AppData\Local\Programs\Python\Python310\lib\site-packages\tweepy\client.py", line 129, in _make_request response = self.request(method, route, params=request_params, File "C:\Users\Watch\AppData\Local\Programs\Python\Python310\lib\site-packages\tweepy\client.py", line 100, in request raise Forbidden(response) tweepy.errors.Forbidden: 403 Forbidden Forbidden
完整代码
import requests import json import tweepy import facebook import os from flask import Flask, render_template, request, redirect, session app = Flask(__name__) app.secret_key = 'nivos' os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' def read_creds(filename): with open(filename) as f: credentials = json.load(f) return credentials credentials = read_creds('credentials.json') twitter_client_id = credentials['twitter']['client_id'] twitter_client_secret = credentials['twitter']['client_secret'] twitter_callback_url = 'http://localhost:5000/twitter-callback' auth = tweepy.OAuth2UserHandler( client_id=twitter_client_id, redirect_uri=twitter_callback_url, scope=["tweet.read", "tweet.write"], client_secret=twitter_client_secret ) facebook_app_id = credentials['facebook']['app_id'] facebook_app_secret = credentials['facebook']['app_secret'] facebook_callback_url = 'http://localhost:5000/facebook-callback' # 设置页面ID page_id = '106571142400269' @app.route('/') def get_auth(): facebook_login_url = 'http://127.0.0.1:5000/facebook-login' twitter_login_url = 'http://127.0.0.1:5000/twitter-login' return render_template('index.html', facebook_login_url=facebook_login_url,twitter_login_url=twitter_login_url) @app.route('/facebook-login', methods=['GET', 'POST']) def facebook_login(): graph = facebook.GraphAPI() link = graph.get_auth_url(facebook_app_id, facebook_callback_url, ['publish_to_groups', 'pages_show_list', 'pages_read_engagement', 'pages_manage_posts']) return redirect(link, code=302) @app.route('/twitter-login', methods=['GET', 'POST']) def twitter_login(): twitter_login_url = auth.get_authorization_url() return redirect(twitter_login_url,code=302) @app.route('/facebook-callback', methods=['GET', 'POST']) def get_token(): code = request.args.get('code') graph = facebook.GraphAPI() access_token = graph.get_access_token_from_code(code, facebook_callback_url, facebook_app_id, facebook_app_secret)['access_token'] # 定义API端点URL和参数 url = f'http://graph.facebook.com/{page_id}' params = { 'fields': 'access_token', 'access_token': access_token } # 发送GET请求到API端点 response = requests.get(url, params=params) session['facebook_access_token'] = response.json()['access_token'] session['facebook_page_id'] = response.json()['id'] return redirect('/') @app.route('/twitter-callback', methods=['GET', 'POST']) def get_twitter_token(): access_token = auth.fetch_token(request.url) session['twitter_access_token'] = access_token['access_token'] print(access_token) return redirect('/') @app.route('/post', methods=['POST']) def index(): if request.method == 'POST': twitter_access_token = session['twitter_access_token'] facebook_access_token = session['facebook_access_token'] facebook_page_id = session['facebook_page_id'] facebook_client = facebook.GraphAPI(access_token=facebook_access_token) twitter_client = tweepy.Client( bearer_token=twitter_access_token ) # 从表单获取消息 message = request.form['message'] # 在页面发布消息 facebook_client.put_object( parent_object=facebook_page_id, connection_name='feed', message=message, ) twitter_client.create_tweet(text=message,user_auth=False) return redirect('/') else: return render_template('index.html') if __name__ == '__main__': app.run()
已尝试的解决方法
- 使用多种OAuth授权方式
- 刷新所有令牌
- 脱离Flask框架单独运行代码
解决方案
1. 修正Tweepy客户端初始化逻辑
当前错误地将用户授权的access token当作bearer_token传入Tweepy Client,Bearer Token是应用级别的访问令牌,而用户授权的token需要通过access_token参数传入,且user_auth需设为True(默认值即为True)。
修改index函数中的Twitter客户端代码:
twitter_client = tweepy.Client( access_token=twitter_access_token ) # 调用create_tweet时无需指定user_auth=False twitter_client.create_tweet(text=message)
2. 检查Twitter开发者平台配置
- 确认应用已开启OAuth 2.0用户认证,且权限范围包含
tweet.write - 若应用处于开发模式,仅关联的测试用户能发推文;如需面向普通用户,需提交应用审核切换到生产模式
- 验证测试用户已授权应用获取
tweet.write权限
3. 完善令牌管理
在get_twitter_token函数中保存刷新令牌和过期时间,避免令牌过期导致的权限问题:
session['twitter_access_token'] = access_token['access_token'] session['twitter_refresh_token'] = access_token['refresh_token'] session['twitter_token_expires'] = access_token['expires_at']
后续可通过auth.refresh_token方法定期刷新过期令牌。
内容的提问来源于stack exchange,提问作者maloni
相关产品推荐
相关产品推荐

