Skip to content

Owen3H/twittxr

Repository files navigation

Twittxr

A simple wrapper library around the Twitter/X Syndication API.
Inspired by: zedeus/nitter#919 (comment)

Codacy Badge Build Status Badge Discord

Overview

The Syndication API is what is used by embedded widgets and its ease-of-use brings some notable limitations.
Twittxr is best suited for setting up a user feed or getting a single tweet, it will not replace a fully fledged scraper/client.

As you may know, Twitter/X ended free access to its API, making IFTTT and other services obsolete for many users.
This library was specifically made to combat this, so I could continue to send new Tweets to a discord channel :)

✅ Features

  • Can include retweets and/or replies by the user.
  • Option to pass cookie object or string to get Sensitive/NSFW Tweets.
  • Ability to pass a Puppeteer page, bypassing potential API auth issues.
  • Works in and out of Node by using the fast request method from Undici, falling back to native fetch in the browser.
  • Intuitive syntax and included type definitions.

❌ Limitations

  • When getting a Timeline, only up to 100 Tweets can be returned. (May be 20 in some cases)

Authentication

Twitter is now known to require a cookie to return any data!
I strongly advise you pass the cookie parameter in all of your requests.

How do I get my session cookie?

  1. Click here -> Right click -> Inspect Element

  2. Refresh the page -> Select the Network tab -> Find the request with the document type.

  3. Under Request Headers, locate the key named Cookie and copy the whole string.

  4. Store this in an .env file like so:

    TWITTER_COOKIE="yourCookieStringHere"

Installation

bun add twittxr

Optionally, you can install puppeteer >=16 to use as a fallback on failed requests.
This can potentially avoid issues with Cloudflare. Ex: "403 Forbidden".

bun add twittxr puppeteer

Usage

import { Timeline, Tweet } from 'twittxr' // ESM
const { Timeline, Tweet } = require('twittxr') // CommonJS

Get a single Tweet

// Does not return the same type as Timeline.get()
const tweet = await Tweet.get('1674865731136020505')

Get a user Timeline

// The retweets and replies default to false.
const timelineWithRts = await Timeline.get('elonmusk', { 
  cookie: process.env.TWITTER_COOKIE,
  retweets: true,
  replies: false, // This is the user's replies, not replies to their Tweets.
})

Using Puppeteer

Note By default, Puppeteer will be used as a fallback for failed requests - if installed.
However, it is possible to solely use Puppeteer by calling await usePuppeteer().

import { Timeline } from 'twittxr'
No config
// Launches a basic headless browser & automatically closes the page.
await Timeline.usePuppeteer()
const tweets = await Timeline.get('elonmusk', { 
  cookie: process.env.TWITTER_COOKIE
})
With custom browser
const puppeteer = require('puppeteer-extra')

// Use plugins if desired
puppeteer.use(ExamplePlugin())

const browser = await puppeteer.launch({ headless: true })

// Creates a new page and closes it automatically after every .get() call
await Timeline.usePuppeteer({ browser, autoClose: true })
const tweets = await Timeline.get('elonmusk', { 
  cookie: process.env.TWITTER_COOKIE
})
With page
const puppeteer = require('puppeteer')
const browser = await puppeteer.launch({ headless: true })
const page = await browser.newPage()

// Pass the page, but do not automatically close it.
await Timeline.usePuppeteer({ page, autoClose: false })
const tweets = await Timeline.get('elonmusk', { 
  cookie: process.env.TWITTER_COOKIE
})

await page.goto('https://google.com') // Continue to manipulate the page.
await page.close() // Close the page manually.

To stop using Puppeteer at any point, you can simply call:

Timeline.disablePuppeteer()

Disclaimer

You must use this library at your own discretion!
I will not be held accountable for any outcomes that may result from its usage, including and not limited to:

  • Banning/Suspension of your Twitter/X account.
  • Lawsuits, fines and other Twitter/X related legal disputes.
  • Hacking of network and/or account when providing a proxy or exposing cookies.