This commit is contained in:
marco
2026-09-09 11:05:09 -03:00
parent a1871a7084
commit ef9ee6bf52
15 changed files with 834 additions and 63 deletions
+69 -37
View File
@@ -3,6 +3,7 @@ import os
import random
import asyncio
import logging
from dataclasses import dataclass
from datetime import datetime
from dotenv import load_dotenv
@@ -17,21 +18,38 @@ logging.basicConfig(
)
log = logging.getLogger(__name__)
# ─── Config ───────────────────────────────────────────────────────────────────
# ─── Config global ────────────────────────────────────────────────────────────
TOKEN = os.getenv("TELEGRAM_TOKEN", "")
CHAT_ID = os.getenv("TELEGRAM_CHAT_ID", "")
SEXO = os.getenv("SEXO", "masculino").strip().lower()
IDADE = int(os.getenv("IDADE", "30"))
INTERVALO = int(os.getenv("INTERVALO_MINUTOS", "5"))
HORA_INICIO = os.getenv("HORA_INICIO", "00:00").strip()
HORA_FIM = os.getenv("HORA_FIM", "23:59").strip()
def dentro_do_horario() -> bool:
agora = datetime.now().strftime("%H:%M")
return HORA_INICIO <= agora <= HORA_FIM
ORDENS_PATH = os.path.join(os.path.dirname(__file__), "ordens.json")
# ─── Config por tipo de envio ─────────────────────────────────────────────────
@dataclass
class ConfigEnvio:
numero: int
ativo: bool
intervalo_minutos: int
arquivo_ordens: str
def carregar_config_envio(numero: int) -> ConfigEnvio:
prefixo = f"ENVIAR{numero}_"
ativo_raw = os.getenv(f"{prefixo}ATIVO", "s").strip().lower()
ativo = ativo_raw == "s"
intervalo = int(os.getenv(f"{prefixo}INTERVALO_MINUTOS", "1"))
arquivo = os.getenv(f"{prefixo}ARQUIVO_ORDENS", f"ordens{numero}.json").strip()
return ConfigEnvio(
numero=numero,
ativo=ativo,
intervalo_minutos=intervalo,
arquivo_ordens=arquivo,
)
# ─── Substituições para sexo feminino ──────────────────────────────────────────
# Ordem importa: mais específicas primeiro
@@ -69,16 +87,17 @@ def adaptar_ordem(ordem: str) -> str:
# ─── Carregar ordens ──────────────────────────────────────────────────────────
def carregar_ordens():
with open(ORDENS_PATH, "r", encoding="utf-8") as f:
def carregar_ordens(arquivo: str) -> list:
caminho = os.path.join(os.path.dirname(__file__), arquivo)
with open(caminho, "r", encoding="utf-8") as f:
ordens = json.load(f)
if not ordens:
raise ValueError("Nenhuma ordem encontrada em ordens.json")
raise ValueError(f"Nenhuma ordem encontrada em {arquivo}")
return ordens
# ─── Envio Telegram ───────────────────────────────────────────────────────────
async def enviar_mensagem(bot: Bot, texto: str):
async def enviar_mensagem(bot: Bot, texto: str) -> None:
try:
await bot.send_message(chat_id=CHAT_ID, text=texto)
log.info("Ordem enviada com sucesso.")
@@ -86,35 +105,41 @@ async def enviar_mensagem(bot: Bot, texto: str):
log.error("Erro ao enviar mensagem: %s", e)
# ─── Comando /start ───────────────────────────────────────────────────────────
async def cmd_start(ordens: list):
bot = Bot(token=TOKEN)
artigo = "o" if SEXO == "masculino" else "a"
msg_start = (
f"Olá {artigo} usuário!\n\n"
f"O sistema de ordens automáticas foi ativado.\n"
f"Sexo: {SEXO} | Idade: {IDADE}\n"
f"Intervalo: {INTERVALO} minuto(s)\n"
f"Total de ordens disponíveis: {len(ordens)}\n\n"
f"A primeira ordem será enviada em {INTERVALO} minuto(s).\n"
f"Prepare-se para cumprir todas as ordens."
)
await enviar_mensagem(bot, msg_start)
# ─── Verificação de horário ───────────────────────────────────────────────────
def dentro_do_horario() -> bool:
agora = datetime.now().strftime("%H:%M")
return HORA_INICIO <= agora <= HORA_FIM
# ─── Loop principal ────────────────────────────────────────────────────────────
async def loop_principal():
# ─── Loop individual de envio ─────────────────────────────────────────────────
async def loop_envio(config: ConfigEnvio) -> None:
if not config.ativo:
log.info("Envio automático %d desativado no .env (ENVIAR%d_ATIVO != 's'). Pulando.", config.numero, config.numero)
return
if not TOKEN or not CHAT_ID:
log.error("TELEGRAM_TOKEN e TELEGRAM_CHAT_ID devem estar configurados no .env")
return
ordens = carregar_ordens()
log.info("Carregando ordens de %s para envio automático %d...", config.arquivo_ordens, config.numero)
ordens = carregar_ordens(config.arquivo_ordens)
random.shuffle(ordens)
bot = Bot(token=TOKEN)
await cmd_start(ordens)
# Mensagem de inicialização
artigo = "o" if SEXO == "masculino" else "a"
msg_start = (
f"🚀 Envio Automático {config.numero} ativado.\n"
f"Sexo: {SEXO} | Idade: {IDADE}\n"
f"Intervalo: {config.intervalo_minutos} minuto(s)\n"
f"Arquivo de ordens: {config.arquivo_ordens}\n"
f"Total de ordens disponíveis: {len(ordens)}\n"
f"Horário de funcionamento: {HORA_INICIO} - {HORA_FIM}\n\n"
f"A primeira ordem será enviada em {config.intervalo_minutos} minuto(s).\n"
f"Prepare-se para cumprir todas as ordens."
)
await enviar_mensagem(bot, msg_start)
agora = datetime.now().strftime("%H:%M")
if not dentro_do_horario():
@@ -122,11 +147,9 @@ async def loop_principal():
await bot.send_message(
chat_id=CHAT_ID,
text=f"Horário atual ({agora}) fora da janela de ordens ({HORA_INICIO}-{HORA_FIM}).\n"
f"As ordens serão retomadas automaticamente às {HORA_INICIO}."
f"As ordens (envio {config.numero}) serão retomadas automaticamente às {HORA_INICIO}.",
)
await asyncio.sleep(INTERVALO * 60)
ordem_index = 0
while True:
if not dentro_do_horario():
@@ -139,23 +162,32 @@ async def loop_principal():
agora = datetime.now().strftime("%d/%m/%Y %H:%M")
texto = (
f"ORDEM #{ordem_index + 1}\n"
f"ORDEM #{ordem_index + 1} [Env. {config.numero}]\n"
f"{agora}\n\n"
f"{ordem_adaptada}\n\n"
f"Proxima ordem em {INTERVALO} minuto(s)."
f"Próxima ordem em {config.intervalo_minutos} minuto(s)."
f"\n\nCumpra agora."
)
await enviar_mensagem(bot, texto)
ordem_index += 1
await asyncio.sleep(INTERVALO * 60)
await asyncio.sleep(config.intervalo_minutos * 60)
# ─── Entry point ──────────────────────────────────────────────────────────────
async def _executar_todos_envios(configs: list) -> None:
await asyncio.gather(*(loop_envio(c) for c in configs))
def main():
try:
asyncio.run(loop_principal())
configs = [
carregar_config_envio(1),
carregar_config_envio(2),
carregar_config_envio(3),
]
asyncio.run(_executar_todos_envios(configs))
except KeyboardInterrupt:
log.info("Sistema encerrado pelo usuário.")
except Exception as e:
@@ -163,4 +195,4 @@ def main():
if __name__ == "__main__":
main()
main()