Completed
Push — master ( ea0713...bd13d1 )
by Vitor
15s
created

SendMessage::execute()   A

Complexity

Conditions 5
Paths 22

Size

Total Lines 40
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 26
c 1
b 0
f 0
dl 0
loc 40
ccs 0
cts 26
cp 0
rs 9.1928
cc 5
nc 22
nop 2
crap 30
1
#!/usr/bin/env php
2
<?php
3
4
declare(strict_types=1);
5
6
/**
7
 * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
8
 * SPDX-License-Identifier: AGPL-3.0-or-later
9
 */
10
11
use danog\MadelineProto\API;
12
use danog\MadelineProto\RPCErrorException;
13
use danog\MadelineProto\Settings;
14
use danog\MadelineProto\Settings\Logger;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Logger. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
15
use Symfony\Component\Console\Attribute\AsCommand;
16
use Symfony\Component\Console\Command\Command;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputOption;
19
use Symfony\Component\Console\Output\OutputInterface;
20
21
#[AsCommand(name: 'telegram:send-message', description: 'Send a message via Telegram Client API')]
22
class SendMessage extends Command {
23
24
	protected function configure(): void {
25
		$this
26
			->addOption(
27
				'session-directory',
28
				's',
29
				InputOption::VALUE_REQUIRED,
30
				'Directory to store the session files',
31
			)
32
			->addOption(
33
				'to',
34
				't',
35
				InputOption::VALUE_REQUIRED,
36
				'Recipient (username or user ID)',
37
			)
38
			->addOption(
39
				'message',
40
				'm',
41
				InputOption::VALUE_REQUIRED,
42
				'Message to send',
43
			);
44
	}
45
46
	protected function execute(InputInterface $input, OutputInterface $output): int {
47
		$sessionDirectory = $input->getOption('session-directory');
48
49
		try {
50
			$settings = (new Settings())
51
				->setLogger((new Logger())->setExtra($sessionDirectory . '/MadelineProto.log'));
52
53
			$message = $input->getOption('message');
54
			$peer = $input->getOption('to');
55
56
			$api = new API($sessionDirectory, $settings);
57
58
			$api->start();
59
60
			if (!str_starts_with($peer, '@')) {
61
				try {
62
					$result = $api->contacts->resolvePhone(phone: $peer);
63
					$peer = $result['peer'];
64
				} catch (RPCErrorException $e) {
65
					if ($e->getMessage() === 'PHONE_NOT_OCCUPIED') {
66
						$output->writeln('<error>Error: The phone number is not associated with any Telegram account.</error>');
67
						return Command::FAILURE;
68
					}
69
					throw $e;
70
				}
71
72
			}
73
74
			$api->messages->sendMessage([
75
				'peer' => $peer,
76
				'message' => $message,
77
				'parse_mode' => 'Markdown',
78
			]);
79
80
			$output->writeln('<info>Message sent successfully!</info>');
81
82
			return Command::SUCCESS;
83
		} catch (\Throwable $e) {
84
			$output->writeln('<error>Error: ' . $e->getMessage() . '</error>');
85
			return Command::FAILURE;
86
		}
87
	}
88
}
89