public void handleDirections(Update update) throws InvalidObjectException {
    Message message = update.getMessage();
    if (message != null && message.hasText()) {
      if (languageMessages.contains(message.getFrom().getId())) {
        onLanguageSelected(message);
      } else {
        String language =
            DatabaseManager.getInstance().getUserLanguage(update.getMessage().getFrom().getId());
        if (message.getText().startsWith(Commands.setLanguageCommand)) {
          onSetLanguageCommand(message, language);
        } else if (message.getText().startsWith(Commands.startDirectionCommand)) {
          onStartdirectionsCommand(message, language);
        } else if ((message.getText().startsWith(Commands.help)
                || (message.getText().startsWith(Commands.startCommand)
                    || !message.isGroupMessage()))
            && DatabaseManager.getInstance().getUserDestinationStatus(message.getFrom().getId())
                == -1) {
          sendHelpMessage(message, language);
        } else if (!message.getText().startsWith("/")) {
          if (DatabaseManager.getInstance().getUserDestinationStatus(message.getFrom().getId())
                  == WATING_ORIGIN_STATUS
              && message.hasReplayMessage()
              && DatabaseManager.getInstance()
                      .getUserDestinationMessageId(message.getFrom().getId())
                  == message.getReplyToMessage().getMessageId()) {
            onOriginReceived(message, language);

          } else if (DatabaseManager.getInstance()
                      .getUserDestinationStatus(message.getFrom().getId())
                  == WATING_DESTINY_STATUS
              && message.hasReplayMessage()
              && DatabaseManager.getInstance()
                      .getUserDestinationMessageId(message.getFrom().getId())
                  == message.getReplyToMessage().getMessageId()) {
            onDestinationReceived(message, language);
          } else if (!message.hasReplayMessage()) {
            if (DatabaseManager.getInstance().getUserDestinationStatus(message.getFrom().getId())
                == -1) {
              sendHelpMessage(message, language);
            } else {
              SendMessage sendMessageRequest = new SendMessage();
              sendMessageRequest.setText(
                  LocalisationService.getInstance().getString("youNeedReplyDirections", language));
              sendMessageRequest.setChatId(message.getChatId().toString());
              SenderHelper.SendApiMethod(sendMessageRequest, TOKEN);
            }
          }
        }
      }
    }
  }
  private void onStartdirectionsCommand(Message message, String language) {
    SendMessage sendMessageRequest = new SendMessage();
    sendMessageRequest.setChatId(message.getChatId().toString());
    sendMessageRequest.setReplayToMessageId(message.getMessageId());
    ForceReplyKeyboard forceReplyKeyboard = new ForceReplyKeyboard();
    forceReplyKeyboard.setSelective(true);
    sendMessageRequest.setReplayMarkup(forceReplyKeyboard);
    sendMessageRequest.setText(
        LocalisationService.getInstance().getString("initDirections", language));

    SenderHelper.SendApiMethodAsync(
        sendMessageRequest,
        TOKEN,
        new SentCallback<Message>() {
          @Override
          public void onResult(BotApiMethod<Message> method, JSONObject jsonObject) {
            Message sentMessage = method.deserializeResponse(jsonObject);
            if (sentMessage != null) {
              DatabaseManager.getInstance()
                  .addUserForDirection(
                      message.getFrom().getId(),
                      WATING_ORIGIN_STATUS,
                      sentMessage.getMessageId(),
                      null);
            }
          }

          @Override
          public void onError(BotApiMethod<Message> method, JSONObject jsonObject) {}
        });
  }
  private void onDestinationReceived(Message message, String language) {
    String origin = DatabaseManager.getInstance().getUserOrigin(message.getFrom().getId());
    String destiny = message.getText();
    List<String> directions =
        DirectionsService.getInstance().getDirections(origin, destiny, language);
    SendMessage sendMessageRequest = new SendMessage();
    sendMessageRequest.setChatId(message.getChatId().toString());
    ReplyKeyboardHide replyKeyboardHide = new ReplyKeyboardHide();
    replyKeyboardHide.setSelective(true);
    sendMessageRequest.setReplayMarkup(replyKeyboardHide);
    sendMessageRequest.setReplayToMessageId(message.getMessageId());
    Message sentMessage = null;
    for (String direction : directions) {
      sendMessageRequest.setText(direction);
      SenderHelper.SendApiMethodAsync(
          sendMessageRequest,
          TOKEN,
          new SentCallback<Message>() {
            @Override
            public void onResult(BotApiMethod<Message> method, JSONObject jsonObject) {
              Message sentMessage = method.deserializeResponse(jsonObject);
              if (sentMessage != null) {
                DatabaseManager.getInstance().deleteUserForDirections(message.getFrom().getId());
              }
            }

            @Override
            public void onError(BotApiMethod<Message> method, JSONObject jsonObject) {}
          });
    }
  }
 private void sendHelpMessage(Message message, String language) throws InvalidObjectException {
   SendMessage sendMessageRequest = new SendMessage();
   String helpDirectionsFormated =
       String.format(
           LocalisationService.getInstance().getString("helpDirections", language),
           Commands.startDirectionCommand);
   sendMessageRequest.setText(helpDirectionsFormated);
   sendMessageRequest.setChatId(message.getChatId().toString());
   SenderHelper.SendApiMethod(sendMessageRequest, TOKEN);
 }
 private void onLanguageSelected(Message message) throws InvalidObjectException {
   String[] parts = message.getText().split("-->", 2);
   SendMessage sendMessageRequest = new SendMessage();
   sendMessageRequest.setChatId(message.getChatId().toString());
   if (LocalisationService.getInstance().getSupportedLanguages().containsKey(parts[0].trim())) {
     DatabaseManager.getInstance().putUserLanguage(message.getFrom().getId(), parts[0].trim());
     sendMessageRequest.setText(
         LocalisationService.getInstance().getString("languageModified", parts[0].trim()));
   } else {
     sendMessageRequest.setText(LocalisationService.getInstance().getString("errorLanguage"));
   }
   sendMessageRequest.setReplayToMessageId(message.getMessageId());
   ReplyKeyboardHide replyKeyboardHide = new ReplyKeyboardHide();
   replyKeyboardHide.setHideKeyboard(true);
   replyKeyboardHide.setSelective(true);
   sendMessageRequest.setReplayMarkup(replyKeyboardHide);
   SenderHelper.SendApiMethod(sendMessageRequest, TOKEN);
   languageMessages.remove(message.getFrom().getId());
 }
 private void onSetLanguageCommand(Message message, String language)
     throws InvalidObjectException {
   SendMessage sendMessageRequest = new SendMessage();
   sendMessageRequest.setChatId(message.getChatId().toString());
   ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup();
   HashMap<String, String> languages = LocalisationService.getInstance().getSupportedLanguages();
   List<List<String>> commands = new ArrayList<>();
   for (Map.Entry<String, String> entry : languages.entrySet()) {
     List<String> commandRow = new ArrayList<>();
     commandRow.add(entry.getKey() + " --> " + entry.getValue());
     commands.add(commandRow);
   }
   replyKeyboardMarkup.setResizeKeyboard(true);
   replyKeyboardMarkup.setOneTimeKeyboad(true);
   replyKeyboardMarkup.setKeyboard(commands);
   replyKeyboardMarkup.setSelective(true);
   sendMessageRequest.setReplayMarkup(replyKeyboardMarkup);
   sendMessageRequest.setText(
       LocalisationService.getInstance().getString("chooselanguage", language));
   SenderHelper.SendApiMethod(sendMessageRequest, TOKEN);
   languageMessages.add(message.getFrom().getId());
 }