From bc792526616fffb99fcec61817d426750713f733 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Sat, 29 Nov 2025 17:28:34 +0700 Subject: [PATCH] feat(go): add some forward logic (wip) --- .env.example | 5 ++-- .gitignore | 2 ++ README.md | 2 +- main.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index 947cd56..0656ae4 100644 --- a/.env.example +++ b/.env.example @@ -6,5 +6,6 @@ TG_PHONE=your_telegram_phone_number APP_ID=your_app_id APP_HASH=your_app_hash -SOURCE_GROUP_ID=-123456789 -TARGET_GROUP_ID=-123456789 +# Group chat id is without -100 +SOURCE_CHAT_ID=-123456789 +TARGET_CHAT_ID=-123456789 diff --git a/.gitignore b/.gitignore index 089a213..fcc9628 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ +.claude .idea +session diff --git a/README.md b/README.md index 34d2e38..585715c 100644 --- a/README.md +++ b/README.md @@ -59,4 +59,4 @@ The application will connect to Telegram and start forwarding messages from the ## The Original Python Version -The original Python version of this project can be found at the `feature/python` branch. +*In 2025, I rewrote this project using Go. The original Python version of this project can be found at the `feature/python` branch.* diff --git a/main.go b/main.go index 75f63cf..3358b9b 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "context" "flag" "fmt" + "math/rand" "os" "os/signal" "path/filepath" @@ -71,6 +72,18 @@ func run(ctx context.Context) error { return errors.New("no app hash") } + sourceChatId, err := strconv.ParseInt(os.Getenv("SOURCE_CHAT_ID"), 10, 0) + if err != nil { + return errors.New("no source chat id") + } + + targetChatId, err := strconv.ParseInt(os.Getenv("TARGET_CHAT_ID"), 10, 0) + if err != nil { + return errors.New("no target chat id") + } + + fmt.Printf("forward from %d to %d\n", sourceChatId, targetChatId) + // Setting up session storage. // This is needed to reuse session and not login every time. sessionDir := filepath.Join("session", sessionFolder(phone)) @@ -181,6 +194,57 @@ func run(ctx context.Context) error { } fmt.Printf("%s: %s\n", p, msg.Message) + + api := client.API() + targetPeer, err := storage.FindPeer(ctx, peerDB, &tg.PeerChat{ChatID: targetChatId}) + _, err = api.MessagesForwardMessages(ctx, &tg.MessagesForwardMessagesRequest{ + ToPeer: targetPeer.AsInputPeer(), + FromPeer: p.AsInputPeer(), + ID: []int{msg.ID}, + RandomID: []int64{rand.Int63()}, + }) + + if err != nil { + fmt.Printf("%s\n", err) + } + + return err + }) + + dispatcher.OnNewChannelMessage(func(ctx context.Context, e tg.Entities, u *tg.UpdateNewChannelMessage) error { + msg, ok := u.Message.(*tg.Message) + if !ok { + return nil + } + if msg.Out { + // Outgoing message. + return nil + } + + // Use PeerID to find peer because *Short updates does not contain any entities, so it necessary to + // store some entities. + // + // Storage can be filled using PeerCollector (i.e. fetching all dialogs first). + p, err := storage.FindPeer(ctx, peerDB, msg.GetPeerID()) + if err != nil { + return err + } + + fmt.Printf("%s: %s\n", p, msg.Message) + + api := client.API() + targetPeer, err := storage.FindPeer(ctx, peerDB, &tg.PeerChat{ChatID: targetChatId}) + _, err = api.MessagesForwardMessages(ctx, &tg.MessagesForwardMessagesRequest{ + ToPeer: targetPeer.AsInputPeer(), + FromPeer: p.AsInputPeer(), + ID: []int{msg.ID}, + RandomID: []int64{rand.Int63()}, + }) + + if err != nil { + fmt.Printf("%s\n", err) + } + return nil })