summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bridge/telegram/handlers.go302
-rw-r--r--bridge/telegram/html.go2
-rw-r--r--bridge/telegram/telegram.go280
3 files changed, 306 insertions, 278 deletions
diff --git a/bridge/telegram/handlers.go b/bridge/telegram/handlers.go
new file mode 100644
index 00000000..810043b5
--- /dev/null
+++ b/bridge/telegram/handlers.go
@@ -0,0 +1,302 @@
+package btelegram
+
+import (
+ "regexp"
+ "strconv"
+ "strings"
+
+ "github.com/42wim/matterbridge/bridge/config"
+ "github.com/42wim/matterbridge/bridge/helper"
+ "github.com/go-telegram-bot-api/telegram-bot-api"
+)
+
+func (b *Btelegram) handleUpdate(rmsg *config.Message, message, posted, edited *tgbotapi.Message) *tgbotapi.Message {
+ // handle channels
+ if posted != nil {
+ message = posted
+ rmsg.Text = message.Text
+ }
+
+ // edited channel message
+ if edited != nil && !b.GetBool("EditDisable") {
+ message = edited
+ rmsg.Text = rmsg.Text + message.Text + b.GetString("EditSuffix")
+ }
+ return message
+}
+
+// handleChannels checks if it's a channel message and if the message is a new or edited messages
+func (b *Btelegram) handleChannels(rmsg *config.Message, message *tgbotapi.Message, update tgbotapi.Update) *tgbotapi.Message {
+ return b.handleUpdate(rmsg, message, update.ChannelPost, update.EditedChannelPost)
+}
+
+// handleGroups checks if it's a group message and if the message is a new or edited messages
+func (b *Btelegram) handleGroups(rmsg *config.Message, message *tgbotapi.Message, update tgbotapi.Update) *tgbotapi.Message {
+ return b.handleUpdate(rmsg, message, update.Message, update.EditedMessage)
+}
+
+// handleForwarded handles forwarded messages
+func (b *Btelegram) handleForwarded(rmsg *config.Message, message *tgbotapi.Message) {
+ if message.ForwardFrom != nil {
+ usernameForward := ""
+ if b.GetBool("UseFirstName") {
+ usernameForward = message.ForwardFrom.FirstName
+ }
+ if usernameForward == "" {
+ usernameForward = message.ForwardFrom.UserName
+ if usernameForward == "" {
+ usernameForward = message.ForwardFrom.FirstName
+ }
+ }
+ if usernameForward == "" {
+ usernameForward = unknownUser
+ }
+ rmsg.Text = "Forwarded from " + usernameForward + ": " + rmsg.Text
+ }
+}
+
+// handleQuoting handles quoting of previous messages
+func (b *Btelegram) handleQuoting(rmsg *config.Message, message *tgbotapi.Message) {
+ if message.ReplyToMessage != nil {
+ usernameReply := ""
+ if message.ReplyToMessage.From != nil {
+ if b.GetBool("UseFirstName") {
+ usernameReply = message.ReplyToMessage.From.FirstName
+ }
+ if usernameReply == "" {
+ usernameReply = message.ReplyToMessage.From.UserName
+ if usernameReply == "" {
+ usernameReply = message.ReplyToMessage.From.FirstName
+ }
+ }
+ }
+ if usernameReply == "" {
+ usernameReply = unknownUser
+ }
+ if !b.GetBool("QuoteDisable") {
+ rmsg.Text = b.handleQuote(rmsg.Text, usernameReply, message.ReplyToMessage.Text)
+ }
+ }
+}
+
+// handleUsername handles the correct setting of the username
+func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Message) {
+ if message.From != nil {
+ rmsg.UserID = strconv.Itoa(message.From.ID)
+ if b.GetBool("UseFirstName") {
+ rmsg.Username = message.From.FirstName
+ }
+ 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.MediaServerUpload != "" {
+ b.handleDownloadAvatar(message.From.ID, rmsg.Channel)
+ }
+ }
+
+ // if we really didn't find a username, set it to unknown
+ if rmsg.Username == "" {
+ rmsg.Username = unknownUser
+ }
+}
+
+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.Error("Getting nil messages, this shouldn't happen.")
+ continue
+ }
+
+ var message *tgbotapi.Message
+
+ rmsg := config.Message{Account: b.Account, Extra: make(map[string][]interface{})}
+
+ // handle channels
+ b.handleChannels(&rmsg, message, update)
+
+ // handle groups
+ b.handleGroups(&rmsg, message, update)
+
+ // set the ID's from the channel or group message
+ rmsg.ID = strconv.Itoa(message.MessageID)
+ rmsg.Channel = strconv.FormatInt(message.Chat.ID, 10)
+
+ // handle username
+ b.handleUsername(&rmsg, message)
+
+ // handle any downloads
+ err := b.handleDownload(&rmsg, message)
+ if err != nil {
+ b.Log.Errorf("download failed: %s", err)
+ }
+
+ // handle forwarded messages
+ b.handleForwarded(&rmsg, message)
+
+ // quote the previous message
+ b.handleQuoting(&rmsg, message)
+
+ if rmsg.Text != "" || len(rmsg.Extra) > 0 {
+ 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.Itoa(message.From.ID), 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
+ }
+ }
+}
+
+// handleDownloadAvatar 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 int, channel string) {
+ rmsg := config.Message{Username: "system",
+ Text: "avatar",
+ Channel: channel,
+ Account: b.Account,
+ UserID: strconv.Itoa(userid),
+ Event: config.EventAvatarDownload,
+ Extra: make(map[string][]interface{})}
+
+ if _, ok := b.avatarMap[strconv.Itoa(userid)]; !ok {
+ photos, err := b.c.GetUserProfilePhotos(tgbotapi.UserProfilePhotosConfig{UserID: userid, Limit: 1})
+ if err != nil {
+ b.Log.Errorf("Userprofile download failed for %#v %s", userid, err)
+ }
+
+ if len(photos.Photos) > 0 {
+ photo := photos.Photos[0][0]
+ url := b.getFileDirectURL(photo.FileID)
+ name := strconv.Itoa(userid) + ".png"
+ b.Log.Debugf("trying to download %#v fileid %#v with size %#v", name, photo.FileID, photo.FileSize)
+
+ err := helper.HandleDownloadSize(b.Log, &rmsg, name, int64(photo.FileSize), b.General)
+ if err != nil {
+ b.Log.Error(err)
+ return
+ }
+ data, err := helper.DownloadFile(url)
+ if err != nil {
+ b.Log.Errorf("download %s failed %#v", url, err)
+ return
+ }
+ helper.HandleDownloadData(b.Log, &rmsg, name, rmsg.Text, "", data, b.General)
+ b.Remote <- rmsg
+ }
+ }
+}
+
+// handleDownloadFile handles file download
+func (b *Btelegram) handleDownload(rmsg *config.Message, message *tgbotapi.Message) error {
+ size := 0
+ var url, name, text string
+ switch {
+ case message.Sticker != nil:
+ text, name, url = b.getDownloadInfo(message.Sticker.FileID, ".webp", true)
+ size = 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 = photos[len(photos)-1].FileSize
+ text, name, url = b.getDownloadInfo(photos[len(photos)-1].FileID, "", true)
+ }
+
+ // if name is empty we didn't match a thing to download
+ if name == "" {
+ return nil
+ }
+ // use the URL instead of native upload
+ if b.GetBool("UseInsecureURL") {
+ b.Log.Debugf("Setting message text to :%s", text)
+ 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
+ }
+ data, err := helper.DownloadFile(url)
+ if err != nil {
+ return err
+ }
+ helper.HandleDownloadData(b.Log, rmsg, name, message.Caption, "", data, b.General)
+ return nil
+}
+
+func (b *Btelegram) getDownloadInfo(id string, suffix string, urlpart bool) (string, string, string) {
+ url := b.getFileDirectURL(id)
+ name := ""
+ if urlpart {
+ urlPart := strings.Split(url, "/")
+ name = urlPart[len(urlPart)-1]
+ }
+ if suffix != "" && !strings.HasSuffix(name, suffix) {
+ name += suffix
+ }
+ text := " " + url
+ return text, name, url
+}
+
+// handleUploadFile handles native upload of files
+func (b *Btelegram) handleUploadFile(msg *config.Message, chatid int64) string {
+ var c tgbotapi.Chattable
+ for _, f := range msg.Extra["file"] {
+ fi := f.(config.FileInfo)
+ file := tgbotapi.FileBytes{
+ Name: fi.Name,
+ Bytes: *fi.Data,
+ }
+ re := regexp.MustCompile(".(jpg|png)$")
+ if re.MatchString(fi.Name) {
+ c = tgbotapi.NewPhotoUpload(chatid, file)
+ } else {
+ c = tgbotapi.NewDocumentUpload(chatid, file)
+ }
+ _, err := b.c.Send(c)
+ if err != nil {
+ b.Log.Errorf("file upload failed: %#v", err)
+ }
+ if fi.Comment != "" {
+ if _, err := b.sendMessage(chatid, msg.Username, fi.Comment); err != nil {
+ b.Log.Errorf("posting file comment %s failed: %s", fi.Comment, err)
+ }
+ }
+ }
+ return ""
+}
+
+func (b *Btelegram) handleQuote(message, quoteNick, quoteMessage string) string {
+ format := b.GetString("quoteformat")
+ if format == "" {
+ format = "{MESSAGE} (re @{QUOTENICK}: {QUOTEMESSAGE})"
+ }
+ format = strings.Replace(format, "{MESSAGE}", message, -1)
+ format = strings.Replace(format, "{QUOTENICK}", quoteNick, -1)
+ format = strings.Replace(format, "{QUOTEMESSAGE}", quoteMessage, -1)
+ return format
+}
diff --git a/bridge/telegram/html.go b/bridge/telegram/html.go
index 12d6d0c6..148f42e6 100644
--- a/bridge/telegram/html.go
+++ b/bridge/telegram/html.go
@@ -34,7 +34,7 @@ func (options *customHTML) Header(out *bytes.Buffer, text func() bool, level int
}
func (options *customHTML) HRule(out io.ByteWriter) {
- out.WriteByte('\n')
+ out.WriteByte('\n') //nolint:errcheck
}
func (options *customHTML) BlockQuote(out *bytes.Buffer, text []byte) {
diff --git a/bridge/telegram/telegram.go b/bridge/telegram/telegram.go
index 7097644e..e16e2bef 100644
--- a/bridge/telegram/telegram.go
+++ b/bridge/telegram/telegram.go
@@ -2,7 +2,6 @@ package btelegram
import (
"html"
- "regexp"
"strconv"
"strings"
@@ -90,7 +89,9 @@ 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) {
- b.sendMessage(chatid, rmsg.Username, rmsg.Text)
+ if _, err := b.sendMessage(chatid, rmsg.Username, rmsg.Text); err != nil {
+ b.Log.Errorf("sendMessage failed: %s", err)
+ }
}
// check if we have files to upload (from slack, telegram or mattermost)
if len(msg.Extra["file"]) > 0 {
@@ -132,130 +133,6 @@ func (b *Btelegram) Send(msg config.Message) (string, error) {
return b.sendMessage(chatid, msg.Username, msg.Text)
}
-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.Error("Getting nil messages, this shouldn't happen.")
- continue
- }
-
- var message *tgbotapi.Message
-
- rmsg := config.Message{Account: b.Account, Extra: make(map[string][]interface{})}
-
- // handle channels
- if update.ChannelPost != nil {
- message = update.ChannelPost
- rmsg.Text = message.Text
- }
-
- // edited channel message
- if update.EditedChannelPost != nil && !b.GetBool("EditDisable") {
- message = update.EditedChannelPost
- rmsg.Text = rmsg.Text + message.Text + b.GetString("EditSuffix")
- }
-
- // handle groups
- if update.Message != nil {
- message = update.Message
- rmsg.Text = message.Text
- }
-
- // edited group message
- if update.EditedMessage != nil && !b.GetBool("EditDisable") {
- message = update.EditedMessage
- rmsg.Text = rmsg.Text + message.Text + b.GetString("EditSuffix")
- }
-
- // set the ID's from the channel or group message
- rmsg.ID = strconv.Itoa(message.MessageID)
- rmsg.Channel = strconv.FormatInt(message.Chat.ID, 10)
-
- // handle username
- if message.From != nil {
- rmsg.UserID = strconv.Itoa(message.From.ID)
- if b.GetBool("UseFirstName") {
- rmsg.Username = message.From.FirstName
- }
- 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.MediaServerUpload != "" {
- b.handleDownloadAvatar(message.From.ID, rmsg.Channel)
- }
- }
-
- // if we really didn't find a username, set it to unknown
- if rmsg.Username == "" {
- rmsg.Username = unknownUser
- }
-
- // handle any downloads
- err := b.handleDownload(message, &rmsg)
- if err != nil {
- b.Log.Errorf("download failed: %s", err)
- }
-
- // handle forwarded messages
- if message.ForwardFrom != nil {
- usernameForward := ""
- if b.GetBool("UseFirstName") {
- usernameForward = message.ForwardFrom.FirstName
- }
- if usernameForward == "" {
- usernameForward = message.ForwardFrom.UserName
- if usernameForward == "" {
- usernameForward = message.ForwardFrom.FirstName
- }
- }
- if usernameForward == "" {
- usernameForward = unknownUser
- }
- rmsg.Text = "Forwarded from " + usernameForward + ": " + rmsg.Text
- }
-
- // quote the previous message
- if message.ReplyToMessage != nil {
- usernameReply := ""
- if message.ReplyToMessage.From != nil {
- if b.GetBool("UseFirstName") {
- usernameReply = message.ReplyToMessage.From.FirstName
- }
- if usernameReply == "" {
- usernameReply = message.ReplyToMessage.From.UserName
- if usernameReply == "" {
- usernameReply = message.ReplyToMessage.From.FirstName
- }
- }
- }
- if usernameReply == "" {
- usernameReply = unknownUser
- }
- if !b.GetBool("QuoteDisable") {
- rmsg.Text = b.handleQuote(rmsg.Text, usernameReply, message.ReplyToMessage.Text)
- }
- }
-
- if rmsg.Text != "" || len(rmsg.Extra) > 0 {
- 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.Itoa(message.From.ID), 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
- }
- }
-}
-
func (b *Btelegram) getFileDirectURL(id string) string {
res, err := b.c.GetFileDirectURL(id)
if err != nil {
@@ -264,146 +141,6 @@ func (b *Btelegram) getFileDirectURL(id string) string {
return res
}
-// handleDownloadAvatar 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 int, channel string) {
- rmsg := config.Message{Username: "system", Text: "avatar", Channel: channel, Account: b.Account, UserID: strconv.Itoa(userid), Event: config.EventAvatarDownload, Extra: make(map[string][]interface{})}
- if _, ok := b.avatarMap[strconv.Itoa(userid)]; !ok {
- photos, err := b.c.GetUserProfilePhotos(tgbotapi.UserProfilePhotosConfig{UserID: userid, Limit: 1})
- if err != nil {
- b.Log.Errorf("Userprofile download failed for %#v %s", userid, err)
- }
-
- if len(photos.Photos) > 0 {
- photo := photos.Photos[0][0]
- url := b.getFileDirectURL(photo.FileID)
- name := strconv.Itoa(userid) + ".png"
- b.Log.Debugf("trying to download %#v fileid %#v with size %#v", name, photo.FileID, photo.FileSize)
-
- err := helper.HandleDownloadSize(b.Log, &rmsg, name, int64(photo.FileSize), b.General)
- if err != nil {
- b.Log.Error(err)
- return
- }
- data, err := helper.DownloadFile(url)
- if err != nil {
- b.Log.Errorf("download %s failed %#v", url, err)
- return
- }
- helper.HandleDownloadData(b.Log, &rmsg, name, rmsg.Text, "", data, b.General)
- b.Remote <- rmsg
- }
- }
-}
-
-// handleDownloadFile handles file download
-func (b *Btelegram) handleDownload(message *tgbotapi.Message, rmsg *config.Message) error {
- size := 0
- var url, name, text string
-
- if message.Sticker != nil {
- v := message.Sticker
- size = v.FileSize
- url = b.getFileDirectURL(v.FileID)
- urlPart := strings.Split(url, "/")
- name = urlPart[len(urlPart)-1]
- if !strings.HasSuffix(name, ".webp") {
- name += ".webp"
- }
- text = " " + url
- }
- if message.Video != nil {
- v := message.Video
- size = v.FileSize
- url = b.getFileDirectURL(v.FileID)
- urlPart := strings.Split(url, "/")
- name = urlPart[len(urlPart)-1]
- text = " " + url
- }
- if message.Photo != nil {
- photos := *message.Photo
- size = photos[len(photos)-1].FileSize
- url = b.getFileDirectURL(photos[len(photos)-1].FileID)
- urlPart := strings.Split(url, "/")
- name = urlPart[len(urlPart)-1]
- text = " " + url
- }
- if message.Document != nil {
- v := message.Document
- size = v.FileSize
- url = b.getFileDirectURL(v.FileID)
- name = v.FileName
- text = " " + v.FileName + " : " + url
- }
- if message.Voice != nil {
- v := message.Voice
- size = v.FileSize
- url = b.getFileDirectURL(v.FileID)
- urlPart := strings.Split(url, "/")
- name = urlPart[len(urlPart)-1]
- text = " " + url
- if !strings.HasSuffix(name, ".ogg") {
- name += ".ogg"
- }
- }
- if message.Audio != nil {
- v := message.Audio
- size = v.FileSize
- url = b.getFileDirectURL(v.FileID)
- urlPart := strings.Split(url, "/")
- name = urlPart[len(urlPart)-1]
- text = " " + url
- }
- // if name is empty we didn't match a thing to download
- if name == "" {
- return nil
- }
- // use the URL instead of native upload
- if b.GetBool("UseInsecureURL") {
- b.Log.Debugf("Setting message text to :%s", text)
- 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
- }
- data, err := helper.DownloadFile(url)
- if err != nil {
- return err
- }
- helper.HandleDownloadData(b.Log, rmsg, name, message.Caption, "", data, b.General)
- return nil
-}
-
-// handleUploadFile handles native upload of files
-func (b *Btelegram) handleUploadFile(msg *config.Message, chatid int64) (string, error) {
- var c tgbotapi.Chattable
- for _, f := range msg.Extra["file"] {
- fi := f.(config.FileInfo)
- file := tgbotapi.FileBytes{
- Name: fi.Name,
- Bytes: *fi.Data,
- }
- re := regexp.MustCompile(".(jpg|png)$")
- if re.MatchString(fi.Name) {
- c = tgbotapi.NewPhotoUpload(chatid, file)
- } else {
- c = tgbotapi.NewDocumentUpload(chatid, file)
- }
- _, err := b.c.Send(c)
- if err != nil {
- b.Log.Errorf("file upload failed: %#v", err)
- }
- if fi.Comment != "" {
- b.sendMessage(chatid, msg.Username, fi.Comment)
- }
- }
- return "", nil
-}
-
func (b *Btelegram) sendMessage(chatid int64, username, text string) (string, error) {
m := tgbotapi.NewMessage(chatid, "")
m.Text = username + text
@@ -437,14 +174,3 @@ func (b *Btelegram) cacheAvatar(msg *config.Message) (string, error) {
}
return "", nil
}
-
-func (b *Btelegram) handleQuote(message, quoteNick, quoteMessage string) string {
- format := b.GetString("quoteformat")
- if format == "" {
- format = "{MESSAGE} (re @{QUOTENICK}: {QUOTEMESSAGE})"
- }
- format = strings.Replace(format, "{MESSAGE}", message, -1)
- format = strings.Replace(format, "{QUOTENICK}", quoteNick, -1)
- format = strings.Replace(format, "{QUOTEMESSAGE}", quoteMessage, -1)
- return format
-}