Ejemplo n.º 1
0
        /// <summary>
        /// Add a new expected reply to the stack. Should be called internally only - New messages should be sent via TelegramAPI.GetExpectedReply
        /// </summary>
        /// <param name="e"></param>
        /// <param name="trySendImmediately">Try and send the message immediately, assuming nothing is outstanding. Will jump the queue, but not override any existing messages</param>
        /// <returns>An integer specifying the message id. -1 indicates it is queueed, long.MinValue indicates a failure</returns>
        public long newExpectedReply(ExpectedReply e, bool trySendImmediately)
        {
            //flag the user as present in the chat
            if (e.isPrivateMessage)
            {
                markPresence(e.userID, e.chatID, e.userName);
            }

            //check if we can send it? Get the messageID back
            long messageID = -1;

            //is this a message to a group?
            if (!e.isPrivateMessage)
            {
                //send, dont queue.
                //TODO - doesnt handle group PMs
                messageID = e.sendMessage();
            }
            //this is a PM. Does the user have anything in the queue?
            else if (!userHasOutstandingMessages(e.userID))
            {
                //send the message.
                messageID = e.sendMessage();
                //queue if it was a question
                if (e.expectsReply)
                {
                    expectedReplies.Add(e);
                }
            }
            //If they have messages in the queue, and we want to jump ahead, has one already been asked, or are we open?
            else if (trySendImmediately && !userHasOutstandingQuestions(e.userID))
            {
                Roboto.log.log("Message jumping queue due to immediatemode", logging.loglevel.verbose);
                //send the message, grab the ID.
                messageID = e.sendMessage();
                //did it work/
                if (messageID == long.MinValue)
                {
                    Roboto.log.log("Tried to send message using immediateMode, but it failed.", logging.loglevel.warn);
                    return(messageID);
                }

                //queue if it was a question
                else if (e.expectsReply)
                {
                    expectedReplies.Add(e);
                }
            }
            else
            {
                //chuck it on the stack if its going to be queued
                expectedReplies.Add(e);
            }

            //make sure we are in a safe state. This will make sure if we sent a message-only, that the next message(s) are processed.
            expectedReplyHousekeeping();

            return(messageID);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Make sure any reply processing is being done
        /// </summary>
        public void expectedReplyHousekeeping()
        {
            //Build up a list of user IDs
            //List<int> userIDs = new List<int>();
            //foreach (ExpectedReply e in expectedReplies) { userIDs.Add(e.userID); }
            //userIDs = (List<int>)userIDs.Distinct<int>();
            try
            {
                List <long> userIDs = expectedReplies.Select(e => e.userID).Distinct().ToList <long>();

                //remove any invalid messages
                List <ExpectedReply> messagesToRemove = expectedReplies.Where(e => e.outboundMessageID > 0 && e.expectsReply == false).ToList();
                if (messagesToRemove.Count > 0)
                {
                    Roboto.log.log("Removing " + messagesToRemove.Count() + " messages from queue as they are sent and dont require a reply", logging.loglevel.warn);
                }
                foreach (ExpectedReply e in messagesToRemove)
                {
                    expectedReplies.Remove(e);
                }



                foreach (long userID in userIDs)
                {
                    bool retry = true;
                    while (retry)
                    {
                        //for each user, check if a message has been sent, and track the oldest message
                        ExpectedReply        oldest      = null;
                        List <ExpectedReply> userReplies = expectedReplies.Where(e => e.userID == userID).ToList();

                        //try find a message to send. Drop out if we already have a sent message on the stack (waiting for a reply)
                        bool sent = false;
                        foreach (ExpectedReply e in userReplies)
                        {
                            if (e.isSent())
                            {
                                sent = true;
                            }                                //message is waiting
                            else
                            {
                                if (oldest == null || e.timeLogged < oldest.timeLogged)
                                {
                                    oldest = e;
                                }
                            }
                        }

                        //send the message if neccessary
                        if (!sent && oldest != null)
                        {
                            oldest.sendMessage();
                            if (!oldest.expectsReply)
                            {
                                expectedReplies.Remove(oldest);
                            }
                            //make sure we are in a safe state. This will make sure if we sent a message-only, that the next message(s) are processed.
                        }

                        //what do we do next?
                        if (sent == true)
                        {
                            retry = false;
                        }                                    // drop out if we have a message awaiting an answer
                        else if (oldest == null)
                        {
                            retry = false;
                        }                                           // drop out if we have no messages to send
                        else if (oldest.expectsReply)
                        {
                            retry = false;
                        }                                                //drop out if we sent a message that expects a reply
                    }
                }
            }
            catch (Exception e)
            {
                Roboto.log.log("Error during expected reply housekeeping " + e.ToString(), logging.loglevel.critical);
            }
        }