private async Task HandleAuthenticatedUserHoursCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { var state = UserState <UserMuteState> .LoadOrDefault(userId); if (parsedCommand.Length != 3 || !int.TryParse(parsedCommand[1], out var hoursFrom) || !int.TryParse(parsedCommand[2], out var hoursTo)) { var r1 = await api.RespondToUpdate(update, $"{from.FirstName}, I need arguments"); return; } state.Data.SetHours(hoursFrom, hoursTo); state.Save(); var r = await api.RespondToUpdate(update, $"{from.FirstName}, bot will mute notifications when outside [{hoursFrom}:00:00, {hoursTo}:00:00]"); }
private async Task HandleAuthenticatedUserDelCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { UnStop(userId); if (parsedCommand.Length < 2 || !int.TryParse(parsedCommand[1], out var idx)) { var rr = await api.RespondToUpdate(update, $"{from.FirstName}, please give arguments to the command"); return; } var state = UserState <UserRssSubscriptions> .LoadOrDefault(userId); if (state.Data.RssEntries == null || idx >= state.Data.RssEntries.Count || idx < 0) { var rr = await api.RespondToUpdate(update, $"{from.FirstName}, index {idx} is not known"); return; } state.Data.RssEntries.RemoveAt(idx); state.Save(); var r = await api.RespondToUpdate(update, $"{from.FirstName}, {idx} was removed"); }
private async Task HandleNonAuthenticatedUserCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { if (parsedCommand.Length == 2 && parsedCommand[0] == "/auth" && parsedCommand[1] == Configuration.BOT_SECRET) { var state = UserState <UserDetails> .LoadOrDefault(userId); state.Data.ChatId = chat.Id; state.Data.UserId = userId; // kind of overkill state.Save(); var r = await api.RespondToUpdate(update, $"{from.FirstName}, you are now authenticated"); } else if (parsedCommand.Length > 1 && parsedCommand[0] == "/start") { await HandleUnauthenticatedUserStartCommand(api, update, from, chat, userId, parsedCommand); } else { var r = await api.RespondToUpdate(update, $"{from.FirstName}, access denied"); } }
private async Task HandleAuthenticatedUserListCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { UnStop(userId); var state = UserState <UserRssSubscriptions> .LoadOrDefault(userId); var r = await api.RespondToUpdate(update, $"{from.FirstName}, here are your subscribtions:"); if (state.Data.RssEntries != null) { for (int i = 0; i < state.Data.RssEntries.Count; ++i) { var entry = state.Data.RssEntries[i]; var kws = string.Join(", ", entry.Keywords); var rr = await api.RespondToUpdate(update, $"{i}: {entry.Url} {kws}"); } } }
private async Task HandleAuthenticatedUserUnknownCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { var r = await api.RespondToUpdate(update, $"Hello {from.FirstName}, I cannot understand {parsedCommand[0]}, try asking for /help"); }
private async Task HandleNonAuthenticatedUserCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { if (parsedCommand.Length == 2 && parsedCommand[0] == "/auth" && parsedCommand[1] == ApiKeys.BOT_SECRET_AUTH_KEY) { UserState <AuthValidFlag> .LoadOrDefault(userId).Save(); var r = await api.RespondToUpdate(update, $"{from.FirstName}, you are now authenticated"); } else { var r = await api.RespondToUpdate(update, $"{from.FirstName}, access denied"); } }
private async Task HandleAuthenticatedUserAddCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { UnStop(userId); if (parsedCommand.Length < 2) { var rr = await api.RespondToUpdate(update, $"{from.FirstName}, please give arguments to the command"); return; } var state = UserState <UserRssSubscriptions> .LoadOrDefault(userId); if (state.Data.RssEntries == null) { state.Data.RssEntries = new List <RssUrlEntry>(); } state.Data.RssEntries.Add( new RssUrlEntry { Url = parsedCommand[1], Keywords = parsedCommand.Skip(2).ToArray() }); state.Save(); var r = await api.RespondToUpdate(update, $"{from.FirstName}, it was added"); }
private async Task HandleAuthenticatedUserUnmuteCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { var state = UserState <UserMuteState> .LoadOrDefault(userId); state.Data.Muted = false; state.Save(); var r = await api.RespondToUpdate(update, $"{from.FirstName}, bot un-muted"); }
private async Task HandleUnauthenticatedUserStartCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { var state = UserState <UserMuteState> .LoadOrDefault(userId); state.Data.Stopped = true; state.Save(); var r = await api.RespondToUpdate(update, $"Saluton {from.FirstName}. Estas propra boto, vi bezonas rajto pro uzi gxin"); }
private async Task HandleAuthenticatedUserHelpCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { var r = await api.RespondToUpdate(update, $@"Hello {from.FirstName}, here are the commands I can understand: /add <rss_url> [optional] [keywords] - subscribe to the rss feed, with optional keywords to filter by /list - list current subscriptions /del <number> - delete subscription by the number /words <number> [optional] [keywords] - update the list of keywords for subscription index, keywords can be empty /words add <number> <word> - add a new keyword to subscription index /words del <number> <word> - del a keyword from subscription index /mute - mute everything, you would keep receiving updates but without any notifications /unmute - unmute everything /hours <from> <to> - set allowed notification hours, in 24 format, inclusive both, e.g. /hours 7 20 would mean notifications are allowed from 7:00:00 to 20:00:00 /stop - stop the bot completely, do any edit to un-stop it GDPR PRIVACY NOTICE: There is no privacy. Consider anything you send to this bot as public. "); }
private async Task UpdateReceiveLoop() { await Task.Yield(); try { var me = await _api.GetMe(); if (me != null) { logger.Info("Bot self identification: {0}", me.ToJsonString()); } long?nextOffset = null; for (; ;) { try { var updates = await _api.GetUpdates( offset : nextOffset, timeout : CallTimeout, limit : CallNumUpdatesLimit ); if (updates != null && updates.Count > 0) { logger.Info($"Got {updates.Count} updates from the network"); foreach (var update in updates) { nextOffset = update.UpdateId + 1; if (update.Message == null) { continue; } User from = update.Message.From; long userId = update.Message.From.Id; string text = update.Message.Text ?? ""; logger.Info($"{from.ToString()}: {userId} {text}"); logger.Debug("full update: {0}", update.ToJsonString()); bool added = false; lock (_queueLock) { if (_queue.Count < QueueMaxSize) { _queue.Enqueue(update); _queueCount.Release(1); added = true; } } if (!added) { logger.Error($"Queue overflow, update dropped"); var msg = await _api.RespondToUpdate(update, "Bot internal queue overflow"); } } } else { logger.Info("No updates"); } await Task.Delay(100); } catch (TaskCanceledException ex) { logger.Error(ex, "Read task cancelled"); await Task.Delay(10 * 1000); } } } catch (Exception ex) { logger.Error(ex, "Telegram update loop got an exception"); throw; } }
private async Task HandleAuthenticatedUserWordsCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { UnStop(userId); if (parsedCommand.Length < 2) { var rr = await api.RespondToUpdate(update, $"{from.FirstName}, please give arguments to the command"); return; } var state = UserState <UserRssSubscriptions> .LoadOrDefault(userId); if (int.TryParse(parsedCommand[1], out var idx)) { if (state.Data.RssEntries == null || idx >= state.Data.RssEntries.Count || idx < 0) { var rr = await api.RespondToUpdate(update, $"{from.FirstName}, index {idx} is not known"); return; } var keyWords = parsedCommand.Skip(2).Select(x => ParseKeyword(x)).ToHashSet(); state.Data.RssEntries[idx].Keywords = keyWords.ToArray(); state.Save(); var r = await api.RespondToUpdate(update, $"{from.FirstName}, {idx} was updated"); } else if (parsedCommand[1] == "add" && parsedCommand.Length >= 4 && int.TryParse(parsedCommand[2], out var addIdx)) { var addWords = parsedCommand.Select(x => ParseKeyword(x)).Skip(3); if (state.Data.RssEntries == null || addIdx >= state.Data.RssEntries.Count || addIdx < 0) { var rr = await api.RespondToUpdate(update, $"{from.FirstName}, index {addIdx} is not known"); return; } if (state.Data.RssEntries[idx].Keywords == null) { state.Data.RssEntries[idx].Keywords = addWords.ToArray(); } else { var words = state.Data.RssEntries[idx].Keywords.ToHashSet(); foreach (var newWord in addWords) { words.Add(newWord); } state.Data.RssEntries[idx].Keywords = words.ToArray(); } state.Save(); var r = await api.RespondToUpdate(update, $"{from.FirstName}, {idx} was updated"); } else if (parsedCommand[1] == "del" && parsedCommand.Length >= 4 && int.TryParse(parsedCommand[2], out var delIdx)) { var delWords = parsedCommand.Select(x => ParseKeyword(x)).Skip(3); if (state.Data.RssEntries == null || delIdx >= state.Data.RssEntries.Count || delIdx < 0) { var rr = await api.RespondToUpdate(update, $"{from.FirstName}, index {delIdx} is not known"); return; } if (state.Data.RssEntries[idx].Keywords != null) { var words = state.Data.RssEntries[idx].Keywords.ToHashSet(); foreach (var delWord in delWords) { words.Remove(delWord); } state.Data.RssEntries[idx].Keywords = words.ToArray(); } state.Save(); var note = (state.Data.RssEntries[idx].Keywords == null || state.Data.RssEntries[idx].Keywords.Length == 0) ? ", WARNING: keyword list is not empty" : ""; var r = await api.RespondToUpdate(update, $"{from.FirstName}, {idx} was updated{note}"); } else { var rr = await api.RespondToUpdate(update, $"{from.FirstName}, please give arguments to the command"); return; } }
private async Task HandleAuthenticatedUserAddCommand( ITelegramBotApi api, Update update, User from, Chat chat, long userId, string[] parsedCommand ) { UnStop(userId); if (parsedCommand.Length < 2) { var rr = await api.RespondToUpdate(update, $"{from.FirstName}, please give arguments to the command"); return; } var state = UserState <UserRssSubscriptions> .LoadOrDefault(userId); if (state.Data.RssEntries == null) { state.Data.RssEntries = new List <RssUrlEntry>(); } var url = parsedCommand[1]; var keyboards = parsedCommand.Skip(2).Select(x => ParseKeyword(x)).ToArray(); if (state.Data.RssEntries.Find(x => x.Url == url) != null) { var re = await api.RespondToUpdate(update, $"{from.FirstName}, the URI {url} is already in your list"); return; } var rssParsed = await _rssReader.FetchAndParse(url); if (rssParsed == null) { var re = await api.RespondToUpdate(update, $"{from.FirstName}, the URI {url} is not looking like a valid RSS"); return; } state.Data.RssEntries.Add(new RssUrlEntry { Url = url, Keywords = keyboards }); state.Save(); var rssPubDates = UserState <UserFeedPubDates> .LoadOrDefault(userId); if (rssPubDates.Data.PubDates == null) { rssPubDates.Data.PubDates = new SerializableDictionary <string, DateTime>(); } rssPubDates.Data.PubDates[url] = rssParsed.LastBuildDate; try { rssPubDates.Save(); } catch (Exception ex) { logger.Error(ex, "Exception while saving xml"); } var r = await api.RespondToUpdate(update, $"{from.FirstName}, it was added"); }
public async Task RunReceiveLoop() { var me = await _api.GetMe(); if (me != null) { Console.WriteLine("me: {0}", me.ToJsonString()); } long?nextOffset = null; for (; ;) { try { var updates = await _api.GetUpdates( offset : nextOffset, timeout : CallTimeout, limit : CallNumUpdatesLimit ); if (updates != null && updates.Count > 0) { foreach (var update in updates) { nextOffset = update.UpdateId + 1; if (update.Message == null) { continue; } if (VerboseLogging) { Telegram.User from = update.Message.From; long userId = update.Message.From.Id; string text = update.Message.Text ?? ""; Console.WriteLine($"{from.ToString()}: {userId} {text}"); } bool added = false; lock (_queueLock) { if (_queue.Count < QueueMaxSize) { _queue.Enqueue(update); Monitor.PulseAll(_queueLock); added = true; } } if (!added) { var msg = await _api.RespondToUpdate(update, "Bot internal queue overflow"); } } } else { Console.WriteLine("No Updates"); } await Task.Delay(100); } catch (TaskCanceledException ex) { await Task.Delay(10 * 1000); } } }