package main import ( "context" "fmt" "log" "os" "strings" "github.com/go-telegram-bot-api/telegram-bot-api" "github.com/neonxp/rutina" "github.com/neonxp/tamtam" ) type message struct { From string To int64 Text string Images []string Sticker string } type routing struct { TgID int64 TTID int64 } func main() { tamtamToken := os.Getenv("TAMTAM") telegramToken := os.Getenv("TELEGRAM") r := rutina.New() routes := []routing{ {TgID: -1001046507545, TTID: -69062921115159}, } tt2tg := make(chan message, 1) tg2tt := make(chan message, 1) // region TamTam tamtamApi := tamtam.New(tamtamToken) ttch := make(chan interface{}, 1) r.Go(func(ctx context.Context) error { for { select { case <-ctx.Done(): return nil case upd := <-ttch: log.Printf("[TT] Received: %#v", upd) switch upd := upd.(type) { case tamtam.UpdateMessageCreated: for _, r := range routes { 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 = "STICKER" } } tt2tg <- message{ To: r.TgID, From: from, Text: upd.Message.Body.Text, Images: images, Sticker: isSticker, } } } default: log.Printf("Unknown type: %#v", upd) } case msg := <-tg2tt: text := fmt.Sprintf("[TG] %s: %s", msg.From, msg.Text) if msg.Sticker != "" { text = fmt.Sprintf("[TG] %s: [%s]", msg.From, msg.Sticker) } if len(msg.Images) > 0 { text += "[IMAGES] " + strings.Join(msg.Images, " ") } res, err := tamtamApi.SendMessage(msg.To, msg.To, &tamtam.NewMessageBody{ Text: text, }) log.Printf("[TT] Answer: %#v %#v", res, err) } } }, rutina.ShutdownIfDone, rutina.RestartIfFail) r.Go(func(ctx context.Context) error { return tamtamApi.GetUpdatesLoop(ctx, ttch) }, rutina.ShutdownIfDone, rutina.RestartIfFail) // endregion // region Telegram tgApi, err := tgbotapi.NewBotAPI(telegramToken) if err != nil { log.Panic(err) } u := tgbotapi.NewUpdate(0) u.Timeout = 60 updates, err := tgApi.GetUpdatesChan(u) r.Go(func(ctx context.Context) error { for { select { case <-ctx.Done(): return nil case upd := <-updates: if upd.Message == nil { // ignore any non-Message Updates continue } for _, r := range routes { 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, _ := tgApi.GetFileDirectURL(upd.Message.Sticker.Thumbnail.FileID) images = append(images, s) } if upd.Message.Photo != nil { for _, p := range *upd.Message.Photo { s, _ := tgApi.GetFileDirectURL(p.FileID) images = append(images, s) } } tg2tt <- message{ To: r.TTID, From: from, Text: upd.Message.Text, Images: images, Sticker: isSticker, } } } case msg := <-tt2tg: att := make([]interface{}, 0) for _, a := range msg.Images { att = append(att, tamtam.Image{Url: a}) } text := fmt.Sprintf("[TT] %s: %s", msg.From, msg.Text) if msg.Sticker != "" { text = fmt.Sprintf("[TT] %s: [%s]", msg.From, msg.Sticker) } if len(msg.Images) > 0 { text += "[IMAGES] " + strings.Join(msg.Images, " ") } m := tgbotapi.NewMessage(msg.To, text) res, err := tgApi.Send(m) log.Printf("[TG] Answer: %#v %#v", res, err) } } }, rutina.ShutdownIfDone, rutina.RestartIfFail) // endregion r.ListenOsSignals() if err := r.Wait(); err != nil { log.Fatal(err) } }