Skip to main content
Glama
history.go4.2 kB
package tg import ( "context" "encoding/json" "fmt" "strings" "time" "github.com/gotd/td/telegram/message" "github.com/gotd/td/tg" mcp "github.com/metoro-io/mcp-golang" "github.com/pkg/errors" ) type HistoryArguments struct { Name string `json:"name" jsonschema:"required,description=Name of the dialog"` Offset int `json:"offset,omitempty" jsonschema:"description=Offset for continuation"` } type HistoryResponse struct { Messages []MessageInfo `json:"messages"` Offset int `json:"offset,omitempty"` } func (c *Client) GetHistory(args HistoryArguments) (*mcp.ToolResponse, error) { var messagesClass tg.MessagesMessagesClass client := c.T() if err := client.Run(context.Background(), func(ctx context.Context) (err error) { api := client.API() inputPeer, err := getInputPeerFromName(ctx, api, args.Name) if err != nil { return fmt.Errorf("get inputPeer from name: %w", err) } messagesClass, err = api.MessagesGetHistory(ctx, &tg.MessagesGetHistoryRequest{ Peer: inputPeer, OffsetID: args.Offset, }) if err != nil { return fmt.Errorf("failed to get history: %w", err) } //Debug //jsonData, _ := json.Marshal(messagesClass) //log.Info().RawJSON("history", cleanJSON(jsonData)).Msg("history") return nil }); err != nil { return nil, errors.Wrap(err, "failed to get history") } h, err := newHistory(messagesClass) if err != nil { return nil, errors.Wrap(err, "failed to process history") } rsp := HistoryResponse{ Messages: h.Info(), Offset: h.Offset(), } jsonData, err := json.Marshal(rsp) if err != nil { return nil, errors.Wrap(err, "failed to marshal response") } 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 } func newHistory(raw tg.MessagesMessagesClass) (*history, error) { var h history switch m := raw.(type) { case *tg.MessagesMessages: h = history{MessagesMessages: *m} case *tg.MessagesMessagesSlice: h = history{MessagesMessages: tg.MessagesMessages{ Messages: m.Messages, Users: m.Users, Chats: m.Chats, }} case *tg.MessagesChannelMessages: h = history{MessagesMessages: tg.MessagesMessages{ Messages: m.Messages, Users: m.Users, Chats: m.Chats, }} default: return nil, fmt.Errorf("unexpected type: %T", raw) } h.users = make(map[int64]*tg.User) for _, u := range h.Users { if user, ok := u.(*tg.User); ok { h.users[user.ID] = user } } return &h, nil } func (h *history) Info() []MessageInfo { messages := make([]MessageInfo, 0, len(h.Messages)) for _, msg := range h.Messages { m, ok := msg.(*tg.Message) if !ok { continue } var who string if m.FromID != nil { switch from := m.FromID.(type) { case *tg.PeerUser: if user, ok := h.users[from.UserID]; ok { who = getUsername(user) } } } messages = append(messages, MessageInfo{ Who: who, When: time.Unix(int64(m.Date), 0).Format(time.DateTime), Text: m.Message, ts: m.Date, }) } return messages } func (h *history) Offset() int { for i := len(h.Messages) - 1; i >= 0; i-- { if msg, ok := h.Messages[i].(*tg.Message); ok { return msg.ID } } return 0 }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/chaindead/telegram-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server