I'm really new to coding and have been using chatgpt to somewhat lean on, in any case I created a discord bot to do a subset of tasks for a gaming server. Activision used to have a stats tracker and it seems they have limited it down to their use. In any case, found you can enter your activision account into this X post and it will return your combat record. I would like to do this straight from my discord bot, however, I ran into this 403 forbidden error. Error fetching original tweet: 403 Forbidden When authenticating requests to the Twitter API v2 endpoints, you must use keys and tokens from a Twitter developer App that is attached to a Project. You can create a project via the developer portal. `import tweepy import os import re import asyncio from dotenv import load_dotenv # Load environment variables from .env file load_dotenv() # Twitter API credentials from .env file CONSUMER_KEY = os.getenv("TWITTER_API_KEY") CONSUMER_SECRET = os.getenv("TWITTER_API_SECRET") BEARER_TOKEN = os.getenv('BEARER_TOKEN') ACCESS_TOKEN = os.getenv("TWITTER_ACCESS_TOKEN") ACCESS_TOKEN_SECRET = os.getenv("TWITTER_ACCESS_SECRET") # Set up Twitter API with tweepy for v2 client = tweepy.Client(bearer_token=BEARER_TOKEN) auth = tweepy.OAuth1UserHandler( consumer_key=CONSUMER_KEY, consumer_secret=CONSUMER_SECRET, access_token=ACCESS_TOKEN, access_token_secret=ACCESS_TOKEN_SECRET ) api = tweepy.API(auth, wait_on_rate_limit=True) # Helper function to extract tweet ID from URL def extract_tweet_id(url): tweet_id_match = re.search(r"status/(\d+)", url) return tweet_id_match.group(1) if tweet_id_match else None # Helper function to get the original tweet in the thread def get_original_tweet_in_thread(tweet_id): try: tweet = client.get_tweet(tweet_id, tweet_fields=["referenced_tweets"]) while 'referenced_tweets' in tweet.data and tweet.data['referenced_tweets']: tweet_id = tweet.data['referenced_tweets'][0]['id'] tweet = client.get_tweet(tweet_id, tweet_fields=["referenced_tweets"]) return tweet.data['id'] except Exception as e: print(f"Error fetching original tweet: {str(e)}") return tweet_id # Function to send combat record request tweet def send_combat_record_request(tweet_url, activision_name): tweet_id = extract_tweet_id(tweet_url) if not tweet_id: return None, "Invalid tweet URL. Please provide a valid tweet link." original_tweet_id = get_original_tweet_in_thread(tweet_id) status_message = f"{activision_name} #CODCombatRecord @CallofDuty" try: response = api.update_status( status=status_message, in_reply_to_status_id=original_tweet_id, auto_populate_reply_metadata=True ) return response.id, None except tweepy.TweepyException as e: return None, f"Error posting tweet: {str(e)}" # Function to check for combat record reply def check_for_combat_record(tweet_id): try: query = f'to:CallofDuty since_id:{tweet_id}' response = client.search_recent_tweets(query=query, tweet_fields=['text', 'in_reply_to_user_id']) for tweet in response.data: if tweet.in_reply_to_user_id and tweet.in_reply_to_user_id == tweet_id: if "combat record" in tweet.text.lower(): return tweet.text return None except Exception as e: print(f"Error fetching replies: {str(e)}") return None # Asynchronous function to monitor replies async def monitor_replies(ctx, tweet_id, activision_name): while True: combat_record = check_for_combat_record(tweet_id) if combat_record: formatted_record = format_combat_record(combat_record) await ctx.send(f"Combat Record for {activision_name}:\n{formatted_record}") break await asyncio.sleep(60) # Function to format the combat record def format_combat_record(combat_record_text): return combat_record_text` Continue reading...