1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 10:38:59 +01:00
MadelineProto/examples/downloadRenameBot.php

213 lines
7.8 KiB
PHP
Raw Normal View History

2019-12-28 20:28:47 +01:00
#!/usr/bin/env php
<?php
/**
* Example bot.
*
2020-02-17 14:13:46 +01:00
* Copyright 2016-2020 Daniil Gentili
2019-12-28 20:28:47 +01:00
* (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/>.
*
* @author Daniil Gentili <daniil@daniil.it>
2023-01-04 12:43:01 +01:00
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
2019-12-28 20:28:47 +01:00
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
* @link https://docs.madelineproto.xyz MadelineProto documentation
*/
2022-12-30 21:54:44 +01:00
use danog\MadelineProto\EventHandler;
use danog\MadelineProto\FileCallback;
use danog\MadelineProto\Logger;
2019-12-31 12:45:49 +01:00
use danog\MadelineProto\RPCErrorException;
2021-12-09 13:25:14 +01:00
use danog\MadelineProto\Settings;
2019-12-29 16:30:15 +01:00
use League\Uri\Contracts\UriException;
2019-12-28 20:28:47 +01:00
/*
* Various ways to load MadelineProto
*/
2022-12-08 20:16:40 +01:00
if (file_exists('vendor/autoload.php')) {
2019-12-28 20:28:47 +01:00
include 'vendor/autoload.php';
} else {
2022-12-08 20:16:40 +01:00
if (!file_exists('madeline.php')) {
copy('https://phar.madelineproto.xyz/madeline.php', 'madeline.php');
2019-12-28 20:28:47 +01:00
}
include 'madeline.php';
}
/**
* Event handler class.
*/
2022-12-30 21:54:44 +01:00
class MyEventHandler extends EventHandler
2019-12-28 20:28:47 +01:00
{
const START = "Send me a file URL and I will download it and send it to you!\n\n".
"Usage: `https://example.com`\n".
"Usage: `https://example.com file name.ext`\n\n".
"I can also rename Telegram files, just send me any file and I will rename it!\n\n".
"Max 1.5GB, parallel upload and download powered by @MadelineProto.";
/**
* @var int|string Username or ID of bot admin
*/
const ADMIN = 'danogentili'; // Change this
/**
* Get peer(s) where to report errors.
*
* @return int|string|array
*/
public function getReportPeers()
{
return [self::ADMIN];
}
2019-12-28 20:28:47 +01:00
2020-02-09 16:24:57 +01:00
/**
* Whether to allow uploads.
*/
private $UPLOAD;
2019-12-28 20:28:47 +01:00
/**
* Array of media objects.
*
* @var array
*/
private $states = [];
2023-07-08 21:42:18 +02:00
public function onStart(): void
2020-04-29 14:43:43 +02:00
{
2023-07-08 17:46:45 +02:00
$this->adminId = $this->getInfo(self::ADMIN)['bot_api_id'];
2020-04-29 14:43:43 +02:00
}
/**
* Handle updates from channels and supergroups.
*
* @param array $update Update
*/
2023-07-08 21:42:18 +02:00
public function onUpdateNewChannelMessage(array $update): void
2019-12-28 20:28:47 +01:00
{
2023-07-08 17:46:45 +02:00
//$this->onUpdateNewMessage($update);
2019-12-28 20:28:47 +01:00
}
/**
* Handle updates from users.
*
* @param array $update Update
*/
2023-07-08 17:46:45 +02:00
public function onUpdateNewMessage(array $update)
2019-12-28 20:28:47 +01:00
{
if ($update['message']['out'] ?? false) {
return;
}
if ($update['message']['_'] !== 'message') {
return;
}
try {
2023-07-08 17:46:45 +02:00
$peer = $this->getInfo($update);
2019-12-28 20:28:47 +01:00
$peerId = $peer['bot_api_id'];
$messageId = $update['message']['id'];
if ($update['message']['message'] === '/start') {
2019-12-30 18:27:28 +01:00
return $this->messages->sendMessage(['peer' => $peerId, 'message' => self::START, 'parse_mode' => 'Markdown', 'reply_to_msg_id' => $messageId]);
2019-12-28 20:28:47 +01:00
}
2020-04-29 14:43:43 +02:00
if ($update['message']['message'] === '/report' && $peerId === $this->adminId) {
2023-07-08 17:46:45 +02:00
$this->reportMemoryProfile();
2020-04-29 14:43:43 +02:00
return;
}
2019-12-29 02:41:06 +01:00
if (isset($update['message']['media']['_']) && $update['message']['media']['_'] !== 'messageMediaWebPage') {
2023-07-08 17:46:45 +02:00
$this->messages->sendMessage(['peer' => $peerId, 'message' => 'Give me a new name for this file: ', 'reply_to_msg_id' => $messageId]);
2019-12-30 18:27:28 +01:00
$this->states[$peerId] = $update['message']['media'];
2019-12-28 20:28:47 +01:00
return;
}
if (isset($this->states[$peerId])) {
$name = $update['message']['message'];
2019-12-30 18:27:28 +01:00
$url = $this->states[$peerId];
2019-12-28 20:28:47 +01:00
unset($this->states[$peerId]);
} else {
2022-12-08 20:16:40 +01:00
$url = explode(' ', $update['message']['message'], 2);
$name = trim($url[1] ?? basename($update['message']['message']));
$url = trim($url[0]);
2019-12-28 20:28:47 +01:00
if (!$url) {
return;
}
2022-12-08 20:16:40 +01:00
if (stripos($url, 'http') !== 0) {
2019-12-28 20:28:47 +01:00
$url = "http://$url";
}
}
2023-07-08 17:46:45 +02:00
$id = $this->messages->sendMessage(['peer' => $peerId, 'message' => 'Preparing...', 'reply_to_msg_id' => $messageId]);
2019-12-30 18:27:28 +01:00
if (!isset($id['id'])) {
2022-12-08 20:16:40 +01:00
$this->report(json_encode($id));
2019-12-30 18:27:28 +01:00
foreach ($id['updates'] as $updat) {
if (isset($updat['id'])) {
$id = $updat['id'];
break;
}
}
} else {
$id = $id['id'];
}
2022-12-30 21:54:44 +01:00
$url = new FileCallback(
2019-12-28 21:07:50 +01:00
$url,
2023-07-08 21:42:18 +02:00
function ($progress, $speed, $time) use ($peerId, $id): void {
2019-12-29 15:20:46 +01:00
$this->logger("Upload progress: $progress%");
2019-12-30 18:27:28 +01:00
static $prev = 0;
2022-12-08 20:16:40 +01:00
$now = time();
2019-12-30 18:27:28 +01:00
if ($now - $prev < 10 && $progress < 100) {
2019-12-28 21:07:50 +01:00
return;
}
2019-12-30 18:27:28 +01:00
$prev = $now;
2019-12-28 21:07:50 +01:00
try {
2023-07-08 17:46:45 +02:00
$this->messages->editMessage(['peer' => $peerId, 'id' => $id, 'message' => "Upload progress: $progress%\nSpeed: $speed mbps\nTime elapsed since start: $time"], ['FloodWaitLimit' => 0]);
2022-12-30 21:54:44 +01:00
} catch (RPCErrorException $e) {
2019-12-28 21:07:50 +01:00
}
2022-12-30 21:54:44 +01:00
},
2019-12-29 14:21:25 +01:00
);
2023-07-08 17:46:45 +02:00
$this->messages->sendMedia(
peer: $peerId,
reply_to_msg_id: $messageId,
media: [
'_' => 'inputMediaUploadedDocument',
'file' => $url,
'attributes' => [
['_' => 'documentAttributeFilename', 'file_name' => $name],
2019-12-28 20:28:47 +01:00
],
2022-12-30 21:54:44 +01:00
],
2023-07-08 17:46:45 +02:00
message: 'Powered by @MadelineProto!',
parse_mode: 'Markdown',
2019-12-28 20:28:47 +01:00
);
2022-12-08 20:16:40 +01:00
if (in_array($peer['type'], ['channel', 'supergroup'])) {
2023-07-08 17:46:45 +02:00
$this->channels->deleteMessages(['channel' => $peerId, 'id' => [$id]]);
2019-12-28 20:28:47 +01:00
} else {
2023-07-08 17:46:45 +02:00
$this->messages->deleteMessages(['revoke' => true, 'id' => [$id]]);
2019-12-28 20:28:47 +01:00
}
2022-12-30 21:54:44 +01:00
} catch (Throwable $e) {
2022-12-08 20:16:40 +01:00
if (strpos($e->getMessage(), 'Could not connect to URI') === false && !($e instanceof UriException) && strpos($e->getMessage(), 'URI') === false) {
2019-12-28 20:28:47 +01:00
$this->report((string) $e);
2022-12-30 21:54:44 +01:00
$this->logger((string) $e, Logger::FATAL_ERROR);
2019-12-28 20:28:47 +01:00
}
2019-12-31 12:45:49 +01:00
if ($e instanceof RPCErrorException && $e->rpc === 'FILE_PARTS_INVALID') {
2022-12-08 20:16:40 +01:00
$this->report(json_encode($url));
2019-12-31 12:45:49 +01:00
}
2019-12-28 20:28:47 +01:00
try {
2023-07-08 17:46:45 +02:00
$this->messages->editMessage(['peer' => $peerId, 'id' => $id, 'message' => 'Error: '.$e->getMessage()]);
2022-12-30 21:54:44 +01:00
} catch (Throwable $e) {
$this->logger((string) $e, Logger::FATAL_ERROR);
2019-12-28 20:28:47 +01:00
}
}
}
}
2021-12-09 13:25:14 +01:00
$settings = new Settings;
$settings->getConnection()
->setMaxMediaSocketCount(1000);
// IMPORTANT: for security reasons, upload by URL will still be allowed
$settings->getFiles()->setAllowAutomaticUpload(true);
// Reduce boilerplate with new wrapper method.
// Also initializes error reporting, catching and reporting all errors surfacing from the event loop.
2021-12-09 13:25:14 +01:00
MyEventHandler::startAndLoop(($argv[1] ?? 'bot').'.madeline', $settings);