feat: add chat support, fix issue #1
This commit is contained in:
parent
8f9efe0135
commit
911e761430
6 changed files with 57 additions and 19 deletions
|
|
@ -257,7 +257,6 @@ func (d *dialogs) processDialog(dialogItem *tg.Dialog) (DialogInfo, error) {
|
||||||
Text: text,
|
Text: text,
|
||||||
IsUnread: dialogItem.UnreadCount > 0,
|
IsUnread: dialogItem.UnreadCount > 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if dialogItem.Peer == nil {
|
if dialogItem.Peer == nil {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/gotd/td/telegram/message"
|
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
mcp "github.com/metoro-io/mcp-golang"
|
mcp "github.com/metoro-io/mcp-golang"
|
||||||
"github.com/pkg/errors"
|
"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) {
|
if err := client.Run(context.Background(), func(ctx context.Context) (err error) {
|
||||||
api := client.API()
|
api := client.API()
|
||||||
|
|
||||||
sender := message.NewSender(api)
|
inputPeer, err := getInputPeerFromName(ctx, api, args.Name)
|
||||||
inputPeer, err := sender.Resolve(args.Name).AsInputPeer(ctx)
|
|
||||||
if err != nil {
|
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{
|
ok, err = api.MessagesSaveDraft(ctx, &tg.MessagesSaveDraftRequest{
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,12 @@ func getUsername(source any) string {
|
||||||
case *tg.User:
|
case *tg.User:
|
||||||
username = u.Username
|
username = u.Username
|
||||||
case *tg.Chat:
|
case *tg.Chat:
|
||||||
username = fmt.Sprintf("chat(%d)", u.ID)
|
username = fmt.Sprintf("cht[%d]", u.ID)
|
||||||
case *tg.Channel:
|
case *tg.Channel:
|
||||||
username = u.Username
|
username = u.Username
|
||||||
|
if username == "" {
|
||||||
|
username = fmt.Sprintf("chn[%d:%d]", u.ID, u.AccessHash)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return username
|
return username
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gotd/td/telegram/message"
|
"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) {
|
if err := client.Run(context.Background(), func(ctx context.Context) (err error) {
|
||||||
api := client.API()
|
api := client.API()
|
||||||
|
|
||||||
sender := message.NewSender(api)
|
inputPeer, err := getInputPeerFromName(ctx, api, args.Name)
|
||||||
inputPeer, err := sender.Resolve(args.Name).AsInputPeer(ctx)
|
|
||||||
if err != nil {
|
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{
|
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
|
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 {
|
type history struct {
|
||||||
tg.MessagesMessages
|
tg.MessagesMessages
|
||||||
users map[int64]*tg.User
|
users map[int64]*tg.User
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/gotd/td/telegram/message"
|
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
mcp "github.com/metoro-io/mcp-golang"
|
mcp "github.com/metoro-io/mcp-golang"
|
||||||
"github.com/pkg/errors"
|
"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 {
|
if err := client.Run(ctx, func(ctx context.Context) error {
|
||||||
api := client.API()
|
api := client.API()
|
||||||
|
|
||||||
sender := message.NewSender(api)
|
inputPeer, err := getInputPeerFromName(ctx, api, args.Name)
|
||||||
inputPeer, err := sender.Resolve(args.Name).AsInputPeer(ctx)
|
|
||||||
if err != nil {
|
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) {
|
switch p := inputPeer.(type) {
|
||||||
case *tg.InputPeerUser:
|
case *tg.InputPeerUser, *tg.InputPeerChat:
|
||||||
affectedMsgs, err = api.MessagesReadHistory(ctx, &tg.MessagesReadHistoryRequest{
|
affectedMsgs, err = api.MessagesReadHistory(ctx, &tg.MessagesReadHistoryRequest{
|
||||||
Peer: inputPeer,
|
Peer: inputPeer,
|
||||||
})
|
})
|
||||||
|
|
@ -58,7 +56,6 @@ func (c *Client) ReadHistory(args ReadArguments) (*mcp.ToolResponse, error) {
|
||||||
PtsCount: 1,
|
PtsCount: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unexpected input peer type: %T", p)
|
return fmt.Errorf("unexpected input peer type: %T", p)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
serve.go
18
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")})
|
answer, err = client.GetHistory(tg.HistoryArguments{Name: os.Getenv("TG_TEST_USERNAME")})
|
||||||
if err != nil {
|
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")
|
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)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("register dialogs tool: %w", err)
|
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 {
|
if err != nil {
|
||||||
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)
|
err = server.RegisterTool("tg_read", "Mark dialog messages as read", client.ReadHistory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("register read tool: %w", err)
|
return fmt.Errorf("register read tool: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue