From 11acf0b2c5ca1640e8611c9c68164fb0b1df773f Mon Sep 17 00:00:00 2001 From: amateurforger Date: Wed, 18 Feb 2026 12:46:01 +0100 Subject: [PATCH 1/5] telegram: Start attachment downloads in the background --- bridge/telegram/handlers.go | 41 +++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/bridge/telegram/handlers.go b/bridge/telegram/handlers.go index b857b56d5..a70b05c1d 100644 --- a/bridge/telegram/handlers.go +++ b/bridge/telegram/handlers.go @@ -238,10 +238,9 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { // handle username b.handleUsername(&rmsg, message) - // handle any downloads - err := b.handleDownload(&rmsg, message) - if err != nil { - b.Log.Errorf("download failed: %s", err) + // File downloads are handled in the background + if b.handleBackgroundDownload(&rmsg, message) { + return } // handle forwarded messages @@ -265,6 +264,40 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { } } +// Check if the incoming telegram message contains attachment, and if so start +// processing it in the background so we don't block the main thread. +// +// Returns true if the message is being handle by this method. +func (b *Btelegram) handleBackgroundDownload(rmsg *config.Message, message *tgbotapi.Message) bool { + if message.Sticker != nil || message.Voice != nil || message.Video != nil || message.Audio != nil || message.Document != nil || message.Photo != nil { + go func() { + err := b.handleDownload(rmsg, message) + if err != nil { + b.Log.Errorf("download failed: %s", err) + } + + // Repeat the end of the handleRecv logic + b.handleForwarded(rmsg, message) + b.handleQuoting(rmsg, message) + + if rmsg.Text != "" || len(rmsg.Extra) > 0 { + if message.From != nil { + rmsg.Avatar = helper.GetAvatar(b.avatarMap, strconv.FormatInt(message.From.ID, 10), b.General) + } + + b.Log.Debugf("<= Sending message from %s on %s to gateway", rmsg.Username, b.Account) + b.Log.Debugf("<= Message is %#v", rmsg) + + b.Remote <- *rmsg + } + }() + + return true + } + + return false +} + func (b *Btelegram) handleGroupUpdate(update tgbotapi.Update) { if msg := update.Message; msg != nil { switch { From 4f7c51bee4af2ed3c85d25a9f054a327a10de216 Mon Sep 17 00:00:00 2001 From: amateurforger Date: Wed, 18 Feb 2026 12:57:38 +0100 Subject: [PATCH 2/5] telegram: handleDownload uses new attachment helpers --- bridge/telegram/handlers.go | 41 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/bridge/telegram/handlers.go b/bridge/telegram/handlers.go index a70b05c1d..fff1d7a93 100644 --- a/bridge/telegram/handlers.go +++ b/bridge/telegram/handlers.go @@ -418,29 +418,22 @@ func (b *Btelegram) maybeConvertWebp(name *string, data *[]byte) { // handleDownloadFile handles file download func (b *Btelegram) handleDownload(rmsg *config.Message, message *tgbotapi.Message) error { - size := int64(0) var url, name, text string switch { case message.Sticker != nil: text, name, url = b.getDownloadInfo(message.Sticker.FileID, ".webp", true) - size = int64(message.Sticker.FileSize) case message.Voice != nil: text, name, url = b.getDownloadInfo(message.Voice.FileID, ".ogg", true) - size = message.Voice.FileSize case message.Video != nil: text, name, url = b.getDownloadInfo(message.Video.FileID, "", true) - size = message.Video.FileSize case message.Audio != nil: text, name, url = b.getDownloadInfo(message.Audio.FileID, "", true) - size = message.Audio.FileSize case message.Document != nil: _, _, url = b.getDownloadInfo(message.Document.FileID, "", false) - size = message.Document.FileSize name = message.Document.FileName text = " " + message.Document.FileName + " : " + url case message.Photo != nil: photos := message.Photo - size = int64(photos[len(photos)-1].FileSize) text, name, url = b.getDownloadInfo(photos[len(photos)-1].FileID, "", true) } @@ -454,28 +447,34 @@ func (b *Btelegram) handleDownload(rmsg *config.Message, message *tgbotapi.Messa rmsg.Text += text return nil } - // if we have a file attached, download it (in memory) and put a pointer to it in msg.Extra - err := helper.HandleDownloadSize(b.Log, rmsg, name, int64(size), b.General) - if err != nil { - return err + + // rename .oga to .ogg https://github.com/42wim/matterbridge/issues/906#issuecomment-741793512 + if strings.HasSuffix(name, ".oga") && message.Audio != nil { + name = strings.Replace(name, ".oga", ".ogg", 1) } - data, err := helper.DownloadFile(url) + + err := b.AddAttachmentFromURL(rmsg, name, "", message.Caption, url) if err != nil { return err } - if strings.HasSuffix(name, ".tgs.webp") { - b.maybeConvertTgs(&name, data) - } else if strings.HasSuffix(name, ".webp") { - b.maybeConvertWebp(&name, data) - } + // TODO: maybe this could be moved to a new helper taking a function/closure + // to perform post-download processing. + for _, f := range rmsg.Extra["file"] { + fi, ok := f.(config.FileInfo) + if !ok { + continue + } - // rename .oga to .ogg https://github.com/42wim/matterbridge/issues/906#issuecomment-741793512 - if strings.HasSuffix(name, ".oga") && message.Audio != nil { - name = strings.Replace(name, ".oga", ".ogg", 1) + // Now that we have the file bytes, we may have some conversions to do + // TODO: I don't think f.SHA is computed already but make sure of it + if strings.HasSuffix(name, ".tgs.webp") { + b.maybeConvertTgs(&fi.Name, fi.Data) + } else if strings.HasSuffix(fi.Name, ".webp") { + b.maybeConvertWebp(&fi.Name, fi.Data) + } } - helper.HandleDownloadData(b.Log, rmsg, name, message.Caption, "", data, b.General) return nil } From 98b35ec7767460b37221a551a6ab5b0ef44ae0e5 Mon Sep 17 00:00:00 2001 From: amateurforger Date: Wed, 18 Feb 2026 13:27:18 +0100 Subject: [PATCH 3/5] telegram: Entire incoming message is processed in the background --- bridge/telegram/handlers.go | 161 ++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 91 deletions(-) diff --git a/bridge/telegram/handlers.go b/bridge/telegram/handlers.go index fff1d7a93..6998d7523 100644 --- a/bridge/telegram/handlers.go +++ b/bridge/telegram/handlers.go @@ -129,7 +129,9 @@ func (b *Btelegram) handleQuoting(rmsg *config.Message, message *tgbotapi.Messag } // handleUsername handles the correct setting of the username -func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Message) { +// +// This method may block due to downloading the remote avatar. +func (b *Btelegram) handleUsernameBlocking(rmsg *config.Message, message *tgbotapi.Message) { if message.From != nil { rmsg.UserID = strconv.FormatInt(message.From.ID, 10) if b.GetBool("UseFirstName") { @@ -148,7 +150,7 @@ func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Messa } // only download avatars if we have a place to upload them (configured mediaserver) if b.General.MediaServerDownload != "" && b.General.MediaDownloadPath != "" { - b.handleDownloadAvatar(message.From.ID, rmsg.Channel) + b.handleDownloadAvatarBlocking(message.From.ID, rmsg.Channel) } } @@ -172,7 +174,7 @@ func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Messa } // only download avatars if we have a place to upload them (configured mediaserver) if b.General.MediaServerDownload != "" && b.General.MediaDownloadPath != "" { - b.handleDownloadAvatar(message.SenderChat.ID, rmsg.Channel) + b.handleDownloadAvatarBlocking(message.SenderChat.ID, rmsg.Channel) } } @@ -187,115 +189,92 @@ func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Messa } } +// All messages are processed in the background, because attachments +// need to be processed in the background, but avatars too. +// +// We don't want to block the main thread! func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { for update := range updates { b.Log.Debugf("== Receiving event: %#v", update.Message) - if update.Message == nil && update.ChannelPost == nil && - update.EditedMessage == nil && update.EditedChannelPost == nil { - b.Log.Info("Received event without messages, skipping.") - continue - } - - if b.GetInt("debuglevel") == 1 { - spew.Dump(update.Message) - } - - b.handleGroupUpdate(update) + go b.handleRecvBackground(update) + } +} - var message *tgbotapi.Message +func (b *Btelegram) handleRecvBackground(update tgbotapi.Update) { + if update.Message == nil && update.ChannelPost == nil && + update.EditedMessage == nil && update.EditedChannelPost == nil { + b.Log.Info("Received event without messages, skipping.") + return + } - rmsg := config.Message{Account: b.Account, Extra: make(map[string][]interface{})} + if b.GetInt("debuglevel") == 1 { + spew.Dump(update.Message) + } - // handle channels - message = b.handleChannels(&rmsg, message, update) + b.handleGroupUpdate(update) - // handle groups - message = b.handleGroups(&rmsg, message, update) + var message *tgbotapi.Message - if message == nil { - b.Log.Error("message is nil, this shouldn't happen.") - continue - } + rmsg := config.Message{Account: b.Account, Extra: make(map[string][]any)} - // set the ID's from the channel or group message - rmsg.ID = strconv.Itoa(message.MessageID) - rmsg.Channel = strconv.FormatInt(message.Chat.ID, 10) - if message.IsTopicMessage { - rmsg.Channel += "/" + strconv.Itoa(message.MessageThreadID) - } + // handle channels + message = b.handleChannels(&rmsg, message, update) - // preserve threading from telegram reply - if message.ReplyToMessage != nil && - // Used to check if the message was a reply to the root topic - (!message.IsTopicMessage || message.ReplyToMessage.MessageID != message.MessageThreadID) { - rmsg.ParentID = strconv.Itoa(message.ReplyToMessage.MessageID) - } + // handle groups + message = b.handleGroups(&rmsg, message, update) - // handle entities (adding URLs) - b.handleEntities(&rmsg, message) + if message == nil { + b.Log.Error("message is nil, this shouldn't happen.") + return + } - // handle username - b.handleUsername(&rmsg, message) + // set the ID's from the channel or group message + rmsg.ID = strconv.Itoa(message.MessageID) - // File downloads are handled in the background - if b.handleBackgroundDownload(&rmsg, message) { - return - } + rmsg.Channel = strconv.FormatInt(message.Chat.ID, 10) + if message.IsTopicMessage { + rmsg.Channel += "/" + strconv.Itoa(message.MessageThreadID) + } - // handle forwarded messages - b.handleForwarded(&rmsg, message) + // preserve threading from telegram reply + if message.ReplyToMessage != nil && + // Used to check if the message was a reply to the root topic + (!message.IsTopicMessage || message.ReplyToMessage.MessageID != message.MessageThreadID) { + rmsg.ParentID = strconv.Itoa(message.ReplyToMessage.MessageID) + } - // quote the previous message - b.handleQuoting(&rmsg, message) + // handle entities (adding URLs) + b.handleEntities(&rmsg, message) - if rmsg.Text != "" || len(rmsg.Extra) > 0 { - // Comment the next line out due to avoid removing empty lines in Telegram - // rmsg.Text = helper.RemoveEmptyNewLines(rmsg.Text) - // channels don't have (always?) user information. see #410 - if message.From != nil { - rmsg.Avatar = helper.GetAvatar(b.avatarMap, strconv.FormatInt(message.From.ID, 10), b.General) - } + // handle username + b.handleUsernameBlocking(&rmsg, message) - b.Log.Debugf("<= Sending message from %s on %s to gateway", rmsg.Username, b.Account) - b.Log.Debugf("<= Message is %#v", rmsg) - b.Remote <- rmsg - } + // File downloads are handled in the background + err := b.handleDownloadBlocking(&rmsg, message) + if err != nil { + b.Log.Errorf("download failed: %s", err) } -} -// Check if the incoming telegram message contains attachment, and if so start -// processing it in the background so we don't block the main thread. -// -// Returns true if the message is being handle by this method. -func (b *Btelegram) handleBackgroundDownload(rmsg *config.Message, message *tgbotapi.Message) bool { - if message.Sticker != nil || message.Voice != nil || message.Video != nil || message.Audio != nil || message.Document != nil || message.Photo != nil { - go func() { - err := b.handleDownload(rmsg, message) - if err != nil { - b.Log.Errorf("download failed: %s", err) - } + // handle forwarded messages + b.handleForwarded(&rmsg, message) - // Repeat the end of the handleRecv logic - b.handleForwarded(rmsg, message) - b.handleQuoting(rmsg, message) - - if rmsg.Text != "" || len(rmsg.Extra) > 0 { - if message.From != nil { - rmsg.Avatar = helper.GetAvatar(b.avatarMap, strconv.FormatInt(message.From.ID, 10), b.General) - } + // quote the previous message + b.handleQuoting(&rmsg, message) - b.Log.Debugf("<= Sending message from %s on %s to gateway", rmsg.Username, b.Account) - b.Log.Debugf("<= Message is %#v", rmsg) + if rmsg.Text != "" || len(rmsg.Extra) > 0 { + // Comment the next line out due to avoid removing empty lines in Telegram + // rmsg.Text = helper.RemoveEmptyNewLines(rmsg.Text) + // channels don't have (always?) user information. see #410 + if message.From != nil { + rmsg.Avatar = helper.GetAvatar(b.avatarMap, strconv.FormatInt(message.From.ID, 10), b.General) + } - b.Remote <- *rmsg - } - }() + b.Log.Debugf("<= Sending message from %s on %s to gateway", rmsg.Username, b.Account) + b.Log.Debugf("<= Message is %#v", rmsg) - return true + b.Remote <- rmsg } - - return false } func (b *Btelegram) handleGroupUpdate(update tgbotapi.Update) { @@ -342,10 +321,10 @@ func (b *Btelegram) handleUserLeave(update tgbotapi.Update) { b.Remote <- rmsg } -// handleDownloadAvatar downloads the avatar of userid from channel +// handleDownloadAvatarBlocking downloads the avatar of userid from channel // sends a EVENT_AVATAR_DOWNLOAD message to the gateway if successful. // logs an error message if it fails -func (b *Btelegram) handleDownloadAvatar(userid int64, channel string) { +func (b *Btelegram) handleDownloadAvatarBlocking(userid int64, channel string) { rmsg := config.Message{ Username: "system", Text: "avatar", @@ -416,8 +395,8 @@ func (b *Btelegram) maybeConvertWebp(name *string, data *[]byte) { } } -// handleDownloadFile handles file download -func (b *Btelegram) handleDownload(rmsg *config.Message, message *tgbotapi.Message) error { +// handleDownloadBlockin handles file download +func (b *Btelegram) handleDownloadBlocking(rmsg *config.Message, message *tgbotapi.Message) error { var url, name, text string switch { case message.Sticker != nil: From fbc3aa7f4f88afe27272e2c88aa75b6826d2397f Mon Sep 17 00:00:00 2001 From: amateurforger Date: Wed, 18 Feb 2026 14:48:24 +0100 Subject: [PATCH 4/5] telegram: Refactor some stuff and add helpers --- bridge/telegram/handlers.go | 98 +++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 52 deletions(-) diff --git a/bridge/telegram/handlers.go b/bridge/telegram/handlers.go index 6998d7523..9ab0d2be8 100644 --- a/bridge/telegram/handlers.go +++ b/bridge/telegram/handlers.go @@ -132,61 +132,51 @@ func (b *Btelegram) handleQuoting(rmsg *config.Message, message *tgbotapi.Messag // // This method may block due to downloading the remote avatar. func (b *Btelegram) handleUsernameBlocking(rmsg *config.Message, message *tgbotapi.Message) { - if message.From != nil { - rmsg.UserID = strconv.FormatInt(message.From.ID, 10) - if b.GetBool("UseFirstName") { - rmsg.Username = message.From.FirstName - } - if b.GetBool("UseFullName") { - if message.From.FirstName != "" && message.From.LastName != "" { - rmsg.Username = message.From.FirstName + " " + message.From.LastName - } - } - if rmsg.Username == "" { - rmsg.Username = message.From.UserName - if rmsg.Username == "" { - rmsg.Username = message.From.FirstName - } - } - // only download avatars if we have a place to upload them (configured mediaserver) - if b.General.MediaServerDownload != "" && b.General.MediaDownloadPath != "" { - b.handleDownloadAvatarBlocking(message.From.ID, rmsg.Channel) - } + var ( + firstName, lastName, userName string + id int64 + ) + + switch { + case message.From != nil: + firstName = message.From.FirstName + lastName = message.From.LastName + userName = message.From.UserName + id = message.From.ID + case message.SenderChat != nil: + // TODO: here previous code was checking for rmsg.Username == "Channel_Bot" + // and performing what i believe was unnecessary steps. If problems arise, + // look at that first. + firstName = message.SenderChat.FirstName + lastName = message.SenderChat.LastName + userName = message.SenderChat.UserName + id = message.SenderChat.ID } - if message.SenderChat != nil { //nolint:nestif - rmsg.UserID = strconv.FormatInt(message.SenderChat.ID, 10) - if b.GetBool("UseFirstName") { - rmsg.Username = message.SenderChat.FirstName - } - if b.GetBool("UseFullName") { - if message.SenderChat.FirstName != "" && message.SenderChat.LastName != "" { - rmsg.Username = message.SenderChat.FirstName + " " + message.SenderChat.LastName - } - } + if b.GetBool("UseFirstName") { + rmsg.Username = firstName + } - if rmsg.Username == "" || rmsg.Username == "Channel_Bot" { - rmsg.Username = message.SenderChat.UserName + if b.GetBool("UseFullName") && lastName != "" { + rmsg.Username = rmsg.Username + " " + lastName + } - if rmsg.Username == "" || rmsg.Username == "Channel_Bot" { - rmsg.Username = message.SenderChat.FirstName - } - } - // only download avatars if we have a place to upload them (configured mediaserver) - if b.General.MediaServerDownload != "" && b.General.MediaDownloadPath != "" { - b.handleDownloadAvatarBlocking(message.SenderChat.ID, rmsg.Channel) + if rmsg.Username == "" { + if userName != "" { + rmsg.Username = userName + } else { + // if we really didn't find a username, set it to unknown + rmsg.Username = unknownUser } } + rmsg.UserID = strconv.FormatInt(id, 10) + b.handleDownloadAvatarBlocking(id, rmsg.Channel) + // Fallback on author signature (used in "channel" type of chat) if rmsg.Username == "" && message.AuthorSignature != "" { rmsg.Username = message.AuthorSignature } - - // if we really didn't find a username, set it to unknown - if rmsg.Username == "" { - rmsg.Username = unknownUser - } } // All messages are processed in the background, because attachments @@ -407,6 +397,10 @@ func (b *Btelegram) handleDownloadBlocking(rmsg *config.Message, message *tgbota text, name, url = b.getDownloadInfo(message.Video.FileID, "", true) case message.Audio != nil: text, name, url = b.getDownloadInfo(message.Audio.FileID, "", true) + // rename .oga to .ogg https://github.com/42wim/matterbridge/issues/906#issuecomment-741793512 + if strings.HasSuffix(name, ".oga") { + name = strings.Replace(name, ".oga", ".ogg", 1) + } case message.Document != nil: _, _, url = b.getDownloadInfo(message.Document.FileID, "", false) name = message.Document.FileName @@ -427,16 +421,18 @@ func (b *Btelegram) handleDownloadBlocking(rmsg *config.Message, message *tgbota return nil } - // rename .oga to .ogg https://github.com/42wim/matterbridge/issues/906#issuecomment-741793512 - if strings.HasSuffix(name, ".oga") && message.Audio != nil { - name = strings.Replace(name, ".oga", ".ogg", 1) - } - err := b.AddAttachmentFromURL(rmsg, name, "", message.Caption, url) if err != nil { return err } + // Perform file format conversions for interop + b.handleDownloadPostProcessBlocking(rmsg) + + return nil +} + +func (b *Btelegram) handleDownloadPostProcessBlocking(rmsg *config.Message) { // TODO: maybe this could be moved to a new helper taking a function/closure // to perform post-download processing. for _, f := range rmsg.Extra["file"] { @@ -447,14 +443,12 @@ func (b *Btelegram) handleDownloadBlocking(rmsg *config.Message, message *tgbota // Now that we have the file bytes, we may have some conversions to do // TODO: I don't think f.SHA is computed already but make sure of it - if strings.HasSuffix(name, ".tgs.webp") { + if strings.HasSuffix(fi.Name, ".tgs.webp") { b.maybeConvertTgs(&fi.Name, fi.Data) } else if strings.HasSuffix(fi.Name, ".webp") { b.maybeConvertWebp(&fi.Name, fi.Data) } } - - return nil } func (b *Btelegram) getDownloadInfo(id string, suffix string, urlpart bool) (string, string, string) { From 677cd2a4dfdf9b256948e64a40ec6d66b2239ef7 Mon Sep 17 00:00:00 2001 From: amateurforger Date: Wed, 18 Feb 2026 15:09:04 +0100 Subject: [PATCH 5/5] telegram: WIP send messages to telegram in the background --- bridge/telegram/telegram.go | 47 +++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/bridge/telegram/telegram.go b/bridge/telegram/telegram.go index 8c15486f9..dbfc349fc 100644 --- a/bridge/telegram/telegram.go +++ b/bridge/telegram/telegram.go @@ -118,6 +118,31 @@ func (b *Btelegram) getIds(channel string) (int64, int, error) { return chatid, topicid, nil } +// Send TODO: We process the message in the background, +// but now we can't return the produced message IDs. +// +// Also, if there are several attachments, `SendMediaGroup` will +// return several messages, but we currently only get 1 message ID +// to store on matterbridge side. Unless the method returns a +// sort of parent message which will aggregate all replies +// (which may be the case, but if so is undocumented), we want +// to map all telegram replies to any of those messages +// back to the original message. +// +// We need to perform more logic somehow with new helpers/channels +// Currently, the logic for saving message IDs is in gateway/handlers.go +// in the `handleMessage` function, returning IDs to +// `gateway/routeur.go:handleReceive` which in turn will +// save all gateway produced message IDs to associate with the +// original message ID being broadcast. It seems like there is no +// gateway-specific association/typing in there so collisions +// between networks is possible???? +// +// So we probably want a new helper like `b.RegisterMessageID(string, []string)` +// which individual bridges can call once they know an association should be +// performed, and which should just silently ignore the case when `rmsg.ID` +// (first argument) is an empty string. (ideally, we'd like to separate IDs +// of different networks, but well let's not get ahead of ourselves). func (b *Btelegram) Send(msg config.Message) (string, error) { b.Log.Debugf("=> Receiving %#v", msg) @@ -135,9 +160,19 @@ func (b *Btelegram) Send(msg config.Message) (string, error) { msg.Text = makeHTML(html.EscapeString(msg.Text)) } + // Perform blocking operations in the background + go b.SendBlocking(&msg, chatid, topicid) + + // TODO: see big TODO above about message ID correctness + return "", nil +} + +func (b *Btelegram) SendBlocking(msg *config.Message, chatid int64, topicid int) { + // TODO: Maybe still produce an error that can be logged by the Send method? + // Delete message if msg.Event == config.EventMsgDelete { - return b.handleDelete(&msg, chatid) + _, _ = b.handleDelete(msg, chatid) } // Handle prefix hint for unthreaded messages. @@ -153,20 +188,20 @@ func (b *Btelegram) Send(msg config.Message) (string, error) { // Upload a file if it exists if msg.Extra != nil { - for _, rmsg := range helper.HandleExtra(&msg, b.General) { + for _, rmsg := range helper.HandleExtra(msg, b.General) { if _, msgErr := b.sendMessage(chatid, topicid, rmsg.Username, rmsg.Text, parentID); msgErr != nil { b.Log.Errorf("sendMessage failed: %s", msgErr) } } // check if we have files to upload (from slack, telegram or mattermost) if len(msg.Extra["file"]) > 0 { - return b.handleUploadFile(&msg, chatid, topicid, parentID) + _, _ = b.handleUploadFile(msg, chatid, topicid, parentID) } } // edit the message if we have a msg ID if msg.ID != "" { - return b.handleEdit(&msg, chatid) + _, _ = b.handleEdit(msg, chatid) } // Post normal message @@ -174,10 +209,8 @@ func (b *Btelegram) Send(msg config.Message) (string, error) { // Ignore empty text field needs for prevent double messages from whatsapp to telegram // when sending media with text caption if msg.Text != "" { - return b.sendMessage(chatid, topicid, msg.Username, msg.Text, parentID) + _, _ = b.sendMessage(chatid, topicid, msg.Username, msg.Text, parentID) } - - return "", nil } func (b *Btelegram) getFileDirectURL(id string) string {