habulaj commited on
Commit
a527503
·
verified ·
1 Parent(s): 95d465d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -29
app.py CHANGED
@@ -36,13 +36,13 @@ TWEETHUNTER_COOKIES = "_ga_F7Q3BYCL54=GS2.1.s1767919580$o2$g1$t1767919660$j60$l0
36
  async def get_tweet_data(tweet_id: str):
37
  """
38
  Busca dados completos de um tweet combinando duas APIs:
39
- - react-tweet.vercel.app: metadados (likes, comentários, verified_type, etc.)
40
- - tweethunter.io: texto completo do tweet
41
  """
42
  try:
43
  # URLs das duas APIs
44
  metadata_url = f"https://react-tweet.vercel.app/api/tweet/{tweet_id}"
45
- fulltext_url = f"https://tweethunter.io/api/thread?tweetId={tweet_id}"
46
 
47
  tweethunter_headers = {
48
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0",
@@ -58,49 +58,59 @@ async def get_tweet_data(tweet_id: str):
58
  # Fazer as duas requisições em paralelo
59
  import asyncio
60
  metadata_task = client.get(metadata_url, timeout=10.0)
61
- fulltext_task = client.get(fulltext_url, headers=tweethunter_headers, timeout=10.0)
62
 
63
- metadata_response, fulltext_response = await asyncio.gather(
64
  metadata_task,
65
- fulltext_task,
66
  return_exceptions=True
67
  )
68
 
69
- # Processar resposta de metadados (obrigatória)
70
- if isinstance(metadata_response, Exception):
71
- raise HTTPException(status_code=500, detail=f"Erro ao buscar metadados: {str(metadata_response)}")
72
 
73
- if metadata_response.status_code != 200:
74
  raise HTTPException(
75
- status_code=metadata_response.status_code,
76
- detail=f"API de metadados retornou {metadata_response.status_code}"
77
  )
78
 
79
- metadata = metadata_response.json()
80
 
81
- # Processar resposta de texto completo (opcional - fallback para texto truncado)
82
- fulltext_html = None
83
- if not isinstance(fulltext_response, Exception) and fulltext_response.status_code == 200:
 
 
 
 
 
 
 
84
  try:
85
- fulltext_data = fulltext_response.json()
86
- if isinstance(fulltext_data, list) and len(fulltext_data) > 0:
87
- fulltext_html = fulltext_data[0].get("textHtml")
 
 
 
 
 
 
 
88
  except:
89
  pass
90
 
91
- # Processar dados
92
- data = metadata.get("data", {})
93
-
94
  # Remover "_normal" da URL do avatar para obter imagem em alta resolução
95
- if "user" in data and "profile_image_url_https" in data["user"]:
96
- avatar_url = data["user"]["profile_image_url_https"]
97
- # Remover _normal antes da extensão (ex: _normal.jpg -> .jpg)
98
- data["user"]["profile_image_url_https"] = avatar_url.replace("_normal.", ".")
99
 
100
- # Combinar os dados
101
  result = {
102
- "data": data,
103
- "fullTextHtml": fulltext_html
104
  }
105
 
106
  return result
 
36
  async def get_tweet_data(tweet_id: str):
37
  """
38
  Busca dados completos de um tweet combinando duas APIs:
39
+ - tweethunter.io: dados principais (texto, likes, retweets, etc.)
40
+ - react-tweet.vercel.app: apenas verificação (is_blue_verified, verified_type, etc.)
41
  """
42
  try:
43
  # URLs das duas APIs
44
  metadata_url = f"https://react-tweet.vercel.app/api/tweet/{tweet_id}"
45
+ tweethunter_url = f"https://tweethunter.io/api/thread?tweetId={tweet_id}"
46
 
47
  tweethunter_headers = {
48
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:146.0) Gecko/20100101 Firefox/146.0",
 
58
  # Fazer as duas requisições em paralelo
59
  import asyncio
60
  metadata_task = client.get(metadata_url, timeout=10.0)
61
+ tweethunter_task = client.get(tweethunter_url, headers=tweethunter_headers, timeout=10.0)
62
 
63
+ metadata_response, tweethunter_response = await asyncio.gather(
64
  metadata_task,
65
+ tweethunter_task,
66
  return_exceptions=True
67
  )
68
 
69
+ # Processar resposta do TweetHunter (fonte principal - obrigatória)
70
+ if isinstance(tweethunter_response, Exception):
71
+ raise HTTPException(status_code=500, detail=f"Erro ao buscar dados do TweetHunter: {str(tweethunter_response)}")
72
 
73
+ if tweethunter_response.status_code != 200:
74
  raise HTTPException(
75
+ status_code=tweethunter_response.status_code,
76
+ detail=f"API do TweetHunter retornou {tweethunter_response.status_code}"
77
  )
78
 
79
+ tweethunter_data = tweethunter_response.json()
80
 
81
+ # Validar se retornou array com dados
82
+ if not isinstance(tweethunter_data, list) or len(tweethunter_data) == 0:
83
+ raise HTTPException(status_code=404, detail="Tweet não encontrado no TweetHunter")
84
+
85
+ # Pegar o primeiro tweet do array
86
+ tweet_data = tweethunter_data[0]
87
+
88
+ # Processar resposta de verificação (opcional)
89
+ verification_data = {}
90
+ if not isinstance(metadata_response, Exception) and metadata_response.status_code == 200:
91
  try:
92
+ metadata = metadata_response.json()
93
+ user_data = metadata.get("data", {}).get("user", {})
94
+
95
+ # Extrair apenas os campos de verificação necessários
96
+ verification_data = {
97
+ "is_blue_verified": user_data.get("is_blue_verified", False),
98
+ "profile_image_shape": user_data.get("profile_image_shape", "Circle"),
99
+ "verified": user_data.get("verified", False),
100
+ "verified_type": user_data.get("verified_type")
101
+ }
102
  except:
103
  pass
104
 
 
 
 
105
  # Remover "_normal" da URL do avatar para obter imagem em alta resolução
106
+ avatar_url = tweet_data.get("avatarUrl", "")
107
+ if avatar_url:
108
+ tweet_data["avatarUrl"] = avatar_url.replace("_normal.", ".")
 
109
 
110
+ # Combinar dados do TweetHunter com dados de verificação
111
  result = {
112
+ **tweet_data, # Dados principais do TweetHunter
113
+ **verification_data # Sobrescrever/adicionar dados de verificação
114
  }
115
 
116
  return result