Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Nieto2020/portalhub/llms.txt

Use this file to discover all available pages before exploring further.

The messaging module (modules/mensajes/) provides a fully internal, database-backed communication layer. There is no email integration — all messages live in the mensajes table and are consumed through the portal’s own inbox and conversation views. Role-based rules govern who can talk to whom, preventing unsolicited contact between unrelated clients and advisors.

Message Types

Each message in the mensajes table carries a tipo enum:
TypeDescription
Chat internoStandard real-time-style direct message between two users
TicketA support or query thread, typically opened by a client
The default type when none is specified is 'Chat interno'.

Sending a Direct Message

Endpoint: POST modules/mensajes/enviar.php enviar.php validates the recipient exists, enforces messaging-permission rules by role, and inserts the message row. Required fields:
FieldTypeDescription
id_destinatariointUser ID of the recipient
contenido_textostringMessage body (cannot be blank after trim)
Optional fields:
FieldTypeDescription
tipostring'Chat interno' (default) or 'Ticket'
ruta_archivo_adjuntostringRelative path to an already-uploaded attachment
{
  "id_destinatario": 5,
  "contenido_texto": "Buenos días, necesito revisar mi declaración trimestral.",
  "tipo": "Chat interno"
}

Messaging Permission Rules

The system enforces role-based restrictions on who each user type may contact:

Admin (ROL_ADMIN)

Unrestricted. May message any user on the platform.

Asesor (ROL_ASESOR)

May message admins, other asesores, or clients actively assigned to them in cliente_asesor.

Cliente (ROL_CLIENTE)

May only message their own assigned asesor. The assignment must be in estado = 'activo'.
if ($id_rol_remitente == ROL_CLIENTE) {
    if ($id_rol_destino != ROL_ASESOR) {
        sendResponse(403, "Solo puedes enviar mensajes a tu asesor asignado");
    }
    $checkAsign = $conexion->prepare("
        SELECT id_asignacion FROM cliente_asesor
        WHERE id_cliente = ? AND id_asesor = ? AND estado = 'activo'
    ");
    $checkAsign->execute([$id_remitente, $id_destinatario]);
    if (!$checkAsign->fetch()) {
        sendResponse(403, "No tienes un asesor asignado activo");
    }
}

Inbox (All Messages)

Endpoint: GET modules/mensajes/listar.php Returns all messages where the logged-in user is either the sender or the recipient, ordered by fecha_envio DESC. Each row includes a computed otro_usuario_correo field that resolves to the email of the other party in the conversation:
[
  {
    "id_mensaje": 317,
    "id_remitente": 42,
    "id_destinatario": 5,
    "tipo": "Chat interno",
    "contenido_texto": "Buenos días, necesito revisar mi declaración trimestral.",
    "ruta_archivo_adjunto": null,
    "fecha_envio": "2025-07-20 11:05:33",
    "otro_usuario_correo": "asesor@consultoria.mx"
  }
]

Conversation View

Endpoint: GET modules/mensajes/conversacion.php Retrieves the chronological message thread between the logged-in user and a specified second user. Use this endpoint to render a chat-style view:
GET /modules/mensajes/conversacion.php?id_otro=5

Contacts List

Endpoint: GET modules/mensajes/contactos.php Returns the list of users the logged-in user is allowed to contact, respecting the role permission rules described above.

Read Receipts

The mensajes table includes a leida boolean column (default false). Two endpoints manage this state:
EndpointMethodDescription
marcar_leido.phpPOSTMarks a specific message as read
no_leidos.phpGETReturns the count of unread messages for the current user
Mark read request:
{
  "id_mensaje": 317
}
Unread count response:
{
  "status": 200,
  "message": "OK",
  "data": {
    "no_leidos": 4
  }
}

Bulk Broadcast (Admin Only)

Endpoint: POST modules/mensajes/enviar_masivo.php Only ROL_ADMIN may call this endpoint. It inserts an identical 'Chat interno' message from the admin to every user matching the target role list in a single database transaction. The sending admin is excluded from the recipient list. Required fields:
FieldTypeDescription
titulostringSubject / title prepended to the message
contenidostringBody text of the broadcast
Optional fields:
FieldTypeDescription
rolesint[]Array of role IDs to target (default: [1, 2, 3] — all roles)
{
  "titulo": "Mantenimiento programado",
  "contenido": "El sistema estará en mantenimiento el sábado de 02:00 a 06:00 hrs.",
  "roles": [2, 3]
}
The stored message body is formatted as:
📢 {titulo}

{contenido}
enviar_masivo.php wraps all inserts in a database transaction (beginTransaction / commit). If any insert fails, a rollBack() is performed and no partial messages are saved.

Build docs developers (and LLMs) love