twittertimeline

package module
v0.0.0-...-13c0fb8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2025 License: MIT Imports: 11 Imported by: 1

README

Twitter Timeline Library

Go library for loading Twitter/X user timeline without authorization.

🚀 Features

  • Get public timeline of any Twitter/X user
  • Works without authorization (automatic guest token acquisition)
  • User ID support - works with numeric Twitter User IDs
  • Username support - automatic resolution and caching
  • Proxy support - HTTP/HTTPS proxy with authentication
  • Rich content processing - HTML generation with clickable links
  • Complete metadata - pinned tweets, types (retweet/reply/quote), statistics
  • Media extraction - automatic image URL extraction
  • Entity parsing - hashtags, URLs, mentions automatically extracted
  • Library and CLI interface with simple, intuitive usage
  • Error handling and rate limit detection

📦 Installation

As a library
go get github.com/n0madic/twitter-timeline
CLI tool
git clone https://github.com/n0madic/twitter-timeline
cd twitter-timeline
go build -o twitter-timeline cmd/twitter-timeline/main.go

📖 Usage

Library Usage
package main

import (
    "fmt"
    "log"

    twittertimeline "github.com/n0madic/twitter-timeline"
)

func main() {
    // Create a new Twitter client
    client := twittertimeline.NewClient()

    // Optional: Configure proxy
    // err := client.SetProxy("http://proxy.example.com:8080")
    // err := client.SetProxy("https://user:pass@proxy.example.com:8080")

    // Option 1: Get user timeline by User ID
    tweets, err := client.GetUserTweets("1624051836033421317")
    if err != nil {
        log.Fatalf("Error getting timeline: %v", err)
    }

    // Option 2: Get user ID from username first (with caching)
    userID, err := client.GetUserID("elonmusk")
    if err != nil {
        log.Fatalf("Error getting user ID: %v", err)
    }

    tweets, err = client.GetUserTweets(userID)
    if err != nil {
        log.Fatalf("Error getting timeline: %v", err)
    }

    // Process tweets - simple flat structure!
    for _, tweet := range tweets {
        fmt.Printf("@%s: %s\n", tweet.Username, tweet.Text)
        fmt.Printf("Stats: %d likes, %d retweets, %d replies\n",
            tweet.Likes, tweet.Retweets, tweet.Replies)
        fmt.Printf("URL: %s\n", tweet.PermanentURL)

        // Tweet type indicators
        if tweet.IsPinned {
            fmt.Println("📌 Pinned")
        }
        if tweet.IsRetweet {
            fmt.Println("🔄 Retweet")
        }
        if tweet.IsReply {
            fmt.Println("💬 Reply")
        }

        // Rich content
        if len(tweet.Images) > 0 {
            fmt.Printf("Images: %v\n", tweet.Images)
        }
        if len(tweet.Hashtags) > 0 {
            fmt.Printf("Hashtags: %v\n", tweet.Hashtags)
        }
        if len(tweet.Mentions) > 0 {
            fmt.Printf("Mentions: %v\n", tweet.Mentions)
        }

        fmt.Println("---")
    }
}
CLI Usage
./twitter-timeline [OPTIONS] <user_id_or_username>
Parameters
  • user_id_or_username - Twitter user ID (numeric) or username (@handle without @)
Options
  • -proxy string - HTTP/HTTPS proxy URL (e.g., http://proxy:8080 or https://user:pass@proxy:8080)
  • -help, -h - Show help message
Examples
# Load tweets from Elon Musk
./twitter-timeline 44196397

# Load tweets using username
./twitter-timeline elonmusk

# Load tweets using proxy
./twitter-timeline -proxy http://proxy.example.com:8080 elonmusk

# Load tweets using authenticated proxy
./twitter-timeline -proxy https://user:pass@proxy.example.com:8080 elonmusk

# Using environment variables for proxy
HTTP_PROXY=http://proxy:8080 ./twitter-timeline elonmusk
HTTPS_PROXY=https://proxy:8080 ./twitter-timeline elonmusk

The CLI tool automatically checks for proxy settings in the following order:

  1. Command line -proxy flag (highest priority)
  2. HTTP_PROXY environment variable
  3. HTTPS_PROXY environment variable

🌐 Proxy Configuration

The library supports HTTP/HTTPS proxies with optional authentication:

client := twittertimeline.NewClient()

// Set proxy without authentication
err := client.SetProxy("http://proxy.example.com:8080")
if err != nil {
    log.Fatal(err)
}

// Set proxy with authentication
err = client.SetProxy("https://username:password@proxy.example.com:8080")
if err != nil {
    log.Fatal(err)
}

// Remove proxy and use direct connection
err = client.SetProxy("")
if err != nil {
    log.Fatal(err)
}

// The proxy setting applies to all subsequent requests
tweets, err := client.GetUserTweets("1624051836033421317")

When proxy is changed or removed:

  • Cookie jar is automatically reset
  • Guest token is cleared and will be re-acquired
  • All subsequent requests will use the new setting (proxy or direct)

🔍 How to find User ID

To use the library or CLI, you can use either the numeric User ID or username of the Twitter account.

Getting User ID from username:
client := twittertimeline.NewClient()

// Using GetUserID (returns user ID with caching)
userID, err := client.GetUserID("elonmusk")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("User ID: %s\n", userID)

// The library automatically caches user IDs for 24 hours
// to improve performance on subsequent requests
Alternative methods to find User IDs:
  • Twitter's web interface (inspect profile elements)
  • Third-party services like tweeterid.com

📊 Tweet Structure

The library returns a clean, flat Tweet structure with all data easily accessible:

type Tweet struct {
    // Basic Information
    ID           string   // Tweet ID
    Text         string   // Tweet text content
    HTML         string   // HTML formatted content with clickable links
    CreatedAt    string   // Creation timestamp
    PermanentURL string   // Direct link to tweet (https://x.com/user/status/id)

    // Author Information
    Username     string   // @username
    UserID       string   // User ID

    // Statistics
    Likes        int      // Like count
    Retweets     int      // Retweet count
    Replies      int      // Reply count

    // Tweet Types
    IsPinned     bool     // Pinned to profile
    IsRetweet    bool     // Is a retweet
    IsQuoted     bool     // Is a quote tweet
    IsReply      bool     // Is a reply

    // Rich Content
    Images       []string // Image URLs
    Hashtags     []string // Hashtag texts (without #)
    URLs         []URL    // Expanded URL information
    Mentions     []string // Mentioned usernames (without @)
}
Key Benefits:
  • No nested structures - direct field access like tweet.Text instead of tweet.Legacy.FullText
  • Rich HTML content - automatically generated with clickable links for URLs, hashtags, mentions
  • Complete metadata - all useful information extracted and easily accessible
  • Type detection - automatic identification of retweets, replies, quotes, pinned tweets

⚙️ How it works

  1. Guest Token Acquisition: Automatically requests guest token from Twitter API
  2. GraphQL Request: Creates properly formatted request with required parameters and headers
  3. JSON Parsing: Parses complex Twitter API response into internal TweetResult structures
  4. Content Processing: Extracts images, generates permanent URLs, creates HTML with clickable links
  5. Structure Conversion: Converts internal TweetResult to clean, flat Tweet structures
  6. Result Delivery: Returns simple []Tweet array with all useful data easily accessible

⚠️ Limitations

  • Works only with public accounts
  • Guest token has rate limiting
  • Username resolution may have occasional issues (use User ID when possible)
  • Twitter may change API without notice
  • Package may require updates when API changes

🔧 Technical details

API Endpoints
  • UserTweets: https://api.x.com/graphql/***/UserTweets
  • UserByScreenName: https://api.x.com/graphql/***/UserByScreenName
  • Guest Token: https://api.x.com/1.1/guest/activate.json
Headers
  • Browser simulation (User-Agent)
  • Authorization via Bearer token
  • Guest token for unauthenticated access
Error handling
  • HTTP timeout (30 seconds)
  • JSON response validation
  • Status code checking

🛠️ Requirements

  • Go 1.18 or higher
  • Internet connection
  • Public access to target account

📝 License

MIT License - see LICENSE file for details.

This project is intended for educational purposes and public data analysis. Use responsibly and in accordance with Twitter/X terms of service.

Documentation

Overview

Package twittertimeline provides a client for accessing Twitter/X API without authorization

Index

Constants

View Source
const (
	BearerToken = "AAAAAAAAAAAAAAAAAAAAAFQODgEAAAAAVHTp76lzh3rFzcHbmHVvQxYYpTw%3DckAlMINMjmCwxUcaXbAN4XqJVdgMJaHqNOFgPMK0zN1qLqLQCF"
	BaseURL     = "https://api.x.com"
	UserAgent   = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36"

	// GraphQL API endpoints
	UserByScreenNamePath = "/graphql/x3RLKWW1Tl7JgU7YtGxuzw/UserByScreenName"
	UserTweetsPath       = "/graphql/bbmwRjH_roUoWsvbgAJY9g/UserTweets"
)

Constants for Twitter API

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client represents a client for working with Twitter API

func NewClient

func NewClient() *Client

NewClient creates a new Twitter client

func (*Client) GetGuestToken

func (c *Client) GetGuestToken() error

GetGuestToken gets guest token from Twitter API

func (*Client) GetUserByScreenName

func (c *Client) GetUserByScreenName(screenName string) (*UserResponse, error)

GetUserByScreenName gets user information by screen_name (username)

func (*Client) GetUserID

func (c *Client) GetUserID(username string) (string, error)

GetUserID gets user ID by username with caching for frequently requested users

func (*Client) GetUserTweets

func (c *Client) GetUserTweets(userID string) ([]Tweet, error)

GetUserTweets gets user timeline by user ID and returns a list of tweets

func (*Client) SetProxy

func (c *Client) SetProxy(proxyURL string) error

SetProxy sets HTTP/HTTPS proxy for the client Example: client.SetProxy("http://proxy.example.com:8080") Example: client.SetProxy("https://user:pass@proxy.example.com:8080") To remove proxy: client.SetProxy("")

type GuestTokenResponse

type GuestTokenResponse struct {
	GuestToken string `json:"guest_token"`
}

Structures for parsing JSON responses

type MediaEntity

type MediaEntity struct {
	MediaURLHTTPS string `json:"media_url_https"`
	Type          string `json:"type"`
}

type TimelineEntry

type TimelineEntry struct {
	EntryID string `json:"entryId"`
	Content struct {
		EntryType   string `json:"entryType"`
		ItemContent *struct {
			TweetResults struct {
				Result TweetResult `json:"result"`
			} `json:"tweet_results"`
		} `json:"itemContent"`
		Items *[]struct {
			EntryID string `json:"entryId"`
			Item    struct {
				ItemContent struct {
					TweetResults struct {
						Result TweetResult `json:"result"`
					} `json:"tweet_results"`
				} `json:"itemContent"`
			} `json:"item"`
		} `json:"items"`
	} `json:"content"`
}

type TimelineResponse

type TimelineResponse struct {
	Data struct {
		User struct {
			Result struct {
				Timeline struct {
					Timeline struct {
						Instructions []struct {
							Type    string          `json:"type"`
							Entries []TimelineEntry `json:"entries"`
							Entry   *TimelineEntry  `json:"entry"`
						} `json:"instructions"`
					} `json:"timeline"`
				} `json:"timeline"`
			} `json:"result"`
		} `json:"user"`
	} `json:"data"`
}

type Tweet

type Tweet struct {
	// Basic information
	ID           string // RestID
	Text         string // FullText
	HTML         string // HTML version with links
	CreatedAt    string // Creation date
	PermanentURL string // Permanent link to tweet

	// Author
	Username string // Username (@username)
	UserID   string // User ID

	// Statistics (top level)
	Likes    int // FavoriteCount
	Retweets int // RetweetCount
	Replies  int // ReplyCount

	// Tweet types (boolean flags as is)
	IsPinned  bool // Whether tweet is pinned
	IsRetweet bool // Retweet
	IsQuoted  bool // Quote
	IsReply   bool // Reply

	// Media and links
	Images   []string // Image URLs
	Hashtags []string // Hashtags (text only)
	URLs     []URL    // Links
	Mentions []string // User mentions (username only)
}

Public API structures

type TweetResult

type TweetResult struct {
	RestID string `json:"rest_id"`
	Core   struct {
		UserResults struct {
			Result struct {
				Core struct {
					ScreenName string `json:"screen_name"`
				} `json:"core"`
			} `json:"result"`
		} `json:"user_results"`
	} `json:"core"`
	Legacy struct {
		FullText             string `json:"full_text"`
		CreatedAt            string `json:"created_at"`
		UserIDStr            string `json:"user_id_str"`
		InReplyToStatusIDStr string `json:"in_reply_to_status_id_str"`
		InReplyToUserIDStr   string `json:"in_reply_to_user_id_str"`
		InReplyToScreenName  string `json:"in_reply_to_screen_name"`
		IsQuoteStatus        bool   `json:"is_quote_status"`
		QuotedStatusIDStr    string `json:"quoted_status_id_str"`
		RetweetedStatusIDStr string `json:"retweeted_status_id_str"`
		Entities             struct {
			Hashtags []struct {
				Text string `json:"text"`
			} `json:"hashtags"`
			Urls []struct {
				URL         string `json:"url"`
				ExpandedURL string `json:"expanded_url"`
				DisplayURL  string `json:"display_url"`
			} `json:"urls"`
			Media []MediaEntity `json:"media"`
		} `json:"entities"`
		ExtendedEntities struct {
			Media []MediaEntity `json:"media"`
		} `json:"extended_entities"`
		FavoriteCount int `json:"favorite_count"`
		RetweetCount  int `json:"retweet_count"`
		ReplyCount    int `json:"reply_count"`
	} `json:"legacy"`
	RetweetedStatusResult struct {
		Result *TweetResult `json:"result"`
	} `json:"retweeted_status_result"`
	IsPinned  bool     `json:"-"` // Not from JSON, set by code
	IsRetweet bool     `json:"-"` // Not from JSON, determined by code
	IsQuoted  bool     `json:"-"` // Not from JSON, determined by code
	IsReply   bool     `json:"-"` // Not from JSON, determined by code
	Images    []string `json:"-"` // Not from JSON, extracted from media
	URL       string   `json:"-"` // Not from JSON, permanent URL to tweet
	HTML      string   `json:"-"` // Not from JSON, HTML formatted content
}

type URL

type URL struct {
	Short    string // t.co ссылка
	Expanded string // Полная ссылка
	Display  string // Отображаемый текст
}

type UserInfo

type UserInfo struct {
	Name           string `json:"name"`
	ScreenName     string `json:"screen_name"`
	Description    string `json:"description"`
	FollowersCount int    `json:"followers_count"`
	FriendsCount   int    `json:"friends_count"`
	StatusesCount  int    `json:"statuses_count"`
}

type UserResponse

type UserResponse struct {
	Data struct {
		User struct {
			Result struct {
				RestID string `json:"rest_id"`
				ID     string `json:"id"`
				Legacy struct {
					UserInfo `json:"legacy"`
				} `json:"legacy"`
				Core struct {
					Name       string `json:"name"`
					ScreenName string `json:"screen_name"`
				} `json:"core"`
			} `json:"result"`
		} `json:"user"`
	} `json:"data"`
	Errors []struct {
		Message string `json:"message"`
		Code    int    `json:"code"`
	} `json:"errors"`
}

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL