Files
mautrix-telegram/pkg/gotd/telegram/peers/members/chat.go
T
2025-06-27 20:03:37 -07:00

127 lines
3.2 KiB
Go

package members
import (
"context"
"time"
"github.com/go-faster/errors"
"go.mau.fi/mautrix-telegram/pkg/gotd/telegram/peers"
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
)
// ChatMembers is chat Members.
type ChatMembers struct {
m *peers.Manager
chat peers.Chat
}
func (c *ChatMembers) queryParticipants(ctx context.Context) (*tg.ChatParticipants, error) {
full, err := c.chat.FullRaw(ctx)
if err != nil {
return nil, errors.Wrap(err, "get full")
}
switch p := full.Participants.(type) {
case *tg.ChatParticipantsForbidden:
return nil, &ChatInfoUnavailableError{Info: p}
case *tg.ChatParticipants:
return p, nil
default:
return nil, errors.Errorf("unexpected type %T", p)
}
}
// ForEach calls cb for every member of chat.
//
// May return ChatInfoUnavailableError.
func (c *ChatMembers) ForEach(ctx context.Context, cb Callback) error {
chatDate := time.Unix(int64(c.chat.Raw().Date), 0)
p, err := c.queryParticipants(ctx)
if err != nil {
return errors.Wrap(err, "query")
}
for i, participant := range p.Participants {
userID := participant.GetUserID()
user, err := c.m.ResolveUserID(ctx, userID)
if err != nil {
return errors.Wrapf(err, "get member %d", userID)
}
var inviter peers.User
switch p := participant.(type) {
case *tg.ChatParticipant:
inviter, err = c.m.ResolveUserID(ctx, p.InviterID)
case *tg.ChatParticipantAdmin:
inviter, err = c.m.ResolveUserID(ctx, p.InviterID)
}
if err != nil {
return errors.Wrap(err, "get inviter")
}
if err := cb(ChatMember{
parent: c,
creatorDate: chatDate,
user: user,
inviter: inviter,
raw: participant,
}); err != nil {
return errors.Wrapf(err, "callback (index: %d)", i)
}
}
return nil
}
// Count returns total count of members.
func (c *ChatMembers) Count(ctx context.Context) (int, error) {
p, err := c.queryParticipants(ctx)
if err != nil {
return 0, errors.Wrap(err, "query")
}
return len(p.Participants), nil
}
// Peer returns chat object.
func (c *ChatMembers) Peer() peers.Peer {
return c.chat
}
// Kick kicks user member.
//
// If revokeHistory is set, will delete all messages from this member.
func (c *ChatMembers) Kick(ctx context.Context, member tg.InputUserClass, revokeHistory bool) error {
if _, err := c.m.API().MessagesDeleteChatUser(ctx, &tg.MessagesDeleteChatUserRequest{
RevokeHistory: revokeHistory,
ChatID: c.chat.ID(),
UserID: member,
}); err != nil {
return errors.Wrapf(err, "delete user (revoke: %v)", revokeHistory)
}
return nil
}
// EditRights edits rights of all members in this chat.
func (c *ChatMembers) EditRights(ctx context.Context, options MemberRights) error {
return editDefaultRights(ctx, c.m.API(), c.chat.InputPeer(), options)
}
// EditAdmin edits admin rights for given user.
func (c *ChatMembers) EditAdmin(ctx context.Context, user tg.InputUserClass, isAdmin bool) error {
if _, err := c.m.API().MessagesEditChatAdmin(ctx, &tg.MessagesEditChatAdminRequest{
ChatID: c.chat.ID(),
UserID: user,
IsAdmin: isAdmin,
}); err != nil {
return errors.Wrap(err, "edit admin")
}
return nil
}
// Chat returns recent chat members.
func Chat(chat peers.Chat) *ChatMembers {
return &ChatMembers{
m: chat.Manager(),
chat: chat,
}
}