aboutsummaryrefslogtreecommitdiff
path: root/telegram/utils.go
diff options
context:
space:
mode:
authorbodqhrohro <bodqhrohro@gmail.com>2019-11-29 03:51:41 +0300
committerbodqhrohro <bodqhrohro@gmail.com>2019-11-29 03:51:41 +0300
commitdbe87fafa8fb3c38d6cb22ac335cc76b70b607a6 (patch)
tree784f16c7e27444c03b865e1f4c03aadac1f18bf8 /telegram/utils.go
parentbcf222b53db2199cb6c784ac8c5b7105d794b6c9 (diff)
Handle updates of user status
Diffstat (limited to 'telegram/utils.go')
-rw-r--r--telegram/utils.go170
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
+}