7a04f298d2
- update to latest telegram layer - remove some references to fields in tg.Entities that don't exist in the schema - originally added here: https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e - referenced here - https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3 - https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
270 lines
6.2 KiB
Go
270 lines
6.2 KiB
Go
package peers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/go-faster/errors"
|
|
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/constant"
|
|
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
|
|
)
|
|
|
|
// User is user peer.
|
|
type User struct {
|
|
raw *tg.User
|
|
m *Manager
|
|
}
|
|
|
|
// User creates new User, attached to this manager.
|
|
func (m *Manager) User(u *tg.User) User {
|
|
m.needsUpdate(userPeerID(u.ID))
|
|
return User{
|
|
raw: u,
|
|
m: m,
|
|
}
|
|
}
|
|
|
|
// GetUser gets User using given tg.InputUserClass.
|
|
func (m *Manager) GetUser(ctx context.Context, p tg.InputUserClass) (User, error) {
|
|
user, err := m.getUser(ctx, p)
|
|
if err != nil {
|
|
return User{}, err
|
|
}
|
|
return m.User(user), nil
|
|
}
|
|
|
|
// Raw returns raw *tg.User.
|
|
func (u User) Raw() *tg.User {
|
|
return u.raw
|
|
}
|
|
|
|
// ID returns entity ID.
|
|
func (u User) ID() int64 {
|
|
return u.raw.GetID()
|
|
}
|
|
|
|
// TDLibPeerID returns TDLibPeerID for this entity.
|
|
func (u User) TDLibPeerID() constant.TDLibPeerID {
|
|
return userPeerID(u.raw.GetID())
|
|
}
|
|
|
|
// VisibleName returns visible name of peer.
|
|
//
|
|
// It returns FirstName + " " + LastName for users, and title for chats and channels.
|
|
func (u User) VisibleName() string {
|
|
firstName := u.raw.FirstName
|
|
lastName := u.raw.LastName
|
|
if lastName == "" {
|
|
return firstName
|
|
}
|
|
return fmt.Sprintf("%s %s", firstName, lastName)
|
|
}
|
|
|
|
// Username returns peer username, if any.
|
|
func (u User) Username() (string, bool) {
|
|
return u.raw.GetUsername()
|
|
}
|
|
|
|
// Restricted whether this user/chat/channel is restricted.
|
|
func (u User) Restricted() ([]tg.RestrictionReason, bool) {
|
|
reason, ok := u.raw.GetRestrictionReason()
|
|
return reason, ok || u.raw.GetRestricted()
|
|
}
|
|
|
|
// Verified whether this user/chat/channel is verified by Telegram.
|
|
func (u User) Verified() bool {
|
|
return u.raw.Verified
|
|
}
|
|
|
|
// Scam whether this user/chat/channel is probably a scam.
|
|
func (u User) Scam() bool {
|
|
return u.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 (u User) Fake() bool {
|
|
return u.raw.Fake
|
|
}
|
|
|
|
// InputPeer returns input peer for this peer.
|
|
func (u User) InputPeer() tg.InputPeerClass {
|
|
if u.Self() {
|
|
return &tg.InputPeerSelf{}
|
|
}
|
|
return &tg.InputPeerUser{
|
|
UserID: u.raw.ID,
|
|
AccessHash: u.raw.AccessHash,
|
|
}
|
|
}
|
|
|
|
// Sync updates current object.
|
|
func (u User) Sync(ctx context.Context) error {
|
|
raw, err := u.m.updateUser(ctx, u.InputUser())
|
|
if err != nil {
|
|
return errors.Wrap(err, "get user")
|
|
}
|
|
*u.raw = *raw
|
|
return nil
|
|
}
|
|
|
|
// Manager returns attached Manager.
|
|
func (u User) Manager() *Manager {
|
|
return u.m
|
|
}
|
|
|
|
// Report reports a peer for violation of telegram's Terms of Service.
|
|
func (u User) Report(ctx context.Context, reason tg.ReportReasonClass, message string) error {
|
|
if _, err := u.m.api.AccountReportPeer(ctx, &tg.AccountReportPeerRequest{
|
|
Peer: u.InputPeer(),
|
|
Reason: reason,
|
|
Message: message,
|
|
}); err != nil {
|
|
return errors.Wrap(err, "report")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Photo returns peer photo, if any.
|
|
func (u User) Photo(ctx context.Context) (*tg.Photo, bool, error) {
|
|
r, err := u.m.api.PhotosGetUserPhotos(ctx, &tg.PhotosGetUserPhotosRequest{
|
|
UserID: u.InputUser(),
|
|
Offset: 0,
|
|
Limit: 1,
|
|
})
|
|
if err != nil {
|
|
return nil, false, errors.Wrap(err, "get user photos")
|
|
}
|
|
|
|
if err := u.m.applyUsers(ctx, r.GetUsers()...); err != nil {
|
|
return nil, false, errors.Wrap(err, "apply users")
|
|
}
|
|
|
|
photos := r.GetPhotos()
|
|
if len(photos) < 1 {
|
|
return nil, false, nil
|
|
}
|
|
p, ok := photos[0].AsNotEmpty()
|
|
return p, ok, nil
|
|
}
|
|
|
|
// FullRaw returns *tg.UserFull for this User.
|
|
func (u User) FullRaw(ctx context.Context) (*tg.UserFull, error) {
|
|
return u.m.getUserFull(ctx, u.InputUser())
|
|
}
|
|
|
|
// ToBot tries to convert this User to Bot.
|
|
func (u User) ToBot() (Bot, bool) {
|
|
if !u.raw.Bot {
|
|
return Bot{}, false
|
|
}
|
|
return Bot{
|
|
User: u,
|
|
}, true
|
|
}
|
|
|
|
// Self whether this user indicates the currently logged-in user.
|
|
func (u User) Self() bool {
|
|
// TODO(tdakkota): return helper instead?
|
|
return u.raw.Self
|
|
}
|
|
|
|
// Contact whether this user is a contact.
|
|
func (u User) Contact() bool {
|
|
return u.raw.Contact
|
|
}
|
|
|
|
// MutualContact whether this user is a mutual contact.
|
|
func (u User) MutualContact() bool {
|
|
return u.raw.MutualContact
|
|
}
|
|
|
|
// Deleted whether the account of this user was deleted.
|
|
func (u User) Deleted() bool {
|
|
return u.raw.Deleted
|
|
}
|
|
|
|
// Support whether this is an official support user.
|
|
func (u User) Support() bool {
|
|
return u.raw.Support
|
|
}
|
|
|
|
// FirstName returns first name.
|
|
func (u User) FirstName() (string, bool) {
|
|
return u.raw.GetFirstName()
|
|
}
|
|
|
|
// LastName returns last name.
|
|
func (u User) LastName() (string, bool) {
|
|
return u.raw.GetLastName()
|
|
}
|
|
|
|
// Phone returns phone, if any.
|
|
func (u User) Phone() (string, bool) {
|
|
return u.raw.GetPhone()
|
|
}
|
|
|
|
// Status returns user status, if any.
|
|
func (u User) Status() (tg.UserStatusClass, bool) {
|
|
return u.raw.GetStatus()
|
|
}
|
|
|
|
// LangCode returns users lang code, if any.
|
|
func (u User) LangCode() (string, bool) {
|
|
return u.raw.GetLangCode()
|
|
}
|
|
|
|
// InputUser returns input user for this user.
|
|
func (u User) InputUser() tg.InputUserClass {
|
|
if u.Self() {
|
|
return &tg.InputUserSelf{}
|
|
}
|
|
return &tg.InputUser{
|
|
UserID: u.raw.ID,
|
|
AccessHash: u.raw.AccessHash,
|
|
}
|
|
}
|
|
|
|
// ReportSpam reports a new incoming chat for spam, if the peer settings of the chat allow us to do that.
|
|
func (u User) ReportSpam(ctx context.Context) error {
|
|
if _, err := u.m.api.MessagesReportSpam(ctx, u.InputPeer()); err != nil {
|
|
return errors.Wrap(err, "report spam")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Block blocks this user.
|
|
func (u User) Block(ctx context.Context) error {
|
|
if _, err := u.m.api.ContactsBlock(ctx, &tg.ContactsBlockRequest{
|
|
ID: u.InputPeer(),
|
|
}); err != nil {
|
|
return errors.Wrap(err, "block")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Unblock unblocks this user.
|
|
func (u User) Unblock(ctx context.Context) error {
|
|
if _, err := u.m.api.ContactsUnblock(ctx, &tg.ContactsUnblockRequest{
|
|
ID: u.InputPeer(),
|
|
}); err != nil {
|
|
return errors.Wrap(err, "unblock")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// InviteTo invites User to given channel.
|
|
func (u User) InviteTo(ctx context.Context, ch tg.InputChannelClass) error {
|
|
if _, err := u.m.api.ChannelsInviteToChannel(ctx, &tg.ChannelsInviteToChannelRequest{
|
|
Channel: ch,
|
|
Users: []tg.InputUserClass{u.InputUser()},
|
|
}); err != nil {
|
|
return errors.Wrap(err, "invite to channel")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// TODO(tdakkota): add more getters, helpers and convertors
|