diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/plugin.go | 7 | ||||
-rw-r--r-- | plugins/tg.go | 129 | ||||
-rw-r--r-- | plugins/tt.go | 107 |
3 files changed, 243 insertions, 0 deletions
diff --git a/plugins/plugin.go b/plugins/plugin.go new file mode 100644 index 0000000..504c4af --- /dev/null +++ b/plugins/plugin.go @@ -0,0 +1,7 @@ +package plugins + +import "context" + +type Plugin interface { + Run(ctx context.Context) error +} diff --git a/plugins/tg.go b/plugins/tg.go new file mode 100644 index 0000000..ccd3a9b --- /dev/null +++ b/plugins/tg.go @@ -0,0 +1,129 @@ +package plugins + +import ( + "context" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "os" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" + "github.com/neonxp/tamtam" + + "transport/lib" +) + +type Telegram struct { + Routing []lib.Routing + API *tgbotapi.BotAPI + Updates chan lib.Message + Bus chan lib.Message +} + +func NewTelegram(token string, updates chan lib.Message, bus chan lib.Message, routing []lib.Routing) *Telegram { + tgApi, err := tgbotapi.NewBotAPI(token) + if err != nil { + log.Panic(err) + } + + return &Telegram{API: tgApi, Updates: updates, Bus: bus, Routing: routing} +} + +func (t *Telegram) Run(ctx context.Context) error { + + u := tgbotapi.NewUpdate(0) + u.Timeout = 60 + + updates, err := t.API.GetUpdatesChan(u) + if err != nil { + return err + } + for { + select { + case <-ctx.Done(): + return nil + case upd := <-updates: + if upd.Message == nil { // ignore any non-Message Updates + continue + } + for _, r := range t.Routing { + if r.TgID == upd.Message.Chat.ID { + from := fmt.Sprintf("%s %s", upd.Message.From.FirstName, upd.Message.From.LastName) + if upd.Message.From.UserName != "" { + from = fmt.Sprintf("%s %s (%s)", upd.Message.From.FirstName, upd.Message.From.LastName, upd.Message.From.UserName) + } + isSticker := "" + images := make([]string, 0) + if upd.Message.Sticker != nil { + isSticker = upd.Message.Sticker.Emoji + s, _ := t.API.GetFileDirectURL(upd.Message.Sticker.Thumbnail.FileID) + images = append(images, s) + } + if upd.Message.Photo != nil && len(*upd.Message.Photo) > 0 { + p := (*upd.Message.Photo)[0] + s, _ := t.API.GetFileDirectURL(p.FileID) + images = append(images, s) + } + t.Bus <- lib.Message{ + To: r.TTID, + From: from, + Text: upd.Message.Text, + Images: images, + Sticker: isSticker, + } + } + } + case msg := <-t.Updates: + att := make([]interface{}, 0) + for _, a := range msg.Images { + att = append(att, tamtam.Image{Url: a}) + } + text := fmt.Sprintf("*%s*:\n%s", msg.From, msg.Text) + if len(msg.Text) > 0 { + res, err := t.API.Send(tgbotapi.MessageConfig{ + BaseChat: tgbotapi.BaseChat{ + ChatID: msg.To, + ReplyToMessageID: 0, + }, + Text: text, + DisableWebPagePreview: false, + ParseMode: "markdown", + }) + log.Printf("[TG] Send text: %#v %#v", res, err) + } + if len(msg.Images) > 0 { + for _, i := range msg.Images { + u, err := t.DownloadFile(i) + if err != nil { + log.Printf("[TG] Download image: %#v", err) + continue + } + m := tgbotapi.NewPhotoUpload(msg.To, u) + m.Caption = msg.Sticker + res, err := t.API.Send(m) + log.Printf("[TG] Send image: %#v %#v", res, err) + } + } + } + } +} + +func (t *Telegram) DownloadFile(u string) (string, error) { + resp, err := http.Get(u) + if err != nil { + return "", err + } + defer resp.Body.Close() + + // Write the body to file + + f, err := ioutil.TempFile(os.TempDir(), "tg*") + if err != nil { + return "", err + } + _, err = io.Copy(f, resp.Body) + defer f.Close() + return f.Name(), nil +} diff --git a/plugins/tt.go b/plugins/tt.go new file mode 100644 index 0000000..89fa77c --- /dev/null +++ b/plugins/tt.go @@ -0,0 +1,107 @@ +package plugins + +import ( + "context" + "fmt" + "log" + + "github.com/neonxp/tamtam" + + "transport/lib" +) + +type TamTam struct { + Routing []lib.Routing + API *tamtam.Api + Updates chan lib.Message + Bus chan lib.Message +} + +func NewTamTam(token string, updates chan lib.Message, bus chan lib.Message, routing []lib.Routing) *TamTam { + return &TamTam{API: tamtam.New(token), Updates: updates, Bus: bus, Routing: routing} +} + +func (t *TamTam) Run(ctx context.Context) error { + updates := make(chan interface{}, 1) + go func() { + if err := t.API.GetUpdatesLoop(ctx, updates); err != nil { + log.Printf("[TT] Error: %#v", err) + } + }() + for { + select { + case <-ctx.Done(): + return nil + case upd := <-updates: + log.Printf("[TT] Received: %#v", upd) + switch upd := upd.(type) { + case tamtam.UpdateMessageCreated: + for _, r := range t.Routing { + if r.TTID == upd.Message.Recipient.ChatId { + from := upd.Message.Sender.Name + if upd.Message.Sender.Username != "" { + from = fmt.Sprintf("%s (%s)", upd.Message.Sender.Name, upd.Message.Sender.Username) + } + isSticker := "" + images := make([]string, 0) + for _, a := range upd.Message.Body.Attachments { + switch a := a.(type) { + case *tamtam.PhotoAttachment: + images = append(images, *a.Payload.Url) + case *tamtam.StickerAttachment: + images = append(images, a.Payload.Url) + isSticker = "СТИКЕР" + } + } + t.Bus <- lib.Message{ + To: r.TgID, + From: from, + Text: upd.Message.Body.Text, + Images: images, + Sticker: isSticker, + } + } + } + + default: + log.Printf("Unknown type: %#v", upd) + } + case msg := <-t.Updates: + + text := fmt.Sprintf("*%s*:\n%s", msg.From, msg.Text) + if msg.Sticker != "" { + text = fmt.Sprintf("*%s*: [%s]", msg.From, msg.Sticker) + } + attachments := make([]interface{}, 0, len(msg.Images)) + if len(msg.Images) > 0 { + toSent := []string{} + for _, i := range msg.Images { + ok := true + for _, j := range toSent { + if i == j { + ok = false + } + } + if ok { + toSent = append(toSent, i) + } + } + for _, i := range toSent { + attachments = append(attachments, tamtam.PhotoAttachment{ + Type: "image", + Payload: tamtam.PhotoAttachmentPayload{ + Url: &i, + }, + }) + } + } + if len(text) > 0 || len(attachments) > 0 { + res, err := t.API.SendMessage(msg.To, msg.To, &tamtam.NewMessageBody{ + Text: text, + Attachments: attachments, + }) + log.Printf("[TT] Answer: %#v %#v", res, err) + } + } + } +} |