{"_id":"57e10500632fd4220007a576","githubsync":"","category":{"_id":"57e0f141ff540c22007b45fa","version":"5703d527bb69fc1700553ce3","__v":0,"project":"5703d527bb69fc1700553ce0","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-09-20T08:20:17.405Z","from_sync":false,"order":3,"slug":"mtproto-module","title":"MTProto module"},"__v":0,"parentDoc":null,"project":"5703d527bb69fc1700553ce0","user":"5631f962c3b04b0d00ba9bf1","version":{"_id":"5703d527bb69fc1700553ce3","hasDoc":true,"__v":6,"hasReference":true,"project":"5703d527bb69fc1700553ce0","createdAt":"2016-04-05T15:09:27.620Z","releaseDate":"2016-04-05T15:09:27.620Z","categories":["5703d527bb69fc1700553ce4","5703d8b7aceacc17003ef303","5703e60b6116142000db25f6","57e0db616a1c2e0e0081fe64","57e0f141ff540c22007b45fa","57e0f14b8929550e00f1d9bc"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"0.0.6","version":"0.0.6"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-09-20T09:44:32.759Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":6,"body":"This is the main class of the module, it handles all the operations. \n[block:callout]\n{\n  \"type\": \"success\",\n  \"title\": \"Use api module\",\n  \"body\": \"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.\"\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"ApiCallback\",\n  \"body\": \"The ApiCallback interface is a simple one-method callback called when a new update is received.\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Create a new handler\"\n}\n[/block]\nYou can create a handler from the AuthResult\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"MTProtoHandler mtProtoHandler = new MTProtoHandler(authResult, null);\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nOr from an existing `AuthKey`, and session (not mandatory)\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"MTProtoHandler mtProtoHandler = new MTProtoHandler(datacenter, authkey, null, null);\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Start listening for incoming messages\"\n}\n[/block]\nYou 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:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mtProtoHandler.startWatchdog();\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nFrom this point, you can now execute rpc calls, execute methods, receive messages, ...\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Init connection\"\n}\n[/block]\nAccording 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, ...).\nTo do that, you need to wrap a method call in an `initConnection` call, itself wrapped in a `invokeWithLayer#da9b0d0d` call.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public <T extends TLObject> T initConnection(MTProtoHandler mtProtoHandler, TLMethod<T> method) throws IOException {\\n    TLRequestInitConnection<T> initConnectionRequest\\n            = new TLRequestInitConnection<T>(application.getApiId(),\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t                         application.getDeviceModel(),\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t                         application.getSystemVersion(),\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t                         application.getAppVersion(),\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t                         application.getLangCode(), method);\\n    return mtProtoHandler.executeMethodSync(new TLRequestInvokeWithLayer<T>(Kotlogram.API_LAYER, initConnectionRequest),\\n                                            TimeUnit.SECONDS.toMillis(10));\\n}\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nHere we use the `executeMethodSync` to have a synchronous call for more convenience, for more info see next section.\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Permission\",\n  \"body\": \"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`.\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Execute a method (TLMethod)\"\n}\n[/block]\nTo execute a method, you have the following methods available:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public <T: TLObject> Observable<T> executeMethod(TLMethod<T> method, long timeout)\\npublic <T: TLObject> T executeMethodSync(TLMethod<T> method, long timeout)\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nThe 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.\nThe 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.\n\nYou 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:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public <T: TLObject> Observable<TLMethod<T>> executeMethods(List<TLMethod<? extends T>> methods, long timeout)\\npublic <T: TLObject> List<T> executeMethodsSync(List<TLMethod<? extends T>> methods, long timeout)\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nIf 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*.\n\n- When using `executeMethodsSync`, the object in the returned list will conserve the order of the argument list.\n- 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.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Acknowledgement queue/Queued method\",\n  \"body\": \"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).\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Queue a method\"\n}\n[/block]\nAt 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:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public <T: TLObject> Observable<T> queueMethod(TLMethod<T> method, int type, long validityTimeout, long timeout)\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\nAs `executeMethod`, you get an observable.\n- 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.\n- `vadilityTimeout`: time before the method expires, may have different behavior according to `type`.\n- `timeout`: observable timeout.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Reset connection\"\n}\n[/block]\nIf for some reason, you have a weird bug/error, and you wish to create a new session (see Telegram official documentation), call:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mtProtoHandler.resetConnection();\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Close connection\"\n}\n[/block]\nWhen you're done, just call:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"mtProtoHandler.close();\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Cleanup\"\n}\n[/block]\nSince 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:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"MTProtoHandler.cleanUp();\",\n      \"language\": \"java\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Note\",\n  \"body\": \"- If you're using api module, you don't need to do that here, rather call `Kotlogram.cleanUp()`.\"\n}\n[/block]","excerpt":"com.github.badoualy.telegram.mtproto.MTProtoHandler","slug":"mtprotohandler","type":"basic","title":"MTProtoHandler"}

MTProtoHandler

com.github.badoualy.telegram.mtproto.MTProtoHandler

This is the main class of the module, it handles all the operations. [block:callout] { "type": "success", "title": "Use api module", "body": "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." } [/block] [block:callout] { "type": "info", "title": "ApiCallback", "body": "The ApiCallback interface is a simple one-method callback called when a new update is received." } [/block] [block:api-header] { "type": "basic", "title": "Create a new handler" } [/block] You can create a handler from the AuthResult [block:code] { "codes": [ { "code": "MTProtoHandler mtProtoHandler = new MTProtoHandler(authResult, null);", "language": "java" } ] } [/block] Or from an existing `AuthKey`, and session (not mandatory) [block:code] { "codes": [ { "code": "MTProtoHandler mtProtoHandler = new MTProtoHandler(datacenter, authkey, null, null);", "language": "java" } ] } [/block] [block:api-header] { "type": "basic", "title": "Start listening for incoming messages" } [/block] 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: [block:code] { "codes": [ { "code": "mtProtoHandler.startWatchdog();", "language": "java" } ] } [/block] From this point, you can now execute rpc calls, execute methods, receive messages, ... [block:api-header] { "type": "basic", "title": "Init connection" } [/block] 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. [block:code] { "codes": [ { "code": "public <T extends TLObject> T initConnection(MTProtoHandler mtProtoHandler, TLMethod<T> method) throws IOException {\n TLRequestInitConnection<T> initConnectionRequest\n = new TLRequestInitConnection<T>(application.getApiId(),\n\t\t\t\t\t\t\t\t\t\t application.getDeviceModel(),\n\t\t\t\t\t\t\t\t\t\t application.getSystemVersion(),\n\t\t\t\t\t\t\t\t\t\t application.getAppVersion(),\n\t\t\t\t\t\t\t\t\t\t application.getLangCode(), method);\n return mtProtoHandler.executeMethodSync(new TLRequestInvokeWithLayer<T>(Kotlogram.API_LAYER, initConnectionRequest),\n TimeUnit.SECONDS.toMillis(10));\n}", "language": "java" } ] } [/block] Here we use the `executeMethodSync` to have a synchronous call for more convenience, for more info see next section. [block:callout] { "type": "warning", "title": "Permission", "body": "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`." } [/block] [block:api-header] { "type": "basic", "title": "Execute a method (TLMethod)" } [/block] To execute a method, you have the following methods available: [block:code] { "codes": [ { "code": "public <T: TLObject> Observable<T> executeMethod(TLMethod<T> method, long timeout)\npublic <T: TLObject> T executeMethodSync(TLMethod<T> method, long timeout)", "language": "java" } ] } [/block] 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: [block:code] { "codes": [ { "code": "public <T: TLObject> Observable<TLMethod<T>> executeMethods(List<TLMethod<? extends T>> methods, long timeout)\npublic <T: TLObject> List<T> executeMethodsSync(List<TLMethod<? extends T>> methods, long timeout)", "language": "java" } ] } [/block] 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. [block:callout] { "type": "info", "title": "Acknowledgement queue/Queued method", "body": "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)." } [/block] [block:api-header] { "type": "basic", "title": "Queue a method" } [/block] 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: [block:code] { "codes": [ { "code": "public <T: TLObject> Observable<T> queueMethod(TLMethod<T> method, int type, long validityTimeout, long timeout)", "language": "java" } ] } [/block] 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. [block:api-header] { "type": "basic", "title": "Reset connection" } [/block] If for some reason, you have a weird bug/error, and you wish to create a new session (see Telegram official documentation), call: [block:code] { "codes": [ { "code": "mtProtoHandler.resetConnection();", "language": "java" } ] } [/block] [block:api-header] { "type": "basic", "title": "Close connection" } [/block] When you're done, just call: [block:code] { "codes": [ { "code": "mtProtoHandler.close();", "language": "java" } ] } [/block] [block:api-header] { "type": "basic", "title": "Cleanup" } [/block] 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: [block:code] { "codes": [ { "code": "MTProtoHandler.cleanUp();", "language": "java" } ] } [/block] [block:callout] { "type": "warning", "title": "Note", "body": "- If you're using api module, you don't need to do that here, rather call `Kotlogram.cleanUp()`." } [/block]