Golang程序运行时如何禁用频道的更新消息

Golang程序运行时如何禁用频道的更新消息 你好 Dylan,

(我在 Go 论坛上发布了这个问题,但尚未收到回复。)

我正在使用 TDlib 开发一个 Telegram Golang 程序。每次运行程序时,它都会获取大约一小时或更早之前的 20 条消息。我希望避免获取这些消息,感谢你的建议。

通常,我会收到实例未激活时错过的所有消息。如果错过的消息很多,启动后很快就会收到大量 updateNewMessage 更新。

我希望通过检查消息的发送 date,跳过所有在实例启动前发送的消息更新。

我的程序大致如下:

// 每 5 秒向 Foursquare 机器人聊天发送 "/start" 文本
go func() {
    // 需要以某种方式获取 chatID,请参考 "getChats" 示例
    chatID := int64(198529620) // Foursquare 机器人聊天 ID

    inputMsgTxt := tdlib.NewInputMessageText(tdlib.NewFormattedText("/start", nil), true, true)
    client.SendMessage(chatID, 0, 0, nil, nil, inputMsgTxt)

    time.Sleep(5 * time.Second)
}()

// rawUpdates 获取来自 tdlib 的所有更新
rawUpdates := client.GetRawUpdatesChannel(100)
for update := range rawUpdates {
    // 显示所有更新
    fmt.Println(update.Data)
    fmt.Print("\n\n")
}

感谢你的建议。

祝好


更多关于Golang程序运行时如何禁用频道的更新消息的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

亲爱的 @skillian@mje

感谢你们的帮助和建议,我已经能够编译程序以避免先前的运行时更新。 我认为现在它可以正常工作了。 如果遇到问题,我会再次请教。

祝好

更多关于Golang程序运行时如何禁用频道的更新消息的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


miketsbk:

rawUpdates := client.GetRawUpdatesChannel(100)
for update := range rawUpdates {
// Show all updates
fmt.Println(update.Data)
fmt.Print("\n\n")
}

我对这个库一无所知,但update中是否包含日期信息?你能否在for update := range rawUpdates循环中检查那个日期,并跳过打印所有你不希望接收的时间段的更新?

亲爱的肖恩,

感谢你的邮件和帮助。消息内容大致如下:

rawUpdates := client.GetRawUpdatesChannel(100)
for update := range rawUpdates {
    // 显示所有更新

    updateMsg := (update).(*tdlib.UpdateNewMessage)
    msgText := updateMsg.Message.Content.(*tdlib.MessageText)
    mangledText := strings.Replace(msgText.Text.Text, "AAA", "BBB", -1)
    mangledText = strings.Replace(mangledText, "CCC", "DDD", -1)

    fmt.Println(update.Data)
    fmt.Print("\n\n")
}

如果能提供一个示例,说明如何对消息应用时间筛选并跳过该时间点之前的消息,我将不胜感激。 另外,我该如何为程序定义运行的开始时间。

祝好

@mje 所说的一致,但 Date 字段在 Jeff 提到的包以及我在谷歌搜索结果中找到的包中似乎都是 int32 类型:https://pkg.go.dev/github.com/Arman92/go-tdlib/v2/tdlib#Message

我找到的包中的 NewMessage 函数(就在 Message 文档下方)将 dateeditDate 参数描述为“Unix 时间戳”。你应该可以使用 time.Unix 并将那个 int32 值作为 Unix 函数的 sec 参数传入(该函数期望参数是 int64,所以你必须进行转换)。然后,你可以执行 Jeff 提到的日期检查,以查看它是否早于你想要的日期。

如果你想获取程序启动的日期,可以使用一个全局变量来保存该日期:

var programStartTime = time.Now()

由于似乎没有 godoc 文档,你需要参考位于 GitHub - zelenin/go-tdlib: Go wrapper for TDLib (Telegram Database Library) 的最终文档。UpdateNewMessage https://github.com/zelenin/go-tdlib/blob/master/client/type.go#L28979-L28983 有一个 *Message 字段,而 Message 有一个 Date 字段:https://github.com/zelenin/go-tdlib/blob/master/client/type.go#L6321-L6322

 // Define the earliest time to allow.  https://pkg.go.dev/time#Date
 earlyTimeLimit := time.Date(2022, 9, 7, 12, 0, 0, 0, time.UTC).Unix(); 


 // Later, filter messages
  if updateMsg.Message.Date < earlyTimeLimit  {
    // Skip message that is too early.
    continue
  }

在TDlib中处理updateNewMessage更新时,可以通过检查消息的发送时间来控制是否处理历史消息。以下是实现方案:

// 在程序启动时记录启动时间
programStartTime := time.Now().Unix()

// 处理更新
rawUpdates := client.GetRawUpdatesChannel(100)
for update := range rawUpdates {
    // 检查是否为消息更新
    if update.Data["@type"] == "updateNewMessage" {
        msgData, ok := update.Data["message"].(map[string]interface{})
        if !ok {
            continue
        }
        
        // 获取消息时间戳
        date, ok := msgData["date"].(float64)
        if !ok {
            continue
        }
        
        // 跳过程序启动前的消息
        if int64(date) < programStartTime {
            continue
        }
        
        // 处理新消息
        fmt.Println("处理新消息:", update.Data)
    }
    
    fmt.Print("\n\n")
}

如果需要更精确的消息过滤,可以结合消息ID进行处理:

// 存储已处理的最新消息ID
var lastProcessedMessageID int64

// 在更新循环中
if update.Data["@type"] == "updateNewMessage" {
    msgData, ok := update.Data["message"].(map[string]interface{})
    if !ok {
        continue
    }
    
    // 获取消息ID
    msgID, ok := msgData["id"].(float64)
    if !ok {
        continue
    }
    
    // 获取消息时间
    date, ok := msgData["date"].(float64)
    if !ok {
        continue
    }
    
    // 跳过旧消息
    if int64(date) < programStartTime || int64(msgID) <= lastProcessedMessageID {
        continue
    }
    
    // 更新最后处理的消息ID
    lastProcessedMessageID = int64(msgID)
    
    // 处理消息
    fmt.Println("处理消息ID:", msgID, "时间:", date)
}

对于TDlib的特定类型,可以使用类型断言:

type UpdateNewMessage struct {
    Message tdlib.Message `json:"message"`
}

// 在更新处理中
updateJSON, _ := json.Marshal(update.Data)
var newMsgUpdate UpdateNewMessage
json.Unmarshal(updateJSON, &newMsgUpdate)

if newMsgUpdate.Message.Date < programStartTime {
    continue
}

这种方法确保只处理程序启动后收到的新消息,避免处理历史消息。

回到顶部