feat: mark read

This commit is contained in:
John Doe 2025-04-07 17:11:09 +03:00
parent 2d629fd3bd
commit ab1a3131b6
3 changed files with 101 additions and 3 deletions

View file

@ -34,7 +34,7 @@ The Model Context Protocol (MCP) is a system that lets AI apps, like Claude Desk
- [x] Get the list of dialogs (chats, channels, groups) - [x] Get the list of dialogs (chats, channels, groups)
- [x] Get the list of messages in the given dialog - [x] Get the list of messages in the given dialog
- [x] Draft a message - [x] Draft a message
- [ ] Mark chanel as read - [x] Mark dialog as read
- [ ] Retrieve messages by date and time - [ ] Retrieve messages by date and time
- [ ] Get the list of contacts - [ ] Get the list of contacts

86
internal/tg/read.go Normal file
View file

@ -0,0 +1,86 @@
package tg
import (
"context"
"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"
)
type ReadArguments struct {
Name string `json:"name" jsonschema:"description=Name of the dialog"`
}
type ReadResponse struct {
Result string `json:"result"`
}
func (c *Client) ReadHistory(args ReadArguments) (*mcp.ToolResponse, error) {
ctx := context.Background()
var affectedMsgs *tg.MessagesAffectedMessages
client := c.T()
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)
if err != nil {
return fmt.Errorf("failed to resolve name: %w", err)
}
switch p := inputPeer.(type) {
case *tg.InputPeerUser:
affectedMsgs, err = api.MessagesReadHistory(ctx, &tg.MessagesReadHistoryRequest{
Peer: inputPeer,
})
case *tg.InputPeerChannel:
var ok bool
ok, err = api.ChannelsReadHistory(ctx, &tg.ChannelsReadHistoryRequest{
Channel: &tg.InputChannel{
ChannelID: p.ChannelID,
AccessHash: p.AccessHash,
},
})
if err != nil {
return fmt.Errorf("failed to read channels: %w", err)
}
affectedMsgs = &tg.MessagesAffectedMessages{}
if ok {
affectedMsgs = &tg.MessagesAffectedMessages{
Pts: 1,
PtsCount: 1,
}
}
default:
return fmt.Errorf("unexpected input peer type: %T", p)
}
if err != nil {
return fmt.Errorf("read history: %w", err)
}
return nil
}); err != nil {
return nil, fmt.Errorf("run client: %w", err)
}
res := "done"
if affectedMsgs.PtsCount == 0 {
res = "unread messages not found"
}
jsonData, err := json.Marshal(ReadResponse{Result: res})
if err != nil {
return nil, errors.Wrap(err, "failed to marshal response")
}
return mcp.NewToolResponse(mcp.NewTextContent(string(jsonData))), nil
}

View file

@ -57,10 +57,17 @@ func serve(ctx context.Context, cmd *cli.Command) error {
answer, err = client.SendDraft(tg.DraftArguments{Name: os.Getenv("TG_TEST_USERNAME"), Text: "test draft"}) answer, err = client.SendDraft(tg.DraftArguments{Name: os.Getenv("TG_TEST_USERNAME"), Text: "test draft"})
if err != nil { if err != nil {
return fmt.Errorf("send draft: %w", err) log.Err(err).Msg("Check SendDraft: FAIL")
} else {
log.Info().RawJSON("answer", []byte(answer.Content[0].TextContent.Text)).Msg("Check SendDraft: OK")
} }
log.Info().RawJSON("answer", []byte(answer.Content[0].TextContent.Text)).Msg("Check SendDraft: OK") answer, err = client.ReadHistory(tg.ReadArguments{Name: os.Getenv("TG_TEST_USERNAME")})
if err != nil {
log.Err(err).Msg("Check ReadHistory: FAIL")
} else {
log.Info().RawJSON("answer", []byte(answer.Content[0].TextContent.Text)).Msg("Check ReadHistory: OK")
}
return nil return nil
} }
@ -85,6 +92,11 @@ func serve(ctx context.Context, cmd *cli.Command) error {
return fmt.Errorf("register dialogs tool: %w", err) return fmt.Errorf("register dialogs tool: %w", err)
} }
err = server.RegisterTool("tg_read", "Mark dialog messages as read (channel, user)", client.ReadHistory)
if err != nil {
return fmt.Errorf("register read tool: %w", err)
}
if err := server.Serve(); err != nil { if err := server.Serve(); err != nil {
return fmt.Errorf("serve: %w", err) return fmt.Errorf("serve: %w", err)
} }