diff --git a/DOCS.md b/DOCS.md index f807849..26bd595 100644 --- a/DOCS.md +++ b/DOCS.md @@ -255,6 +255,18 @@ Disables notifications for this message + disable_notification: true ``` +Send the message to a specific topic (message thread) of a forum supergroup + +```diff + - name: send telegram notification + image: appleboy/drone-telegram + settings: + token: xxxxxxxxxx + to: telegram_group_id + message: send message to a forum topic ++ message_thread_id: 12345 +``` + ## Parameter Reference token @@ -263,6 +275,9 @@ token to : telegram user id (can be requested from the @userinfobot inside Telegram) +message_thread_id +: unique identifier of the target message thread (forum topic) of a forum supergroup; only needed when sending to a specific topic + message : overwrite the default message template diff --git a/go.mod b/go.mod index fe876fa..e536e98 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/appleboy/drone-telegram go 1.25.13 require ( + github.com/OvyFlash/telegram-bot-api v0.0.0-20260715235732-aca8bf3898bb github.com/appleboy/drone-template-lib v1.3.0 - github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible github.com/joho/godotenv v1.5.1 github.com/stretchr/testify v1.9.0 github.com/urfave/cli v1.22.15 @@ -27,7 +27,6 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/cast v1.7.0 // indirect - github.com/technoweenie/multipartstreamer v1.0.1 // indirect golang.org/x/crypto v0.55.0 // indirect golang.org/x/sys v0.47.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index ddd3604..b37f855 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,8 @@ github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+ github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= +github.com/OvyFlash/telegram-bot-api v0.0.0-20260715235732-aca8bf3898bb h1:MvKVOrwsx25AOMkMTGilUTqjFJ4S/OR3nyNq1PsEwTE= +github.com/OvyFlash/telegram-bot-api v0.0.0-20260715235732-aca8bf3898bb/go.mod h1:2nRUdsKyWhvezqW/rBGWEQdcTQeTtnbSNd2dgx76WYA= github.com/appleboy/drone-template-lib v1.3.0 h1:aX36/1za3v8JsEyBeMY1Bp/VNRtZa8qPYkfkjBszW+A= github.com/appleboy/drone-template-lib v1.3.0/go.mod h1:edlmXkFMKYAVypff8r2oN7aFlHfOZE5sLyPEnRHONeA= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= @@ -16,8 +18,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU= -github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -60,8 +60,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM= -github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog= github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM= github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0= golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= diff --git a/main.go b/main.go index 47f5a41..b5a1c0c 100644 --- a/main.go +++ b/main.go @@ -39,6 +39,11 @@ func main() { Usage: "telegram user", EnvVar: "PLUGIN_TO,TELEGRAM_TO,INPUT_TO", }, + cli.IntFlag{ + Name: "message.thread.id", + Usage: "telegram message thread id (unique identifier of the forum topic)", + EnvVar: "PLUGIN_MESSAGE_THREAD_ID,TELEGRAM_MESSAGE_THREAD_ID,INPUT_MESSAGE_THREAD_ID", + }, cli.StringFlag{ Name: "message", Usage: "send telegram message", @@ -310,6 +315,7 @@ func run(c *cli.Context) error { Debug: c.Bool("debug"), MatchEmail: c.Bool("match.email"), To: c.StringSlice("to"), + MessageThreadID: c.Int("message.thread.id"), Message: c.String("message"), MessageFile: c.String("message.file"), TemplateVars: c.String("template.vars"), diff --git a/plugin.go b/plugin.go index f297a48..871c46f 100644 --- a/plugin.go +++ b/plugin.go @@ -14,8 +14,8 @@ import ( "strconv" "strings" + tgbotapi "github.com/OvyFlash/telegram-bot-api" "github.com/appleboy/drone-template-lib/template" - tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" ) const ( @@ -71,6 +71,7 @@ type ( Debug bool MatchEmail bool To []string + MessageThreadID int Message string MessageFile string TemplateVarsFile string @@ -312,7 +313,7 @@ func (p *Plugin) Exec() (err error) { } } - var bot *tgbotapi.BotAPI + var opts []tgbotapi.BotAPIOption if len(p.Config.Socks5) > 0 { var proxyURL *url.URL proxyURL, err = url.Parse(p.Config.Socks5) @@ -320,11 +321,10 @@ func (p *Plugin) Exec() (err error) { return fmt.Errorf("unable to parse socks5 proxy URL '%s': %w", p.Config.Socks5, err) } proxyClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)}} - bot, err = tgbotapi.NewBotAPIWithClient(p.Config.Token, proxyClient) - } else { - bot, err = tgbotapi.NewBotAPI(p.Config.Token) + opts = append(opts, tgbotapi.WithHTTPClient(proxyClient)) } + bot, err := tgbotapi.NewBotAPIWithOptions(p.Config.Token, opts...) if err != nil { return err } @@ -384,8 +384,9 @@ func (p *Plugin) Exec() (err error) { for _, user := range ids { for _, txt := range renderedMessages { msg := tgbotapi.NewMessage(user, txt) + msg.MessageThreadID = p.Config.MessageThreadID msg.ParseMode = p.Config.Format - msg.DisableWebPagePreview = p.Config.DisableWebPagePreview + msg.LinkPreviewOptions.IsDisabled = p.Config.DisableWebPagePreview msg.DisableNotification = p.Config.DisableNotification if err := p.Send(bot, msg); err != nil { return err @@ -393,28 +394,32 @@ func (p *Plugin) Exec() (err error) { } for _, value := range photos { - msg := tgbotapi.NewPhotoUpload(user, value) + msg := tgbotapi.NewPhoto(user, tgbotapi.FilePath(value)) + msg.MessageThreadID = p.Config.MessageThreadID if err := p.Send(bot, msg); err != nil { return err } } for _, value := range documents { - msg := tgbotapi.NewDocumentUpload(user, value) + msg := tgbotapi.NewDocument(user, tgbotapi.FilePath(value)) + msg.MessageThreadID = p.Config.MessageThreadID if err := p.Send(bot, msg); err != nil { return err } } for _, value := range stickers { - msg := tgbotapi.NewStickerUpload(user, value) + msg := tgbotapi.NewSticker(user, tgbotapi.FilePath(value)) + msg.MessageThreadID = p.Config.MessageThreadID if err := p.Send(bot, msg); err != nil { return err } } for _, value := range audios { - msg := tgbotapi.NewAudioUpload(user, value) + msg := tgbotapi.NewAudio(user, tgbotapi.FilePath(value)) + msg.MessageThreadID = p.Config.MessageThreadID msg.Title = "Audio Message" if err := p.Send(bot, msg); err != nil { return err @@ -422,14 +427,16 @@ func (p *Plugin) Exec() (err error) { } for _, value := range voices { - msg := tgbotapi.NewVoiceUpload(user, value) + msg := tgbotapi.NewVoice(user, tgbotapi.FilePath(value)) + msg.MessageThreadID = p.Config.MessageThreadID if err := p.Send(bot, msg); err != nil { return err } } for _, value := range videos { - msg := tgbotapi.NewVideoUpload(user, value) + msg := tgbotapi.NewVideo(user, tgbotapi.FilePath(value)) + msg.MessageThreadID = p.Config.MessageThreadID msg.Caption = "Video Message" if err := p.Send(bot, msg); err != nil { return err @@ -438,6 +445,7 @@ func (p *Plugin) Exec() (err error) { for _, loc := range parsedLocations { msg := tgbotapi.NewLocation(user, loc.Latitude, loc.Longitude) + msg.MessageThreadID = p.Config.MessageThreadID if err := p.Send(bot, msg); err != nil { return err } @@ -451,6 +459,7 @@ func (p *Plugin) Exec() (err error) { loc.Latitude, loc.Longitude, ) + msg.MessageThreadID = p.Config.MessageThreadID if err := p.Send(bot, msg); err != nil { return err }