Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/owen3h/twittxr

Twitter syndication API wrapper.
https://github.com/owen3h/twittxr

api-wrapper syndication tweets twitter xdotcom

Last synced: 3 days ago
JSON representation

Twitter syndication API wrapper.

Awesome Lists containing this project

README

        

# Twittxr

A simple wrapper library around the Twitter/X Syndication API.

Inspired by: https://github.com/zedeus/nitter/issues/919#issuecomment-1616703690

[![Codacy Badge](https://app.codacy.com/project/badge/Grade/3295160336cf41108ab4b409f6baf6c5)](https://app.codacy.com/gh/Owen3H/twittxr/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![Build Status Badge](https://img.shields.io/github/actions/workflow/status/Owen3H/twittxr/main.yml)](https://github.com/Owen3H/twittxr/actions)
[![Discord](https://img.shields.io/discord/1215213004824645674?logo=discord&logoColor=white&color=blue)](https://discord.gg/64Vq7cpdGV)

## Overview
The [Syndication API](https://syndication.twitter.com/srv/timeline-profile/screen-name/elonmusk) 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](https://ifttt.com) 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](https://pptr.dev) 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](https://syndication.twitter.com/srv/timeline-profile/screen-name/elonmusk) -> 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:

```js
TWITTER_COOKIE="yourCookieStringHere"
```

## Installation
```console
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".

```console
bun add twittxr puppeteer
```

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

### Get a single Tweet
```ts
// Does not return the same type as Timeline.get()
const tweet = await Tweet.get('1674865731136020505')
```

### Get a user Timeline
```ts
// 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()`.

```js
import { Timeline } from 'twittxr'
```

No config

```js
// 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

```js
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

```js
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:
```js
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.