首页 > 解决方案 > 如何根据内容按顺序对消息进行分组

问题描述

以下代码用于在 Telegram 机器人中显示消息。

当应用程序打印文本时,它被放入一个队列中,队列被合并并定期刷新。这是为了尽量减少 API 调用的数量。

同时,每条发送的消息有 4kb 的限制,因此只要总数不超过 4kb,消息就会被分组。

此外,消息可以声明为降价或纯文本。所有消息通常作为降价发送,但包含堆栈跟踪等的错误消息在降价模式下不起作用,Telegram 只是忽略它们。那里的消息总是标有一些“警报”符号。他们必须自己发送。

例如:

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

将被发送为:

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

这是使用的代码:

    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')

它有效,但我认为它不是很可读。此外,发送消息的代码正在再次查找警报字符:

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

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

所以,总的来说,我正在寻找一种更优雅的方式来处理这个问题。

标签: f#

解决方案


推荐阅读