# TwitterTool Technical Documentation ## Class Overview The TwitterTool class provides a comprehensive interface for interacting with Twitter's API. It encapsulates common Twitter operations and provides error handling, logging, and integration capabilities with AI agents. ## Installation Requirements ```bash pip install swarms-tools ``` ## Class Definition ### Constructor Parameters The `options` dictionary accepts the following keys: | Parameter | Type | Required | Default | Description | |-----------|------|----------|----------|-------------| | id | str | No | "twitter_plugin" | Unique identifier for the tool instance | | name | str | No | "Twitter Plugin" | Display name for the tool | | description | str | No | Default description | Tool description | | credentials | Dict[str, str] | Yes | None | Twitter API credentials | The `credentials` dictionary requires: | Credential | Type | Required | Description | |------------|------|----------|-------------| | apiKey | str | Yes | Twitter API key | | apiSecretKey | str | Yes | Twitter API secret key | | accessToken | str | Yes | Twitter access token | | accessTokenSecret | str | Yes | Twitter access token secret | ## Public Methods ### available_functions ```python @property def available_functions(self) -> List[str] ``` Returns a list of available function names that can be executed by the tool. **Returns:** - List[str]: Names of available functions ['get_metrics', 'reply_tweet', 'post_tweet', 'like_tweet', 'quote_tweet'] **Example:** ```python twitter_tool = TwitterTool(options) functions = twitter_tool.available_functions print(f"Available functions: {functions}") ``` ### get_function ```python def get_function(self, fn_name: str) -> Callable ``` Retrieves a specific function by name for execution. **Parameters:** - fn_name (str): Name of the function to retrieve **Returns:** - Callable: The requested function **Raises:** - ValueError: If the function name is not found **Example:** ```python post_tweet = twitter_tool.get_function('post_tweet') metrics_fn = twitter_tool.get_function('get_metrics') ``` ## Protected Methods ### _get_metrics ```python def _get_metrics(self) -> Dict[str, int] ``` Fetches user metrics including followers, following, and tweet counts. **Returns:** - Dict[str, int]: Dictionary containing metrics - followers: Number of followers - following: Number of accounts following - tweets: Total tweet count **Example:** ```python metrics = twitter_tool._get_metrics() print(f"Followers: {metrics['followers']}") print(f"Following: {metrics['following']}") print(f"Total tweets: {metrics['tweets']}") ``` ### _reply_tweet ```python def _reply_tweet(self, tweet_id: int, reply: str) -> None ``` Posts a reply to a specific tweet. **Parameters:** - tweet_id (int): ID of the tweet to reply to - reply (str): Text content of the reply **Example:** ```python twitter_tool._reply_tweet( tweet_id=1234567890, reply="Thank you for sharing this insight!" ) ``` ### _post_tweet ```python def _post_tweet(self, tweet: str) -> Dict[str, Any] ``` Creates a new tweet. **Parameters:** - tweet (str): Text content of the tweet **Returns:** - Dict[str, Any]: Response from Twitter API **Example:** ```python twitter_tool._post_tweet( tweet="Exploring the fascinating world of AI and machine learning! #AI #ML" ) ``` ### _like_tweet ```python def _like_tweet(self, tweet_id: int) -> None ``` Likes a specific tweet. **Parameters:** - tweet_id (int): ID of the tweet to like **Example:** ```python twitter_tool._like_tweet(tweet_id=1234567890) ``` ### _quote_tweet ```python def _quote_tweet(self, tweet_id: int, quote: str) -> None ``` Creates a quote tweet. **Parameters:** - tweet_id (int): ID of the tweet to quote - quote (str): Text content to add to the quote **Example:** ```python twitter_tool._quote_tweet( tweet_id=1234567890, quote="This is a fascinating perspective on AI development!" ) ``` ## Integration Examples ### Basic Usage with Environment Variables ```python import os from dotenv import load_dotenv from swarms_tools import TwitterTool load_dotenv() options = { "id": "twitter_bot", "name": "AI Twitter Bot", "description": "An AI-powered Twitter bot", "credentials": { "apiKey": os.getenv("TWITTER_API_KEY"), "apiSecretKey": os.getenv("TWITTER_API_SECRET_KEY"), "accessToken": os.getenv("TWITTER_ACCESS_TOKEN"), "accessTokenSecret": os.getenv("TWITTER_ACCESS_TOKEN_SECRET"), } } twitter_tool = TwitterTool(options) ``` ### Integration with AI Agent for Content Generation ```python from swarms import Agent from swarms_models import OpenAIChat from swarms_tools import TwitterTool import os from dotenv import load_dotenv load_dotenv() # Initialize the model model = OpenAIChat( model_name="gpt-4", max_tokens=3000, openai_api_key=os.getenv("OPENAI_API_KEY") ) # Create content generation agent content_agent = Agent( agent_name="Content Creator", system_prompt=""" You are an expert content creator for Twitter. Create engaging, informative tweets that: 1. Are under 280 characters 2. Use appropriate hashtags 3. Maintain a professional tone 4. Include relevant calls to action """, llm=model ) class TwitterContentBot: def __init__(self, twitter_tool: TwitterTool, agent: Agent): self.twitter_tool = twitter_tool self.agent = agent self.post_tweet = twitter_tool.get_function('post_tweet') def generate_and_post(self, topic: str) -> None: """ Generates and posts content about a specific topic. Args: topic (str): The topic to create content about """ prompt = f"Create an engaging tweet about {topic}" tweet_content = self.agent.run(prompt) self.post_tweet(tweet_content) # Usage bot = TwitterContentBot(twitter_tool, content_agent) bot.generate_and_post("artificial intelligence") ``` ### Automated Engagement System ```python import time from typing import List, Dict class TwitterEngagementSystem: def __init__(self, twitter_tool: TwitterTool): self.twitter_tool = twitter_tool self.like_tweet = twitter_tool.get_function('like_tweet') self.reply_tweet = twitter_tool.get_function('reply_tweet') self.get_metrics = twitter_tool.get_function('get_metrics') # Track engagement history self.engagement_history: List[Dict] = [] def engage_with_tweet(self, tweet_id: int, should_like: bool = True, reply_text: Optional[str] = None) -> None: """ Engages with a specific tweet through likes and replies. Args: tweet_id (int): The ID of the tweet to engage with should_like (bool): Whether to like the tweet reply_text (Optional[str]): Text to reply with, if any """ try: if should_like: self.like_tweet(tweet_id) if reply_text: self.reply_tweet(tweet_id, reply_text) # Record engagement self.engagement_history.append({ 'timestamp': time.time(), 'tweet_id': tweet_id, 'actions': { 'liked': should_like, 'replied': bool(reply_text) } }) except Exception as e: print(f"Failed to engage with tweet {tweet_id}: {e}") # Usage engagement_system = TwitterEngagementSystem(twitter_tool) engagement_system.engage_with_tweet( tweet_id=1234567890, should_like=True, reply_text="Great insights! Thanks for sharing." ) ``` ### Scheduled Content System ```python import schedule from datetime import datetime, timedelta class ScheduledTwitterBot: def __init__(self, twitter_tool: TwitterTool, agent: Agent): self.twitter_tool = twitter_tool self.agent = agent self.post_tweet = twitter_tool.get_function('post_tweet') self.posted_tweets: List[str] = [] def generate_daily_content(self) -> None: """ Generates and posts daily content based on the current date. """ today = datetime.now() prompt = f""" Create an engaging tweet for {today.strftime('%A, %B %d')}. Focus on technology trends and insights. """ tweet_content = self.agent.run(prompt) # Avoid duplicate content if tweet_content not in self.posted_tweets: self.post_tweet(tweet_content) self.posted_tweets.append(tweet_content) # Keep only last 100 tweets in memory if len(self.posted_tweets) > 100: self.posted_tweets.pop(0) # Usage scheduled_bot = ScheduledTwitterBot(twitter_tool, content_agent) # Schedule daily posts schedule.every().day.at("10:00").do(scheduled_bot.generate_daily_content) schedule.every().day.at("15:00").do(scheduled_bot.generate_daily_content) # Run the scheduler while True: schedule.run_pending() time.sleep(60) ``` ## Error Handling The TwitterTool implements comprehensive error handling through try-except blocks. All methods catch and handle `tweepy.TweepyException` for Twitter API-specific errors. Here's an example of implementing custom error handling: ```python class TwitterToolWithCustomErrors(TwitterTool): def _post_tweet(self, tweet: str) -> Dict[str, Any]: """ Enhanced tweet posting with custom error handling. Args: tweet (str): The tweet content to post Returns: Dict[str, Any]: Response from Twitter API Raises: ValueError: If tweet exceeds character limit """ if len(tweet) > 280: raise ValueError("Tweet exceeds 280 character limit") try: return super()._post_tweet(tweet) except tweepy.TweepyException as e: self.logger.error(f"Twitter API error: {e}") raise ``` ## Rate Limiting Twitter's API has rate limits that should be respected. Here's an example implementation of rate limiting: ```python from time import time, sleep from collections import deque class RateLimitedTwitterTool(TwitterTool): def __init__(self, options: Dict[str, Any]) -> None: super().__init__(options) self.tweet_timestamps = deque(maxlen=300) # Track last 300 tweets self.max_tweets_per_15min = 300 def _check_rate_limit(self) -> None: """ Checks if we're within rate limits and waits if necessary. """ now = time() # Remove timestamps older than 15 minutes while self.tweet_timestamps and self.tweet_timestamps[0] < now - 900: self.tweet_timestamps.popleft() if len(self.tweet_timestamps) >= self.max_tweets_per_15min: sleep_time = 900 - (now - self.tweet_timestamps[0]) if sleep_time > 0: sleep(sleep_time) self.tweet_timestamps.append(now) def _post_tweet(self, tweet: str) -> Dict[str, Any]: self._check_rate_limit() return super()._post_tweet(tweet) ``` ## Best Practices 1. Always use environment variables for credentials: ```python from dotenv import load_dotenv load_dotenv() options = { "credentials": { "apiKey": os.getenv("TWITTER_API_KEY"), "apiSecretKey": os.getenv("TWITTER_API_SECRET_KEY"), "accessToken": os.getenv("TWITTER_ACCESS_TOKEN"), "accessTokenSecret": os.getenv("TWITTER_ACCESS_TOKEN_SECRET") } } ``` 2. Implement proper logging: ```python import logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) ``` 3. Use type hints consistently: ```python from typing import Optional, Dict, Any, List def process_tweet( tweet_id: int, action: str, content: Optional[str] = None ) -> Dict[str, Any]: pass ``` 4. Handle API rate limits gracefully: ```python from time import sleep def retry_with_backoff(func, max_retries: int = 3): for attempt in range(max_retries): try: return func() except tweepy.TweepyException as e: if attempt == max_retries - 1: raise sleep_time = (2 ** attempt) + random.uniform(0, 1) sleep(sleep_time) ``` 5. Validate input data: ```python def validate_tweet(tweet: str) -> bool: if not tweet or len(tweet) > 280: return False return True ``` ## Testing Example of a basic test suite for the TwitterTool: ```python from swarms_tools import TwitterTool import os from dotenv import load_dotenv load_dotenv() def test_twitter_tool(): # Test configuration options = { "id": "test_bot", "credentials": { "apiKey": os.getenv("TWITTER_API_KEY"), "apiSecretKey": os.getenv("TWITTER_API_SECRET_KEY"), "accessToken": os.getenv("TWITTER_ACCESS_TOKEN"), "accessTokenSecret": os.getenv("TWITTER_ACCESS_TOKEN_SECRET") } } # Initialize tool tool = TwitterTool(options) # Test available functions assert 'post_tweet' in tool.available_functions assert 'get_metrics' in tool.available_functions # Test function retrieval post_tweet = tool.get_function('post_tweet') assert callable(post_tweet) # Test metrics metrics = tool._get_metrics() assert isinstance(metrics, dict) assert 'followers' in metrics assert 'following' in metrics assert 'tweets' in metrics ``` Remember to always test your code thoroughly before deploying it in a production environment. The TwitterTool is designed to be extensible, so you can add new features and customizations as needed for your specific use case.