You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:13:11