from __future__ import annotations import asyncio import logging from yuxi.channel.extensions.twitter.auth import create_tweepy_client logger = logging.getLogger(__name__) class TwitterSocial: @staticmethod async def like_tweet(account: dict, tweet_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: await asyncio.to_thread(client.like, user_id=user_id, tweet_id=tweet_id) return True except Exception as e: logger.warning("Twitter like error: %s", e) return False @staticmethod async def unlike_tweet(account: dict, tweet_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: await asyncio.to_thread(client.unlike, user_id=user_id, tweet_id=tweet_id) return True except Exception as e: logger.warning("Twitter unlike error: %s", e) return False @staticmethod async def retweet(account: dict, tweet_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: await asyncio.to_thread(client.retweet, user_id=user_id, tweet_id=tweet_id) return True except Exception as e: logger.warning("Twitter retweet error: %s", e) return False @staticmethod async def unretweet(account: dict, tweet_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: await asyncio.to_thread( client.unretweet, user_id=user_id, tweet_id=tweet_id ) return True except Exception as e: logger.warning("Twitter unretweet error: %s", e) return False @staticmethod async def follow_user(account: dict, target_user_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: await asyncio.to_thread( client.follow_user, source_user_id=user_id, target_user_id=target_user_id, ) return True except Exception as e: logger.warning("Twitter follow error: %s", e) return False @staticmethod async def unfollow_user(account: dict, target_user_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: await asyncio.to_thread( client.unfollow_user, source_user_id=user_id, target_user_id=target_user_id, ) return True except Exception as e: logger.warning("Twitter unfollow error: %s", e) return False @staticmethod async def bookmark_tweet(account: dict, tweet_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: await asyncio.to_thread(client.bookmark, user_id=user_id, tweet_id=tweet_id) return True except Exception as e: logger.warning("Twitter bookmark error: %s", e) return False @staticmethod async def unbookmark_tweet(account: dict, tweet_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: await asyncio.to_thread( client.unbookmark, user_id=user_id, tweet_id=tweet_id ) return True except Exception as e: logger.warning("Twitter unbookmark error: %s", e) return False @staticmethod async def get_following( account: dict, *, max_results: int = 100, ) -> list[dict] | None: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: response = await asyncio.to_thread( client.get_users_following, id=user_id, max_results=max_results, user_fields=["id", "username", "name", "profile_image_url"], ) return response.get("data", []) except Exception as e: logger.warning("Twitter get_following error: %s", e) return None @staticmethod async def get_followers( account: dict, *, max_results: int = 100, ) -> list[dict] | None: client = create_tweepy_client(account) user_id = account.get("user_id", "") try: response = await asyncio.to_thread( client.get_users_followers, id=user_id, max_results=max_results, user_fields=["id", "username", "name", "profile_image_url"], ) return response.get("data", []) except Exception as e: logger.warning("Twitter get_followers error: %s", e) return None @staticmethod async def get_liking_users( account: dict, tweet_id: str, *, max_results: int = 100, ) -> list[dict] | None: client = create_tweepy_client(account) try: response = await asyncio.to_thread( client.get_liking_users, id=tweet_id, max_results=max_results, user_fields=["id", "username", "name"], ) return response.get("data", []) except Exception as e: logger.warning("Twitter get_liking_users error: %s", e) return None @staticmethod async def get_retweeted_by( account: dict, tweet_id: str, *, max_results: int = 100, ) -> list[dict] | None: client = create_tweepy_client(account) try: response = await asyncio.to_thread( client.get_retweeters, id=tweet_id, max_results=max_results, user_fields=["id", "username", "name"], ) return response.get("data", []) except Exception as e: logger.warning("Twitter get_retweeted_by error: %s", e) return None @staticmethod async def get_user_liked_tweets( account: dict, user_id: str | None = None, *, max_results: int = 100, ) -> list[dict] | None: client = create_tweepy_client(account) uid = user_id or account.get("user_id", "") if not uid: return None try: response = await asyncio.to_thread( client.get_liked_tweets, id=uid, max_results=max_results, tweet_fields=[ "id", "text", "created_at", "author_id", "public_metrics", ], expansions=["author_id"], ) return response.get("data", []) except Exception as e: logger.warning("Twitter get_user_liked_tweets error: %s", e) return None @staticmethod async def get_quote_tweets( account: dict, tweet_id: str, *, max_results: int = 100, ) -> list[dict] | None: client = create_tweepy_client(account) try: response = await asyncio.to_thread( client.get_quote_tweets, id=tweet_id, max_results=max_results, tweet_fields=[ "id", "text", "created_at", "author_id", "public_metrics", ], expansions=["author_id"], ) return response.get("data", []) except Exception as e: logger.warning("Twitter get_quote_tweets error: %s", e) return None @staticmethod async def block_user(account: dict, target_user_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") if not user_id: return False try: await asyncio.to_thread( client.block, user_id=user_id, target_user_id=target_user_id ) return True except Exception as e: logger.warning("Twitter block_user error: %s", e) return False @staticmethod async def unblock_user(account: dict, target_user_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") if not user_id: return False try: await asyncio.to_thread( client.unblock, user_id=user_id, target_user_id=target_user_id ) return True except Exception as e: logger.warning("Twitter unblock_user error: %s", e) return False @staticmethod async def mute_user(account: dict, target_user_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") if not user_id: return False try: await asyncio.to_thread( client.mute, user_id=user_id, target_user_id=target_user_id ) return True except Exception as e: logger.warning("Twitter mute_user error: %s", e) return False @staticmethod async def unmute_user(account: dict, target_user_id: str) -> bool: client = create_tweepy_client(account) user_id = account.get("user_id", "") if not user_id: return False try: await asyncio.to_thread( client.unmute, user_id=user_id, target_user_id=target_user_id ) return True except Exception as e: logger.warning("Twitter unmute_user error: %s", e) return False