-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscheduled_twitter_bot.py
More file actions
89 lines (69 loc) · 2.99 KB
/
Copy pathscheduled_twitter_bot.py
File metadata and controls
89 lines (69 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import os
import json
import requests
import logging
import random
import sys
import time
from datetime import datetime
from babel.dates import format_date
# USAMOS TU MÓDULO DE CONEXIÓN QUE YA TIENE AMBOS MOTORES
from connect_Twitter import connect_to_twitter
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(message)s")
logger = logging.getLogger(__name__)
def post_hemeroteca_hybrid():
json_path = os.path.join(os.path.dirname(__file__), "data.json")
with open(json_path, "r", encoding="utf-8") as f:
tweets = json.load(f)
# Selección aleatoria estilo Chuchu
candidatos = [t for t in tweets if t.get("veces_publicado", 0) < 3]
if not candidatos:
logger.warning("No hay candidatos.")
return
item = random.choice(candidatos)
idx = tweets.index(item)
# Obtenemos Client (v2) y API (v1.1) de tu propio módulo
x_client, x_api = connect_to_twitter()
try:
# 1. Preparar Imagen
img_url = item["image"]
if not img_url.startswith("http"):
img_url = os.getenv("CLOUDINARY_BASE_URL") + img_url
temp_img = "temp_hemeroteca.jpg"
res = requests.get(img_url, timeout=15)
with open(temp_img, "wb") as f:
f.write(res.content)
# 2. SUBIR MEDIA (v1.1 - Único endpoint v1.1 permitido)
logger.info(f"Subiendo imagen para item {item.get('id')}...")
media = x_api.media_upload(filename=temp_img)
media_id = media.media_id
# 3. PUBLICAR TEXTO (v2 - Obligatorio para tu nivel de acceso)
texto = f"📰 {item['text']}\n\n📚 Fuente: {item['source']}"
max_retries = 5 # Aumentamos intentos ante la inestabilidad de X
for intento in range(max_retries):
try:
logger.info(f"Publicando tuit (v2) - Intento {intento + 1}...")
x_client.create_tweet(text=texto, media_ids=[media_id])
# ÉXITO: Actualizar base de datos
item["veces_publicado"] = item.get("veces_publicado", 0) + 1
item["isPublished"] = True
with open(json_path, "w", encoding="utf-8") as f:
json.dump(tweets, f, indent=4, ensure_ascii=False)
logger.info("✅ Publicación exitosa tras los reintentos.")
break
except Exception as e:
# Si es el error 503 (Servidor ocupado), esperamos mucho más tiempo
if "503" in str(e) and intento < max_retries - 1:
wait = (intento + 1) * 60 # Esperamos 1 min, luego 2 mins...
logger.warning(
f"⚠️ X sigue saturado (503). Esperando {wait}s para reintentar..."
)
time.sleep(wait)
else:
raise e
if os.path.exists(temp_img):
os.remove(temp_img)
except Exception as e:
logger.error(f"💥 Error final en el bot: {e}")
if __name__ == "__main__":
post_hemeroteca_hybrid()