tdlight-team / tdlight-java

Complete Bot and Userbot Telegram library based on TDLib
https://t.me/TDLight
GNU Lesser General Public License v3.0
261 stars 43 forks source link

modify the way to enter the login verification code #220

Closed zybot666 closed 2 months ago

zybot666 commented 3 months ago

I would like to ask how to modify the way to enter the login verification code, I want to use a bot to let the program receive the verification code and log in to a user account, instead of entering it in the console?

SachukS commented 3 months ago

I think you need to write your own ClientInteraction class, and then assign it to your client like in this code below:

public static void loginClient(Partner partner) {
        LOG.error("Telegram login");
        APIToken apiToken = new APIToken(111111, "token");
        TDLibSettings settings = TDLibSettings.create(apiToken);

        Path sessionPath = Paths.get("tdlight-session-"+partner.getPhone());
        settings.setDatabaseDirectoryPath(sessionPath.resolve("data"));
        settings.setDownloadedFilesDirectoryPath(sessionPath.resolve("downloads"));

        SimpleTelegramClientBuilder clientBuilder = simpleTelegramClientFactory.builder(settings);

        SimpleAuthenticationSupplier<?> authenticationData = AuthenticationSupplier.qrCode();

        clientBuilder.addUpdateHandler(TdApi.UpdateAuthorizationState.class, Telegram::onUpdateAuthorizationState);

        clientBuilder.addUpdateHandler(TdApi.UpdateChatReadOutbox.class, Telegram::onUpdateChatReadOutbox);

        clientBuilder.addUpdateHandler(TdApi.UpdateMessageSendSucceeded.class, Telegram::onUpdateMessageSendSucceeded);

        clientBuilder.addUpdateHandler(TdApi.UpdateMessageSendFailed.class, Telegram::onUpdateMessageSendFailed);

        clientBuilder.addUpdateHandler(TdApi.UpdateNewMessage.class, Telegram::onUpdateNewMessage);

        client = clientBuilder.build(authenticationData);
        clientInteraction = new SpringClientInteraction(blockingExecutor, client);
        client.setClientInteraction(clientInteraction);
    }
SachukS commented 3 months ago

this is my custom class

public class SpringClientInteraction implements ClientInteraction {
    private final ExecutorService blockingExecutor;
    private final Authenticable authenticable;

    public static String qr = "";

    public SpringClientInteraction(ExecutorService blockingExecutor, Authenticable authenticable) {
        this.blockingExecutor = blockingExecutor;
        this.authenticable = authenticable;
    }

    @Override
    public CompletableFuture<String> onParameterRequest(InputParameter parameter, ParameterInfo parameterInfo) {
        AuthenticationSupplier<?> authSupplier = this.authenticable.getAuthenticationSupplier();
        AuthenticationData authData = this.getAuthDataNowOrNull(authSupplier);
        return CompletableFuture.supplyAsync(() -> {
            boolean useRealWho = authData != null;
            String who;
            if (!useRealWho) {
                who = "login";
            } else if (authData.isQrCode()) {
                who = "QR login";
            } else if (authData.isBot()) {
                who = authData.getBotToken().split(":", 2)[0];
            } else {
                who = "+" + authData.getUserPhoneNumber();
            }

            boolean trim = false;
            String question;
            switch (parameter) {
                case ASK_FIRST_NAME:
                    question = "Enter first name";
                    trim = true;
                    break;
                case ASK_LAST_NAME:
                    question = "Enter last name";
                    trim = true;
                    break;
                case ASK_CODE:
                    question = "Enter authentication code";
                    ParameterInfoCode codeInfo = (ParameterInfoCode)parameterInfo;
                    question = question + "\n\tPhone number: " + codeInfo.getPhoneNumber();
                    question = question + "\n\tTimeout: " + codeInfo.getTimeout() + " seconds";
                    question = question + "\n\tCode type: " + codeInfo.getType().getClass().getSimpleName().replace("AuthenticationCodeType", "");
                    if (codeInfo.getNextType() != null) {
                        question = question + "\n\tNext code type: " + codeInfo.getNextType().getClass().getSimpleName().replace("AuthenticationCodeType", "");
                    }

                    trim = true;
                    break;
                case ASK_PASSWORD:
                    question = "Enter your password";
                    String passwordMessage = "Password authorization:";
                    String hint = ((ParameterInfoPasswordHint)parameterInfo).getHint();
                    if (hint != null && !hint.isEmpty()) {
                        passwordMessage = passwordMessage + "\n\tHint: " + hint;
                    }

                    boolean hasRecoveryEmailAddress = ((ParameterInfoPasswordHint)parameterInfo).hasRecoveryEmailAddress();
                    passwordMessage = passwordMessage + "\n\tHas recovery email: " + hasRecoveryEmailAddress;
                    String recoveryEmailAddressPattern = ((ParameterInfoPasswordHint)parameterInfo).getRecoveryEmailAddressPattern();
                    if (recoveryEmailAddressPattern != null && !recoveryEmailAddressPattern.isEmpty()) {
                        passwordMessage = passwordMessage + "\n\tRecovery email address pattern: " + recoveryEmailAddressPattern;
                    }

                    System.out.println(passwordMessage);
                    break;
                case NOTIFY_LINK:
                    String link = ((ParameterInfoNotifyLink)parameterInfo).getLink();

                    qr = link;

                    return "";
                case TERMS_OF_SERVICE:
                    TdApi.TermsOfService tos = ((ParameterInfoTermsOfService)parameterInfo).getTermsOfService();
                    question = "Terms of service:\n\t" + tos.text.text;
                    if (tos.minUserAge > 0) {
                        question = question + "\n\tMinimum user age: " + tos.minUserAge;
                    }

                    if (!tos.showPopup) {
                        System.out.println(question);
                        return "";
                    }

                    question = question + "\nPlease press enter.";
                    trim = true;
                    break;
                default:
                    question = parameter.toString();
            }

            String result = ScannerUtils.askParameter(who, question);
            return trim ? result.trim() : (String) Objects.requireNonNull(result);
        }, this.blockingExecutor);
    }

    private AuthenticationData getAuthDataNowOrNull(AuthenticationSupplier<?> authSupplier) {
        try {
            return (AuthenticationData)authSupplier.get().getNow(null);
        } catch (Throwable var3) {
            return null;
        }
    }
}
zybot666 commented 3 months ago

Screenshot_2024_0714_222617 Thank you. I think it should be modified here to receive the verification code through the robot, right? But I thought for a moment, I can only prompt the user to enter the verification code here, but I can't get the return value of the information input by the user. Is there any other way?

SachukS commented 3 months ago

Yes, you need to implement here logic that send "question" with robot and then to make the thread to wait for the response (maybe looping it with GET requests, idk)

SachukS commented 3 months ago

Screenshot_2024_0714_222617 Thank you. I think it should be modified here to receive the verification code through the robot, right? But I thought for a moment, I can only prompt the user to enter the verification code here, but I can't get the return value of the information input by the user. Is there any other way?

is there any results?

zybot666 commented 3 months ago

I already know what to do. Thank you for your reply

tLikWer commented 2 months ago

I already know what to do. Thank you for your reply

can u help me, i dont understand the solution, may be u can give me a project with this solution