MessageText
in package
Turning a message from one network into text the other will accept.
What lives here is the half that has nothing to do with any particular platform: stripping the control characters no chat should carry, rendering Discord's mention markup as something legible, fitting attachment links into a budget, and truncating without cutting a character in half.
What does not live here is anything a connector's own network requires — IRC line sanitisation, Telegram's HTML escaping, the format of a channel reference. Those belong to the connector, which is the only code that should need to know them, and they are built out of the primitives below.
Every method is static and every one is pure: the routing, the pacing and the delivery all have sockets in them, and this deliberately does not.
Tags
Table of Contents
Constants
- DISCORD_LIMIT : mixed = 2000
- Discord's own message limit.
Methods
- attachmentLinks() : string
- Renders attachment URLs into the space left over, whole links only.
- collapseWhitespace() : string
- Every run of whitespace reduced to one space, and the ends trimmed.
- escapeMarkdown() : string
- Escapes Discord markdown in text that came from elsewhere.
- filename() : string
- The last path segment of a URL, for labelling an attachment link.
- forDiscord() : string|null
- Formats a message from another network for Discord, or `null` when there is nothing worth relaying.
- isRelayableUrl() : bool
- Whether a URL is safe to put in front of a public chat as a link.
- length() : int
- Characters, not bytes: every limit these networks publish is a character count.
- resolveMentions() : string
- Rewrites Discord's `<@id>` / `<#id>` / `<@&id>` / `<a:name:id>` markup into something legible in a plain-text chat. Unknown ids degrade to a readable placeholder rather than leaking a raw snowflake.
- sanitize() : string
- Strips the control characters no network should ever carry, while keeping the ones that carry meaning in a chat message.
- truncate() : string
- Truncates on a character boundary, marking that it happened.
Constants
DISCORD_LIMIT
Discord's own message limit.
public
mixed
DISCORD_LIMIT
= 2000
Methods
attachmentLinks()
Renders attachment URLs into the space left over, whole links only.
public
static attachmentLinks(array<int, string> $urls, int $budget[, callable(string): string|null $sanitise = null ]) : string
Fits as many as the budget allows and counts the rest, since a truncated URL is worse than an honest "(+2 more)" — it looks clickable and goes nowhere. When not even one fits, it degrades to a bare count, which is at least a signal that something was posted.
A caveat worth knowing rather than discovering: Discord's CDN links are signed and expire roughly a day after they are issued. A relayed link works for people reading along live, and will be dead by the time anyone reads the logs. Nothing here can prevent that — the unsigned form of these URLs no longer exists.
Parameters
- $urls : array<int, string>
- $budget : int
- $sanitise : callable(string): string|null = null
-
How the destination network needs each URL cleaned; defaults to sanitize().
Return values
stringcollapseWhitespace()
Every run of whitespace reduced to one space, and the ends trimmed.
public
static collapseWhitespace(string $text) : string
For sources that are line-oriented by nature — IRC cannot express a newline inside a message, so a run of them means nothing was there.
Parameters
- $text : string
Return values
stringescapeMarkdown()
Escapes Discord markdown in text that came from elsewhere.
public
static escapeMarkdown(string $text) : string
For structured output — a chat title in a panel, a name in a heading — where an underscore should read as an underscore rather than silently italicising the rest of the line. Relayed messages are deliberately not escaped this way; see forDiscord().
Parameters
- $text : string
Return values
stringfilename()
The last path segment of a URL, for labelling an attachment link.
public
static filename(string $url) : string
Parameters
- $url : string
Return values
stringforDiscord()
Formats a message from another network for Discord, or `null` when there is nothing worth relaying.
public
static forDiscord(string $content[, int $limit = self::DISCORD_LIMIT ][, bool $flatten = false ]) : string|null
Content is passed through as written. Nothing is escaped, because the
delivery side sends allowed_mentions: none — that neuters @everyone
at the API rather than by mangling the text, so someone who types an @
still reads as having typed one. The sending network's own markup is left
alone for the same reason: mangling asterisks to stop Discord bolding
them is a worse result than the occasional stray bold.
Parameters
- $content : string
- $limit : int = self::DISCORD_LIMIT
- $flatten : bool = false
-
Whether the source is line-oriented, so runs of whitespace carry no meaning and should collapse.
Return values
string|nullisRelayableUrl()
Whether a URL is safe to put in front of a public chat as a link.
public
static isRelayableUrl(string $url) : bool
The host is deliberately not pinned to Discord's CDN. These come from the gateway's own attachment objects, so they are already trusted, and hard-coding hostnames would mean a future CDN domain silently degrading every attachment to a bare count. What is checked is the shape: HTTPS only, and nothing that could break out of a single line.
Parameters
- $url : string
Return values
boollength()
Characters, not bytes: every limit these networks publish is a character count.
public
static length(string $text) : int
Parameters
- $text : string
Return values
intresolveMentions()
Rewrites Discord's `<@id>` / `<#id>` / `<@&id>` / `<a:name:id>` markup into something legible in a plain-text chat. Unknown ids degrade to a readable placeholder rather than leaking a raw snowflake.
public
static resolveMentions(string $content[, array<string, string> $userNames = [] ][, array<string, string> $channelNames = [] ][, array<string, string> $roleNames = [] ]) : string
Parameters
- $content : string
- $userNames : array<string, string> = []
- $channelNames : array<string, string> = []
- $roleNames : array<string, string> = []
Return values
stringsanitize()
Strips the control characters no network should ever carry, while keeping the ones that carry meaning in a chat message.
public
static sanitize(string $text) : string
Newline and tab survive; everything else in C0, plus DEL, goes. A bare carriage return is normalised rather than dropped so a message pasted from Windows does not arrive with its lines run together.
Parameters
- $text : string
Return values
stringtruncate()
Truncates on a character boundary, marking that it happened.
public
static truncate(string $text, int $limit) : string
Parameters
- $text : string
- $limit : int