Skip to content

Dividir Mensajes Largos para Redes Sociales: Una Utilidad PHP para Límites de Caracteres

Introducción

Al construir chatbots, herramientas para redes sociales o aplicaciones con IA, inevitablemente enfrentarás un desafío común: el texto que quieres enviar es más largo de lo que la plataforma permite.

Los DMs de Instagram tienen un límite de 1,000 caracteres. Twitter/X limita los posts a 280 caracteres. Los mensajes SMS se dividen en 160 caracteres. Y cuando trabajas con respuestas generadas por IA, rara vez respetan estos límites.

El enfoque ingenuo—cortar el texto exactamente en el límite de caracteres—resulta en palabras cortadas y mensajes ilegibles. Lo que necesitas es una división inteligente que respete los límites de las palabras y produzca fragmentos limpios y legibles.

El Problema

Considera este escenario: tu asistente de IA genera una respuesta de 3,000 caracteres para una consulta de un cliente. Necesitas enviarla por DM de Instagram (límite de 1,000 caracteres). Simplemente cortar en la posición 1000 podría producir:

...y el mejor enfoque sería reconfi

En lugar de:

...y el mejor enfoque sería

Tus usuarios merecen algo mejor.

La Solución

Aquí hay una función utilitaria PHP que divide mensajes largos en límites naturales—espacios y saltos de línea—respetando tu límite de caracteres:

php
public static function splitMessageByLength(string $message, int $length = 4096): array
{
    // Normaliza saltos de línea a \n
    $message = str_replace("\r\n", "\n", $message);
    $message = str_replace("\r", "\n", $message);

    $messages = [];
    $current_message = '';

    // Recorre el mensaje carácter por carácter
    for ($i = 0, $count = mb_strlen($message, 'UTF-8'); $i < $count; $i++) {
        $char = mb_substr($message, $i, 1, 'UTF-8');

        // Agrega el carácter
        $current_message .= $char;

        // Verifica si el mensaje actual excede el límite
        if (mb_strlen($current_message, 'UTF-8') >= $length) {
            // Encuentra la última ocurrencia de espacio o salto de línea
            $lastSpace = mb_strrpos($current_message, ' ', 0, 'UTF-8');
            $lastBreak = mb_strrpos($current_message, "\n", 0, 'UTF-8');

            // Determina la posición de corte (prefiere salto de línea sobre espacio)
            $splitPos = $lastBreak !== false ? $lastBreak : $lastSpace;

            // Si no hay espacio o salto, fuerza corte en el límite máximo
            if ($splitPos === false || $splitPos === 0) {
                $splitPos = $length;
            }

            // Agrega el fragmento actual al array de mensajes
            $messages[] = mb_substr($current_message, 0, $splitPos, 'UTF-8');

            // Inicia el siguiente fragmento con el contenido restante
            $current_message = mb_substr($current_message, $splitPos, null, 'UTF-8');
        }
    }

    // Agrega el resto si existe
    if (!empty($current_message)) {
        $messages[] = $current_message;
    }

    // Limpieza: elimina espacios y filtra strings vacíos
    $messages = array_map('trim', $messages);
    $filtered_messages = array_filter($messages, function ($message) {
        return (bool) $message;
    });

    return array_values($filtered_messages);
}

Cómo Funciona

El algoritmo sigue estos pasos:

  1. Normaliza saltos de línea - Convierte saltos de Windows (\r\n) y Mac antiguo (\r) al estilo Unix (\n) para un manejo consistente.

  2. Recorre carácter por carácter - Usa funciones multibyte seguras (mb_strlen, mb_substr) para manejar correctamente caracteres Unicode como emojis y letras acentuadas.

  3. Detección inteligente de límites - Cuando se alcanza el límite, busca hacia atrás el último espacio o salto de línea. Los saltos de línea se prefieren ya que representan puntos de división más naturales.

  4. Fallback para casos extremos - Si no existe un punto de división adecuado (ej: una sola palabra muy larga), fuerza la división en el límite exacto.

  5. Limpieza - Elimina espacios de cada fragmento y descarta strings vacíos que puedan resultar de la división.

Ejemplos de Uso

Uso Básico

php
$mensajeLargo = "Este es un mensaje muy largo que necesita ser dividido...";
$partes = TextUtil::splitMessageByLength($mensajeLargo, 100);

foreach ($partes as $indice => $parte) {
    echo "Parte " . ($indice + 1) . ": " . $parte . "\n";
}

Límites Específicos por Plataforma

php
class DivisorMensajes
{
    const INSTAGRAM_DM = 1000;
    const TWITTER = 280;
    const SMS = 160;
    const WHATSAPP = 4096;
    const TELEGRAM = 4096;

    public static function paraInstagram(string $mensaje): array
    {
        return TextUtil::splitMessageByLength($mensaje, self::INSTAGRAM_DM);
    }

    public static function paraTwitter(string $mensaje): array
    {
        return TextUtil::splitMessageByLength($mensaje, self::TWITTER);
    }

    public static function paraSMS(string $mensaje): array
    {
        return TextUtil::splitMessageByLength($mensaje, self::SMS);
    }
}

Con Respuestas de IA

php
// Obtiene respuesta de la IA (puede ser muy larga)
$respuestaIA = $anthropicService->chat($prompt);

// Divide para envío por DM de Instagram
$partes = TextUtil::splitMessageByLength($respuestaIA, 1000);

foreach ($partes as $parte) {
    $instagramApi->sendDirectMessage($userId, $parte);
    // Agrega delay para mantener orden de mensajes
    usleep(500000); // 500ms
}

Referencia de Límites por Plataforma

PlataformaLímiteNotas
Instagram DM1,000Por mensaje
Instagram Caption2,200Truncado en 125 en el feed
Twitter/X280Usuarios premium tienen más
SMS160Mayor = múltiples segmentos
WhatsApp4,096Por mensaje
Telegram4,096Por mensaje
Facebook Post63,206Pero 40-80 caracteres es ideal
LinkedIn3,000Truncado en 140 en el feed

Engagement Óptimo

Estudios muestran que mensajes más cortos generan mejor engagement. Posts en Twitter con menos de 100 caracteres tienen 17% más engagement. Captions de Instagram entre 138-150 caracteres tienen mejor rendimiento.

Mejoras a Considerar

Agregando Números de Parte

php
public static function dividirConNumeros(string $mensaje, int $limite): array
{
    $partes = self::splitMessageByLength($mensaje, $limite - 10); // Reserva espacio
    $total = count($partes);

    if ($total === 1) {
        return $partes;
    }

    return array_map(function ($parte, $indice) use ($total) {
        return $parte . "\n\n(" . ($indice + 1) . "/" . $total . ")";
    }, $partes, array_keys($partes));
}

Preservando Estructura de Párrafos

php
public static function dividirPorParrafos(string $mensaje, int $limite): array
{
    $parrafos = explode("\n\n", $mensaje);
    $partes = [];
    $actual = '';

    foreach ($parrafos as $parrafo) {
        $prueba = $actual ? $actual . "\n\n" . $parrafo : $parrafo;

        if (mb_strlen($prueba, 'UTF-8') <= $limite) {
            $actual = $prueba;
        } else {
            if ($actual) {
                $partes[] = $actual;
            }
            // Si un solo párrafo excede el límite, usa división por carácter
            if (mb_strlen($parrafo, 'UTF-8') > $limite) {
                $partes = array_merge($partes,
                    self::splitMessageByLength($parrafo, $limite));
                $actual = '';
            } else {
                $actual = $parrafo;
            }
        }
    }

    if ($actual) {
        $partes[] = $actual;
    }

    return $partes;
}

Consideraciones sobre Emojis

Los emojis pueden tener 1-4 bytes pero cuentan como 1-2 caracteres dependiendo de la plataforma. Prueba cuidadosamente con contenido rico en emojis para asegurar una división precisa.

Conclusión

Dividir mensajes largos puede parecer trivial, pero hacerlo correctamente—respetando límites de palabras, manejando Unicode adecuadamente y limpiando los resultados—marca la diferencia entre una aplicación profesional y una experiencia frustrante para el usuario.

Los puntos clave:

  • Siempre usa funciones de string multibyte para seguridad Unicode
  • Prefiere puntos de división naturales (saltos de línea > espacios > cortes forzados)
  • Limpia los resultados eliminando espacios y filtrando fragmentos vacíos
  • Considera optimizaciones específicas por plataforma para tu caso de uso

Esta utilidad se vuelve especialmente valiosa al integrar servicios de IA en plataformas de mensajería, donde el tamaño de las respuestas es impredecible y los límites de caracteres son estrictos.