Created
October 27, 2022 18:54
-
-
Save HeIIow2/78b5c8d2b88d000b042012aa36401357 to your computer and use it in GitHub Desktop.
how to call the twitter api
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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