tdlib / td

Cross-platform library for building Telegram clients
https://core.telegram.org/tdlib
Boost Software License 1.0
7.11k stars 1.44k forks source link

Identifying returned UpdateHandler object for multiple clients. #2767

Closed ToYashDeepSingh closed 9 months ago

ToYashDeepSingh commented 9 months ago

Hi TDLib Community, I am trying to create a Telegram Web Client for multiple users in java.

I am able to log in multiple users by following suggestions in https://github.com/tdlib/td/issues/40 and https://github.com/tdlib/td/issues/718 and fetch all relevant details such as user details, chat-list, chat-id and messages successfully. Also for all logged-in users I am receiving all updates through UpdateHandler class in real time.

I want to segregate all the updates based on the phone number of the user that is currently logged-in, but I am unable to differentiate between the updates being received. For example, if users A and B are logged in at the same time and a message from a common user C is sent then the updates for both look the same with the sender ID being the same for both A and B. Below are the objects being received:

2024-01-18 18:03:18,020 [TDLib thread] INFO  i.n.TelegramWebClient.UpdateHandler:23 - UpdateNewMessage {
  message = Message {
    id = 471**********
    senderId = MessageSenderUser {
      userId = **C's USER ID**
    }
    chatId = **C's USER ID**
    sendingState = null
    schedulingState = null
    isOutgoing = false
    isPinned = false
    canBeEdited = false
    canBeForwarded = true
    canBeRepliedInAnotherChat = true
    canBeSaved = true
    canBeDeletedOnlyForSelf = true
    canBeDeletedForAllUsers = true
    canGetAddedReactions = false
    canGetStatistics = false
    canGetMessageThread = false
    canGetViewers = false
    canGetMediaTimestampLinks = false
    canReportReactions = false
    hasTimestampedMedia = true
    isChannelPost = false
    isTopicMessage = false
    containsUnreadMention = false
    date = 1705581198
    editDate = 0
    forwardInfo = null
    importInfo = null
    interactionInfo = null
    unreadReactions = vector[0] {
    }
    replyTo = null
    messageThreadId = 0
    selfDestructType = null
    selfDestructIn = 0.000000
    autoDeleteIn = 0.000000
    viaBotUserId = 0
    authorSignature = ""
    mediaAlbumId = 0
    restrictionReason = ""
    content = MessageText {
      text = FormattedText {
        text = "Hi 31"
        entities = vector[0] {
        }
      }
      webPage = null
      linkPreviewOptions = null
    }
    replyMarkup = null
  }
}

2024-01-18 18:03:18,020 [TDLib thread] INFO  i.n.TelegramWebClient.UpdateHandler:23 - UpdateChatLastMessage {
  chatId = **C's USER ID**
  lastMessage = Message {
    id = 471**********
    senderId = MessageSenderUser {
      userId = **C's USER ID**
    }
    chatId = **C's USER ID**
    sendingState = null
    schedulingState = null
    isOutgoing = false
    isPinned = false
    canBeEdited = false
    canBeForwarded = true
    canBeRepliedInAnotherChat = true
    canBeSaved = true
    canBeDeletedOnlyForSelf = true
    canBeDeletedForAllUsers = true
    canGetAddedReactions = false
    canGetStatistics = false
    canGetMessageThread = false
    canGetViewers = false
    canGetMediaTimestampLinks = false
    canReportReactions = false
    hasTimestampedMedia = true
    isChannelPost = false
    isTopicMessage = false
    containsUnreadMention = false
    date = 1705581198
    editDate = 0
    forwardInfo = null
    importInfo = null
    interactionInfo = null
    unreadReactions = vector[0] {
    }
    replyTo = null
    messageThreadId = 0
    selfDestructType = null
    selfDestructIn = 0.000000
    autoDeleteIn = 0.000000
    viaBotUserId = 0
    authorSignature = ""
    mediaAlbumId = 0
    restrictionReason = ""
    content = MessageText {
      text = FormattedText {
        text = "Hi 31"
        entities = vector[0] {
        }
      }
      webPage = null
      linkPreviewOptions = null
    }
    replyMarkup = null
  }
  positions = vector[0] {
  }
}
2024-01-18 18:03:36,493 [TDLib thread] INFO  i.n.TelegramWebClient.UpdateHandler:23 - UpdateNewMessage {
  message = Message {
    id = 430**********
    senderId = MessageSenderUser {
      userId = **C's USER ID**
    }
    chatId = **C's USER ID**
    sendingState = null
    schedulingState = null
    isOutgoing = false
    isPinned = false
    canBeEdited = false
    canBeForwarded = true
    canBeRepliedInAnotherChat = true
    canBeSaved = true
    canBeDeletedOnlyForSelf = true
    canBeDeletedForAllUsers = true
    canGetAddedReactions = false
    canGetStatistics = false
    canGetMessageThread = false
    canGetViewers = false
    canGetMediaTimestampLinks = false
    canReportReactions = false
    hasTimestampedMedia = true
    isChannelPost = false
    isTopicMessage = false
    containsUnreadMention = false
    date = 1705581217
    editDate = 0
    forwardInfo = null
    importInfo = null
    interactionInfo = null
    unreadReactions = vector[0] {
    }
    replyTo = null
    messageThreadId = 0
    selfDestructType = null
    selfDestructIn = 0.000000
    autoDeleteIn = 0.000000
    viaBotUserId = 0
    authorSignature = ""
    mediaAlbumId = 0
    restrictionReason = ""
    content = MessageText {
      text = FormattedText {
        text = "Hi 32"
        entities = vector[0] {
        }
      }
      webPage = null
      linkPreviewOptions = null
    }
    replyMarkup = null
  }
}

2024-01-18 18:03:36,493 [TDLib thread] INFO  i.n.TelegramWebClient.UpdateHandler:23 - UpdateChatLastMessage {
  chatId = **C's USER ID**
  lastMessage = Message {
    id = 430**********
    senderId = MessageSenderUser {
      userId = **C's USER ID**
    }
    chatId = **C's USER ID**
    sendingState = null
    schedulingState = null
    isOutgoing = false
    isPinned = false
    canBeEdited = false
    canBeForwarded = true
    canBeRepliedInAnotherChat = true
    canBeSaved = true
    canBeDeletedOnlyForSelf = true
    canBeDeletedForAllUsers = true
    canGetAddedReactions = false
    canGetStatistics = false
    canGetMessageThread = false
    canGetViewers = false
    canGetMediaTimestampLinks = false
    canReportReactions = false
    hasTimestampedMedia = true
    isChannelPost = false
    isTopicMessage = false
    containsUnreadMention = false
    date = 1705581217
    editDate = 0
    forwardInfo = null
    importInfo = null
    interactionInfo = null
    unreadReactions = vector[0] {
    }
    replyTo = null
    messageThreadId = 0
    selfDestructType = null
    selfDestructIn = 0.000000
    autoDeleteIn = 0.000000
    viaBotUserId = 0
    authorSignature = ""
    mediaAlbumId = 0
    restrictionReason = ""
    content = MessageText {
      text = FormattedText {
        text = "Hi 32"
        entities = vector[0] {
        }
      }
      webPage = null
      linkPreviewOptions = null
    }
    replyMarkup = null
  }
  positions = vector[1] {
    ChatPosition {
      list = ChatListMain {
      }
      order = 7325415547686879643
      isPinned = false
      source = null
    }
  }
}

If anyone can point me towards a potential solution I thank you in advance.

levlam commented 9 months ago

Which interface do you use to interact with TDLib?

ToYashDeepSingh commented 9 months ago

@levlam I am using Java 17.

levlam commented 9 months ago

No, which interface/classes do you use for interaction with TDLib?

ToYashDeepSingh commented 9 months ago

I use the UpdateHandler class which implements Client.ResultHandler:

package in.nobroker.TelegramWebClient;

import lombok.extern.slf4j.Slf4j;
import org.drinkless.tdlib.Client;
import org.drinkless.tdlib.TdApi;

import static in.nobroker.TelegramWebClient.constants.Constants.basicGroups;
import static in.nobroker.TelegramWebClient.constants.Constants.basicGroupsFullInfo;
import static in.nobroker.TelegramWebClient.constants.Constants.chats;
import static in.nobroker.TelegramWebClient.constants.Constants.mainChatList;
import static in.nobroker.TelegramWebClient.constants.Constants.secretChats;
import static in.nobroker.TelegramWebClient.constants.Constants.supergroups;
import static in.nobroker.TelegramWebClient.constants.Constants.supergroupsFullInfo;
import static in.nobroker.TelegramWebClient.constants.Constants.users;
import static in.nobroker.TelegramWebClient.constants.Constants.usersFullInfo;

@Slf4j
public class UpdateHandler implements Client.ResultHandler {

    AuthorizationStateUpdate authorizationStateUpdate = new AuthorizationStateUpdate();
    @Override
    public void onResult(TdApi.Object object) {
        log.info(String.valueOf(object));
        switch (object.getConstructor()) {
            case TdApi.UpdateAuthorizationState.CONSTRUCTOR:
                authorizationStateUpdate.onAuthorizationStateUpdated(((TdApi.UpdateAuthorizationState) object).authorizationState);
                break;
            case TdApi.UpdateUser.CONSTRUCTOR:
                TdApi.UpdateUser updateUser = (TdApi.UpdateUser) object;
                users.put(updateUser.user.id, updateUser.user);
                break;
            case TdApi.UpdateUserStatus.CONSTRUCTOR: {
                TdApi.UpdateUserStatus updateUserStatus = (TdApi.UpdateUserStatus) object;
                TdApi.User user = users.get(updateUserStatus.userId);
                synchronized (user) {
                    user.status = updateUserStatus.status;
                }
                break;
            }
            case TdApi.UpdateBasicGroup.CONSTRUCTOR:
                TdApi.UpdateBasicGroup updateBasicGroup = (TdApi.UpdateBasicGroup) object;
                basicGroups.put(updateBasicGroup.basicGroup.id, updateBasicGroup.basicGroup);
                break;
            case TdApi.UpdateSupergroup.CONSTRUCTOR:
                TdApi.UpdateSupergroup updateSupergroup = (TdApi.UpdateSupergroup) object;
                supergroups.put(updateSupergroup.supergroup.id, updateSupergroup.supergroup);
                break;
            case TdApi.UpdateSecretChat.CONSTRUCTOR:
                TdApi.UpdateSecretChat updateSecretChat = (TdApi.UpdateSecretChat) object;
                secretChats.put(updateSecretChat.secretChat.id, updateSecretChat.secretChat);
                break;

            case TdApi.UpdateNewChat.CONSTRUCTOR: {
                TdApi.UpdateNewChat updateNewChat = (TdApi.UpdateNewChat) object;
                TdApi.Chat chat = updateNewChat.chat;
                synchronized (chat) {
                    chats.put(chat.id, chat);

                    TdApi.ChatPosition[] positions = chat.positions;
                    chat.positions = new TdApi.ChatPosition[0];
                    setChatPositions(chat, positions);
                }
                break;
            }
            case TdApi.UpdateChatTitle.CONSTRUCTOR: {
                TdApi.UpdateChatTitle updateChat = (TdApi.UpdateChatTitle) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.title = updateChat.title;
                }
                break;
            }
            case TdApi.UpdateChatPhoto.CONSTRUCTOR: {
                TdApi.UpdateChatPhoto updateChat = (TdApi.UpdateChatPhoto) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.photo = updateChat.photo;
                }
                break;
            }
            case TdApi.UpdateChatPermissions.CONSTRUCTOR: {
                TdApi.UpdateChatPermissions update = (TdApi.UpdateChatPermissions) object;
                TdApi.Chat chat = chats.get(update.chatId);
                synchronized (chat) {
                    chat.permissions = update.permissions;
                }
                break;
            }
            case TdApi.UpdateChatLastMessage.CONSTRUCTOR: {
                TdApi.UpdateChatLastMessage updateChat = (TdApi.UpdateChatLastMessage) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.lastMessage = updateChat.lastMessage;
                    setChatPositions(chat, updateChat.positions);
                }
                break;
            }
            case TdApi.UpdateChatPosition.CONSTRUCTOR: {
                TdApi.UpdateChatPosition updateChat = (TdApi.UpdateChatPosition) object;
                if (updateChat.position.list.getConstructor() != TdApi.ChatListMain.CONSTRUCTOR) {
                    break;
                }

                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    int i;
                    for (i = 0; i < chat.positions.length; i++) {
                        if (chat.positions[i].list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) {
                            break;
                        }
                    }
                    TdApi.ChatPosition[] new_positions = new TdApi.ChatPosition[chat.positions.length + (updateChat.position.order == 0 ? 0 : 1) - (i < chat.positions.length ? 1 : 0)];
                    int pos = 0;
                    if (updateChat.position.order != 0) {
                        new_positions[pos++] = updateChat.position;
                    }
                    for (int j = 0; j < chat.positions.length; j++) {
                        if (j != i) {
                            new_positions[pos++] = chat.positions[j];
                        }
                    }
                    assert pos == new_positions.length;

                    setChatPositions(chat, new_positions);
                }
                break;
            }
            case TdApi.UpdateChatReadInbox.CONSTRUCTOR: {
                TdApi.UpdateChatReadInbox updateChat = (TdApi.UpdateChatReadInbox) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.lastReadInboxMessageId = updateChat.lastReadInboxMessageId;
                    chat.unreadCount = updateChat.unreadCount;
                }
                break;
            }
            case TdApi.UpdateChatReadOutbox.CONSTRUCTOR: {
                TdApi.UpdateChatReadOutbox updateChat = (TdApi.UpdateChatReadOutbox) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.lastReadOutboxMessageId = updateChat.lastReadOutboxMessageId;
                }
                break;
            }
            case TdApi.UpdateChatActionBar.CONSTRUCTOR: {
                TdApi.UpdateChatActionBar updateChat = (TdApi.UpdateChatActionBar) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.actionBar = updateChat.actionBar;
                }
                break;
            }
            case TdApi.UpdateChatAvailableReactions.CONSTRUCTOR: {
                TdApi.UpdateChatAvailableReactions updateChat = (TdApi.UpdateChatAvailableReactions) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.availableReactions = updateChat.availableReactions;
                }
                break;
            }
            case TdApi.UpdateChatDraftMessage.CONSTRUCTOR: {
                TdApi.UpdateChatDraftMessage updateChat = (TdApi.UpdateChatDraftMessage) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.draftMessage = updateChat.draftMessage;
                    setChatPositions(chat, updateChat.positions);
                }
                break;
            }
            case TdApi.UpdateChatMessageSender.CONSTRUCTOR: {
                TdApi.UpdateChatMessageSender updateChat = (TdApi.UpdateChatMessageSender) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.messageSenderId = updateChat.messageSenderId;
                }
                break;
            }
            case TdApi.UpdateChatMessageAutoDeleteTime.CONSTRUCTOR: {
                TdApi.UpdateChatMessageAutoDeleteTime updateChat = (TdApi.UpdateChatMessageAutoDeleteTime) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.messageAutoDeleteTime = updateChat.messageAutoDeleteTime;
                }
                break;
            }
            case TdApi.UpdateChatNotificationSettings.CONSTRUCTOR: {
                TdApi.UpdateChatNotificationSettings update = (TdApi.UpdateChatNotificationSettings) object;
                TdApi.Chat chat = chats.get(update.chatId);
                synchronized (chat) {
                    chat.notificationSettings = update.notificationSettings;
                }
                break;
            }
            case TdApi.UpdateChatPendingJoinRequests.CONSTRUCTOR: {
                TdApi.UpdateChatPendingJoinRequests update = (TdApi.UpdateChatPendingJoinRequests) object;
                TdApi.Chat chat = chats.get(update.chatId);
                synchronized (chat) {
                    chat.pendingJoinRequests = update.pendingJoinRequests;
                }
                break;
            }
            case TdApi.UpdateChatReplyMarkup.CONSTRUCTOR: {
                TdApi.UpdateChatReplyMarkup updateChat = (TdApi.UpdateChatReplyMarkup) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.replyMarkupMessageId = updateChat.replyMarkupMessageId;
                }
                break;
            }
            case TdApi.UpdateChatBackground.CONSTRUCTOR: {
                TdApi.UpdateChatBackground updateChat = (TdApi.UpdateChatBackground) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.background = updateChat.background;
                }
                break;
            }
            case TdApi.UpdateChatTheme.CONSTRUCTOR: {
                TdApi.UpdateChatTheme updateChat = (TdApi.UpdateChatTheme) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.themeName = updateChat.themeName;
                }
                break;
            }
            case TdApi.UpdateChatUnreadMentionCount.CONSTRUCTOR: {
                TdApi.UpdateChatUnreadMentionCount updateChat = (TdApi.UpdateChatUnreadMentionCount) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.unreadMentionCount = updateChat.unreadMentionCount;
                }
                break;
            }
            case TdApi.UpdateChatUnreadReactionCount.CONSTRUCTOR: {
                TdApi.UpdateChatUnreadReactionCount updateChat = (TdApi.UpdateChatUnreadReactionCount) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.unreadReactionCount = updateChat.unreadReactionCount;
                }
                break;
            }
            case TdApi.UpdateChatVideoChat.CONSTRUCTOR: {
                TdApi.UpdateChatVideoChat updateChat = (TdApi.UpdateChatVideoChat) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.videoChat = updateChat.videoChat;
                }
                break;
            }
            case TdApi.UpdateChatDefaultDisableNotification.CONSTRUCTOR: {
                TdApi.UpdateChatDefaultDisableNotification update = (TdApi.UpdateChatDefaultDisableNotification) object;
                TdApi.Chat chat = chats.get(update.chatId);
                synchronized (chat) {
                    chat.defaultDisableNotification = update.defaultDisableNotification;
                }
                break;
            }
            case TdApi.UpdateChatHasProtectedContent.CONSTRUCTOR: {
                TdApi.UpdateChatHasProtectedContent updateChat = (TdApi.UpdateChatHasProtectedContent) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.hasProtectedContent = updateChat.hasProtectedContent;
                }
                break;
            }
            case TdApi.UpdateChatIsTranslatable.CONSTRUCTOR: {
                TdApi.UpdateChatIsTranslatable update = (TdApi.UpdateChatIsTranslatable) object;
                TdApi.Chat chat = chats.get(update.chatId);
                synchronized (chat) {
                    chat.isTranslatable = update.isTranslatable;
                }
                break;
            }
            case TdApi.UpdateChatIsMarkedAsUnread.CONSTRUCTOR: {
                TdApi.UpdateChatIsMarkedAsUnread update = (TdApi.UpdateChatIsMarkedAsUnread) object;
                TdApi.Chat chat = chats.get(update.chatId);
                synchronized (chat) {
                    chat.isMarkedAsUnread = update.isMarkedAsUnread;
                }
                break;
            }
            case TdApi.UpdateChatBlockList.CONSTRUCTOR: {
                TdApi.UpdateChatBlockList update = (TdApi.UpdateChatBlockList) object;
                TdApi.Chat chat = chats.get(update.chatId);
                synchronized (chat) {
                    chat.blockList = update.blockList;
                }
                break;
            }
            case TdApi.UpdateChatHasScheduledMessages.CONSTRUCTOR: {
                TdApi.UpdateChatHasScheduledMessages update = (TdApi.UpdateChatHasScheduledMessages) object;
                TdApi.Chat chat = chats.get(update.chatId);
                synchronized (chat) {
                    chat.hasScheduledMessages = update.hasScheduledMessages;
                }
                break;
            }

            case TdApi.UpdateMessageMentionRead.CONSTRUCTOR: {
                TdApi.UpdateMessageMentionRead updateChat = (TdApi.UpdateMessageMentionRead) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.unreadMentionCount = updateChat.unreadMentionCount;
                }
                break;
            }
            case TdApi.UpdateMessageUnreadReactions.CONSTRUCTOR: {
                TdApi.UpdateMessageUnreadReactions updateChat = (TdApi.UpdateMessageUnreadReactions) object;
                TdApi.Chat chat = chats.get(updateChat.chatId);
                synchronized (chat) {
                    chat.unreadReactionCount = updateChat.unreadReactionCount;
                }
                break;
            }

            case TdApi.UpdateUserFullInfo.CONSTRUCTOR:
                TdApi.UpdateUserFullInfo updateUserFullInfo = (TdApi.UpdateUserFullInfo) object;
                usersFullInfo.put(updateUserFullInfo.userId, updateUserFullInfo.userFullInfo);
                break;
            case TdApi.UpdateBasicGroupFullInfo.CONSTRUCTOR:
                TdApi.UpdateBasicGroupFullInfo updateBasicGroupFullInfo = (TdApi.UpdateBasicGroupFullInfo) object;
                basicGroupsFullInfo.put(updateBasicGroupFullInfo.basicGroupId, updateBasicGroupFullInfo.basicGroupFullInfo);
                break;
            case TdApi.UpdateSupergroupFullInfo.CONSTRUCTOR:
                TdApi.UpdateSupergroupFullInfo updateSupergroupFullInfo = (TdApi.UpdateSupergroupFullInfo) object;
                supergroupsFullInfo.put(updateSupergroupFullInfo.supergroupId, updateSupergroupFullInfo.supergroupFullInfo);
                break;
            default:
                log.info("Unsupported update:" + object);
        }
    }

    private static void setChatPositions(TdApi.Chat chat, TdApi.ChatPosition[] positions) {
        synchronized (mainChatList) {
            synchronized (chat) {
                for (TdApi.ChatPosition position : chat.positions) {
                    if (position.list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) {
                        boolean isRemoved = mainChatList.remove(new OrderedChat(chat.id, position));
                        assert isRemoved;
                    }
                }
                chat.positions = positions;

                for (TdApi.ChatPosition position : chat.positions) {
                    if (position.list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) {
                        boolean isAdded = mainChatList.add(new OrderedChat(chat.id, position));
                        assert isAdded;
                    }
                }
            }
        }
    }
}
levlam commented 9 months ago

Then, you passed the UpdateHandler when creating specifing Client, so you can store in the updates handler any information about the client after it is created. You can also make the UpdatesHandler self-contained and store all relevant data inside the object during updates handling.

ToYashDeepSingh commented 9 months ago

Hello @levlam , I am creating a new springboot project from scratch and added TDApi and Client class as a jar file and added it as a dependency in my maven, so that I can update the said classes if any new updates/changes are made. I have restructured the given Example.java code only and changed how the setTDLibParameters are said for particular phoneNumber/User:

public void initializeClient(String phoneNumber) {
        // set log message handler to handle only fatal errors (0) and plain log messages (-1)
        Client.setLogMessageHandler(0, new LogMessageHandler());
        // disable TDLib log and redirect fatal errors and plain log messages to a file
        try {
            Client.execute(new TdApi.SetLogVerbosityLevel(0));
            Client.execute(new TdApi.SetLogStream(new TdApi.LogStreamFile("tdlib_"+phoneNumber+".log", 1 << 27, false)));
        } catch (Client.ExecutionException error) {
            throw new IOError(new IOException("Write access to the current directory is required"));
        }
        // create client
        Client client = Client.create(new UpdateHandler(), null, null);
        Constants.clientHashMap.put(phoneNumber, client);
    }

public void setTdlibParameters(String phoneNumber)
    {
        TdApi.SetTdlibParameters request = new TdApi.SetTdlibParameters();
        request.databaseDirectory = "storage/"+phoneNumber+"/db";
        request.filesDirectory = "storage/"+phoneNumber+"/files";
        request.useMessageDatabase = false;
        request.useFileDatabase = false;
        request.useSecretChats = false;
        request.apiId = **********;
        request.apiHash = "*************************************";
        request.systemLanguageCode = "en";
        request.deviceModel = "Desktop";
        request.applicationVersion = "1.0";
        request.enableStorageOptimizer = true;
        log.info("Initialized TDLibParams.");
        clientHashMap.get(phoneNumber).send(request, new AuthorizationRequestHandler());
    }

    public void setReceivedOTP(String OTP, String phoneNumber){
        clientHashMap.get(phoneNumber).send(new TdApi.CheckAuthenticationCode(OTP), new AuthorizationRequestHandler());
    }

    public void setEnteredPhoneNumber(String phoneNumber){
        clientHashMap.get(phoneNumber).send(new TdApi.SetAuthenticationPhoneNumber(phoneNumber, null), new AuthorizationRequestHandler());
    }

Are you suggesting that I make changes to TDApi.class and Client.class? Can it be done without changing TDApi or Client class?

levlam commented 9 months ago

No, you need only changes to the Example.java. The example doesn't support mulptiple users for simplicity and has most fields declared as static. This has to be changed to support multiple users.

ToYashDeepSingh commented 9 months ago

Hello @levlam , Thanks for your prompt and helpful responses. I was able to accomplish what you said by writing the following code:

@Slf4j
@Getter
public class UpdateHandler implements Client.ResultHandler {

    public UpdateHandler(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    private String phoneNumber;
    AuthorizationStateUpdate authorizationStateUpdate = new AuthorizationStateUpdate();
    @Override
    public void onResult(TdApi.Object object) {
        log.info(String.valueOf(object));
        log.info("Event coming for phone number {}", phoneNumber); // this prints the passed phone number.
        switch (object.getConstructor()) {
            case TdApi.User.CONSTRUCTOR:
                log.info("User " + object);
                //...
                //...
                // other constructors

I guess I will apply this for AuthorizationRequestHandler as well to know for which phone numbers the authorization updates, if any, might have failed.

As I keep moving forward in exploring your library further I most probably would ask more questions that might be simple/stupid :stuck_out_tongue: ,

Thanks for your continued support and help.