From 9c39f7a79f643ed22a9f4569f32913c056fb02ed Mon Sep 17 00:00:00 2001 From: Amarnathcjd Date: Mon, 17 Oct 2022 11:45:45 +0530 Subject: [PATCH] v1.0.2 --- mtproto.go | 2 +- telegram/auth.go | 22 ++++- telegram/const.go | 2 +- telegram/inlinequery.go | 16 ++++ telegram/messages.go | 20 +++- telegram/types.go | 197 ---------------------------------------- telegram/updates.go | 94 +++++++++++++++---- 7 files changed, 132 insertions(+), 221 deletions(-) delete mode 100644 telegram/types.go diff --git a/mtproto.go b/mtproto.go index c3a84e70..c6bdc1d7 100644 --- a/mtproto.go +++ b/mtproto.go @@ -173,7 +173,7 @@ func (m *MTProto) ReconnectToNewDC(dc int) (*MTProto, error) { sender, _ := NewMTProto(cfg) sender.serverRequestHandlers = m.serverRequestHandlers m.stopRoutines() - m.Logger.Info("User Migrated to DC: ", dc) + m.Logger.Info(fmt.Sprintf("User Migrated to DC: %d", dc)) err := sender.CreateConnection(true) if err != nil { return nil, fmt.Errorf("creating connection: %w", err) diff --git a/telegram/auth.go b/telegram/auth.go index 9b083cbf..80126e68 100644 --- a/telegram/auth.go +++ b/telegram/auth.go @@ -60,6 +60,15 @@ func (c *Client) SendCode(phoneNumber string) (hash string, err error) { return resp.PhoneCodeHash, nil } +type LoginOptions struct { + Password string `json:"password,omitempty"` + Code string `json:"code,omitempty"` + CodeHash string `json:"code_hash,omitempty"` + CodeCallback func() string `json:"-"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` +} + // Authorize client with phone number, code and phone code hash, // If phone code hash is empty, it will be requested from telegram server func (c *Client) Login(phoneNumber string, options ...*LoginOptions) (bool, error) { @@ -92,11 +101,11 @@ func (c *Client) Login(phoneNumber string, options ...*LoginOptions) (bool, erro break } if matchError(err, "The phone code entered was invalid") { - fmt.Println("The phone code entered was invalid, please try again") + fmt.Println("The phone code entered was invalid, please try again!") continue } else if matchError(err, "Two-steps verification is enabled") { var passwordInput string - fmt.Println("Two-step verification is enabled") + fmt.Println("Two-steps verification is enabled") for { fmt.Printf("Enter password: ") fmt.Scanln(&passwordInput) @@ -143,6 +152,7 @@ func (c *Client) Login(phoneNumber string, options ...*LoginOptions) (bool, erro AuthResultSwitch: switch auth := Auth.(type) { case *AuthAuthorizationSignUpRequired: + fmt.Println("Signing up...") var firstName, lastName string if opts.FirstName == "" { fmt.Printf("Enter first name: ") @@ -195,6 +205,14 @@ func (c *Client) AcceptTOS() (bool, error) { } } +type PasswordOptions struct { + Hint string `json:"hint,omitempty"` + Email string `json:"email,omitempty"` + EmailCodeCallback func() string `json:"email_code_callback,omitempty"` +} + +// Edit2FA changes the 2FA password of the current user, +// if 2fa is already enabled, should provide the current password. func (c *Client) Edit2FA(currPwd string, newPwd string, opts ...*PasswordOptions) (bool, error) { if currPwd == "" && newPwd == "" { return false, errors.New("current password and new password both cannot be empty") diff --git a/telegram/const.go b/telegram/const.go index ed4724f6..997fc044 100644 --- a/telegram/const.go +++ b/telegram/const.go @@ -4,7 +4,7 @@ import "regexp" const ( ApiVersion = 147 - Version = "v1.0.1a" + Version = "v1.0.2" DefaultDC = 4 diff --git a/telegram/inlinequery.go b/telegram/inlinequery.go index c8af5957..a458d87d 100644 --- a/telegram/inlinequery.go +++ b/telegram/inlinequery.go @@ -45,6 +45,22 @@ func (b *InlineBuilder) Results() []InputBotInlineResult { return b.InlineResults } +type ArticleOptions struct { + ID string `json:"id,omitempty"` + ExcludeMedia bool `json:"exclude_media,omitempty"` + Thumb InputWebDocument `json:"thumb,omitempty"` + Content InputWebDocument `json:"content,omitempty"` + LinkPreview bool `json:"link_preview,omitempty"` + ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` + Entities []MessageEntity `json:"entities,omitempty"` + ParseMode string `json:"parse_mode,omitempty"` + Caption string `json:"caption,omitempty"` + Venue *InputBotInlineMessageMediaVenue `json:"venue,omitempty"` + Location *InputBotInlineMessageMediaGeo `json:"location,omitempty"` + Contact *InputBotInlineMessageMediaContact `json:"contact,omitempty"` + Invoice *InputBotInlineMessageMediaInvoice `json:"invoice,omitempty"` +} + func (b *InlineBuilder) Article(title, description, text string, options ...*ArticleOptions) InputBotInlineResult { var opts ArticleOptions if len(options) > 0 { diff --git a/telegram/messages.go b/telegram/messages.go index 28034686..44283f76 100644 --- a/telegram/messages.go +++ b/telegram/messages.go @@ -430,6 +430,24 @@ func (c *Client) SendDice(peerID interface{}, emoji string) (*NewMessage, error) return c.SendMedia(peerID, &InputMediaDice{Emoticon: emoji}) } +type ActionResult struct { + Peer InputPeer `json:"peer,omitempty"` + Client *Client `json:"client,omitempty"` +} + +// Cancel the pointed Action, +// Returns true if the action was cancelled +func (a *ActionResult) Cancel() bool { + if a.Peer == nil || a.Client == nil { + return false // Avoid nil pointer dereference + } + b, err := a.Client.MessagesSetTyping(a.Peer, 0, &SendMessageCancelAction{}) + if err != nil { + return false + } + return b +} + // SendAction sends a chat action. // This method is a wrapper for messages.setTyping. func (c *Client) SendAction(PeerID interface{}, Action interface{}, topMsgID ...int32) (*ActionResult, error) { @@ -460,7 +478,7 @@ func (c *Client) SendReadAck(PeerID interface{}, MaxID ...int32) (*MessagesAffec if err != nil { return nil, err } - maxID := getVariadic(MaxID, 0).(int32) + maxID := getVariadic(MaxID, int32(0)).(int32) return c.MessagesReadHistory(peerChat, maxID) } diff --git a/telegram/types.go b/telegram/types.go deleted file mode 100644 index 74a8b220..00000000 --- a/telegram/types.go +++ /dev/null @@ -1,197 +0,0 @@ -package telegram - -import ( - "log" - "sync" -) - -type ( - Filters struct { - IsPrivate bool - IsGroup bool - IsChannel bool - IsCommand bool - IsText bool - IsMedia bool - Func func(*NewMessage) bool - BlackListChats []int64 - WhiteListChats []int64 - Users []int64 - Outgoing bool - Incoming bool - } - - MessageHandle struct { - Pattern interface{} - Handler func(m *NewMessage) error - Client *Client - Filters *Filters - } - - ChatActionHandle struct { - Handler func(m *NewMessage) error - Client *Client - } - - InlineHandle struct { - Pattern interface{} - Handler func(m *InlineQuery) error - Client *Client - } - - CallbackHandle struct { - Pattern interface{} - Handler func(m *CallbackQuery) error - Client *Client - } - - RawHandle struct { - updateType Update - Handler func(m Update) error - Client *Client - } - - MessageEditHandle struct { - Pattern interface{} - Handler func(m *NewMessage) error - Client *Client - } - - Command struct { - Cmd string - Prefix string - } -) - -type ( - Progress struct { - Current int64 - Total int64 - rwlock sync.RWMutex - } - - LoginOptions struct { - Password string `json:"password,omitempty"` - Code string `json:"code,omitempty"` - CodeHash string `json:"code_hash,omitempty"` - CodeCallback func() string `json:"-"` - FirstName string `json:"first_name,omitempty"` - LastName string `json:"last_name,omitempty"` - } - - ActionResult struct { - Peer InputPeer `json:"peer,omitempty"` - Client *Client `json:"client,omitempty"` - } - - ArticleOptions struct { - ID string `json:"id,omitempty"` - ExcludeMedia bool `json:"exclude_media,omitempty"` - Thumb InputWebDocument `json:"thumb,omitempty"` - Content InputWebDocument `json:"content,omitempty"` - LinkPreview bool `json:"link_preview,omitempty"` - ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` - Entities []MessageEntity `json:"entities,omitempty"` - ParseMode string `json:"parse_mode,omitempty"` - Caption string `json:"caption,omitempty"` - Venue *InputBotInlineMessageMediaVenue `json:"venue,omitempty"` - Location *InputBotInlineMessageMediaGeo `json:"location,omitempty"` - Contact *InputBotInlineMessageMediaContact `json:"contact,omitempty"` - Invoice *InputBotInlineMessageMediaInvoice `json:"invoice,omitempty"` - } - - PasswordOptions struct { - Hint string `json:"hint,omitempty"` - Email string `json:"email,omitempty"` - EmailCodeCallback func() string `json:"email_code_callback,omitempty"` - } - - Log struct { - Logger *log.Logger - } -) - -var ( - ParticipantsAdmins = &ParticipantOptions{ - Filter: &ChannelParticipantsAdmins{}, - Query: "", - Offset: 0, - Limit: 50, - } -) - -func (p *Progress) Set(value int64) { - p.rwlock.Lock() - defer p.rwlock.Unlock() - p.Current = value -} - -func (p *Progress) Get() int64 { - p.rwlock.RLock() - defer p.rwlock.RUnlock() - return p.Current -} - -func (p *Progress) Data() (total int64, current int64) { - p.rwlock.RLock() - defer p.rwlock.RUnlock() - return p.Total, p.Current -} - -func (p *Progress) Percentage() float64 { - p.rwlock.RLock() - defer p.rwlock.RUnlock() - return float64(p.Current) / float64(p.Total) * 100 -} - -func (p *Progress) SetTotal(total int64) { - p.rwlock.Lock() - defer p.rwlock.Unlock() - p.Total = total -} - -func (p *Progress) Init() { - p.rwlock.Lock() - defer p.rwlock.Unlock() - p.Total = 0 - p.Current = 0 -} - -func (p *Progress) Add(value int64) { - p.rwlock.Lock() - defer p.rwlock.Unlock() - p.Current += value -} - -// Cancel the pointed Action, -// Returns true if the action was cancelled -func (a *ActionResult) Cancel() bool { - if a.Peer == nil || a.Client == nil { - return false // Avoid nil pointer dereference - } - b, err := a.Client.MessagesSetTyping(a.Peer, 0, &SendMessageCancelAction{}) - if err != nil { - return false - } - return b -} - -// Custom logger - -func (l *Log) Error(err error) { - if l.Logger != nil { - l.Logger.Println("Client - Error: ", err) - } -} - -func (l *Log) Info(msg string) { - if l.Logger != nil { - l.Logger.Println("Client - Info: ", msg) - } -} - -func (l *Log) Debug(msg string) { - if l.Logger != nil { - l.Logger.Println("Client - Debug: ", msg) - } -} diff --git a/telegram/updates.go b/telegram/updates.go index 144c7751..f1c205ca 100644 --- a/telegram/updates.go +++ b/telegram/updates.go @@ -12,12 +12,12 @@ import ( ) var ( - MessageHandles = []MessageHandle{} - InlineHandles = []InlineHandle{} - CallbackHandles = []CallbackHandle{} - MessageEdit = []MessageEditHandle{} - ActionHandles = []ChatActionHandle{} - RawHandles = []RawHandle{} + MessageHandles = []messageHandle{} + InlineHandles = []inlineHandle{} + CallbackHandles = []callbackHandle{} + MessageEdit = []messageEditHandle{} + ActionHandles = []chatActionHandle{} + RawHandles = []rawHandle{} ) func HandleMessageUpdateWithDiffrence(update Message, Pts int32, Limit int32) { @@ -61,7 +61,19 @@ func (c *Client) getDiffrence(Pts int32, Limit int32) (Message, error) { return nil, nil } -func handleMessage(message Message, h MessageHandle) error { +type messageHandle struct { + Pattern interface{} + Handler func(m *NewMessage) error + Client *Client + Filters *Filters +} + +type chatActionHandle struct { + Handler func(m *NewMessage) error + Client *Client +} + +func handleMessage(message Message, h messageHandle) error { m := packMessage(h.Client, message) if h.Filters != nil && h.Filter(m) { if err := h.Handler(m); err != nil { @@ -92,6 +104,12 @@ func HandleMessageUpdate(update Message) { } } +type messageEditHandle struct { + Pattern interface{} + Handler func(m *NewMessage) error + Client *Client +} + func HandleEditUpdate(update Message) { switch msg := update.(type) { case *MessageObj: @@ -105,6 +123,12 @@ func HandleEditUpdate(update Message) { } } +type inlineHandle struct { + Pattern interface{} + Handler func(m *InlineQuery) error + Client *Client +} + func HandleInlineUpdate(update *UpdateBotInlineQuery) { for _, handle := range InlineHandles { if handle.IsMatch(update.Query) { @@ -115,6 +139,12 @@ func HandleInlineUpdate(update *UpdateBotInlineQuery) { } } +type callbackHandle struct { + Pattern interface{} + Handler func(m *CallbackQuery) error + Client *Client +} + func HandleCallbackUpdate(update *UpdateBotCallbackQuery) { for _, handle := range CallbackHandles { if handle.IsMatch(update.Data) { @@ -125,6 +155,12 @@ func HandleCallbackUpdate(update *UpdateBotCallbackQuery) { } } +type rawHandle struct { + updateType Update + Handler func(m Update) error + Client *Client +} + func HandleRawUpdate(update Update) { for _, handle := range RawHandles { if reflect.TypeOf(handle.updateType) == reflect.TypeOf(update) { @@ -135,7 +171,7 @@ func HandleRawUpdate(update Update) { } } -func (h *InlineHandle) IsMatch(text string) bool { +func (h *inlineHandle) IsMatch(text string) bool { switch pattern := h.Pattern.(type) { case string: if pattern == OnInlineQuery { @@ -150,7 +186,7 @@ func (h *InlineHandle) IsMatch(text string) bool { } } -func (e *MessageEditHandle) IsMatch(text string) bool { +func (e *messageEditHandle) IsMatch(text string) bool { switch pattern := e.Pattern.(type) { case string: if pattern == OnEditMessage { @@ -165,7 +201,7 @@ func (e *MessageEditHandle) IsMatch(text string) bool { } } -func (h *CallbackHandle) IsMatch(data []byte) bool { +func (h *callbackHandle) IsMatch(data []byte) bool { switch pattern := h.Pattern.(type) { case string: p := regexp.MustCompile("^" + pattern) @@ -177,7 +213,12 @@ func (h *CallbackHandle) IsMatch(data []byte) bool { } } -func (h *MessageHandle) IsMatch(text string) bool { +type Command struct { + Command string + Prefix string +} + +func (h *messageHandle) IsMatch(text string) bool { switch Pattern := h.Pattern.(type) { case string: if Pattern == OnNewMessage { @@ -186,7 +227,7 @@ func (h *MessageHandle) IsMatch(text string) bool { pattern := regexp.MustCompile("^" + Pattern) return pattern.MatchString(text) || strings.HasPrefix(text, Pattern) case Command: - Patt := fmt.Sprintf("^[%s]%s", Pattern.Prefix, Pattern.Cmd) + Patt := fmt.Sprintf("^[%s]%s", Pattern.Prefix, Pattern.Command) pattern, err := regexp.Compile(Patt) if err != nil { return false @@ -199,7 +240,7 @@ func (h *MessageHandle) IsMatch(text string) bool { } } -func (h *MessageHandle) Filter(msg *NewMessage) bool { +func (h *messageHandle) Filter(msg *NewMessage) bool { if h.Filters.IsPrivate && !msg.IsPrivate() { return false } @@ -245,12 +286,27 @@ func (h *MessageHandle) Filter(msg *NewMessage) bool { return true } +type Filters struct { + IsPrivate bool `json:"is_private,omitempty"` + IsGroup bool `json:"is_group,omitempty"` + IsChannel bool `json:"is_channel,omitempty"` + IsCommand bool `json:"is_command,omitempty"` + IsText bool `json:"is_text,omitempty"` + IsMedia bool `json:"is_media,omitempty"` + Func func(*NewMessage) bool `json:"func,omitempty"` + BlackListChats []int64 `json:"black_list_chats,omitempty"` + WhiteListChats []int64 `json:"white_list_chats,omitempty"` + Users []int64 `json:"users,omitempty"` + Outgoing bool `json:"outgoing,omitempty"` + Incoming bool `json:"incoming,omitempty"` +} + func (c *Client) AddMessageHandler(pattern interface{}, handler func(m *NewMessage) error, filters ...*Filters) { var FILTER *Filters if len(filters) > 0 { FILTER = filters[0] } - MessageHandles = append(MessageHandles, MessageHandle{ + MessageHandles = append(MessageHandles, messageHandle{ Pattern: pattern, Handler: handler, Filters: FILTER, @@ -259,26 +315,26 @@ func (c *Client) AddMessageHandler(pattern interface{}, handler func(m *NewMessa } func (c *Client) AddActionHandler(handler func(m *NewMessage) error) { - ActionHandles = append(ActionHandles, ChatActionHandle{ + ActionHandles = append(ActionHandles, chatActionHandle{ Handler: handler, Client: c, }) } func (c *Client) AddEditHandler(pattern interface{}, handler func(m *NewMessage) error) { - MessageEdit = append(MessageEdit, MessageEditHandle{pattern, handler, c}) + MessageEdit = append(MessageEdit, messageEditHandle{pattern, handler, c}) } func (c *Client) AddInlineHandler(pattern interface{}, handler func(m *InlineQuery) error) { - InlineHandles = append(InlineHandles, InlineHandle{pattern, handler, c}) + InlineHandles = append(InlineHandles, inlineHandle{pattern, handler, c}) } func (c *Client) AddCallbackHandler(pattern interface{}, handler func(m *CallbackQuery) error) { - CallbackHandles = append(CallbackHandles, CallbackHandle{pattern, handler, c}) + CallbackHandles = append(CallbackHandles, callbackHandle{pattern, handler, c}) } func (c *Client) AddRawHandler(updateType Update, handler func(m Update) error) { - RawHandles = append(RawHandles, RawHandle{updateType, handler, c}) + RawHandles = append(RawHandles, rawHandle{updateType, handler, c}) } func (c *Client) RemoveRawHandler(updateType Update) {