diff options
author | bodqhrohro <bodqhrohro@gmail.com> | 2019-11-29 03:51:41 +0300 |
---|---|---|
committer | bodqhrohro <bodqhrohro@gmail.com> | 2019-11-29 03:51:41 +0300 |
commit | dbe87fafa8fb3c38d6cb22ac335cc76b70b607a6 (patch) | |
tree | 784f16c7e27444c03b865e1f4c03aadac1f18bf8 /telegram/utils.go | |
parent | bcf222b53db2199cb6c784ac8c5b7105d794b6c9 (diff) |
Handle updates of user status
Diffstat (limited to 'telegram/utils.go')
-rw-r--r-- | telegram/utils.go | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/telegram/utils.go b/telegram/utils.go new file mode 100644 index 0000000..7fb78d9 --- /dev/null +++ b/telegram/utils.go @@ -0,0 +1,170 @@ +package telegram + +import ( + "crypto/sha1" + "github.com/pkg/errors" + "io" + "os" + "strconv" + "time" + + "dev.narayana.im/narayana/telegabber/xmpp/gateway" + + log "github.com/sirupsen/logrus" + "github.com/soheilhy/args" + "github.com/zelenin/go-tdlib/client" +) + +var errOffline = errors.New("TDlib instance is offline") + +// GetContactByUsername resolves username to user id retrieves user and chat information +func (c *Client) GetContactByUsername(username string) (*client.Chat, *client.User, error) { + if !c.online { + return nil, nil, errOffline + } + + chat, err := c.client.SearchPublicChat(&client.SearchPublicChatRequest{ + Username: username, + }) + + if err != nil { + return nil, nil, err + } + + return c.GetContactByID(int32(chat.Id), chat) +} + +// GetContactByID gets user and chat information from cache (or tries to retrieve it, if missing) +func (c *Client) GetContactByID(id int32, chat *client.Chat) (*client.Chat, *client.User, error) { + if !c.online { + return nil, nil, errOffline + } + + var user *client.User + var cacheChat *client.Chat + var ok bool + var err error + + user, ok = cache.users[id] + if !ok && id > 0 { + user, err = c.client.GetUser(&client.GetUserRequest{ + UserId: id, + }) + if err != nil { + return nil, nil, err + } + + cache.users[id] = user + } + + chatID := int64(id) + cacheChat, ok = cache.chats[chatID] + if !ok { + if chat == nil { + cacheChat, err = c.client.GetChat(&client.GetChatRequest{ + ChatId: chatID, + }) + if err != nil { + return nil, nil, err + } + + cache.chats[chatID] = cacheChat + } else { + cache.chats[chatID] = chat + } + } + if chat == nil { + chat = cacheChat + } + + return chat, user, nil +} + +func (c *Client) processStatusUpdate(chatID int32, status *client.UserStatus, args ...args.V) error { + if !c.online { + return nil + } + + log.WithFields(log.Fields{ + "chat_id": chatID, + }).Info("Status update for") + + chat, user, err := c.GetContactByID(chatID, nil) + if err != nil { + return err + } + + var photo string + if chat != nil && chat.Photo != nil { + path := chat.Photo.Small.Local.Path + file, err := os.Open(path) + if err == nil { + defer file.Close() + + hash := sha1.New() + _, err = io.Copy(hash, file) + if err == nil { + photo = string(hash.Sum(nil)) + } else { + log.Errorf("Error calculating hash: %v", path) + } + } else if path != "" { + log.Errorf("Photo does not exist: %v", path) + } + } + + if status == nil && user != nil { + status = &user.Status + } + + var show, textStatus string + if status == nil { + show = "chat" + if chat.Title != "" { + textStatus = chat.Title + } + } else { + switch (*status).UserStatusType() { + case client.TypeUserStatusOnline: + textStatus = "Online" + case client.TypeUserStatusRecently: + show, textStatus = "dnd", "Last seen recently" + case client.TypeUserStatusLastWeek: + show, textStatus = "unavailable", "Last seen last week" + case client.TypeUserStatusLastMonth: + show, textStatus = "unavailable", "Last seen last month" + case client.TypeUserStatusEmpty: + show, textStatus = "unavailable", "Last seen a long time ago" + case client.TypeUserStatusOffline: + offlineStatus, ok := (*status).(*client.UserStatusOffline) + if !ok { + log.Fatal("Status type changed before conversion!") + } + // this will stop working in 2038 O\ + elapsed := time.Now().Unix() - int64(offlineStatus.WasOnline) + if elapsed < 3600 { + show = "away" + } else { + show = "xa" + } + // TODO: timezone + textStatus = time.Unix(int64(offlineStatus.WasOnline), 0).Format("Last seen at 15:03 02/01/2006") + } + } + + gateway.SendPresence( + c.xmpp, + c.jid, + gateway.SPFrom(strconv.Itoa(int(chatID))), + gateway.SPShow(show), + gateway.SPStatus(textStatus), + gateway.SPPhoto(photo), + gateway.SPImmed(gateway.SPImmed.Get(args)), + ) + + return nil +} + +func (c *Client) ProcessOutgoingMessage(chatID int, text string, messageID int) { + // TODO +} |