feat: mark read
This commit is contained in:
parent
2d629fd3bd
commit
ab1a3131b6
3 changed files with 101 additions and 3 deletions
|
|
@ -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
86
internal/tg/read.go
Normal 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
|
||||||
|
}
|
||||||
16
serve.go
16
serve.go
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue