This commit is contained in:
Daniil Gentili 2017-01-23 16:29:28 +01:00
commit 970b79d973
15 changed files with 2340 additions and 28 deletions

View File

@ -61,6 +61,9 @@ description: Documentation of old mtproto layers
'.$layer_list);
$doc = new \danog\MadelineProto\AnnotationsBuilder($docs[1]);
$doc->mk_annotations();
foreach ($docs as $settings) {
$doc = new \danog\MadelineProto\DocsBuilder($settings);
$doc->mk_docs();

View File

@ -6,11 +6,14 @@
"homepage": "https://daniil.it/MadelineProto",
"keywords": ["telegram", "mtproto", "protocol", "bytes", "messenger", "client", "PHP", "video", "stickers", "audio", "files", "GB"],
"require": {
"php": ">=5.6.0",
"danog/phpstruct": "^1.2",
"phpseclib/phpseclib": "dev-master|^2.0.4",
"php": ">=5.6.0",
"vlucas/phpdotenv": "^2.4"
},
"require-dev": {
"phpdocumentor/reflection-docblock": "^3.1"
},
"authors": [
{
"name": "Daniil Gentili",

328
composer.lock generated
View File

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "2620601f51f3b8074fc1fe4b606a9054",
"content-hash": "055f6111941ad34ac71efe5c718ff3d6",
"hash": "e8bbb62792931576147b60ac9015be7a",
"content-hash": "88f022c06bcba63b61978fccad258d1a",
"packages": [
{
"name": "danog/phpstruct",
@ -61,21 +61,132 @@
"time": "2016-11-14 15:09:50"
},
{
"name": "phpseclib/phpseclib",
"version": "2.0.x-dev",
"name": "paragonie/constant_time_encoding",
"version": "v2.0.3",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "00325a3050b320f1020aff42f8a44df6048013dd"
"url": "https://github.com/paragonie/constant_time_encoding.git",
"reference": "e085e08c939de49707dbf64315d178d90fbc708d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/00325a3050b320f1020aff42f8a44df6048013dd",
"reference": "00325a3050b320f1020aff42f8a44df6048013dd",
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/e085e08c939de49707dbf64315d178d90fbc708d",
"reference": "e085e08c939de49707dbf64315d178d90fbc708d",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"php": "^7"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"type": "library",
"autoload": {
"psr-4": {
"ParagonIE\\ConstantTime\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com",
"role": "Maintainer"
},
{
"name": "Steve 'Sc00bz' Thomas",
"email": "steve@tobtu.com",
"homepage": "https://www.tobtu.com",
"role": "Original Developer"
}
],
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
"keywords": [
"base16",
"base32",
"base32_decode",
"base32_encode",
"base64",
"base64_decode",
"base64_encode",
"bin2hex",
"encoding",
"hex",
"hex2bin",
"rfc4648"
],
"time": "2016-07-11 20:32:06"
},
{
"name": "paragonie/random_compat",
"version": "v2.0.4",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e",
"reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2016-11-07 23:38:38"
},
{
"name": "phpseclib/phpseclib",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "74abcb45ed9de9508c61ab15371f1bc40292b9fd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/74abcb45ed9de9508c61ab15371f1bc40292b9fd",
"reference": "74abcb45ed9de9508c61ab15371f1bc40292b9fd",
"shasum": ""
},
"require": {
"paragonie/constant_time_encoding": "^1|^2",
"paragonie/random_compat": "^1.4|^2.0",
"php": ">=7.0"
},
"require-dev": {
"phing/phing": "~2.7",
@ -203,7 +314,204 @@
"time": "2016-09-01 10:05:43"
}
],
"packages-dev": [],
"packages-dev": [
{
"name": "phpdocumentor/reflection-common",
"version": "1.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
"shasum": ""
},
"require": {
"php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "^4.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": [
"src"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jaap van Otterdijk",
"email": "opensource@ijaap.nl"
}
],
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
"homepage": "http://www.phpdoc.org",
"keywords": [
"FQSEN",
"phpDocumentor",
"phpdoc",
"reflection",
"static analysis"
],
"time": "2015-12-27 11:43:31"
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "3.1.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
"reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
"shasum": ""
},
"require": {
"php": ">=5.5",
"phpdocumentor/reflection-common": "^1.0@dev",
"phpdocumentor/type-resolver": "^0.2.0",
"webmozart/assert": "^1.0"
},
"require-dev": {
"mockery/mockery": "^0.9.4",
"phpunit/phpunit": "^4.4"
},
"type": "library",
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"time": "2016-09-30 07:12:33"
},
{
"name": "phpdocumentor/type-resolver",
"version": "0.2.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
"reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
"reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
"shasum": ""
},
"require": {
"php": ">=5.5",
"phpdocumentor/reflection-common": "^1.0"
},
"require-dev": {
"mockery/mockery": "^0.9.4",
"phpunit/phpunit": "^5.2||^4.8.24"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\Reflection\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
}
],
"time": "2016-11-25 06:54:22"
},
{
"name": "webmozart/assert",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
"reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
"reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.6",
"sebastian/version": "^1.0.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Bernhard Schussek",
"email": "bschussek@gmail.com"
}
],
"description": "Assertions to validate method input/output with nice error messages.",
"keywords": [
"assert",
"check",
"validate"
],
"time": "2016-11-23 20:04:58"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {

View File

@ -28,9 +28,18 @@ The MadelineProto API documentations (old layers) can be found [here](https://gi
## Usage
### Installation
```
git clone https://github.com/danog/MadelineProto
cd MadelineProto
```
Now copy .env.example to .env, edit the its values, read the docs and take a look at testing.php, bot.php.
### Dependencies
This project depends on [PHPStruct](https://github.com/danog/PHPStruct), [phpseclib](https://github.com/phpseclib/phpseclib), https://packagist.org/packages/paragonie/constant_time_encoding and https://packagist.org/packages/paragonie/random_compat
This project depends on [PHPStruct](https://github.com/danog/PHPStruct), [phpseclib](https://github.com/phpseclib/phpseclib)
To install dependencies install composer and run:
```

View File

@ -14,6 +14,66 @@ namespace danog\MadelineProto;
class APIFactory
{
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var channels
*/
public $channels;
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var help
*/
public $help;
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var upload
*/
public $upload;
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var photos
*/
public $photos;
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var updates
*/
public $updates;
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var messages
*/
public $messages;
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var contacts
*/
public $contacts;
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var users
*/
public $users;
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var account
*/
public $account;
/**
* @internal this is a internal property generated by build_docs.php, dont change manually
*
* @var auth
*/
public $auth;
public $namespace;
public $API;

View File

@ -0,0 +1,137 @@
<?php
/*
Copyright 2016 Daniil Gentili
(https://daniil.it)
This file is part of MadelineProto.
MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Affero General Public License for more details.
You should have received a copy of the GNU General Public License along with MadelineProto.
If not, see <http://www.gnu.org/licenses/>.
*/
namespace danog\MadelineProto;
use phpDocumentor\Reflection\DocBlockFactory;
class AnnotationsBuilder
{
use \danog\MadelineProto\TL\TL;
public function __construct($settings)
{
$this->construct_TL($settings['tl_schema']);
$this->settings = $settings;
}
public function mk_annotations()
{
\danog\MadelineProto\Logger::log('Generating annotations...');
$this->setProperties();
$this->createInternalClasses();
}
/**
* Open file of class APIFactory
* Insert properties
* save the file with new content.
*/
private function setProperties()
{
\danog\MadelineProto\Logger::log('Generating properties...');
$fixture = DocBlockFactory::createInstance();
$class = new \ReflectionClass(APIFactory::class);
$content = file_get_contents($filename = $class->getFileName());
foreach ($class->getProperties() as $property) {
if ($raw_docblock = $property->getDocComment()) {
$docblock = $fixture->create($raw_docblock);
if ($docblock->hasTag('internal')) {
$content = str_replace("\n ".$raw_docblock."\n public $".$property->getName().';', '', $content);
}
}
}
foreach ($this->methods->method_namespace as $namespace) {
$content = preg_replace(
'/(class( \w+[,]?){0,}\n{\n)/',
'${1}'.
" /**\n".
" * @internal this is a internal property generated by build_docs.php, don't change manually\n".
" *\n".
" * @var $namespace\n".
" */\n".
" public \$$namespace;\n",
$content
);
}
file_put_contents($filename, $content);
}
/**
* Create file InternalDoc with all interfaces.
*/
private function createInternalClasses()
{
\danog\MadelineProto\Logger::log('Creating internal classes...');
$handle = fopen(dirname(__FILE__).'/InternalDoc.php', 'w');
foreach ($this->methods->method as $key => $rmethod) {
if (!strpos($rmethod, '.')) {
continue;
}
list($namespace, $method) = explode('.', $rmethod);
if (!in_array($namespace, $this->methods->method_namespace)) {
continue;
}
$type = str_replace(['.', '<', '>'], ['_', '_of_', ''], $this->methods->type[$key]);
foreach ($this->methods->params[$key] as $param) {
if (in_array($param['name'], ['flags', 'random_id'])) {
continue;
}
$stype = 'type';
if (isset($param['subtype'])) {
$stype = 'subtype';
}
$ptype = str_replace('.', '_', $param[$stype]);
switch ($ptype) {
case 'true':
case 'false':
$ptype = 'boolean';
}
$internalDoc[$namespace][$method]['attr'][$param['name']] = $ptype;
}
if ($type == 'Bool') {
$type = strtolower($type);
}
$internalDoc[$namespace][$method]['return'] = $type;
}
fwrite($handle, "<?php\n");
fwrite($handle, "/**\n");
fwrite($handle, " * This file is automatic generated by build_docs.php file\n");
fwrite($handle, " * and is used only for autocomplete in multiple IDE\n");
fwrite($handle, " * dont modify manually.\n");
fwrite($handle, " */\n\n");
fwrite($handle, "namespace danog\MadelineProto;\n");
foreach ($internalDoc as $namespace => $methods) {
fwrite($handle, "\ninterface $namespace\n{");
foreach ($methods as $method => $properties) {
fwrite($handle, "\n /**\n");
if (isset($properties['attr'])) {
fwrite($handle, " * @param array params [\n");
foreach ($properties['attr'] as $name => $type) {
fwrite($handle, " * $type $name,\n");
}
fwrite($handle, " * ]\n");
fwrite($handle, " *\n");
}
fwrite($handle, " * @return {$properties['return']}\n");
fwrite($handle, " */\n");
fwrite($handle, " public function $method(");
if (isset($properties['attr'])) {
fwrite($handle, 'array $params');
}
fwrite($handle, ");\n");
}
fwrite($handle, "}\n");
}
fclose($handle);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,9 @@ trait UpdateHandler
\danog\MadelineProto\Logger::log($e->getMessage());
}
}
if (isset($this->settings['pwr']['update_handler'])) $this->settings['pwr']['update_handler']($update);
if (isset($this->settings['pwr']['update_handler'])) {
$this->settings['pwr']['update_handler']($update);
}
}
public function get_updates_update_handler($update)

View File

View File

Before

Width:  |  Height:  |  Size: 215 KiB

After

Width:  |  Height:  |  Size: 215 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -10,7 +10,7 @@ See the GNU Affero General Public License for more details.
You should have received a copy of the GNU General Public License along with MadelineProto.
If not, see <http://www.gnu.org/licenses/>.
*/
chdir(dirname(__FILE__).'/../');
require_once 'vendor/autoload.php';
if (file_exists('web_data.php')) {
require_once 'web_data.php';
@ -20,7 +20,7 @@ echo 'Deserializing MadelineProto from session.madeline...'.PHP_EOL;
$MadelineProto = \danog\MadelineProto\Serialization::deserialize('session.madeline');
if (file_exists('.env')) {
$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv = new Dotenv\Dotenv(getcwd());
$dotenv->load();
}
$settings = json_decode(getenv('MTPROTO_SETTINGS'), true) ?: [];
@ -52,34 +52,34 @@ $mention = $mention['user_id']; // Selects only the numeric user id
$media = [];
// Photo uploaded as document
$inputFile = $MadelineProto->upload('faust.jpg', 'fausticorn.jpg'); // This gets an inputFile object with file name magic
$media['document_photo'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('faust.jpg'), 'caption' => 'This file was uploaded using MadelineProto', 'attributes' => [['_' => 'documentAttributeImageSize', 'w' => 1280, 'h' => 914]]];
$inputFile = $MadelineProto->upload('tests/faust.jpg', 'fausticorn.jpg'); // This gets an inputFile object with file name magic
$media['document_photo'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/faust.jpg'), 'caption' => 'This file was uploaded using MadelineProto', 'attributes' => [['_' => 'documentAttributeImageSize', 'w' => 1280, 'h' => 914]]];
// Photo
$media['photo'] = ['_' => 'inputMediaUploadedPhoto', 'file' => $inputFile, 'mime_type' => mime_content_type('faust.jpg'), 'caption' => 'This photo was uploaded using MadelineProto'];
$media['photo'] = ['_' => 'inputMediaUploadedPhoto', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/faust.jpg'), 'caption' => 'This photo was uploaded using MadelineProto'];
// GIF
$inputFile = $MadelineProto->upload('pony.mp4');
$media['gif'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('pony.mp4'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeAnimated']]];
$inputFile = $MadelineProto->upload('tests/pony.mp4');
$media['gif'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/pony.mp4'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeAnimated']]];
// Sticker
$inputFile = $MadelineProto->upload('lel.webp');
$media['sticker'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('lel.webp'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeSticker', 'alt' => 'LEL', 'stickerset' => ['_' => 'inputStickerSetEmpty']]]];
$inputFile = $MadelineProto->upload('tests/lel.webp');
$media['sticker'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/lel.webp'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeSticker', 'alt' => 'LEL', 'stickerset' => ['_' => 'inputStickerSetEmpty']]]];
// Video
$inputFile = $MadelineProto->upload('swing.mp4');
$media['video'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('swing.mp4'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeVideo', 'duration' => 5, 'w' => 1280, 'h' => 720]]];
$inputFile = $MadelineProto->upload('tests/swing.mp4');
$media['video'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/swing.mp4'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeVideo', 'duration' => 5, 'w' => 1280, 'h' => 720]]];
// audio
$inputFile = $MadelineProto->upload('mosconi.mp3');
$media['audio'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('mosconi.mp3'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => false, 'duration' => 1, 'title' => 'AH NON LO SO', 'performer' => 'IL DIO GERARDO MOSCONI']]];
$inputFile = $MadelineProto->upload('tests/mosconi.mp3');
$media['audio'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/mosconi.mp3'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => false, 'duration' => 1, 'title' => 'AH NON LO SO', 'performer' => 'IL DIO GERARDO MOSCONI']]];
// voice
$media['voice'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('mosconi.mp3'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => true, 'duration' => 1, 'title' => 'AH NON LO SO', 'performer' => 'IL DIO GERARDO MOSCONI']]];
$media['voice'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => mime_content_type('tests/mosconi.mp3'), 'caption' => 'test', 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => true, 'duration' => 1, 'title' => 'AH NON LO SO', 'performer' => 'IL DIO GERARDO MOSCONI']]];
// Document
$time = time();
$inputFile = $MadelineProto->upload('60', 'magic'); // This gets an inputFile object with file name magic
$inputFile = $MadelineProto->upload('tests/60', 'magic'); // This gets an inputFile object with file name magic
var_dump(time() - $time);
$media['document'] = ['_' => 'inputMediaUploadedDocument', 'file' => $inputFile, 'mime_type' => 'magic/magic', 'caption' => 'This file was uploaded using MadelineProto', 'attributes' => [['_' => 'documentAttributeFilename', 'file_name' => 'magic.magic']]];