LemonChannels.Telegram.Truncate (lemon_channels v0.1.0)

View Source

Truncation and splitting logic for Telegram messages.

Telegram has a message length limit of 4096 characters. When a message exceeds this limit, we split it into multiple messages with smart break-point selection.

Splitting Algorithm

  1. If text fits in one message, return it as-is
  2. If we need to split:
    • Find the first newline (\n) within 80% of the limit
    • If no newline, find a word boundary (space) within the last 5% of the limit
    • If no word boundary, hard-split at 99% of the limit
  3. Preserve resume lines on the last chunk

Legacy Truncation

truncate_for_telegram/1 still exists for simple truncation use-cases such as status messages. New outbound text flows should prefer split_messages/1.

Summary

Functions

Returns the Telegram message length limit.

Split text into one or more chunks that each fit within Telegram's message limit.

Truncate text to fit within Telegram's message limit while preserving resume lines.

Functions

max_length()

@spec max_length() :: pos_integer()

Returns the Telegram message length limit.

split_messages(text)

@spec split_messages(String.t()) :: [String.t()]

Split text into one or more chunks that each fit within Telegram's message limit.

Uses smart break-point selection: prefers newlines within 80% of the limit, falls back to word boundaries, and finally hard-splits.

Resume lines are preserved on the last chunk.

Returns

A non-empty list of strings, each with String.length/1 <= 4096.

truncate_for_telegram(text)

@spec truncate_for_telegram(String.t()) :: String.t()

Truncate text to fit within Telegram's message limit while preserving resume lines.

Resume lines at the end of the message are preserved even if truncation is needed.

Returns

The (possibly truncated) text that fits within Telegram's 4096 character limit.

Examples

iex> short_text = "Hello world"
iex> Truncate.truncate_for_telegram(short_text)
"Hello world"

iex> long_text = String.duplicate("x", 5000) <> "\nlemon resume abc123"
iex> result = Truncate.truncate_for_telegram(long_text)
iex> String.length(result) <= 4096
true
iex> String.ends_with?(result, "lemon resume abc123")
true