feat: implement watch for monitoring chat messages

- Added a new command handler for /watch that allows users to listen to messages from a specified chat and save them according to storage rules.
- Introduced filtering options for messages using regular expressions.
- Implemented functionality to start and stop watching chats, including error handling for invalid inputs and user settings.
- Created a new utility package for message element handling related to the watch feature.
- Updated the user model to manage watched chats, including methods to add, remove, and check if a chat is being watched.
This commit is contained in:
krau
2025-08-03 16:55:56 +08:00
parent 8f9ef07d1c
commit 133453b5d4
14 changed files with 377 additions and 69 deletions

View File

@@ -6,13 +6,17 @@ import (
"github.com/celestix/gotgproto"
"github.com/celestix/gotgproto/dispatcher"
"github.com/celestix/gotgproto/dispatcher/handlers"
"github.com/celestix/gotgproto/dispatcher/handlers/filters"
"github.com/celestix/gotgproto/ext"
"github.com/celestix/gotgproto/sessionMaker"
"github.com/charmbracelet/log"
"github.com/gotd/td/telegram/dcs"
"github.com/krau/SaveAny-Bot/client/middleware"
"github.com/krau/SaveAny-Bot/common/utils/netutil"
"github.com/krau/SaveAny-Bot/config"
"github.com/krau/SaveAny-Bot/database"
"github.com/ncruces/go-sqlite3/gormlite"
"golang.org/x/net/proxy"
)
@@ -106,6 +110,15 @@ func Login(ctx context.Context) (*gotgproto.Client, error) {
return nil, r.err
}
uc = r.client
uc.Dispatcher.AddHandler(handlers.NewMessage(filters.Message.Media, func(ctx *ext.Context, u *ext.Update) error {
chatId := u.EffectiveChat().GetID()
watchChats, err := database.GetWatchChatsByChatID(ctx, chatId)
if err != nil || watchChats == nil {
return dispatcher.EndGroups
}
return dispatcher.ContinueGroups
}))
uc.Dispatcher.AddHandler(handlers.NewMessage(filters.Message.Media, handleMediaMessage))
log.FromContext(ctx).Infof("User client logged in successfully: %s", uc.Self.FirstName+" "+uc.Self.LastName)
return uc, nil
}

53
client/user/watch.go Normal file
View File

@@ -0,0 +1,53 @@
package user
import (
"github.com/celestix/gotgproto/dispatcher"
"github.com/celestix/gotgproto/ext"
"github.com/gotd/td/tg"
"github.com/krau/SaveAny-Bot/common/utils/tgutil"
"github.com/krau/SaveAny-Bot/pkg/tfile"
)
type MediaMessageEvent struct {
Ctx *ext.Context
ChatID int64 // from witch the media message was sent
File tfile.TGFileMessage
}
var mediaMessageCh = make(chan MediaMessageEvent, 100)
func GetMediaMessageCh() chan MediaMessageEvent {
return mediaMessageCh
}
func handleMediaMessage(ctx *ext.Context, update *ext.Update) error {
message := update.EffectiveMessage
media, ok := message.GetMedia()
if !ok || media == nil {
return dispatcher.EndGroups
}
support := func() bool {
switch media.(type) {
case *tg.MessageMediaDocument, *tg.MessageMediaPhoto:
return true
default:
return false
}
}()
if !support {
return dispatcher.EndGroups
}
file, err := tfile.FromMediaMessage(media, ctx.Raw, message.Message, tfile.WithNameIfEmpty(
tgutil.GenFileNameFromMessage(*message.Message),
))
if err != nil {
return err
}
chatId := update.EffectiveChat().GetID()
mediaMessageCh <- MediaMessageEvent{
Ctx: ctx,
ChatID: chatId,
File: file,
}
return dispatcher.EndGroups
}