Skip to content

Commit

Permalink
fix-up some bugs, add support to name diffrent sessions, add filter s…
Browse files Browse the repository at this point in the history
…upport for editMessage and callbackQuery, customisable logger and cache now, v1.4.5
  • Loading branch information
AmarnathCJD committed Dec 1, 2024
1 parent be3b1b4 commit e0e41e4
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 36 deletions.
5 changes: 5 additions & 0 deletions internal/utils/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ func (l *Logger) Color() bool {
return !l.nocolor
}

func (l *Logger) SetPrefix(prefix string) *Logger {
l.Prefix = prefix
return l
}

func (l *Logger) colorize(color []byte, s string) string {
if l.nocolor {
return s
Expand Down
59 changes: 44 additions & 15 deletions telegram/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ type CacheConfig struct {
MaxSize int // Max size of cache: TODO
LogLevel utils.LogLevel
LogNoColor bool
LogName string
Memory bool
Disabled bool
}
Expand All @@ -90,13 +91,14 @@ func NewCache(fileName string, opts ...*CacheConfig) *CACHE {
InputUsers: make(map[int64]int64),
InputChats: make(map[int64]int64),
},
memory: opt.Memory,
logger: utils.NewLogger("gogram [cache]").
memory: opt.Memory,
disabled: opt.Disabled,
logger: utils.NewLogger("gogram " + getLogPrefix("cache", opt.LogName)).
SetLevel(opt.LogLevel).
NoColor(opt.LogNoColor),
}

if !c.memory && !opt.Disabled {
if !opt.Memory && !opt.Disabled {
c.logger.Debug("initialized cache (" + c.fileName + ") successfully")
}

Expand Down Expand Up @@ -172,7 +174,7 @@ func (c *CACHE) ReadFile() {
}

defer file.Close()
var totalLoaded int
var totalLoaded = []int{0, 0, 0}

c.Lock()
for {
Expand All @@ -198,18 +200,20 @@ func (c *CACHE) ReadFile() {
switch entryType {
case 1:
c.InputPeers.InputUsers[id] = accessHash
totalLoaded[0]++
case 2:
c.InputPeers.InputChats[id] = accessHash
totalLoaded[1]++
case 3:
c.InputPeers.InputChannels[id] = accessHash
totalLoaded[2]++
}

totalLoaded++
}
c.Unlock()

if totalLoaded != 0 {
c.logger.Debug("loaded ", totalLoaded, " peers from cacheFile")
if !c.memory {
c.logger.Debug("loaded ", totalLoaded[0], " users, ", totalLoaded[1], " chats, ", totalLoaded[2], " channels from cache")
}
}

Expand Down Expand Up @@ -486,33 +490,58 @@ func (cache *CACHE) UpdatePeersToCache(users []User, chats []Chat) {
totalUpdates := [2]int{0, 0}

for _, user := range users {
if us, ok := user.(*UserObj); ok {
switch us := user.(type) {
case *UserObj:
if updated := cache.UpdateUser(us); updated {
totalUpdates[0]++
}
case *UserEmpty:
}
}

for _, chat := range chats {
if ch, ok := chat.(*ChatObj); ok {
switch ch := chat.(type) {
case *ChatObj:
if updated := cache.UpdateChat(ch); updated {
totalUpdates[1]++
}
} else if channel, ok := chat.(*Channel); ok {
if updated := cache.UpdateChannel(channel); updated {
case *Channel:
if updated := cache.UpdateChannel(ch); updated {
totalUpdates[1]++
}
case *ChatForbidden:
cache.Lock()
if _, ok := cache.InputPeers.InputChats[ch.ID]; !ok {
cache.chats[ch.ID] = &ChatObj{
ID: ch.ID,
}
cache.InputPeers.InputChats[ch.ID] = ch.ID
}
cache.Unlock()
case *ChannelForbidden:
cache.Lock()
if _, ok := cache.InputPeers.InputChannels[ch.ID]; !ok {
cache.channels[ch.ID] = &Channel{
ID: ch.ID,
Broadcast: ch.Broadcast,
Megagroup: ch.Megagroup,
AccessHash: ch.AccessHash,
Title: ch.Title,
}
cache.InputPeers.InputChannels[ch.ID] = ch.AccessHash
}
cache.Unlock()
case *ChatEmpty:
}
}

if totalUpdates[0] > 0 || totalUpdates[1] > 0 {
if !cache.memory {
go cache.WriteFile() // Write to file asynchronously
go cache.WriteFile() // write to file asynchronously
}
cache.logger.Debug(
fmt.Sprintf("updated %d users and %d chats to %s (users: %d, chats: %d)",
totalUpdates[0], totalUpdates[1], cache.fileName,
len(cache.InputPeers.InputUsers), len(cache.InputPeers.InputChats),
fmt.Sprintf("updated %d users %d chats and %d channels in cache (u: %d, c: %d)",
totalUpdates[0], totalUpdates[1], totalUpdates[1], len(users), len(chats),
),
)
}
Expand Down
21 changes: 16 additions & 5 deletions telegram/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type ClientConfig struct {
DeviceConfig DeviceConfig
Session string
StringSession string
SessionName string
LangCode string
ParseMode string
MemorySession bool
Expand All @@ -76,6 +77,7 @@ type ClientConfig struct {
DisableCache bool
TestMode bool
LogLevel utils.LogLevel
Logger *utils.Logger
Proxy *url.URL
ForceIPv6 bool
Cache *CACHE
Expand All @@ -101,17 +103,26 @@ func (s *Session) Encode() string {
func NewClient(config ClientConfig) (*Client, error) {
client := &Client{
wg: sync.WaitGroup{},
Log: utils.NewLogger("gogram [client]"),
stopCh: make(chan struct{}),
}

if config.Logger != nil {
client.Log = config.Logger
client.Log.Prefix = "gogram " + getLogPrefix("client ", config.SessionName)
config.LogLevel = config.Logger.Lev()
} else {
client.Log = utils.NewLogger("gogram " + getLogPrefix("client ", config.SessionName))
}

config = client.cleanClientConfig(config)
client.setupClientData(config)

if config.Cache == nil {
client.Cache = NewCache("cache.db", &CacheConfig{
Disabled: config.DisableCache,
LogLevel: config.LogLevel,
client.Cache = NewCache(fmt.Sprintf("cache%s.db", config.SessionName), &CacheConfig{
Disabled: config.DisableCache,
LogLevel: config.LogLevel,
LogName: config.SessionName,
LogNoColor: !client.Log.Color(),
})
} else {
client.Cache = config.Cache
Expand Down Expand Up @@ -149,7 +160,7 @@ func (c *Client) setupMTProto(config ClientConfig) error {
ServerHost: toIpAddr(),
PublicKey: config.PublicKeys[0],
DataCenter: config.DataCenter,
Logger: utils.NewLogger("gogram [mtproto]").
Logger: utils.NewLogger("gogram " + getLogPrefix("mtproto", config.SessionName)).
SetLevel(config.LogLevel).
NoColor(!c.Log.Color()),
StringSession: config.StringSession,
Expand Down
2 changes: 1 addition & 1 deletion telegram/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

const (
ApiVersion = 195
Version = "v1.4.4"
Version = "v1.4.5"

LogDebug = utils.DebugLevel
LogInfo = utils.InfoLevel
Expand Down
75 changes: 60 additions & 15 deletions telegram/updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func (h *inlineHandle) GetGroup() string {
type callbackHandle struct {
Pattern any
Handler CallbackHandler
Filters []Filter
Group string
sortTrigger chan any
}
Expand Down Expand Up @@ -235,9 +236,9 @@ type UpdateDispatcher struct {
}

// creates and populates a new UpdateDispatcher
func (c *Client) NewUpdateDispatcher() {
func (c *Client) NewUpdateDispatcher(sessionName ...string) {
c.dispatcher = &UpdateDispatcher{
logger: utils.NewLogger("gogram [dispatcher]").
logger: utils.NewLogger("gogram " + getLogPrefix("dispatcher", getVariadic(sessionName, ""))).
SetLevel(c.Log.Lev()),
}
c.dispatcher.SortTrigger()
Expand Down Expand Up @@ -370,7 +371,7 @@ func (c *Client) handleMessageUpdate(update Message) {
if handler.IsMatch(msg.Message, c) {
handle := func(h *messageHandle) error {
packed := packMessage(c, msg)
if c.runFilterChain(packed, h.Filters) {
if handler.runFilterChain(packed, h.Filters) {
defer c.NewRecovery()()
if err := h.Handler(packed); err != nil {
if errors.Is(err, EndGroup) {
Expand Down Expand Up @@ -497,7 +498,7 @@ func (c *Client) handleEditUpdate(update Message) {
handle := func(h *messageEditHandle) error {
packed := packMessage(c, msg)
defer c.NewRecovery()()
if c.runFilterChain(packed, h.Filters) {
if handler.runFilterChain(packed, h.Filters) {
if err := h.Handler(packed); err != nil {
if errors.Is(err, EndGroup) {
return err
Expand Down Expand Up @@ -527,12 +528,14 @@ func (c *Client) handleCallbackUpdate(update *UpdateBotCallbackQuery) {
if handler.IsMatch(update.Data) {
handle := func(h *callbackHandle) error {
packed := packCallbackQuery(c, update)
defer c.NewRecovery()()
if err := h.Handler(packed); err != nil {
if errors.Is(err, EndGroup) {
return err
if handler.runFilterChain(packed, h.Filters) {
defer c.NewRecovery()()
if err := h.Handler(packed); err != nil {
if errors.Is(err, EndGroup) {
return err
}
c.Log.Error(errors.Wrap(err, "[callbackQuery]"))
}
c.Log.Error(errors.Wrap(err, "[callbackQuery]"))
}
return nil
}
Expand Down Expand Up @@ -754,8 +757,8 @@ func (h *messageHandle) IsMatch(text string, c *Client) bool {
}

if strings.HasPrefix(Pattern, "cmd:") {
//(?i)^[!/-]ping(?: |$|@botusername)(.*)$
Pattern = "(?i)^[!/]" + strings.TrimPrefix(Pattern, "cmd:")
//(?i)^[!/-?]ping(?: |$|@botusername)(.*)$
Pattern = "(?i)^[!/?]" + strings.TrimPrefix(Pattern, "cmd:")
if me := c.Me(); me != nil && me.Username != "" && me.Bot {
Pattern += "(?: |$|@" + me.Username + ")(.*)"
} else {
Expand All @@ -775,7 +778,7 @@ func (h *messageHandle) IsMatch(text string, c *Client) bool {
return false
}

func (c *Client) runFilterChain(m *NewMessage, filters []Filter) bool {
func (h *messageHandle) runFilterChain(m *NewMessage, filters []Filter) bool {
var (
actAsBlacklist bool
actUsers, actGroups []int64
Expand Down Expand Up @@ -845,10 +848,39 @@ func (c *Client) runFilterChain(m *NewMessage, filters []Filter) bool {
return true
}

func (h *messageEditHandle) runFilterChain(m *NewMessage, filters []Filter) bool {
var message = &messageHandle{}
return message.runFilterChain(m, filters)
}

func (h *callbackHandle) runFilterChain(c *CallbackQuery, filters []Filter) bool {
if len(filters) > 0 {
for _, filter := range filters {
if filter.Private && !c.IsPrivate() || filter.Group && !c.IsGroup() || filter.Channel && !c.IsChannel() {
return false
}
if filter.FromBot {
if c.Sender == nil || !c.Sender.Bot {
return false
}
}

if filter.Func != nil {
if !filter.FuncCallback(c) {
return false
}
}
}
}

return true
}

type Filter struct {
Private, Group, Channel, Media, Command, Reply, Forward, FromBot, Blacklist, Mention bool
Users, Chats []int64
Func func(m *NewMessage) bool
FuncCallback func(c *CallbackQuery) bool
}

var (
Expand All @@ -871,6 +903,9 @@ var (
FilterFunc = func(f func(m *NewMessage) bool) Filter {
return Filter{Func: f}
}
FilterFuncCallback = func(f func(c *CallbackQuery) bool) Filter {
return Filter{Func: func(m *NewMessage) bool { return true }}
}
)

func (c *Client) AddMessageHandler(pattern any, handler MessageHandler, filters ...Filter) Handle {
Expand Down Expand Up @@ -937,11 +972,16 @@ func (c *Client) AddActionHandler(handler MessageHandler) Handle {
// - Message Edited
// - Channel Post Edited
func (c *Client) AddEditHandler(pattern any, handler MessageHandler, filters ...Filter) Handle {
var messageFilters []Filter
if len(filters) > 0 {
messageFilters = filters
}

if c.dispatcher.messageEditHandles == nil {
c.dispatcher.messageEditHandles = make(map[string][]*messageEditHandle)
}

handle := messageEditHandle{Pattern: pattern, Handler: handler, sortTrigger: c.dispatcher.sortTrigger}
handle := messageEditHandle{Pattern: pattern, Handler: handler, sortTrigger: c.dispatcher.sortTrigger, Filters: messageFilters}
c.dispatcher.messageEditHandles["default"] = append(c.dispatcher.messageEditHandles["default"], &handle)
return c.dispatcher.messageEditHandles["default"][len(c.dispatcher.messageEditHandles["default"])-1]
}
Expand All @@ -964,12 +1004,17 @@ func (c *Client) AddInlineHandler(pattern any, handler InlineHandler) Handle {
//
// Included Updates:
// - Callback Query
func (c *Client) AddCallbackHandler(pattern any, handler CallbackHandler) Handle {
func (c *Client) AddCallbackHandler(pattern any, handler CallbackHandler, filters ...Filter) Handle {
var messageFilters []Filter
if len(filters) > 0 {
messageFilters = filters
}

if c.dispatcher.callbackHandles == nil {
c.dispatcher.callbackHandles = make(map[string][]*callbackHandle)
}

handle := callbackHandle{Pattern: pattern, Handler: handler, sortTrigger: c.dispatcher.sortTrigger}
handle := callbackHandle{Pattern: pattern, Handler: handler, sortTrigger: c.dispatcher.sortTrigger, Filters: messageFilters}
c.dispatcher.callbackHandles["default"] = append(c.dispatcher.callbackHandles["default"], &handle)
return c.dispatcher.callbackHandles["default"][len(c.dispatcher.callbackHandles["default"])-1]
}
Expand Down
12 changes: 12 additions & 0 deletions telegram/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"strings"
"time"

"github.com/amarnathcjd/gogram/internal/utils"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -435,6 +436,13 @@ func getPeerUser(userID int64) *PeerUser {
}
}

func getLogPrefix(loggerName string, sessionName string) string {
if sessionName == "" {
return fmt.Sprintf("[%s]", loggerName)
}
return fmt.Sprintf("[%s] {%s}", loggerName, sessionName)
}

func IsURL(str string) bool {
u, err := url.Parse(str)
return err == nil && u.Scheme != "" && u.Host != ""
Expand Down Expand Up @@ -676,3 +684,7 @@ func IsFfmpegInstalled() bool {
_, err := exec.LookPath("ffmpeg")
return err == nil
}

func NewLogger(level utils.LogLevel, prefix ...string) *utils.Logger {
return utils.NewLogger(getVariadic(prefix, "gogram")).SetLevel(level)
}

0 comments on commit e0e41e4

Please sign in to comment.