Skip to main content
Using Deno in production at your company? Earn free Deno merch.
Give us feedback

deno twitter guest api

basic twitter api for deno that doesn’t require you to have a twitter account to use

use

import {
    getSearchQueryTweetsFromQuery,
    getTweetsFromURL,
    getRecommendedTweetsFromURL
} from "https://deno.land/x/deno_twitter_guest_api@v0.3.0/mod.ts";
// get most recent tweets based on twitter search query
const tweets = await getSearchQueryTweetsFromQuery("from:zhusu -filter:replies min_faves:700");
// get tweet/tweet-thread based on tweet url
const tweets = await getTweetsFromURL("https://twitter.com/zhusu/status/1516675652438851589");
// get recommended tweets based on tweet url
const tweets = await getRecommendedTweetsFromURL("https://twitter.com/zhusu/status/1516675652438851589");

use outside of deno (node/tauri/electron/browser)

since this library is in deno-flavored typescript, you must transpile the library to a javascript bundle (or you could just copy the one i made (in this repo; twitterGuestAPI.bundle.js)):

git clone https://github.com/nogira/deno-twitter-guest-api.git
cd deno-twitter-guest-api
# use file `mod.ts` as entry point to transpile library to the new file `twitterGuestAPI.bundle.js`
deno bundle ./mod.ts twitterGuestAPI.bundle.js

fetch compatibility

if the default fetch function is not compatible (e.g. if using tauri or electron), you can simply create a new fetch function wrapper and pass it into any of the functions you call.

this is the default fetch wrapper:

async function defaultFetch(
    url: string,
    method: string,
    AUTHORIZATION: string,
    xGuestToken: string = "", // must include default value of `""`
    ): Promise<any> {
    
    const headers = {
        "authorization": AUTHORIZATION,
    };
    if (xGuestToken !== "") {
        headers["x-guest-token"] = xGuestToken;
    }
    return await fetch(url, {
            "method": method, // e.g. "GET" or "POST"
            "credentials": "omit",
            "headers": headers,
        })
        .then(r => r.json())
        .catch(() => ({}));
}

this is an example for tauri:

import { fetch } from "@tauri-apps/api/http";

async function tauriFetch(
    url: string,
    method: string,
    AUTHORIZATION: string,
    xGuestToken: string = "",
    ): Promise<any> {
    
    const headers = {
        "authorization": AUTHORIZATION,
    };
    if (xGuestToken !== "") {
        headers["x-guest-token"] = xGuestToken;
    }
    return await fetch(url, {
            "method": method,
            "headers": headers,
        })
        .then(r => r.data)
        .catch(() => ({}));
}

// then call a function with the fetch function as an argument:
const  = await queryToTweets("from:ElonMusk", tauriFetch);

extra info about how to find twitter’s private APIs

for getNewGuestToken():
  open a private window and open webinspector before you go to twitter.com/search
   -> go to twitter.com
   -> in webinspector
     -> Network tab
     -> Fetch/XHR
     -> Look for one named "activate.json"

for getUnparsedTweets():
  web inspector
   -> Network tab
   -> Fetch/XHR
   -> Look for one starting with "TweetDetail?variables="

for getUnparsedSearchQueryTweets():
  web inspector
   -> Network tab
   -> Fetch/XHR
   -> Look for one starting with "adaptive.json?"


-- IT SEEMS THE TWITTER STANDARD V1.1 API ACTUALLY WORKS WITH GUEST BEARER TOKEN TOO --

https://developer.twitter.com/en/docs/twitter-api/v1

timeline:
  https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/api-reference/get-statuses-user_timeline

search:
  https://developer.twitter.com/en/docs/twitter-api/v1/tweets/search/overview