Cliente Python para ToDus (mensajería cubana) — chat, grupos, archivos, stickers y más
Project description
📱 toDus-API
Cliente Python para ToDus — la plataforma de mensajería instantánea cubana. Soporta chat privado, grupos MUC Light, archivos, imágenes, videos, stickers, botones interactivos y más.
- Versión: 1.3.9
- Python: >= 3.11
- Autor: ElJoker63
- Licencia: MIT
📦 Instalación
pip install toDus-API
O directamente desde el repositorio:
pip install git+https://github.com/ElJoker63/toDus-API.git
Para desarrollo:
git clone https://github.com/ElJoker63/toDus-API.git
cd toDus-API
pip install -e ".[dev]"
🔐 Autenticación (¡Importante!)
ToDus no usa contraseñas elegidas por el usuario. El proceso de autenticación tiene dos pasos:
- Obtener un token largo (96 caracteres) mediante validación por SMS.
- Usar ese token para hacer login y obtener un JWT de sesión, que se usa para todas las comunicaciones.
El cliente ToDusClient2 guarda ese token largo en el atributo password (nombre histórico), pero en la práctica debes entenderlo como auth_token.
🔹 Flujo para primera vez (SMS)
from todus import ToDusClient2
client = ToDusClient2(phone_number="535xxxxxxx") # sin password aún
# 1. Pedir código SMS
client.request_code() # te llega un PIN de 6 dígitos
# 2. Validar el código
client.validate_code("123456")
# Ahora client.password contiene el token largo (96 caracteres)
# ¡Guárdalo en un lugar seguro para futuras sesiones!
# 3. Obtener el JWT de sesión
client.login() # ahora client.logged == True
🔹 Si ya tienes el token largo (de una sesión anterior)
client = ToDusClient2(phone_number="535xxxxxxx", password="ese_token_largo_que_guardaste")
client.login() # obtiene el JWT internamente
⚠️ Importante: Nunca pases un JWT directamente al constructor. El cliente se encarga de renovarlo automáticamente cuando expira. El parámetro password espera el token largo de 96 caracteres.
🚀 Uso Rápido
Enviar mensajes (privados y grupos automáticamente)
# Asumiendo que ya hiciste login
client.send_message("535yyyyyyy", "¡Hola mundo!") # privado
client.send_message("mi-grupo-id", "Hola grupo!") # grupo (auto-detectado)
Enviar imagen (con subida previa)
from todus import FileType
# 1. Subir la imagen
with open("foto.jpg", "rb") as f:
image_data = f.read()
url = client.upload_file(image_data, FileType.PICTURE)
# 2. Enviar el mensaje con la imagen
client.send_image_message(
"535yyyyyyy",
url=url,
file_name="foto.jpg",
file_size=len(image_data),
caption="Mi foto"
)
Escuchar mensajes entrantes
def on_message(msg):
if msg.get("body"):
print(f"{msg['from']}: {msg['body']}")
client.listen_messages(on_message) # bucle infinito
🤖 Bot de Ejemplo
En la carpeta examples/ encontrarás un bot funcional con comandos:
| Comando | Respuesta |
|---|---|
/start | Mensaje de bienvenida con lista de comandos |
/info | Información sobre la librería |
/ping | pong |
Ejecútalo con:
export TODUS_PHONE=535xxxxxxx
export TODUS_AUTH_TOKEN=token_largo_de_96_caracteres
python examples/bot.py
📡 Tipos de Mensaje Soportados
La librería soporta los siguientes tipos de mensaje:
| Tipo | Método (ToDusClient2) |
|---|---|
| Texto | send_message(to, body) |
| Imagen | send_image_message(to, url, file_name, file_size, ...) |
| Video | send_video_message(to, url, video_id, file_name, ...) |
| Archivo | send_file_message(to, url, file_type, ...) |
| Sticker | send_sticker_message(to, sticker_id, ...) |
| Contacto | send_contact_message(to, contact_id, ...) |
| Botones | send_button_message(to, text, buttons) |
| Ubicación | send_location_message(to, lat, lon, ...) |
| Evento | send_event_message(to, title, start, end, ...) |
| Editar | edit_message(to, new_body, original_msg_id) |
| Eliminar | delete_message(to, message_id) |
Auto-detección de destino: si el to no es un número cubano (10 dígitos empezando por 53), se asume que es un group_id y el mensaje se envía al grupo automáticamente.
👥 Grupos MUC Light
# Unirse a un grupo
client.groups.join("mi-grupo-id")
# Enviar mensaje al grupo (auto-detectado)
client.send_message("mi-grupo-id", "Hola grupo!")
# Callback específico para mensajes de ese grupo
def on_group_msg(msg):
print(f"{msg['sender_phone']}: {msg['body']}")
client.groups.on_group_message("mi-grupo-id", on_group_msg)
# Salir del grupo
client.groups.leave("mi-grupo-id")
📤 Subir y Descargar Archivos
# Subir cualquier archivo
with open("documento.pdf", "rb") as f:
url = client.upload_file(f.read(), FileType.FILE)
# Descargar a una carpeta
size, path = client.download_file_to_folder(url, "./descargas")
print(f"Descargado {size} bytes en {path}")
⚠️ Excepciones
| Excepción | Cuándo ocurre |
|---|---|
AuthenticationError | Credenciales inválidas o falta autenticación |
TokenExpiredError | El token JWT expiró (el cliente lo renueva automáticamente si usas ToDusClient2) |
ConnectionLostError | Se perdió la conexión XMPP |
UploadError | Error al subir/descargar archivo |
GroupError | Error en operación de grupo |
ParseError | Stanza malformada |
🗂️ Estructura del Proyecto
toDus-API/
├── todus/ # Paquete principal
│ ├── __init__.py # Exports y versión
│ ├── client/ # Cliente XMPP/HTTP
│ │ ├── __init__.py # ToDusClient y ToDusClient2
│ │ ├── base.py # Conexión y transporte
│ │ ├── auth.py # Autenticación SMS/JWT
│ │ ├── message.py # Envío/recepción de mensajes
│ │ ├── file.py # Subida/descarga de archivos
│ │ └── profile.py # Perfil de usuario
│ ├── stanzas/ # Generadores de stanzas XML
│ │ ├── __init__.py
│ │ ├── private.py # Chat privado
│ │ ├── group.py # Chat grupal
│ │ ├── presence.py # Presencia XMPP
│ │ └── utils.py # Utilidades de protocolo
│ ├── group.py # Cliente de grupos MUC Light
│ ├── parser.py # Parser incremental de stanzas
│ ├── stanza.py # Re-exports unificados
│ ├── types.py # Enums (FileType, ChatState, etc.)
│ ├── util.py # Utilidades (JID, XML, JWT)
│ ├── constants.py # Hosts, puertos, versiones
│ └── errors.py # Excepciones personalizadas
├── tests/ # Tests unitarios
│ ├── test_util.py
│ ├── test_types.py
│ └── test_stanzas.py
├── examples/ # Ejemplos de uso
│ └── bot.py
├── .github/workflows/ # CI/CD
│ ├── ci.yml # Tests en push/PR
│ └── pypi-publish.yml # Publicación a PyPI
├── pyproject.toml # Configuración del paquete
├── LICENSE # Licencia MIT
├── CHANGELOG.md # Registro de cambios
├── CONTRIBUTING.md # Guía para contribuir
├── MANIFEST.in # Archivos incluidos en sdist
└── README.md # Este archivo
🔗 Recursos
- ToDus oficial: ToDus
- Apklis: Apklis
- PyPI: toDus-API
- Changelog: CHANGELOG.md
- Contribuir: CONTRIBUTING.md
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file todus_api-1.3.9.tar.gz.
File metadata
- Download URL: todus_api-1.3.9.tar.gz
- Upload date:
- Size: 35.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c82efbb4640b4dc068f95f49162623195b94e1e6303a6e6125205eac703f3b66
|
|
| MD5 |
30ee03e1f3335de08ff3470ce89d6e1c
|
|
| BLAKE2b-256 |
f6b2f3565036cba627fe923a14ab5a3b5032fc4e318b66af6b85638a642ffd8b
|
File details
Details for the file todus_api-1.3.9-py3-none-any.whl.
File metadata
- Download URL: todus_api-1.3.9-py3-none-any.whl
- Upload date:
- Size: 33.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
529688ce1907472dea665cec2c13b81d1b263bbe622547ca312f8d9516d389e7
|
|
| MD5 |
2735e38adfe89590873a700590a442bf
|
|
| BLAKE2b-256 |
56526fc1096000543e047bb7ed30a02f929528a6f3f8e2c7dfed08b001317117
|