@@ -19,29 +19,98 @@ internal class TelegramConnector(
1919 private readonly TelegramBotClient _botClient = new ( options . Value . Token ) ;
2020 private readonly CancellationTokenSource _cancellationTokenSource = new ( ) ;
2121
22+ private const int MaxRetries = 5 ;
23+ private const int MaxRetryDelaySeconds = 30 ;
24+
2225 private string ? _botName ;
26+ private volatile bool _isConnected ;
2327
2428 public async Task Connect ( )
2529 {
2630 await registeredChatService . LoadRegisteredChats ( ) ;
2731
28- var botCommands = commands
29- . Where ( c => ! c . HideFromMenu )
30- . Select ( c => new BotCommand { Command = c . Name , Description = c . Description } )
31- . ToList ( ) ;
32-
33- foreach ( var chat in registeredChatService . RegisteredChats )
34- {
35- await _botClient . SetMyCommandsAsync ( botCommands , BotCommandScope . Chat ( new ChatId ( chat . ChatId ) ) , cancellationToken : _cancellationTokenSource . Token ) ;
36- }
37-
38- _botClient . StartReceiving ( ReceiveUpdate , HandleError , cancellationToken : _cancellationTokenSource . Token ) ;
39-
40- var bot = await _botClient . GetMeAsync ( ) ;
32+ // Start connection in background to avoid blocking application startup
33+ _ = Task . Run ( async ( ) =>
34+ {
35+ try
36+ {
37+ await ConnectAsync ( _cancellationTokenSource . Token ) ;
38+ }
39+ catch ( Exception ex )
40+ {
41+ logger . LogError ( ex , "Unhandled exception in Telegram connection task: {Exception}" , ex . Message ) ;
42+ }
43+ } ) ;
44+ }
4145
42- _botName = bot . Username ;
46+ private async Task ConnectAsync ( CancellationToken cancellationToken )
47+ {
48+ var retryCount = 0 ;
4349
44- logger . LogInformation ( "Telegram bot connected: {Bot}" , bot ) ;
50+ while ( ! cancellationToken . IsCancellationRequested )
51+ {
52+ try
53+ {
54+ logger . LogInformation ( "Attempting to connect to Telegram bot (attempt {Attempt}/{MaxRetries})..." , retryCount + 1 , MaxRetries ) ;
55+
56+ var bot = await _botClient . GetMeAsync ( cancellationToken ) ;
57+ _botName = bot . Username ;
58+
59+ logger . LogInformation ( "Telegram bot connected: {Bot}" , bot ) ;
60+
61+ var botCommands = commands
62+ . Where ( c => ! c . HideFromMenu )
63+ . Select ( c => new BotCommand { Command = c . Name , Description = c . Description } )
64+ . ToList ( ) ;
65+
66+ foreach ( var chat in registeredChatService . RegisteredChats )
67+ {
68+ try
69+ {
70+ await _botClient . SetMyCommandsAsync ( botCommands , BotCommandScope . Chat ( new ChatId ( chat . ChatId ) ) , cancellationToken : cancellationToken ) ;
71+ }
72+ catch ( Exception ex )
73+ {
74+ logger . LogWarning ( ex , "Failed to set commands for chat {ChatId}" , chat . ChatId ) ;
75+ }
76+ }
77+
78+ _botClient . StartReceiving ( ReceiveUpdate , HandleError , cancellationToken : cancellationToken ) ;
79+
80+ _isConnected = true ;
81+
82+ // Connection successful, exit retry loop
83+ return ;
84+ }
85+ catch ( OperationCanceledException )
86+ {
87+ logger . LogInformation ( "Telegram bot connection cancelled during shutdown." ) ;
88+ return ;
89+ }
90+ catch ( Exception ex )
91+ {
92+ retryCount ++ ;
93+ logger . LogError ( ex , "Error connecting to Telegram bot (attempt {Attempt}/{MaxRetries}): {Exception}" , retryCount , MaxRetries , ex . Message ) ;
94+
95+ if ( retryCount >= MaxRetries )
96+ {
97+ logger . LogError ( "Failed to connect to Telegram bot after {MaxRetries} attempts. Telegram functionality will be unavailable." , MaxRetries ) ;
98+ return ;
99+ }
100+
101+ try
102+ {
103+ var delaySeconds = Math . Min ( MaxRetryDelaySeconds , 1 << retryCount ) ;
104+ logger . LogInformation ( "Retrying Telegram connection in {Delay} seconds..." , delaySeconds ) ;
105+ await Task . Delay ( TimeSpan . FromSeconds ( delaySeconds ) , cancellationToken ) ;
106+ }
107+ catch ( OperationCanceledException )
108+ {
109+ logger . LogInformation ( "Telegram bot connection retry cancelled during shutdown." ) ;
110+ return ;
111+ }
112+ }
113+ }
45114 }
46115
47116 public async Task DisconnectAsync ( )
@@ -98,11 +167,23 @@ private async Task ReceiveUpdateAsync(ITelegramBotClient client, Update update,
98167
99168 public async Task SendAsync ( string message )
100169 {
101- foreach ( var registeredChat in registeredChatService . RegisteredChats )
170+ if ( ! _isConnected )
102171 {
103- await _botClient . SendTextMessageAsync ( registeredChat . ChatId , message , parseMode : ParseMode . Html ) ;
172+ logger . LogWarning ( "Cannot send message - Telegram bot is not connected yet." ) ;
173+ return ;
174+ }
104175
105- logger . LogInformation ( "Message sent to chat {ChatId} with user {User}: {Message}" , registeredChat . ChatId , registeredChat . Username , message ) ;
176+ foreach ( var registeredChat in registeredChatService . RegisteredChats )
177+ {
178+ try
179+ {
180+ await _botClient . SendTextMessageAsync ( registeredChat . ChatId , message , parseMode : ParseMode . Html ) ;
181+ logger . LogInformation ( "Message sent to chat {ChatId} with user {User}: {Message}" , registeredChat . ChatId , registeredChat . Username , message ) ;
182+ }
183+ catch ( Exception ex )
184+ {
185+ logger . LogError ( ex , "Failed to send message to chat {ChatId}: {Exception}" , registeredChat . ChatId , ex . Message ) ;
186+ }
106187 }
107188 }
108189}
0 commit comments