import json import os import random import asyncio import logging from dataclasses import dataclass from datetime import datetime from dotenv import load_dotenv from telegram import Bot from telegram.error import TelegramError load_dotenv() logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", ) log = logging.getLogger(__name__) # ─── 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")) HORA_INICIO = os.getenv("HORA_INICIO", "00:00").strip() HORA_FIM = os.getenv("HORA_FIM", "23:59").strip() # ─── Config por tipo de envio ───────────────────────────────────────────────── @dataclass class ConfigEnvio: numero: int ativo: bool intervalo_minutos: int arquivo_ordens: str quantidade_ordens: int # 0 = sem limite 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() quantidade = int(os.getenv(f"{prefixo}QUANTIDADE_ORDENS", "0")) return ConfigEnvio( numero=numero, ativo=ativo, intervalo_minutos=intervalo, arquivo_ordens=arquivo, quantidade_ordens=quantidade, ) # ─── Substituições para sexo feminino ────────────────────────────────────────── # Ordem importa: mais específicas primeiro SUBSTITUICOES_FEMININO = [ ("a cabeça do pau", "o clitóris"), ("cabeça do pau", "clitóris"), ("da cabeça do pau", "do clitóris"), ("a glande", "o clitóris"), ("da glande", "do clitóris"), ("glande", "clitóris"), ("do pau", "da buceta"), ("no pau", "na buceta"), ("o pau", "a buceta"), ("um pau", "uma buceta"), ("pau", "buceta"), ("o saco", "a xota"), ("do saco", "da xota"), ("no saco", "na xota"), ("saco", "xota"), ("a cueca", "a calcinha"), ("da cueca", "da calcinha"), ("na cueca", "na calcinha"), ("cueca", "calcinha"), ("punheta", "siririca"), ("porra", "gozo"), ("próstata", "ponto G"), ] def adaptar_ordem(ordem: str) -> str: if SEXO == "feminino": for masculino, feminino in SUBSTITUICOES_FEMININO: ordem = ordem.replace(masculino, feminino) return ordem # ─── Carregar ordens ────────────────────────────────────────────────────────── 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(f"Nenhuma ordem encontrada em {arquivo}") return ordens # ─── Envio Telegram ─────────────────────────────────────────────────────────── 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.") except TelegramError as e: log.error("Erro ao enviar mensagem: %s", e) # ─── Verificação de horário ─────────────────────────────────────────────────── def dentro_do_horario() -> bool: agora = datetime.now().strftime("%H:%M") return HORA_INICIO <= agora <= HORA_FIM # ─── 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 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) # Mensagem de inicialização artigo = "o" if SEXO == "masculino" else "a" if config.quantidade_ordens > 1: info_quantidade = f"Ordens por ciclo: {config.quantidade_ordens}\n" else: info_quantidade = "Ordens por ciclo: 1\n" 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"{info_quantidade}" 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(s) primeira(s) ordem(ns) será(ão) enviada(s) imediatamente.\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(): log.info("Horário atual %s fora da janela %s-%s. Aguardando...", agora, HORA_INICIO, HORA_FIM) 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 (envio {config.numero}) serão retomadas automaticamente às {HORA_INICIO}.", ) ordem_index = 0 while True: if not dentro_do_horario(): log.info("Fora do horário de funcionamento (%s-%s). Aguardando...", HORA_INICIO, HORA_FIM) await asyncio.sleep(60) continue # Quantidade de ordens a enviar neste ciclo qtd = config.quantidade_ordens if config.quantidade_ordens > 0 else 1 # Envia lote de ordens for i in range(qtd): ordem = ordens[(ordem_index + i) % len(ordens)] ordem_adaptada = adaptar_ordem(ordem) agora = datetime.now().strftime("%d/%m/%Y %H:%M") texto = ( f"ORDEM #{ordem_index + i + 1} [Env. {config.numero}]\n" f"{agora}\n\n" f"{ordem_adaptada}\n\n" f"Próxima ordem em {config.intervalo_minutos} minuto(s)." f"\n\nCumpra agora." ) await enviar_mensagem(bot, texto) ordem_index += qtd 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: configs = [ carregar_config_envio(1), carregar_config_envio(2), carregar_config_envio(3), carregar_config_envio(4), carregar_config_envio(5), carregar_config_envio(6), carregar_config_envio(7), carregar_config_envio(8), carregar_config_envio(9), ] asyncio.run(_executar_todos_envios(configs)) except KeyboardInterrupt: log.info("Sistema encerrado pelo usuário.") except Exception as e: log.error("Erro fatal: %s", e) if __name__ == "__main__": main()