fix: unescape literal \n sequences in Telegram message formatting#193
fix: unescape literal \n sequences in Telegram message formatting#193ptone wants to merge 2 commits into
Conversation
Message text arriving at the Telegram formatter can contain literal backslash-n escape sequences instead of actual newlines — either from JSON encoding round-trips (FormatForDelivery) or from shell arguments that don't interpret \n. Apply unescapeNewlines in FormatMessage and FormatMessageV2 so Telegram displays proper line breaks. Closes #48
There was a problem hiding this comment.
Code Review
This pull request introduces a helper function unescapeNewlines to replace literal escape sequences (\n and \t) with their actual characters in formatted Telegram messages, and adds corresponding unit tests. Feedback suggests optimizing this helper by declaring the strings.Replacer as a package-level variable to avoid the overhead of recreating it on every function call.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| // unescapeNewlines replaces literal escape sequences (\n, \t) with their actual | ||
| // characters. Message text may arrive with these sequences when it passes through | ||
| // JSON encoding (e.g. FormatForDelivery) and is later forwarded without decoding, | ||
| // or when shell arguments carry un-interpreted backslash escapes. | ||
| func unescapeNewlines(s string) string { | ||
| return strings.NewReplacer(`\n`, "\n", `\t`, "\t").Replace(s) | ||
| } |
There was a problem hiding this comment.
Creating a new strings.Replacer on every call to unescapeNewlines is inefficient because strings.NewReplacer performs preprocessing to build its internal lookup structures. Declaring the replacer as a package-level variable avoids this overhead and improves performance.
| // unescapeNewlines replaces literal escape sequences (\n, \t) with their actual | |
| // characters. Message text may arrive with these sequences when it passes through | |
| // JSON encoding (e.g. FormatForDelivery) and is later forwarded without decoding, | |
| // or when shell arguments carry un-interpreted backslash escapes. | |
| func unescapeNewlines(s string) string { | |
| return strings.NewReplacer(`\n`, "\n", `\t`, "\t").Replace(s) | |
| } | |
| var unescapeReplacer = strings.NewReplacer("\\n", "\n", "\\t", "\t") | |
| // unescapeNewlines replaces literal escape sequences (\n, \t) with their actual | |
| // characters. Message text may arrive with these sequences when it passes through | |
| // JSON encoding (e.g. FormatForDelivery) and is later forwarded without decoding, | |
| // or when shell arguments carry un-interpreted backslash escapes. | |
| func unescapeNewlines(s string) string { | |
| return unescapeReplacer.Replace(s) | |
| } |
Avoids re-allocating the replacer on every call to unescapeNewlines.
Summary
unescapeNewlineshelper that replaces literal\nand\tescape sequences with actual newline and tab charactersFormatMessageandFormatMessageV2before writingmsg.Msgto the output bufferFormatForDelivery) and is forwarded without decoding, or when shell arguments carry un-interpreted backslash escapesCloses #48
Test plan
TestUnescapeNewlineswith 7 cases covering no escapes, single/double newlines, tabs, mixed, actual newlines unchanged, and empty stringTestFormatMessage_UnescapesLiteralNewlinesverifying FormatMessage output contains actual newlinesTestFormatMessageV2_UnescapesLiteralNewlinesverifying FormatMessageV2 output contains actual newlines