Skip to content

Instantly share code, notes, and snippets.

@HeIIow2
Created October 27, 2022 18:54
Show Gist options
  • Save HeIIow2/78b5c8d2b88d000b042012aa36401357 to your computer and use it in GitHub Desktop.
Save HeIIow2/78b5c8d2b88d000b042012aa36401357 to your computer and use it in GitHub Desktop.
how to call the twitter api
import datetime
import json
import mysql.connector
from src.websites.website import Website
from src.user import User
"""
OAuth2 - BEARER Token - https://www.devopsschool.com/blog/what-is-bearer-token-and-how-it-works/
Das Bearer Token ist im grunde ein Token, dass man an einen Server schicken kann, sodas dieser die ein temporäres
Authentifizierungstoken für API's zurückschicken kann.
Meist bekommt jeder der Zugang zu einer API, die mit OAuth2 gesichert ist ein Individuelles Bearer Token, und kann sich
damit dann eine Limitierte Anzahl an Zugangstokens generieren, die auf ihn zurückzuführen sind.
In diesem Fall war aber ein Bearer Token in den Tiefen des Twitter source code versteckt, mit dem man sich unendlich
viele guest Zugangs Tokens für die Twitter OAuth2 API generieren kann. Diese können auch nicht zurückverfolgt werden, da
sie dem Zweck dienen daten ohne einen Account zu haben (also öffentlich) mit Daten zu beliefern.
Vermutlich, das ist jedoch ungetestet haben diese Zugangstokens sehr limitierte Rechte.
"""
BEARER_TOKEN = "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA"
"""
Wenn das BEARER TOKEN ungültig ist, dann gehe auf diesen Link: https://abs.twimg.com/responsive-web/client-web/main.f79e7a58.js
und suche in dem File mit strg + f nach ",s="
Es sollte mehrere suchergebnisse geben, dann einfach das naheliegendste nehmen.
"""
def get_from_dict(data: dict, key: str):
if key in data:
if data[key] == "":
return None
return data[key]
return None
class Twitter(Website):
def __init__(self, db: mysql.connector.connect, user: User, account_id: int, update=True):
super().__init__(db, user, account_id, update=update)
def fetch_from_websites(self):
self.session.headers["authorization"] = f"Bearer {BEARER_TOKEN}"
self.session.headers["Origin"] = "https://twitter.com"
# get the guest token and authenticate with it
url = "https://api.twitter.com/1.1/guest/activate.json"
r = self.session.post(url)
if r.status_code != 200:
raise ConnectionError(r.text)
guest_token_key = "guest_token"
token_data = r.json()
if guest_token_key not in token_data:
raise Exception(f"{r.json()} doesn't contain a guest token, which key is {guest_token_key}")
self.session.headers["x-guest-token"] = token_data[guest_token_key]
# the username has to be lowercase, because urls are case-insensitive, the system twitter uses isn't though
api_endpoint = 'https://twitter.com/i/api/graphql/mCbpQvZAw6zu_4PvuAUVVQ/UserByScreenName?variables={"screen_name":"' + self.username.lower() + '","withSafetyModeUserFields":true,"withSuperFollowsUserFields":true}'
r = self.session.get(api_endpoint)
if r.status_code != 200:
raise ConnectionError(f"{r.status_code}: {r.text}")
"""
self.sys_id: data.user.result.rest_id
sonst sind alle anderen interesannten daten in: data.user.result.legacy
das wird ab jetzt der root pfad
self.joined_at: created_at
date format example: "Mon Apr 11 15:50:52 +0000 2016"
self.avatar_url:
wenn "default_profile_image" true ist, dan wird der avatar ignoriert, sonst ist die url dort:
"profile_image_url_https"
self.flair: "description"
self.homepage: "url" # need to get the redirected page
self.clear_name: "name"
"""
root = r.json()["data"]["user"]["result"]
self.sys_id = root["rest_id"]
root = root["legacy"]
timestamp = get_from_dict(root, "created_at")
if timestamp is not None:
# Mon Apr 11 15:50:52 +0000 2016
time_format = "%a %b %d %H:%M:%S %z %Y"
self.joined_at = datetime.datetime.strptime(timestamp, time_format)
if not root["default_profile_image"]:
self.avatar_url = get_from_dict(root, "profile_image_url_https")
self.flair = get_from_dict(root, "description")
if "url" in root:
r = self.session.get(root["url"])
self.homepage = r.url
self.clear_name = get_from_dict(root, "name")
def get_page(db: mysql.connector.connect, user: User, account_id: int, update=True):
return Twitter(db, user, account_id, update=update)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment