1 // 2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 package org.drinkless.tdlib.example; 8 9 import org.drinkless.tdlib.Client; 10 import org.drinkless.tdlib.TdApi; 11 12 import java.io.IOError; 13 import java.io.IOException; 14 import java.io.BufferedReader; 15 import java.io.InputStreamReader; 16 import java.util.NavigableSet; 17 import java.util.TreeSet; 18 import java.util.concurrent.ConcurrentHashMap; 19 import java.util.concurrent.ConcurrentMap; 20 import java.util.concurrent.locks.Condition; 21 import java.util.concurrent.locks.Lock; 22 import java.util.concurrent.locks.ReentrantLock; 23 24 /** 25 * Example class for TDLib usage from Java. 26 */ 27 public final class Example { 28 private static Client client = null; 29 30 private static TdApi.AuthorizationState authorizationState = null; 31 private static volatile boolean haveAuthorization = false; 32 private static volatile boolean needQuit = false; 33 private static volatile boolean canQuit = false; 34 35 private static final Client.ResultHandler defaultHandler = new DefaultHandler(); 36 37 private static final Lock authorizationLock = new ReentrantLock(); 38 private static final Condition gotAuthorization = authorizationLock.newCondition(); 39 40 private static final ConcurrentMap<Long, TdApi.User> users = new ConcurrentHashMap<Long, TdApi.User>(); 41 private static final ConcurrentMap<Long, TdApi.BasicGroup> basicGroups = new ConcurrentHashMap<Long, TdApi.BasicGroup>(); 42 private static final ConcurrentMap<Long, TdApi.Supergroup> supergroups = new ConcurrentHashMap<Long, TdApi.Supergroup>(); 43 private static final ConcurrentMap<Integer, TdApi.SecretChat> secretChats = new ConcurrentHashMap<Integer, TdApi.SecretChat>(); 44 45 private static final ConcurrentMap<Long, TdApi.Chat> chats = new ConcurrentHashMap<Long, TdApi.Chat>(); 46 private static final NavigableSet<OrderedChat> mainChatList = new TreeSet<OrderedChat>(); 47 private static boolean haveFullMainChatList = false; 48 49 private static final ConcurrentMap<Long, TdApi.UserFullInfo> usersFullInfo = new ConcurrentHashMap<Long, TdApi.UserFullInfo>(); 50 private static final ConcurrentMap<Long, TdApi.BasicGroupFullInfo> basicGroupsFullInfo = new ConcurrentHashMap<Long, TdApi.BasicGroupFullInfo>(); 51 private static final ConcurrentMap<Long, TdApi.SupergroupFullInfo> supergroupsFullInfo = new ConcurrentHashMap<Long, TdApi.SupergroupFullInfo>(); 52 53 private static final String newLine = System.getProperty("line.separator"); 54 private static final String commandsLine = "Enter command (gcs - GetChats, gc <chatId> - GetChat, me - GetMe, sm <chatId> <message> - SendMessage, lo - LogOut, q - Quit): "; 55 private static volatile String currentPrompt = null; 56 57 static { 58 try { 59 System.loadLibrary("tdjni"); 60 } catch (UnsatisfiedLinkError e) { 61 e.printStackTrace(); 62 } 63 } 64 print(String str)65 private static void print(String str) { 66 if (currentPrompt != null) { 67 System.out.println(""); 68 } 69 System.out.println(str); 70 if (currentPrompt != null) { 71 System.out.print(currentPrompt); 72 } 73 } 74 setChatPositions(TdApi.Chat chat, TdApi.ChatPosition[] positions)75 private static void setChatPositions(TdApi.Chat chat, TdApi.ChatPosition[] positions) { 76 synchronized (mainChatList) { 77 synchronized (chat) { 78 for (TdApi.ChatPosition position : chat.positions) { 79 if (position.list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) { 80 boolean isRemoved = mainChatList.remove(new OrderedChat(chat.id, position)); 81 assert isRemoved; 82 } 83 } 84 85 chat.positions = positions; 86 87 for (TdApi.ChatPosition position : chat.positions) { 88 if (position.list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) { 89 boolean isAdded = mainChatList.add(new OrderedChat(chat.id, position)); 90 assert isAdded; 91 } 92 } 93 } 94 } 95 } 96 onAuthorizationStateUpdated(TdApi.AuthorizationState authorizationState)97 private static void onAuthorizationStateUpdated(TdApi.AuthorizationState authorizationState) { 98 if (authorizationState != null) { 99 Example.authorizationState = authorizationState; 100 } 101 switch (Example.authorizationState.getConstructor()) { 102 case TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR: 103 TdApi.TdlibParameters parameters = new TdApi.TdlibParameters(); 104 parameters.databaseDirectory = "tdlib"; 105 parameters.useMessageDatabase = true; 106 parameters.useSecretChats = true; 107 parameters.apiId = 94575; 108 parameters.apiHash = "a3406de8d171bb422bb6ddf3bbd800e2"; 109 parameters.systemLanguageCode = "en"; 110 parameters.deviceModel = "Desktop"; 111 parameters.applicationVersion = "1.0"; 112 parameters.enableStorageOptimizer = true; 113 114 client.send(new TdApi.SetTdlibParameters(parameters), new AuthorizationRequestHandler()); 115 break; 116 case TdApi.AuthorizationStateWaitEncryptionKey.CONSTRUCTOR: 117 client.send(new TdApi.CheckDatabaseEncryptionKey(), new AuthorizationRequestHandler()); 118 break; 119 case TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR: { 120 String phoneNumber = promptString("Please enter phone number: "); 121 client.send(new TdApi.SetAuthenticationPhoneNumber(phoneNumber, null), new AuthorizationRequestHandler()); 122 break; 123 } 124 case TdApi.AuthorizationStateWaitOtherDeviceConfirmation.CONSTRUCTOR: { 125 String link = ((TdApi.AuthorizationStateWaitOtherDeviceConfirmation) Example.authorizationState).link; 126 System.out.println("Please confirm this login link on another device: " + link); 127 break; 128 } 129 case TdApi.AuthorizationStateWaitCode.CONSTRUCTOR: { 130 String code = promptString("Please enter authentication code: "); 131 client.send(new TdApi.CheckAuthenticationCode(code), new AuthorizationRequestHandler()); 132 break; 133 } 134 case TdApi.AuthorizationStateWaitRegistration.CONSTRUCTOR: { 135 String firstName = promptString("Please enter your first name: "); 136 String lastName = promptString("Please enter your last name: "); 137 client.send(new TdApi.RegisterUser(firstName, lastName), new AuthorizationRequestHandler()); 138 break; 139 } 140 case TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR: { 141 String password = promptString("Please enter password: "); 142 client.send(new TdApi.CheckAuthenticationPassword(password), new AuthorizationRequestHandler()); 143 break; 144 } 145 case TdApi.AuthorizationStateReady.CONSTRUCTOR: 146 haveAuthorization = true; 147 authorizationLock.lock(); 148 try { 149 gotAuthorization.signal(); 150 } finally { 151 authorizationLock.unlock(); 152 } 153 break; 154 case TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR: 155 haveAuthorization = false; 156 print("Logging out"); 157 break; 158 case TdApi.AuthorizationStateClosing.CONSTRUCTOR: 159 haveAuthorization = false; 160 print("Closing"); 161 break; 162 case TdApi.AuthorizationStateClosed.CONSTRUCTOR: 163 print("Closed"); 164 if (!needQuit) { 165 client = Client.create(new UpdateHandler(), null, null); // recreate client after previous has closed 166 } else { 167 canQuit = true; 168 } 169 break; 170 default: 171 System.err.println("Unsupported authorization state:" + newLine + Example.authorizationState); 172 } 173 } 174 toInt(String arg)175 private static int toInt(String arg) { 176 int result = 0; 177 try { 178 result = Integer.parseInt(arg); 179 } catch (NumberFormatException ignored) { 180 } 181 return result; 182 } 183 getChatId(String arg)184 private static long getChatId(String arg) { 185 long chatId = 0; 186 try { 187 chatId = Long.parseLong(arg); 188 } catch (NumberFormatException ignored) { 189 } 190 return chatId; 191 } 192 promptString(String prompt)193 private static String promptString(String prompt) { 194 System.out.print(prompt); 195 currentPrompt = prompt; 196 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 197 String str = ""; 198 try { 199 str = reader.readLine(); 200 } catch (IOException e) { 201 e.printStackTrace(); 202 } 203 currentPrompt = null; 204 return str; 205 } 206 getCommand()207 private static void getCommand() { 208 String command = promptString(commandsLine); 209 String[] commands = command.split(" ", 2); 210 try { 211 switch (commands[0]) { 212 case "gcs": { 213 int limit = 20; 214 if (commands.length > 1) { 215 limit = toInt(commands[1]); 216 } 217 getMainChatList(limit); 218 break; 219 } 220 case "gc": 221 client.send(new TdApi.GetChat(getChatId(commands[1])), defaultHandler); 222 break; 223 case "me": 224 client.send(new TdApi.GetMe(), defaultHandler); 225 break; 226 case "sm": { 227 String[] args = commands[1].split(" ", 2); 228 sendMessage(getChatId(args[0]), args[1]); 229 break; 230 } 231 case "lo": 232 haveAuthorization = false; 233 client.send(new TdApi.LogOut(), defaultHandler); 234 break; 235 case "q": 236 needQuit = true; 237 haveAuthorization = false; 238 client.send(new TdApi.Close(), defaultHandler); 239 break; 240 default: 241 System.err.println("Unsupported command: " + command); 242 } 243 } catch (ArrayIndexOutOfBoundsException e) { 244 print("Not enough arguments"); 245 } 246 } 247 getMainChatList(final int limit)248 private static void getMainChatList(final int limit) { 249 synchronized (mainChatList) { 250 if (!haveFullMainChatList && limit > mainChatList.size()) { 251 // send GetChats request if there are some unknown chats and have not enough known chats 252 client.send(new TdApi.LoadChats(new TdApi.ChatListMain(), limit - mainChatList.size()), new Client.ResultHandler() { 253 @Override 254 public void onResult(TdApi.Object object) { 255 switch (object.getConstructor()) { 256 case TdApi.Error.CONSTRUCTOR: 257 if (((TdApi.Error) object).code == 404) { 258 synchronized (mainChatList) { 259 haveFullMainChatList = true; 260 } 261 } else { 262 System.err.println("Receive an error for GetChats:" + newLine + object); 263 } 264 break; 265 case TdApi.Ok.CONSTRUCTOR: 266 // chats had already been received through updates, let's retry request 267 getMainChatList(limit); 268 break; 269 default: 270 System.err.println("Receive wrong response from TDLib:" + newLine + object); 271 } 272 } 273 }); 274 return; 275 } 276 277 java.util.Iterator<OrderedChat> iter = mainChatList.iterator(); 278 System.out.println(); 279 System.out.println("First " + limit + " chat(s) out of " + mainChatList.size() + " known chat(s):"); 280 for (int i = 0; i < limit && i < mainChatList.size(); i++) { 281 long chatId = iter.next().chatId; 282 TdApi.Chat chat = chats.get(chatId); 283 synchronized (chat) { 284 System.out.println(chatId + ": " + chat.title); 285 } 286 } 287 print(""); 288 } 289 } 290 sendMessage(long chatId, String message)291 private static void sendMessage(long chatId, String message) { 292 // initialize reply markup just for testing 293 TdApi.InlineKeyboardButton[] row = {new TdApi.InlineKeyboardButton("https://telegram.org?1", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?2", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?3", new TdApi.InlineKeyboardButtonTypeUrl())}; 294 TdApi.ReplyMarkup replyMarkup = new TdApi.ReplyMarkupInlineKeyboard(new TdApi.InlineKeyboardButton[][]{row, row, row}); 295 296 TdApi.InputMessageContent content = new TdApi.InputMessageText(new TdApi.FormattedText(message, null), false, true); 297 client.send(new TdApi.SendMessage(chatId, 0, 0, null, replyMarkup, content), defaultHandler); 298 } 299 main(String[] args)300 public static void main(String[] args) throws InterruptedException { 301 // disable TDLib log 302 Client.execute(new TdApi.SetLogVerbosityLevel(0)); 303 if (Client.execute(new TdApi.SetLogStream(new TdApi.LogStreamFile("tdlib.log", 1 << 27, false))) instanceof TdApi.Error) { 304 throw new IOError(new IOException("Write access to the current directory is required")); 305 } 306 307 // create client 308 client = Client.create(new UpdateHandler(), null, null); 309 310 // test Client.execute 311 defaultHandler.onResult(Client.execute(new TdApi.GetTextEntities("@telegram /test_command https://telegram.org telegram.me @gif @test"))); 312 313 // main loop 314 while (!needQuit) { 315 // await authorization 316 authorizationLock.lock(); 317 try { 318 while (!haveAuthorization) { 319 gotAuthorization.await(); 320 } 321 } finally { 322 authorizationLock.unlock(); 323 } 324 325 while (haveAuthorization) { 326 getCommand(); 327 } 328 } 329 while (!canQuit) { 330 Thread.sleep(1); 331 } 332 } 333 334 private static class OrderedChat implements Comparable<OrderedChat> { 335 final long chatId; 336 final TdApi.ChatPosition position; 337 OrderedChat(long chatId, TdApi.ChatPosition position)338 OrderedChat(long chatId, TdApi.ChatPosition position) { 339 this.chatId = chatId; 340 this.position = position; 341 } 342 343 @Override compareTo(OrderedChat o)344 public int compareTo(OrderedChat o) { 345 if (this.position.order != o.position.order) { 346 return o.position.order < this.position.order ? -1 : 1; 347 } 348 if (this.chatId != o.chatId) { 349 return o.chatId < this.chatId ? -1 : 1; 350 } 351 return 0; 352 } 353 354 @Override equals(Object obj)355 public boolean equals(Object obj) { 356 OrderedChat o = (OrderedChat) obj; 357 return this.chatId == o.chatId && this.position.order == o.position.order; 358 } 359 } 360 361 private static class DefaultHandler implements Client.ResultHandler { 362 @Override onResult(TdApi.Object object)363 public void onResult(TdApi.Object object) { 364 print(object.toString()); 365 } 366 } 367 368 private static class UpdateHandler implements Client.ResultHandler { 369 @Override onResult(TdApi.Object object)370 public void onResult(TdApi.Object object) { 371 switch (object.getConstructor()) { 372 case TdApi.UpdateAuthorizationState.CONSTRUCTOR: 373 onAuthorizationStateUpdated(((TdApi.UpdateAuthorizationState) object).authorizationState); 374 break; 375 376 case TdApi.UpdateUser.CONSTRUCTOR: 377 TdApi.UpdateUser updateUser = (TdApi.UpdateUser) object; 378 users.put(updateUser.user.id, updateUser.user); 379 break; 380 case TdApi.UpdateUserStatus.CONSTRUCTOR: { 381 TdApi.UpdateUserStatus updateUserStatus = (TdApi.UpdateUserStatus) object; 382 TdApi.User user = users.get(updateUserStatus.userId); 383 synchronized (user) { 384 user.status = updateUserStatus.status; 385 } 386 break; 387 } 388 case TdApi.UpdateBasicGroup.CONSTRUCTOR: 389 TdApi.UpdateBasicGroup updateBasicGroup = (TdApi.UpdateBasicGroup) object; 390 basicGroups.put(updateBasicGroup.basicGroup.id, updateBasicGroup.basicGroup); 391 break; 392 case TdApi.UpdateSupergroup.CONSTRUCTOR: 393 TdApi.UpdateSupergroup updateSupergroup = (TdApi.UpdateSupergroup) object; 394 supergroups.put(updateSupergroup.supergroup.id, updateSupergroup.supergroup); 395 break; 396 case TdApi.UpdateSecretChat.CONSTRUCTOR: 397 TdApi.UpdateSecretChat updateSecretChat = (TdApi.UpdateSecretChat) object; 398 secretChats.put(updateSecretChat.secretChat.id, updateSecretChat.secretChat); 399 break; 400 401 case TdApi.UpdateNewChat.CONSTRUCTOR: { 402 TdApi.UpdateNewChat updateNewChat = (TdApi.UpdateNewChat) object; 403 TdApi.Chat chat = updateNewChat.chat; 404 synchronized (chat) { 405 chats.put(chat.id, chat); 406 407 TdApi.ChatPosition[] positions = chat.positions; 408 chat.positions = new TdApi.ChatPosition[0]; 409 setChatPositions(chat, positions); 410 } 411 break; 412 } 413 case TdApi.UpdateChatTitle.CONSTRUCTOR: { 414 TdApi.UpdateChatTitle updateChat = (TdApi.UpdateChatTitle) object; 415 TdApi.Chat chat = chats.get(updateChat.chatId); 416 synchronized (chat) { 417 chat.title = updateChat.title; 418 } 419 break; 420 } 421 case TdApi.UpdateChatPhoto.CONSTRUCTOR: { 422 TdApi.UpdateChatPhoto updateChat = (TdApi.UpdateChatPhoto) object; 423 TdApi.Chat chat = chats.get(updateChat.chatId); 424 synchronized (chat) { 425 chat.photo = updateChat.photo; 426 } 427 break; 428 } 429 case TdApi.UpdateChatLastMessage.CONSTRUCTOR: { 430 TdApi.UpdateChatLastMessage updateChat = (TdApi.UpdateChatLastMessage) object; 431 TdApi.Chat chat = chats.get(updateChat.chatId); 432 synchronized (chat) { 433 chat.lastMessage = updateChat.lastMessage; 434 setChatPositions(chat, updateChat.positions); 435 } 436 break; 437 } 438 case TdApi.UpdateChatPosition.CONSTRUCTOR: { 439 TdApi.UpdateChatPosition updateChat = (TdApi.UpdateChatPosition) object; 440 if (updateChat.position.list.getConstructor() != TdApi.ChatListMain.CONSTRUCTOR) { 441 break; 442 } 443 444 TdApi.Chat chat = chats.get(updateChat.chatId); 445 synchronized (chat) { 446 int i; 447 for (i = 0; i < chat.positions.length; i++) { 448 if (chat.positions[i].list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) { 449 break; 450 } 451 } 452 TdApi.ChatPosition[] new_positions = new TdApi.ChatPosition[chat.positions.length + (updateChat.position.order == 0 ? 0 : 1) - (i < chat.positions.length ? 1 : 0)]; 453 int pos = 0; 454 if (updateChat.position.order != 0) { 455 new_positions[pos++] = updateChat.position; 456 } 457 for (int j = 0; j < chat.positions.length; j++) { 458 if (j != i) { 459 new_positions[pos++] = chat.positions[j]; 460 } 461 } 462 assert pos == new_positions.length; 463 464 setChatPositions(chat, new_positions); 465 } 466 break; 467 } 468 case TdApi.UpdateChatReadInbox.CONSTRUCTOR: { 469 TdApi.UpdateChatReadInbox updateChat = (TdApi.UpdateChatReadInbox) object; 470 TdApi.Chat chat = chats.get(updateChat.chatId); 471 synchronized (chat) { 472 chat.lastReadInboxMessageId = updateChat.lastReadInboxMessageId; 473 chat.unreadCount = updateChat.unreadCount; 474 } 475 break; 476 } 477 case TdApi.UpdateChatReadOutbox.CONSTRUCTOR: { 478 TdApi.UpdateChatReadOutbox updateChat = (TdApi.UpdateChatReadOutbox) object; 479 TdApi.Chat chat = chats.get(updateChat.chatId); 480 synchronized (chat) { 481 chat.lastReadOutboxMessageId = updateChat.lastReadOutboxMessageId; 482 } 483 break; 484 } 485 case TdApi.UpdateChatUnreadMentionCount.CONSTRUCTOR: { 486 TdApi.UpdateChatUnreadMentionCount updateChat = (TdApi.UpdateChatUnreadMentionCount) object; 487 TdApi.Chat chat = chats.get(updateChat.chatId); 488 synchronized (chat) { 489 chat.unreadMentionCount = updateChat.unreadMentionCount; 490 } 491 break; 492 } 493 case TdApi.UpdateMessageMentionRead.CONSTRUCTOR: { 494 TdApi.UpdateMessageMentionRead updateChat = (TdApi.UpdateMessageMentionRead) object; 495 TdApi.Chat chat = chats.get(updateChat.chatId); 496 synchronized (chat) { 497 chat.unreadMentionCount = updateChat.unreadMentionCount; 498 } 499 break; 500 } 501 case TdApi.UpdateChatReplyMarkup.CONSTRUCTOR: { 502 TdApi.UpdateChatReplyMarkup updateChat = (TdApi.UpdateChatReplyMarkup) object; 503 TdApi.Chat chat = chats.get(updateChat.chatId); 504 synchronized (chat) { 505 chat.replyMarkupMessageId = updateChat.replyMarkupMessageId; 506 } 507 break; 508 } 509 case TdApi.UpdateChatDraftMessage.CONSTRUCTOR: { 510 TdApi.UpdateChatDraftMessage updateChat = (TdApi.UpdateChatDraftMessage) object; 511 TdApi.Chat chat = chats.get(updateChat.chatId); 512 synchronized (chat) { 513 chat.draftMessage = updateChat.draftMessage; 514 setChatPositions(chat, updateChat.positions); 515 } 516 break; 517 } 518 case TdApi.UpdateChatPermissions.CONSTRUCTOR: { 519 TdApi.UpdateChatPermissions update = (TdApi.UpdateChatPermissions) object; 520 TdApi.Chat chat = chats.get(update.chatId); 521 synchronized (chat) { 522 chat.permissions = update.permissions; 523 } 524 break; 525 } 526 case TdApi.UpdateChatNotificationSettings.CONSTRUCTOR: { 527 TdApi.UpdateChatNotificationSettings update = (TdApi.UpdateChatNotificationSettings) object; 528 TdApi.Chat chat = chats.get(update.chatId); 529 synchronized (chat) { 530 chat.notificationSettings = update.notificationSettings; 531 } 532 break; 533 } 534 case TdApi.UpdateChatDefaultDisableNotification.CONSTRUCTOR: { 535 TdApi.UpdateChatDefaultDisableNotification update = (TdApi.UpdateChatDefaultDisableNotification) object; 536 TdApi.Chat chat = chats.get(update.chatId); 537 synchronized (chat) { 538 chat.defaultDisableNotification = update.defaultDisableNotification; 539 } 540 break; 541 } 542 case TdApi.UpdateChatIsMarkedAsUnread.CONSTRUCTOR: { 543 TdApi.UpdateChatIsMarkedAsUnread update = (TdApi.UpdateChatIsMarkedAsUnread) object; 544 TdApi.Chat chat = chats.get(update.chatId); 545 synchronized (chat) { 546 chat.isMarkedAsUnread = update.isMarkedAsUnread; 547 } 548 break; 549 } 550 case TdApi.UpdateChatIsBlocked.CONSTRUCTOR: { 551 TdApi.UpdateChatIsBlocked update = (TdApi.UpdateChatIsBlocked) object; 552 TdApi.Chat chat = chats.get(update.chatId); 553 synchronized (chat) { 554 chat.isBlocked = update.isBlocked; 555 } 556 break; 557 } 558 case TdApi.UpdateChatHasScheduledMessages.CONSTRUCTOR: { 559 TdApi.UpdateChatHasScheduledMessages update = (TdApi.UpdateChatHasScheduledMessages) object; 560 TdApi.Chat chat = chats.get(update.chatId); 561 synchronized (chat) { 562 chat.hasScheduledMessages = update.hasScheduledMessages; 563 } 564 break; 565 } 566 567 case TdApi.UpdateUserFullInfo.CONSTRUCTOR: 568 TdApi.UpdateUserFullInfo updateUserFullInfo = (TdApi.UpdateUserFullInfo) object; 569 usersFullInfo.put(updateUserFullInfo.userId, updateUserFullInfo.userFullInfo); 570 break; 571 case TdApi.UpdateBasicGroupFullInfo.CONSTRUCTOR: 572 TdApi.UpdateBasicGroupFullInfo updateBasicGroupFullInfo = (TdApi.UpdateBasicGroupFullInfo) object; 573 basicGroupsFullInfo.put(updateBasicGroupFullInfo.basicGroupId, updateBasicGroupFullInfo.basicGroupFullInfo); 574 break; 575 case TdApi.UpdateSupergroupFullInfo.CONSTRUCTOR: 576 TdApi.UpdateSupergroupFullInfo updateSupergroupFullInfo = (TdApi.UpdateSupergroupFullInfo) object; 577 supergroupsFullInfo.put(updateSupergroupFullInfo.supergroupId, updateSupergroupFullInfo.supergroupFullInfo); 578 break; 579 default: 580 // print("Unsupported update:" + newLine + object); 581 } 582 } 583 } 584 585 private static class AuthorizationRequestHandler implements Client.ResultHandler { 586 @Override onResult(TdApi.Object object)587 public void onResult(TdApi.Object object) { 588 switch (object.getConstructor()) { 589 case TdApi.Error.CONSTRUCTOR: 590 System.err.println("Receive an error:" + newLine + object); 591 onAuthorizationStateUpdated(null); // repeat last action 592 break; 593 case TdApi.Ok.CONSTRUCTOR: 594 // result is already received through UpdateAuthorizationState, nothing to do 595 break; 596 default: 597 System.err.println("Receive wrong response from TDLib:" + newLine + object); 598 } 599 } 600 } 601 }