Reputation: 51
I am struggling on how to get the text of a message to my C#-console tool with a telegram bot. Here is a piece of that is supposed to just print all messages in the telegram channel
private async Task getTelegramMessage()
{
var bot = new Telegram.Bot.TelegramBotClient("token")
var updates = await bot.GetUpdatesAsync();
foreach (var update in updates)
{
Console.WriteLine("Bot: " + update.Message.Text);
}
}
the problem is that i always get all old updates. The maximum length of the array updates is 100. So after I sent 100 messages in the telegram channel, I would only have access to the first 100 messages and no access to the newest. How can I get access to the most recent update? Or can I somehow delete the message after my tool has processed it?
I have seen that the bot provides the Event OnUpdate but I couldnt figure out how to use it.
Thanks a lot for help on that issue.
Upvotes: 3
Views: 14860
Reputation: 1
I was developing a Telegtam bot for the corporate tech support team and ran into the same problem. The offset -1
parameter in the GetUpdatesAsync
method helped me. I emulated a situation when the internet was down on the server and after turning it back on I got one last update. I got rid of it using a temporary window. Here is the sample code of the update handler:
private static DateTime _lastUpdateTime = DateTime.UtcNow;
async static Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
{
bool isBotAlive = await botClient.TestApiAsync();
Update[] updates = await botClient.GetUpdatesAsync(-1, null, null, null, cancellationToken); //-1 to reject old updates
foreach (var updateItem in updates)
{
try
{
DateTime updateTimestamp = updateItem.Message?.Date ?? DateTime.UtcNow;
TimeSpan timeSinceLastUpdate = updateTimestamp - _lastUpdateTime;
if ((timeSinceLastUpdate.TotalSeconds <= 15) && (DateTime.UtcNow - _lastUpdateTime < TimeSpan.FromSeconds(30)))
{
//My code for processing Update.Message and Update.callbackQuery
}
else
{
Console.WriteLine($"Old message. Received in {DateTime.Now.ToString("HH:mm:ss dd/MM/yyyy")}\n");
}
if (isBotAlive)
{
_lastUpdateTime = updateTimestamp;
}
}
catch (Exception ex)
{
var error = $"Error update was caught {ex.Message}";
Console.WriteLine(error);
_logger.Error(error);
}
}
}
I also used ThrowPendingUpdates = true
parameter in ReceiverOptions when starting the bot, but I can't say for sure that this parameter works.
Upvotes: 0
Reputation: 31
Instead subscribe to the BotOnUpdateReceived
event to handle the updates. In main.cs:
Bot.OnUpdate += BotOnUpdateReceived;
Bot.StartReceiving(Array.Empty<UpdateType>());
Console.WriteLine($"Start listening!!");
Console.ReadLine();
Bot.StopReceiving();
And handle the event:
private static async void BotOnUpdateReceived(object sender, UpdateEventArgs e)
{
var message = e.Update.Message;
if (message == null || message.Type != MessageType.Text) return;
var text = message.Text;
Console.WriteLine(text);
await Bot.SendTextMessageAsync(message.Chat.Id, "_Received Update._", ParseMode.Markdown);
}
The Offset is internally working in it and it also internally call GetUpdatesAsync()
.
From Here you can also get channel post via:
var message = e.Update.ChannelPost.Text; // For Text Messages
I hope it will Help!!
Upvotes: 3
Reputation:
According documentation, you can use offset -1 to get the last update. Just put in mind all previous updates will forgotten.
https://api.telegram.org/bot{TOKEN}/getUpdates?offset=-1
Upvotes: 5
Reputation: 51
oh, I just figured it out. for the offset you have to set the ID returned in the update.
Notes 2. In order to avoid getting duplicate updates, recalculate offset after each server response.
Upvotes: 2