Beispiel #1
0
        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]");
        }
Beispiel #2
0
        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");
        }
Beispiel #3
0
        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");
            }
        }
Beispiel #4
0
        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}");
                }
            }
        }
Beispiel #5
0
 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");
 }
Beispiel #6
0
        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");
            }
        }
Beispiel #7
0
        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");
        }
Beispiel #8
0
        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");
        }
Beispiel #9
0
        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");
        }
Beispiel #10
0
        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.
");
        }
Beispiel #11
0
        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;
            }
        }
Beispiel #12
0
        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;
            }
        }
Beispiel #13
0
        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");
        }
Beispiel #14
0
        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);
                }
            }
        }