X (Twitter)

Post, reply, quote, and interact with X (Twitter) using the X API v2

X Tool enables agents to post content, reply to posts, create quote posts, manage polls, upload media, and interact with X (formerly Twitter) using the official X API v2.

python
from praisonaiagents import Agent
from praisonai_tools import XTool

agent = Agent(name="SocialAgent", tools=[XTool()])
agent.start('Post on X: "Just deployed our latest feature!"')

The user drafts a post; the agent publishes or reads timelines through the X tool.

Diagram

X Tool OAuth Flow

๐Ÿ”‘ Credentials

๐Ÿ” OAuth 1.0a

๐Ÿฆ X API v2

๐Ÿ“ค Post/Reply/Quote

Quick Start

Get started with X Tool in three simple steps.

  1. Simple Post
    python
    from praisonai_tools import post_to_x
    
    # Simple post
    result = post_to_x("Shipping a new feature today! ๐Ÿš€")
    print(f"Posted: {result['url']}")
  2. Function Helper
    python
    from praisonai_tools import post_to_x, reply_to_x, quote_x_post
    
    # Post with media
    post_result = post_to_x("Check out this image!", media_paths=["image.jpg"])
    post_id = post_result['data']['id']
    
    # Reply to post
    reply_to_x(post_id, "Great update!")
    
    # Quote tweet
    quote_x_post(post_id, "This is exactly what we needed!")
  3. Agent Usage
    python
    from praisonaiagents import Agent
    from praisonai_tools import post_to_x
    
    agent = Agent(
        name="social_poster",
        llm="gpt-4o-mini",
        instructions="When asked to post on X, call post_to_x and return the URL.",
        tools=[post_to_x],
    )
    
    agent.start('Post on X: "Just deployed our latest feature!"')

Installation

Install the required packages to get started with X Tool.

bash
pip install praisonai-tools requests-oauthlib

How It Works

X Tool supports three authentication modes for different use cases.

ModeUse CaseCan PostCan ReadSetup Required
OAuth 1.0a UserFull access (recommended)โœ…โœ…X Developer Portal
OAuth 2.0 User BearerRead-only accessโŒโœ…X Developer Portal
App-only BearerPublic data onlyโŒโœ…X Developer Portal

OAuth 1.0a Setup (Recommended for Posting)

  1. Create X Developer Account

    Visit developer.x.com and create a developer account.

  2. Create App and Get Keys
    1. Create a new app in the X Developer Portal
    2. Generate API Key and API Key Secret
    3. Enable OAuth 1.0a with read/write permissions
    4. Generate Access Token and Access Token Secret
  3. Configure Environment Variables
    .env
    X_API_KEY=
    X_API_SECRET=
    X_ACCESS_TOKEN=
    X_ACCESS_SECRET=
    Export
    export X_API_KEY=
    export X_API_SECRET=
    export X_ACCESS_TOKEN=
    export X_ACCESS_SECRET=
  4. Test Authentication
    python
    from praisonai_tools import XTool
    
    # Test connection
    x_tool = XTool()
    user_info = x_tool.get_user("your_username")
    print(f"Connected as: {user_info['data']['name']}")

Configuration Options

Configure X Tool with your API credentials and preferences.

OptionTypeDefaultDescription
api_keystrNoneX API key (from env var X_API_KEY if not provided)
api_key_secretstrNoneX API secret (from env var X_API_SECRET if not provided)
access_tokenstrNoneOAuth access token (from env var X_ACCESS_TOKEN if not provided)
access_token_secretstrNoneOAuth access token secret (from env var X_ACCESS_SECRET if not provided)

XTool Class

python
from praisonai_tools import XTool

x_tool = XTool(
    api_key="your_api_key",               # Optional if env var set
    api_key_secret="your_api_secret",     # Optional if env var set
    access_token="your_access_token",     # Optional if env var set
    access_token_secret="your_access_secret"  # Optional if env var set
)

XTool.post() Parameters

text str

The text content of the post (up to 280 characters for basic accounts)

reply_to str

ID of post to reply to

quote_tweet_id str

ID of post to quote (Enterprise plan required)

media_ids List[str]

List of uploaded media IDs to attach

media_paths List[str]

List of local file paths to upload and attach

poll_options List[str]

Poll choices (2-4 options, each up to 25 chars)

poll_duration_minutes int

Poll duration in minutes (5-10080, default 24 hours)

Function Helpers

FunctionDescriptionReturns
post_to_x(text, **kwargs)Create a new postPost ID and URL
reply_to_x(post_id, text, **kwargs)Reply to a postReply ID and URL
quote_x_post(post_id, text, **kwargs)Quote a postQuote ID and URL
delete_x_post(post_id)Delete a postSuccess status
search_x(query, **kwargs)Search postsSearch results
get_x_user(username)Get user infoUser data

Common Patterns

Simple Post

python
from praisonai_tools import post_to_x

# Basic text post
result = post_to_x("Hello X! ๐Ÿ‘‹")
print(f"Post URL: {result['url']}")

Post with Media

python
from praisonai_tools import post_to_x

# Post with image
result = post_to_x(
    text="Check out our new feature! ๐Ÿš€",
    media_paths=["screenshot.png"]
)
print(f"Posted with media: {result['url']}")

Thread Creation

python
from praisonai_tools import post_to_x, reply_to_x

# Create thread
main_post = post_to_x("๐Ÿงต Thread about AI agents: 1/3")

reply_1 = reply_to_x(
    main_post['data']['id'], 
    "AI agents can automate social media posting... 2/3"
)

reply_2 = reply_to_x(
    reply_1['data']['id'],
    "The future is autonomous content creation! 3/3"
)

Poll Creation

python
from praisonai_tools import post_to_x

# Create poll
result = post_to_x(
    text="What's your favorite AI model? ๐Ÿค–",
    poll_options=["GPT-4", "Claude", "Gemini", "Llama"],
    poll_duration_minutes=1440  # 24 hours
)

Agent Integration Patterns

Social Media Manager

python
from praisonaiagents import Agent
from praisonai_tools import post_to_x, reply_to_x, search_x

agent = Agent(
    name="social_manager",
    llm="gpt-4o",
    instructions="""You manage social media presence on X. 
    - Post engaging content
    - Reply to mentions
    - Share updates about our products""",
    tools=[post_to_x, reply_to_x, search_x]
)

# Schedule posts
agent.start("Post about our new AI feature launch")

Customer Support Bot

python
from praisonaiagents import Agent
from praisonai_tools import search_x, reply_to_x

support_agent = Agent(
    name="support_bot",
    instructions="""Monitor mentions and provide helpful responses.
    Be professional and solution-oriented.""",
    tools=[search_x, reply_to_x]
)

# Monitor and respond
support_agent.start("Check for mentions of our brand and respond helpfully")

Content Curator

python
from praisonaiagents import Agent
from praisonai_tools import search_x, quote_x_post, post_to_x

curator = Agent(
    name="content_curator",
    instructions="""Find and share interesting tech content.
    Add thoughtful commentary when quoting posts.""",
    tools=[search_x, quote_x_post, post_to_x]
)

curator.start("Find and share interesting AI news with commentary")

Authentication Flow Diagram

Diagram
๐Ÿฆ X API v2๐Ÿ”ง X Tool๐Ÿค– AgentUser๐Ÿฆ X API v2๐Ÿ”ง X Tool๐Ÿค– AgentUserOAuth 1.0a for postingBearer token for reading“Post on X”post_to_x(text)OAuth 1.0a RequestResponse + Post ID{id, url}“Posted: twitter.com/i/status/123”

Best Practices

Use OAuth 1.0a for Posting

OAuth 1.0a provides full posting capabilities, while app-only bearer tokens are read-only.

python
# โœ… Use OAuth 1.0a for posting  
x_tool = XTool(
    api_key="key",
    api_key_secret="secret", 
    access_token="token",
    access_token_secret="token_secret"
)
Handle Rate Limits Gracefully

Implement exponential backoff to handle rate limits (300 posts per 15 minutes).

python
import time
from praisonai_tools import post_to_x

def post_with_retry(text, max_retries=3):
    for attempt in range(max_retries):
        try:
            return post_to_x(text)
        except Exception as e:
            if attempt < max_retries - 1:
                time.sleep(2 ** attempt)  # Exponential backoff
            else:
                raise
Manage Character Limits

Split long content into threaded posts for better readability.

python
from praisonai_tools import post_to_x, reply_to_x

def safe_post(text, max_chunk=270):
    if len(text) <= 280:
        return post_to_x(text)
    # Split into thread; each chunk leaves room for " N/M" suffix
    chunks = [text[i:i+max_chunk] for i in range(0, len(text), max_chunk)]
    total = len(chunks)
    first = post_to_x(f"{chunks[0]} 1/{total}")
    prev_id = first['data']['id']
    for i, chunk in enumerate(chunks[1:], start=2):
        reply = reply_to_x(prev_id, f"{chunk} {i}/{total}")
        prev_id = reply['data']['id']
    return first
Secure Credential Management

Store credentials in environment variables rather than hardcoding them.

bash
# .env file
X_API_KEY=your_api_key
X_API_SECRET=your_api_secret
X_ACCESS_TOKEN=your_access_token
X_ACCESS_SECRET=your_access_secret

Premium Features

Quote Posts:

python
# Available on all plans via X API v2
quote_x_post("1234567890", "Adding my thoughts on this important topic...")

Extended Posts:

python
# Premium accounts can post up to 25,000 characters
long_post = "A" * 5000  # Long content
post_to_x(long_post)  # Works with Premium

Related