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 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 void UnStop(long userId) { var state = UserState <UserMuteState> .LoadOrDefault(userId); if (state.Data.Stopped) { state.Data.Stopped = false; state.Save(); } }
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 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 HandleUserMessageAsync(ITelegramBotApi api, Update update) { User from = update.Message.From; Chat chat = update.Message.Chat; long userId = update.Message.From.Id; string text = update.Message.Text ?? ""; string[] commandItems = text.Split(' '); if (commandItems.Length < 1) { return; } if (UserState <UserDetails> .ExistsFor(userId) && UserState <UserDetails> .LoadOrDefault(userId).Data.AuthValid) { await HandleAuthenticatedUserCommand(api, update, from, chat, userId, commandItems); } else { await HandleNonAuthenticatedUserCommand(api, update, from, chat, userId, commandItems); } }
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 RunFetcherAsync(UserDetails user) { var rssDetails = UserState <UserRssSubscriptions> .LoadOrDefault(user.UserId); var rssPubDates = UserState <UserFeedPubDates> .LoadOrDefault(user.UserId); var muteSettings = UserState <UserMuteState> .LoadOrDefault(user.UserId); if (muteSettings.Data.Stopped) { logger.Info($"Bot is stopped for {user.UserId} -- skipping"); return; } var now = DateTime.Now; bool isMuted = muteSettings.Data.IsMutedNow(ref now); logger.Info($"User {user.UserId} has {rssDetails.Data.RssEntries?.Count} feeds"); if ((rssDetails.Data.RssEntries?.Count ?? 0) == 0) { return; } var fetchAndParseTasks = rssDetails.Data .RssEntries .Select(feed => _rssReader.FetchAndParse(feed.Url)) .ToArray(); RssFeed[] results = await Task.WhenAll(fetchAndParseTasks); if (rssPubDates.Data.PubDates == null) { rssPubDates.Data.PubDates = new SerializableDictionary <string, DateTime>(); } for (int feedIdx = 0; feedIdx < results.Length; ++feedIdx) { var feedInfo = rssDetails.Data.RssEntries[feedIdx]; var feedData = results[feedIdx]; if (feedData == null) { logger.Info($"User {user.UserId}, feed {feedInfo.Url}: fetch/parse failed"); continue; } if (rssPubDates.Data.PubDates.TryGetValue(feedInfo.Url, out var prevPubDate)) { if (prevPubDate == feedData.LastBuildDate && prevPubDate != DateTime.MinValue) { logger.Info($"User {user.UserId}, feed {feedInfo.Url}: Feed didnt update"); continue; } } else { prevPubDate = DateTime.MinValue; } logger.Info($"User {user.UserId}, feed {feedInfo.Url}: Feed did update, new pub date: {feedData.LastBuildDate}"); rssPubDates.Data.PubDates[feedInfo.Url] = feedData.LastBuildDate; foreach (var item in feedData.Items) { if (item.PublicationDate <= prevPubDate && prevPubDate != DateTime.MinValue) { continue; // skipping the old item } logger.Info($"User {user.UserId}, feed {feedInfo.Url}: new feed item: {item.Title}, {item.Link}"); if (rssPubDates.Data.IsRecent(item.Link)) { logger.Info($"User {user.UserId}, feed {feedInfo.Url}: user has seen this recently, skipping: {item.Link}"); continue; } bool hasKeywords = feedInfo.Keywords.Length == 0; foreach (var kw in feedInfo.Keywords) { if (item.Title.Contains(kw, StringComparison.InvariantCultureIgnoreCase)) { hasKeywords = true; break; } else if (item.Description.Contains(kw, StringComparison.InvariantCultureIgnoreCase)) { hasKeywords = true; break; } } if (hasKeywords) { if (rssPubDates.Data.IsRecentNotification(item.Title, item.Description)) { logger.Info($"User {user.UserId}, feed {feedInfo.Url}: user has seen this recently, skipping: {item.Link} - skipped by the notification content that was sent today"); continue; } rssPubDates.Data.AddRecentLink(item.Link); rssPubDates.Data.AddRecentNotification(item.Title, item.Description); await SendRssItem(user, item, isMuted); } } } rssPubDates.Save(); }
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"); }