MTProtoHandler

com.github.badoualy.telegram.mtproto.MTProtoHandler

This is the main class of the module, it handles all the operations.

👍

Use api module

You should not be using this class directly, unless you know what you're doing. Most of the time, using a TelegramClient will be way easier.

📘

ApiCallback

The ApiCallback interface is a simple one-method callback called when a new update is received.

Create a new handler

You can create a handler from the AuthResult

MTProtoHandler mtProtoHandler = new MTProtoHandler(authResult, null);

Or from an existing AuthKey, and session (not mandatory)

MTProtoHandler mtProtoHandler = new MTProtoHandler(datacenter, authkey, null, null);

Start listening for incoming messages

You now have a running MTProtoHandler (created from an AuthResult or from an existing auth key). To start listening for incoming messages (rpc messages), just call:

mtProtoHandler.startWatchdog();

From this point, you can now execute rpc calls, execute methods, receive messages, ...

Init connection

According to MTProto specs, you need to use the initConnection#69796de9 method to init the connection. This will basically tell Telegram which api layer you want to use, which language (english, ...).
To do that, you need to wrap a method call in an initConnection call, itself wrapped in a invokeWithLayer#da9b0d0d call.

public <T extends TLObject> T initConnection(MTProtoHandler mtProtoHandler, TLMethod<T> method) throws IOException {
    TLRequestInitConnection<T> initConnectionRequest
            = new TLRequestInitConnection<T>(application.getApiId(),
                                                                 application.getDeviceModel(),
                                                                 application.getSystemVersion(),
                                                                 application.getAppVersion(),
                                                                 application.getLangCode(), method);
    return mtProtoHandler.executeMethodSync(new TLRequestInvokeWithLayer<T>(Kotlogram.API_LAYER, initConnectionRequest),
                                            TimeUnit.SECONDS.toMillis(10));
}

Here we use the executeMethodSync to have a synchronous call for more convenience, for more info see next section.

🚧

Permission

If you call the above method before the user is actually signed in (via auth.signIn#bcd51581 method), you'll have to use a method that doesn't require to be signed in, like help.getNearestDc#1fb33026.

Execute a method (TLMethod)

To execute a method, you have the following methods available:

public <T: TLObject> Observable<T> executeMethod(TLMethod<T> method, long timeout)
public <T: TLObject> T executeMethodSync(TLMethod<T> method, long timeout)

The first method returns an RxJava's Observable, the method will actually be executed when you subscribe to this observable. This allows to manually handle threading for advance usage when needed.
The second method is more simple, and just use to first one, then convert it to a BlockingObservable and get the response. This will cause the current thread to hang until the response arrives.

You may want to execute multiple methods at once, for example when downloading a file, you'll want to execute methods to get a few parts at once, rather than requesting one part, waiting for the response, then request the next part, etc. To do this you can use the following methods:

public <T: TLObject> Observable<TLMethod<T>> executeMethods(List<TLMethod<? extends T>> methods, long timeout)
public <T: TLObject> List<T> executeMethodsSync(List<TLMethod<? extends T>> methods, long timeout)

If you want to execute methods with different return type, you'll have to create a List of a common supertype (being at least a TLObject). You can also use a upper bounded wildcard.

  • When using executeMethodsSync, the object in the returned list will conserve the order of the argument list.
  • When using executeMethods, the order is not assured, and the response can arrive in any order (due to Telegram's API behavior). To help with that, the returned observable is actually an Observable<TLMethod<>>. You can then get the response via getResponse() accessor.

📘

Acknowledgement queue/Queued method

When executing a method, some additional data may be sent in the same message. In this case a container is created and contains all the different messages. This is usually the case when the acknowledgement queue (messages received from Telegram that needs to be ack) is not empty, or when a method is queued (see below).

Queue a method

At some point, you may want to execute a method, but without sending it now, but rather add it to a queue and send it with the next message sent to the server. You can do that by calling:

public <T: TLObject> Observable<T> queueMethod(TLMethod<T> method, int type, long validityTimeout, long timeout)

As executeMethod, you get an observable.

  • type is the type of queue you want to push, for now, the only possible value is MTProtoHandler.QUEUE_TYPE_DISCARD, the method will be discarded if no message is sent to the server in the next validityTimeout ms.
  • vadilityTimeout: time before the method expires, may have different behavior according to type.
  • timeout: observable timeout.

Reset connection

If for some reason, you have a weird bug/error, and you wish to create a new session (see Telegram official documentation), call:

mtProtoHandler.resetConnection();

Close connection

When you're done, just call:

mtProtoHandler.close();

Cleanup

Since Kotlogram was designed to allow multiple-instances easily, while staying scalable, it uses some static resources (Timers, Thread-pool, ...). If you need to finish your program, just call:

MTProtoHandler.cleanUp();

🚧

Note

  • If you're using api module, you don't need to do that here, rather call Kotlogram.cleanUp().

Did this page help you?