diff --git a/internal/tg/dialogs.go b/internal/tg/dialogs.go index c980064..f6c2197 100644 --- a/internal/tg/dialogs.go +++ b/internal/tg/dialogs.go @@ -257,7 +257,6 @@ func (d *dialogs) processDialog(dialogItem *tg.Dialog) (DialogInfo, error) { Text: text, IsUnread: dialogItem.UnreadCount > 0, } - } if dialogItem.Peer == nil { diff --git a/internal/tg/draft.go b/internal/tg/draft.go index 926f9d4..e934597 100644 --- a/internal/tg/draft.go +++ b/internal/tg/draft.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" - "github.com/gotd/td/telegram/message" "github.com/gotd/td/tg" mcp "github.com/metoro-io/mcp-golang" "github.com/pkg/errors" @@ -26,10 +25,9 @@ func (c *Client) SendDraft(args DraftArguments) (*mcp.ToolResponse, error) { if err := client.Run(context.Background(), func(ctx context.Context) (err error) { api := client.API() - sender := message.NewSender(api) - inputPeer, err := sender.Resolve(args.Name).AsInputPeer(ctx) + inputPeer, err := getInputPeerFromName(ctx, api, args.Name) if err != nil { - return fmt.Errorf("failed to resolve name: %w", err) + return fmt.Errorf("get inputPeer from name: %w", err) } ok, err = api.MessagesSaveDraft(ctx, &tg.MessagesSaveDraftRequest{ diff --git a/internal/tg/helpers.go b/internal/tg/helpers.go index fc76bfa..8fe2258 100644 --- a/internal/tg/helpers.go +++ b/internal/tg/helpers.go @@ -32,9 +32,12 @@ func getUsername(source any) string { case *tg.User: username = u.Username case *tg.Chat: - username = fmt.Sprintf("chat(%d)", u.ID) + username = fmt.Sprintf("cht[%d]", u.ID) case *tg.Channel: username = u.Username + if username == "" { + username = fmt.Sprintf("chn[%d:%d]", u.ID, u.AccessHash) + } } return username diff --git a/internal/tg/history.go b/internal/tg/history.go index 3afcaf5..1a2319c 100644 --- a/internal/tg/history.go +++ b/internal/tg/history.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "strings" "time" "github.com/gotd/td/telegram/message" @@ -28,10 +29,9 @@ func (c *Client) GetHistory(args HistoryArguments) (*mcp.ToolResponse, error) { if err := client.Run(context.Background(), func(ctx context.Context) (err error) { api := client.API() - sender := message.NewSender(api) - inputPeer, err := sender.Resolve(args.Name).AsInputPeer(ctx) + inputPeer, err := getInputPeerFromName(ctx, api, args.Name) if err != nil { - return fmt.Errorf("failed to resolve name: %w", err) + return fmt.Errorf("get inputPeer from name: %w", err) } messagesClass, err = api.MessagesGetHistory(ctx, &tg.MessagesGetHistoryRequest{ @@ -69,6 +69,37 @@ func (c *Client) GetHistory(args HistoryArguments) (*mcp.ToolResponse, error) { return mcp.NewToolResponse(mcp.NewTextContent(string(jsonData))), nil } +func getInputPeerFromName(ctx context.Context, api *tg.Client, name string) (tg.InputPeerClass, error) { + isCustom := strings.Contains(name, "[") && strings.Contains(name, "]") + + switch { + case strings.HasPrefix(name, "chn") && isCustom: + var channelPeer tg.InputPeerChannel + _, err := fmt.Sscanf(name, "chn[%d:%d]", &channelPeer.ChannelID, &channelPeer.AccessHash) + if err != nil { + return nil, errors.Wrapf(err, "scan channel peer(%q)", name) + } + + return &channelPeer, nil + case strings.HasPrefix(name, "cht") && isCustom: + var chatPeer tg.InputPeerChat + _, err := fmt.Sscanf(name, "cht[%d]", &chatPeer.ChatID) + if err != nil { + return nil, errors.Wrapf(err, "scan chat peer(%q)", name) + } + + return &chatPeer, nil + default: + sender := message.NewSender(api) + inputPeer, err := sender.Resolve(name).AsInputPeer(ctx) + if err != nil { + return nil, fmt.Errorf("failed to resolve name: %w", err) + } + + return inputPeer, nil + } +} + type history struct { tg.MessagesMessages users map[int64]*tg.User diff --git a/internal/tg/read.go b/internal/tg/read.go index c702bb5..8659330 100644 --- a/internal/tg/read.go +++ b/internal/tg/read.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" - "github.com/gotd/td/telegram/message" "github.com/gotd/td/tg" mcp "github.com/metoro-io/mcp-golang" "github.com/pkg/errors" @@ -27,14 +26,13 @@ func (c *Client) ReadHistory(args ReadArguments) (*mcp.ToolResponse, error) { if err := client.Run(ctx, func(ctx context.Context) error { api := client.API() - sender := message.NewSender(api) - inputPeer, err := sender.Resolve(args.Name).AsInputPeer(ctx) + inputPeer, err := getInputPeerFromName(ctx, api, args.Name) if err != nil { - return fmt.Errorf("failed to resolve name: %w", err) + return fmt.Errorf("get inputPeer from name: %w", err) } switch p := inputPeer.(type) { - case *tg.InputPeerUser: + case *tg.InputPeerUser, *tg.InputPeerChat: affectedMsgs, err = api.MessagesReadHistory(ctx, &tg.MessagesReadHistoryRequest{ Peer: inputPeer, }) @@ -58,7 +56,6 @@ func (c *Client) ReadHistory(args ReadArguments) (*mcp.ToolResponse, error) { PtsCount: 1, } } - default: return fmt.Errorf("unexpected input peer type: %T", p) } diff --git a/serve.go b/serve.go index 2e4d2ac..f69d239 100644 --- a/serve.go +++ b/serve.go @@ -50,7 +50,17 @@ func serve(ctx context.Context, cmd *cli.Command) error { answer, err = client.GetHistory(tg.HistoryArguments{Name: os.Getenv("TG_TEST_USERNAME")}) if err != nil { - return fmt.Errorf("get histore: %w", err) + return fmt.Errorf("get nickname history: %w", err) + } + + answer, err = client.GetHistory(tg.HistoryArguments{Name: "cht[4626931529]"}) + if err != nil { + return fmt.Errorf("get chat history: %w", err) + } + + answer, err = client.GetHistory(tg.HistoryArguments{Name: "chn[2225853048:8934705438195741763]"}) + if err != nil { + return fmt.Errorf("get chan history: %w", err) } log.Info().RawJSON("answer", []byte(answer.Content[0].TextContent.Text)).Msg("Check GetHistory: OK") @@ -82,17 +92,17 @@ func serve(ctx context.Context, cmd *cli.Command) error { return fmt.Errorf("register dialogs tool: %w", err) } - err = server.RegisterTool("tg_dialog", "Get messages of telegram dialog (channel, user)", client.GetHistory) + err = server.RegisterTool("tg_dialog", "Get messages of telegram dialog", client.GetHistory) if err != nil { return fmt.Errorf("register dialogs tool: %w", err) } - err = server.RegisterTool("tg_send", "Send draft message to dialog (channel, user)", client.SendDraft) + err = server.RegisterTool("tg_send", "Send draft message to dialog", client.SendDraft) if err != nil { return fmt.Errorf("register dialogs tool: %w", err) } - err = server.RegisterTool("tg_read", "Mark dialog messages as read (channel, user)", client.ReadHistory) + err = server.RegisterTool("tg_read", "Mark dialog messages as read", client.ReadHistory) if err != nil { return fmt.Errorf("register read tool: %w", err) }