package peers import ( "context" "github.com/go-faster/errors" "go.mau.fi/mautrix-telegram/pkg/gotd/constant" "go.mau.fi/mautrix-telegram/pkg/gotd/tg" ) // Channel is channel peer. type Channel struct { raw *tg.Channel m *Manager } // Channel creates new Channel, attached to this manager. func (m *Manager) Channel(u *tg.Channel) Channel { m.needsUpdate(channelPeerID(u.ID)) return Channel{ raw: u, m: m, } } // GetChannel gets Channel using given tg.InputChannelClass. func (m *Manager) GetChannel(ctx context.Context, p tg.InputChannelClass) (Channel, error) { ch, err := m.getChannel(ctx, p) if err != nil { return Channel{}, err } return m.Channel(ch), nil } // Raw returns raw *tg.Channel. func (c Channel) Raw() *tg.Channel { return c.raw } // ID returns entity ID. func (c Channel) ID() int64 { return c.raw.GetID() } // TDLibPeerID returns TDLibPeerID for this entity. func (c Channel) TDLibPeerID() constant.TDLibPeerID { return channelPeerID(c.raw.GetID()) } // VisibleName returns visible name of peer. // // It returns FirstName + " " + LastName for users, and title for chats and channels. func (c Channel) VisibleName() string { return c.raw.GetTitle() } // Username returns peer username, if any. func (c Channel) Username() (string, bool) { return c.raw.GetUsername() } // Restricted whether this user/chat/channel is restricted. func (c Channel) Restricted() ([]tg.RestrictionReason, bool) { reason, ok := c.raw.GetRestrictionReason() return reason, ok || c.raw.GetRestricted() } // Verified whether this user/chat/channel is verified by Telegram. func (c Channel) Verified() bool { return c.raw.Verified } // Scam whether this user/chat/channel is probably a scam. func (c Channel) Scam() bool { return c.raw.Scam } // Fake whether this user/chat/channel was reported by many users as a fake or scam: be // careful when interacting with it. func (c Channel) Fake() bool { return c.raw.Fake } // InputPeer returns input peer for this peer. func (c Channel) InputPeer() tg.InputPeerClass { return &tg.InputPeerChannel{ ChannelID: c.raw.ID, AccessHash: c.raw.AccessHash, } } // Sync updates current object. func (c Channel) Sync(ctx context.Context) error { raw, err := c.m.updateChannel(ctx, c.raw.AsInput()) if err != nil { return errors.Wrap(err, "get channel") } *c.raw = *raw return nil } // Manager returns attached Manager. func (c Channel) Manager() *Manager { return c.m } // Report reports a peer for violation of telegram's Terms of Service. func (c Channel) Report(ctx context.Context, reason tg.ReportReasonClass, message string) error { if _, err := c.m.api.AccountReportPeer(ctx, &tg.AccountReportPeerRequest{ Peer: c.InputPeer(), Reason: reason, Message: message, }); err != nil { return errors.Wrap(err, "report") } return nil } // Photo returns peer photo, if any. func (c Channel) Photo(ctx context.Context) (*tg.Photo, bool, error) { full, err := c.FullRaw(ctx) if err != nil { return nil, false, err } p, ok := full.ChatPhoto.AsNotEmpty() return p, ok, nil } // FullRaw returns *tg.ChannelFull for this Channel. func (c Channel) FullRaw(ctx context.Context) (*tg.ChannelFull, error) { return c.m.getChannelFull(ctx, c.InputChannel()) } // ToBroadcast tries to convert this Channel to Broadcast. func (c Channel) ToBroadcast() (Broadcast, bool) { if !c.IsBroadcast() { return Broadcast{}, false } return Broadcast{ Channel: c, }, true } // IsBroadcast whether this Channel is Broadcast. func (c Channel) IsBroadcast() bool { return c.raw.Broadcast } // ToSupergroup tries to convert this Channel to Supergroup. func (c Channel) ToSupergroup() (Supergroup, bool) { if !c.IsSupergroup() { return Supergroup{}, false } return Supergroup{ Channel: c, }, true } // IsSupergroup whether this Channel is Supergroup. func (c Channel) IsSupergroup() bool { return c.raw.Megagroup } // InviteLinks returns InviteLinks for this peer. func (c Channel) InviteLinks() InviteLinks { return InviteLinks{ peer: c, m: c.m, } } // InputChannel returns input user for this user. func (c Channel) InputChannel() tg.InputChannelClass { return &tg.InputChannel{ ChannelID: c.raw.ID, AccessHash: c.raw.AccessHash, } } // Creator whether the current user is the creator of this channel. func (c Channel) Creator() bool { return c.raw.Creator } // Left whether the current user has left this channel. func (c Channel) Left() bool { return c.raw.Left } // HasLink whether this channel has a private join link. func (c Channel) HasLink() bool { return c.raw.HasLink } // HasGeo whether this channel has a geoposition. func (c Channel) HasGeo() bool { return c.raw.HasGeo } // CallActive whether a group call or livestream is currently active. func (c Channel) CallActive() bool { return c.raw.CallActive } // CallNotEmpty whether there's anyone in the group call or livestream. func (c Channel) CallNotEmpty() bool { return c.raw.CallNotEmpty } // NoForwards whether that message forwarding from this channel is not allowed. func (c Channel) NoForwards() bool { return c.raw.Noforwards } // AdminRights returns admin rights of the user in this channel. // // See https://core.telegram.org/api/rights. func (c Channel) AdminRights() (tg.ChatAdminRights, bool) { // TODO(tdakkota): add wrapper for raw object? return c.raw.GetAdminRights() } // BannedRights returns banned rights of the user in this channel. // // See https://core.telegram.org/api/rights. func (c Channel) BannedRights() (tg.ChatBannedRights, bool) { // TODO(tdakkota): add wrapper for raw object? return c.raw.GetBannedRights() } // DefaultBannedRights returns default chat rights. // // See https://core.telegram.org/api/rights. func (c Channel) DefaultBannedRights() (tg.ChatBannedRights, bool) { // TODO(tdakkota): add wrapper for raw object? return c.raw.GetDefaultBannedRights() } // ParticipantsCount returns count of participants. func (c Channel) ParticipantsCount() int { v, _ := c.raw.GetParticipantsCount() return v } // Join joins this channel. func (c Channel) Join(ctx context.Context) error { if _, err := c.m.api.ChannelsJoinChannel(ctx, c.InputChannel()); err != nil { return errors.Wrap(err, "join channel") } return nil } // Delete deletes this channel. func (c Channel) Delete(ctx context.Context) error { if _, err := c.m.api.ChannelsDeleteChannel(ctx, c.InputChannel()); err != nil { return errors.Wrap(err, "delete channel") } return nil } // Leave leaves this channel. func (c Channel) Leave(ctx context.Context) error { if _, err := c.m.api.ChannelsLeaveChannel(ctx, c.InputChannel()); err != nil { return errors.Wrap(err, "leave channel") } return nil } // SetTitle sets new title for this Chat. func (c Channel) SetTitle(ctx context.Context, title string) error { if _, err := c.m.api.ChannelsEditTitle(ctx, &tg.ChannelsEditTitleRequest{ Channel: c.InputChannel(), Title: title, }); err != nil { return errors.Wrap(err, "edit channel title") } return nil } // SetDescription sets new description for this Chat. func (c Channel) SetDescription(ctx context.Context, about string) error { return c.m.editAbout(ctx, c.InputPeer(), about) } // SetReactions sets list of available reactions. // // Empty list disables reactions at all. func (c Channel) SetReactions(ctx context.Context, reactions ...tg.ReactionClass) error { return c.m.editReactions(ctx, c.InputPeer(), &tg.ChatReactionsSome{ Reactions: reactions, }) } // DisableReactions disables reactions. func (c Channel) DisableReactions(ctx context.Context) error { return c.m.editReactions(ctx, c.InputPeer(), &tg.ChatReactionsNone{}) } // TODO(tdakkota): add more getters, helpers and convertors