This commit is contained in:
trevorhobenshield
2023-03-12 15:04:39 -07:00
parent a14c01e987
commit 856f9e08ec
5 changed files with 29 additions and 24 deletions

View File

@@ -19,6 +19,12 @@ from twitter.login import login
usr, pwd = ..., ...
session = login(usr, pwd)
# DM 1 user
dm('hello world', [123], session)
# DM group of users
dm('foo bar', [123, 456, 789], session)
# create tweet with images, videos, gifs, and tagged users
r = tweet('test 123', session, media=[{'file': 'image.jpeg', 'tagged_users': [123234345456], 'alt': 'some image'}])
r = tweet('test 123', session, media=['test.jpg', 'test.png'])

View File

@@ -1,7 +1,7 @@
import sys
from textwrap import dedent
from setuptools import find_packages, setup
from textwrap import dedent
install_requires = [
"ujson",
@@ -14,7 +14,7 @@ if sys.platform != 'win32':
setup(
name="twitter-api-client",
version="0.2.0",
version="0.2.1",
description="Twitter API",
long_description=dedent('''
## The Undocumented Twitter API

View File

@@ -3170,9 +3170,7 @@ operations = {
"tweet": None
},
"requestId": None,
"target": {
"conversation_id": None
}
"target": None,
},
}
}

View File

@@ -15,7 +15,7 @@ content_settings = {
'include_ranked_timeline': True,
'include_alt_text_compose': True,
'display_sensitive_media': True,
'protected': True,
'protected': False,
'discoverable_by_email': False,
'discoverable_by_mobile_phone': False,
'allow_dms_from': 'following', ## {'all'}
@@ -61,6 +61,6 @@ follow_settings = {
}
account_search_settings = {
"optInFiltering": False,
"optInBlocking": True,
"optInFiltering": True, # filter out nsfw content
"optInBlocking": True, # filter out blocked accounts
}

View File

@@ -22,12 +22,14 @@ from .utils import find_key
try:
if get_ipython().__class__.__name__ == 'ZMQInteractiveShell':
import nest_asyncio
nest_asyncio.apply()
except:
...
if sys.platform != 'win32':
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
else:
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
@@ -303,6 +305,7 @@ def unretweet(tweet_id: int, session: Session) -> Response:
return graphql_request(tweet_id, Operation.DeleteRetweet.name, 'source_tweet_id', session)
@log(level=logging.DEBUG, info=['json'])
def get_tweets(user_id: int, session: Session) -> Response:
operation = Operation.UserTweets.name
qid = operations[operation]['queryId']
@@ -367,13 +370,10 @@ def unblock(user_id: int, session: Session) -> Response:
@log(level=logging.DEBUG, info=['text'])
def update_search_settings(session: Session, **kwargs) -> Response:
if kwargs.get('incognito'):
kwargs.pop('incognito')
settings = account_search_settings.copy()
else:
settings = {}
settings |= kwargs
def update_search_settings(session: Session, hide_blocked=False, hide_nsfw=False) -> Response:
settings = account_search_settings.copy()
settings['optInFiltering'] = hide_nsfw
settings['optInBlocking'] = hide_blocked
twid = int(session.cookies.get_dict()['twid'].split('=')[-1].strip('"'))
headers = get_auth_headers(session=session)
r = session.post(
@@ -393,13 +393,8 @@ def update_content_settings(session: Session, **kwargs) -> Response:
@param kwargs: settings to enable/disable
@return: updated settings
"""
if kwargs.get('incognito'):
kwargs.pop('incognito')
settings = content_settings.copy()
else:
settings = {}
settings |= kwargs
return api_request(settings, 'account/settings.json', session)
kwargs |= content_settings
return api_request(kwargs, 'account/settings.json', session)
def build_query(params: dict) -> str:
@@ -420,11 +415,17 @@ def stats(rest_id: int, session: Session) -> Response:
@log(level=logging.DEBUG, info=['json'])
def dm(text: str, sender: int, receiver: int, session: Session, filename: str = '') -> Response:
def dm(text: str, receivers: list[int], session: Session, filename: str = '') -> Response:
operation = Operation.useSendMessageMutation.name
qid = operations[operation]['queryId']
params = operations[operation]
params['variables']['target']['conversation_id'] = '-'.join(map(str, sorted((sender, receiver))))
## todo single DM request not needed, `participant_ids` field handles single DM request
# if len(receivers) == 1:
# params['variables']['target'] = {'conversation_id': '-'.join(map(str, sorted((sender, *receivers))))}
# else:
params['variables']['target'] = {"participant_ids": receivers}
params['variables']['requestId'] = str(uuid1(getnode())) # can be anything
url = f"https://api.twitter.com/graphql/{qid}/{operation}"
if filename: