2020年12月23日星期三

How to group messages, in order, based on the contents

The following code is used to display message in a Telegram bot.

When the application prints text, it is put in a queue and the queue gets consolidated and is flushed at regular intervals. This is meant to minimize the number of API calls.

At the same time, there is a limit of 4kb per message sent, so the messages get grouped as long as the total does not exceed 4kb.

Additionally, messages can be declared as markdown or plain text. All messages are typically sent as markdown, but error messages that contain stack traces, etc don't work in markdown mode, Telegram just ignores them. There messages always get marked with some 'alert' symbol. And they have to be sent on their own.

For example:

message 1  message 2  Alert message 3  message 4  message 5  message LARGE SIZE 6  message 7  

would be sent as:

message 1 + message 2 (markdown)  Alert message 3 (plain)  message 4 + message 5 (markdown)  message LARGE SIZE 6 (markdown)  message 7 (markdown)  

this is the code used:

let hasAlertCharacter (message: string) = message.Contains(interruptIcon) || message.Contains(waitForUserIcon) || message.Contains(waitForEventIcon) || message.Contains(warningIcon) || message.Contains(errorIcon)

let sizeLimit = 4000  let rec takeMessages (message: string) =      let r, m = messageQueue.TryPeek()      if r && message.Length + m.Length + 1 < sizeLimit then          if hasAlertCharacter m then              if String.IsNullOrEmpty(message) then                  messageQueue.TryDequeue() |> ignore                  m              else                  message          else              messageQueue.TryDequeue() |> ignore              takeMessages $"{message}\n{m}"      else          message      let messagesString = (takeMessages String.Empty).TrimStart('\n')  

it works, but I think it's not very readable. Additionally, the code that sends the message is looking for the alert characters again:

let parseMode = match hasAlertCharacter messagesString with | true -> ParseMode.Default | false -> ParseMode.Markdown

client.SendTextMessageAsync(chatId, messagesString, parseMode)  |> Async.AwaitTask  |> Async.RunSynchronously  |> ignore  

so, overall, I am looking for a more elegant way to handle this.

https://stackoverflow.com/questions/65432784/how-to-group-messages-in-order-based-on-the-contents December 24, 2020 at 09:05AM

没有评论:

发表评论