diff --git a/.gitignore b/.gitignore index f538a5a..8daf8e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -tiktok/tiktok -instagram/instagram +dlbot diff --git a/Taskfile.yml b/Taskfile.yml index 05b6a5f..b253510 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -2,26 +2,12 @@ version: '3' tasks: build: - dir: "{{.WHICH}}" - label: "build-{{.WHICH}}" cmds: - CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' . upload: deps: - task: build - vars: - WHICH: "{{.WHICH}}" - dir: "{{.WHICH}}" - label: "upload-{{.WHICH}}" cmds: - - ssh -p993 root@nulo.in sv stop dlbot-{{.WHICH}} - - scp -P993 {{.WHICH}} dlbot@nulo.in:/home/dlbot/bin/ - - ssh -p993 root@nulo.in sv start dlbot-{{.WHICH}} - upload-all: - deps: - - task: upload - vars: - WHICH: tiktok - - task: upload - vars: - WHICH: instagram + - ssh -p993 root@nulo.in sv stop dlbot + - scp -P993 dlbot dlbot@nulo.in:/home/dlbot/bin/ + - ssh -p993 root@nulo.in sv start dlbot diff --git a/common/main.go b/common/main.go index 42be5d5..adee096 100644 --- a/common/main.go +++ b/common/main.go @@ -1,17 +1,11 @@ package common import ( - "log" - "net/url" - "os" "strings" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) -type Config struct { - Respond func(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) Result -} type Result uint8 const ( @@ -20,40 +14,6 @@ const ( Uploaded ) -func Main(config Config) { - token := os.Getenv("TELEGRAM_TOKEN") - if token == "" { - log.Panic("No telegram token") - } - - var debug bool - if os.Getenv("DEBUG") != "" { - debug = true - } - - bot, err := tgbotapi.NewBotAPI(token) - if err != nil { - log.Panic(err) - } - - bot.Debug = debug - - log.Printf("Authorized on account %s", bot.Self.UserName) - - u := tgbotapi.NewUpdate(0) - u.Timeout = 60 - - updates := bot.GetUpdatesChan(u) - - for update := range updates { - if update.Message == nil { - continue - } - - go config.handleMessage(bot, update) - } -} - func respondWith(msg *tgbotapi.Message, str string) tgbotapi.MessageConfig { res := tgbotapi.NewMessage(msg.Chat.ID, str) res.ReplyToMessageID = msg.MessageID @@ -69,54 +29,3 @@ func RespondWithMany(msg *tgbotapi.Message, s ...string) tgbotapi.MessageConfig } return respondWith(msg, res.String()) } - -func (config Config) handleMessage(bot *tgbotapi.BotAPI, update tgbotapi.Update) { - var explicit bool - - msg := update.Message - if strings.HasPrefix(msg.Text, "/dl") || msg.Chat.IsPrivate() { - explicit = true - } - - searchMsg := msg - if msg.ReplyToMessage != nil && explicit { - searchMsg = msg.ReplyToMessage - } - - hasDownloadables := false - - for i := 0; i < len(searchMsg.Entities); i++ { - e := searchMsg.Entities[i] - if e.Type != "url" { - continue - } - - urlString := searchMsg.Text[e.Offset : e.Offset+e.Length] - url, err := url.Parse(urlString) - if err != nil { - if explicit { - bot.Send(RespondWithMany(msg, "No se pudo detectar la URL ", urlString, ".")) - } - continue - } - - result := config.Respond(bot, update, url) - - if explicit && result == NotValid { - bot.Send(RespondWithMany(msg, "La URL ", urlString, " no es compatible con este bot.")) - continue - } - - if result == HadError || result == Uploaded { - hasDownloadables = true - } - - if result == HadError { - bot.Send(RespondWithMany(update.Message, "Hubo un error al descargar ", urlString, ".")) - continue - } - } - if !hasDownloadables && explicit { - bot.Send(RespondWithMany(msg, "No encontré URLs descargables en ese mensaje.")) - } -} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..13ef9da --- /dev/null +++ b/go.mod @@ -0,0 +1,16 @@ +module nulo.in/dlbot + +go 1.19 + +require ( + github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 + nulo.in/dlbot/common v0.0.0-00010101000000-000000000000 + nulo.in/dlbot/instagram v0.0.0-00010101000000-000000000000 + nulo.in/dlbot/tiktok v0.0.0-00010101000000-000000000000 +) + +replace nulo.in/dlbot/common => ./common + +replace nulo.in/dlbot/instagram => ./instagram + +replace nulo.in/dlbot/tiktok => ./tiktok diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..db8e45c --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= +github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= diff --git a/instagram/instagram.go b/instagram/instagram.go index 07f9b7a..7770845 100644 --- a/instagram/instagram.go +++ b/instagram/instagram.go @@ -1,4 +1,4 @@ -package main +package instagram import ( "encoding/json" @@ -9,7 +9,7 @@ import ( "path" ) -type QueryResponse struct { +type queryResponse struct { Data struct { ShortcodeMedia *struct { Type string `json:"__typename"` @@ -29,16 +29,16 @@ type QueryResponse struct { } `json:"data"` } -type Response struct { +type lookupResponse struct { VideoUrl string Author string Text string } -func Lookup(urlSrc string) (Response, error) { +func lookup(urlSrc string) (lookupResponse, error) { urlSrcParsed, err := url.Parse(urlSrc) if err != nil { - return Response{}, err + return lookupResponse{}, err } url, _ := url.Parse("https://www.instagram.com/graphql/query/?query_hash=b3055c01b4b222b8a47dc12b090e4e64") @@ -48,23 +48,23 @@ func Lookup(urlSrc string) (Response, error) { resp, err := http.Get(url.String()) if err != nil { - return Response{}, err + return lookupResponse{}, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) - var response QueryResponse + var response queryResponse err = json.Unmarshal(body, &response) if err != nil { - return Response{}, err + return lookupResponse{}, err } if response.Data.ShortcodeMedia == nil { - return Response{}, errors.New("No encontré el video.") + return lookupResponse{}, errors.New("No encontré el video.") } if response.Data.ShortcodeMedia.Type != "GraphVideo" { - return Response{}, errors.New("Esto no es un video.") + return lookupResponse{}, errors.New("Esto no es un video.") } - return Response{ + return lookupResponse{ VideoUrl: response.Data.ShortcodeMedia.VideoUrl, Author: response.Data.ShortcodeMedia.Owner.Username, Text: response.Data.ShortcodeMedia.EdgeMediaToCaption.Edges[0].Node.Text, diff --git a/instagram/main.go b/instagram/main.go index b13f31a..03aec8c 100644 --- a/instagram/main.go +++ b/instagram/main.go @@ -1,4 +1,4 @@ -package main +package instagram import ( "log" @@ -10,7 +10,7 @@ import ( tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) -func respond(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) common.Result { +func Respond(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) common.Result { if url.Hostname() != "instagram.com" && url.Hostname() != "www.instagram.com" { return common.NotValid } @@ -19,7 +19,7 @@ func respond(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) common. } log.Printf("Downloading %s", url.String()) - lookup, err := Lookup(url.String()) + lookup, err := lookup(url.String()) if err != nil { log.Println(err) return common.HadError @@ -32,7 +32,3 @@ func respond(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) common. bot.Send(res) return common.Uploaded } - -func main() { - common.Main(common.Config{Respond: respond}) -} diff --git a/main.go b/main.go new file mode 100644 index 0000000..b91b601 --- /dev/null +++ b/main.go @@ -0,0 +1,116 @@ +package main + +import ( + "log" + "net/url" + "os" + "strings" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "nulo.in/dlbot/common" + "nulo.in/dlbot/instagram" + "nulo.in/dlbot/tiktok" +) + +type Responder func(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) common.Result +type Config struct { + Responders []Responder +} + +func (config Config) handleMessage(bot *tgbotapi.BotAPI, update tgbotapi.Update) { + var explicit bool + + msg := update.Message + if strings.HasPrefix(msg.Text, "/dl") || msg.Chat.IsPrivate() { + explicit = true + } + + searchMsg := msg + if msg.ReplyToMessage != nil && explicit { + searchMsg = msg.ReplyToMessage + } + + hasDownloadables := false + + for i := 0; i < len(searchMsg.Entities); i++ { + e := searchMsg.Entities[i] + if e.Type != "url" { + continue + } + + urlString := searchMsg.Text[e.Offset : e.Offset+e.Length] + url, err := url.Parse(urlString) + if err != nil { + if explicit { + bot.Send(common.RespondWithMany(msg, "No se pudo detectar la URL ", urlString, ".")) + } + continue + } + + var result common.Result + for _, respond := range config.Responders { + result = respond(bot, update, url) + if result != common.NotValid { + break + } + } + + if explicit && result == common.NotValid { + bot.Send(common.RespondWithMany(msg, "La URL ", urlString, " no es compatible con este bot.")) + continue + } + + if result == common.HadError || result == common.Uploaded { + hasDownloadables = true + } + + if result == common.HadError { + bot.Send(common.RespondWithMany(update.Message, "Hubo un error al descargar ", urlString, ".")) + continue + } + } + if !hasDownloadables && explicit { + bot.Send(common.RespondWithMany(msg, "No encontré URLs descargables en ese mensaje.")) + } +} + +func main() { + config := Config{ + Responders: []Responder{ + instagram.Respond, + tiktok.Respond, + }, + } + + token := os.Getenv("TELEGRAM_TOKEN") + if token == "" { + log.Panic("No telegram token") + } + + var debug bool + if os.Getenv("DEBUG") != "" { + debug = true + } + + bot, err := tgbotapi.NewBotAPI(token) + if err != nil { + log.Panic(err) + } + + bot.Debug = debug + + log.Printf("Authorized on account %s", bot.Self.UserName) + + u := tgbotapi.NewUpdate(0) + u.Timeout = 60 + + updates := bot.GetUpdatesChan(u) + + for update := range updates { + if update.Message == nil { + continue + } + + go config.handleMessage(bot, update) + } +} diff --git a/readme.md b/readme.md index c14f346..437adad 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,6 @@ -Esta repo tiene el código de distintos bots para Telegram que permiten descargar videos de distintos lugares. +Un bot para Telegram que permite descargar videos de distintos lugares. -- TikTok: [@dlthefourthbot](https://t.me/dlthefourthbot) (código: [[tiktok/]]) -- Instagram Reels: [@inst4gramdlbot](https://t.me/inst4gramdlbot) (código: [[instagram/]]) +[@dlthefourthbot](https://t.me/dlthefourthbot) Son rápidos ya que ni siquiera descargan el video, solo le pasan a Telegram la URL para descargarlos. diff --git a/tiktok/main.go b/tiktok/main.go index 5785318..13c51d9 100644 --- a/tiktok/main.go +++ b/tiktok/main.go @@ -1,4 +1,4 @@ -package main +package tiktok import ( "log" @@ -12,7 +12,7 @@ import ( // Gracias a https://github.com/Xenzi-XN1/Tiktok-Download // por enseñarme tikmate.app -func respond(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) common.Result { +func Respond(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) common.Result { if url.Hostname() != "vm.tiktok.com" && url.Hostname() != "tiktok.com" { return common.NotValid } @@ -22,7 +22,7 @@ func respond(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) common. url.Host = "vm.tiktok.com" log.Printf("Downloading %s", urlString) - lookup, err := Lookup(url.String()) + lookup, err := lookup(urlString) if err != nil { log.Println(err) return common.HadError @@ -34,7 +34,3 @@ func respond(bot *tgbotapi.BotAPI, update tgbotapi.Update, url *url.URL) common. bot.Send(res) return common.Uploaded } - -func main() { - common.Main(common.Config{Respond: respond}) -} diff --git a/tiktok/tikmate.go b/tiktok/tikmate.go index a890eab..5bc328f 100644 --- a/tiktok/tikmate.go +++ b/tiktok/tikmate.go @@ -1,4 +1,4 @@ -package main +package tiktok import ( "encoding/json" @@ -8,7 +8,7 @@ import ( "net/url" ) -type LookupResponse struct { +type lookupResponse struct { AuthorAvatar string `json:"author_avatar"` AuthorID string `json:"author_id"` AuthorName string `json:"author_name"` @@ -22,7 +22,7 @@ type LookupResponse struct { Token string `json:"token"` } -func Lookup(urlS string) (string, error) { +func lookup(urlS string) (string, error) { resp, err := http.PostForm( "https://api.tikmate.app/api/lookup", url.Values{"url": {urlS}}, @@ -33,7 +33,7 @@ func Lookup(urlS string) (string, error) { defer resp.Body.Close() body, err := io.ReadAll(resp.Body) - var lookup LookupResponse + var lookup lookupResponse err = json.Unmarshal(body, &lookup) if err != nil { return "", err