| | | 1 | | namespace TeleFlow.Telegram.Internal; |
| | | 2 | | |
| | | 3 | | internal static class TelegramBotUsernameNormalizer |
| | | 4 | | { |
| | | 5 | | private const int MinLength = 5; |
| | | 6 | | private const int MaxLength = 32; |
| | | 7 | | |
| | | 8 | | public static bool TryNormalize( |
| | | 9 | | string? botUsername, |
| | | 10 | | out string? normalizedUsername, |
| | | 11 | | out string? error) |
| | | 12 | | { |
| | 1041 | 13 | | if (botUsername is null) |
| | | 14 | | { |
| | 944 | 15 | | normalizedUsername = null; |
| | 944 | 16 | | error = null; |
| | 944 | 17 | | return true; |
| | | 18 | | } |
| | | 19 | | |
| | 97 | 20 | | var trimmed = botUsername.Trim(); |
| | 97 | 21 | | if (trimmed.StartsWith('@')) |
| | | 22 | | { |
| | 8 | 23 | | trimmed = trimmed[1..]; |
| | | 24 | | } |
| | | 25 | | |
| | 97 | 26 | | if (trimmed.Length is < MinLength or > MaxLength) |
| | | 27 | | { |
| | 3 | 28 | | normalizedUsername = null; |
| | 3 | 29 | | error = $"Telegram bot username must be between {MinLength} and {MaxLength} characters."; |
| | 3 | 30 | | return false; |
| | | 31 | | } |
| | | 32 | | |
| | 1862 | 33 | | foreach (var character in trimmed) |
| | | 34 | | { |
| | 838 | 35 | | if (!IsTelegramUsernameCharacter(character)) |
| | | 36 | | { |
| | 2 | 37 | | normalizedUsername = null; |
| | 2 | 38 | | error = "Telegram bot username can contain only ASCII letters, digits, and underscores."; |
| | 2 | 39 | | return false; |
| | | 40 | | } |
| | | 41 | | } |
| | | 42 | | |
| | 92 | 43 | | normalizedUsername = trimmed; |
| | 92 | 44 | | error = null; |
| | 92 | 45 | | return true; |
| | | 46 | | } |
| | | 47 | | |
| | | 48 | | private static bool IsTelegramUsernameCharacter(char character) |
| | | 49 | | { |
| | 838 | 50 | | return character is >= 'A' and <= 'Z' || |
| | 838 | 51 | | character is >= 'a' and <= 'z' || |
| | 838 | 52 | | character is >= '0' and <= '9' || |
| | 838 | 53 | | character == '_'; |
| | | 54 | | } |
| | | 55 | | } |