generated from mirzaev/pot-php-telegram
Compare commits
4 Commits
680a9659e3
...
1.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f7c6b6c36 | |||
| fe9e5f7256 | |||
| 7342cb7a0b | |||
| 3d4e1a9cd2 |
40
README.md
40
README.md
@@ -1,2 +1,40 @@
|
||||
# campanula
|
||||
# Campanula
|
||||
Receive and send messages through Gammu server and Telegram messenger interface
|
||||
|
||||
## Preparation
|
||||
1. **Ubuntu** linux distributive
|
||||
2. Any **SIM-modem**, for example **[SIM900](https://ali.click/xxe9vh?erid=2SDnjdoLMq2)**
|
||||
</br><sub><sup>Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158</sup></sub>
|
||||
3. **UART** → **USB** adapter
|
||||
4. **[Gammu](https://docs.gammu.org/smsd/smsd.html)** installed and configured
|
||||
|
||||
## Installation
|
||||
|
||||
### Download the repository and its dependencies
|
||||
```bash
|
||||
cd /var/www
|
||||
git clone https://git.svoboda.works/garden/campanula
|
||||
cd campanula
|
||||
composer update
|
||||
```
|
||||
|
||||
### Edit settings files
|
||||
```bash
|
||||
cd garden/campanula/system/settings
|
||||
nvim system.php
|
||||
nvim telegram.php
|
||||
nvim gammu.php
|
||||
```
|
||||
|
||||
### Test manually launch
|
||||
```bash
|
||||
cd ../public
|
||||
php telegram_week.php
|
||||
```
|
||||
*The robot will send a message only if you have already started a conversation with it*
|
||||
|
||||
### Write script launch into crontab
|
||||
```bash
|
||||
cat ../../../../examples/crontab/records.sh
|
||||
sudo crontab -e
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Robot
|
||||
define('ROBOT', [
|
||||
'identifier' => null,
|
||||
'key' => ''
|
||||
]);
|
||||
@@ -33,7 +33,10 @@
|
||||
"badfarm/zanzara": "^0.9.1",
|
||||
"twig/twig": "^3.2",
|
||||
"twig/extra-bundle": "^3.7",
|
||||
"twig/intl-extra": "^3.10"
|
||||
"twig/intl-extra": "^3.10",
|
||||
"nyholm/psr7": "^1.8",
|
||||
"react/filesystem": "^0.1.2",
|
||||
"react/async": "^4.3"
|
||||
},
|
||||
"suggest": {
|
||||
"mirzaev/files": "Easy working with files",
|
||||
@@ -52,5 +55,11 @@
|
||||
},
|
||||
"scripts": {
|
||||
"pre-update-cmd": "./install.sh"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"php-http/discovery": true,
|
||||
"wyrihaximus/composer-update-bin-autoload-path": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
5748
composer.lock
generated
Normal file
5748
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
1
examples/crontab/records.sh
Normal file
1
examples/crontab/records.sh
Normal file
@@ -0,0 +1 @@
|
||||
* * * * * /var/www/campanula/examples/crontab/week.sh
|
||||
11
examples/crontab/week.sh
Executable file
11
examples/crontab/week.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Loop 6 times (60 seconds / 10 seconds = 6 iterations)
|
||||
for i in {1..6}; do
|
||||
php /var/www/campanula/garden/campanula/system/public/telegram_week.php
|
||||
|
||||
# Wait 10 seconds before next iteration (skip sleep after the last run)
|
||||
if [ $i -lt 6 ]; then
|
||||
sleep 5
|
||||
fi
|
||||
done
|
||||
57
garden/campanula/system/databases/scripts/message.php
Normal file
57
garden/campanula/system/databases/scripts/message.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace garden\campanula;
|
||||
|
||||
// Files of the project
|
||||
use garden\campanula\models\account,
|
||||
garden\campanula\models\authorizations,
|
||||
garden\campanula\models\message;
|
||||
|
||||
// Svoboda time
|
||||
use svoboda\time\statement as svoboda;
|
||||
|
||||
// Baza database
|
||||
use mirzaev\baza\record;
|
||||
|
||||
// Enabling debugging
|
||||
/* ini_set('error_reporting', E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1); */
|
||||
|
||||
// Initializing path to the public directory
|
||||
define('INDEX', __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'public');
|
||||
|
||||
// Initializing path to the root directory
|
||||
define('ROOT', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR);
|
||||
|
||||
// Initializing path to the settings directory
|
||||
define('SETTINGS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'settings');
|
||||
|
||||
// Initializing path to the storage directory
|
||||
define('STORAGE', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'storage');
|
||||
|
||||
// Initializing path to the databases directory
|
||||
define('DATABASES', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'databases');
|
||||
|
||||
// Initializing path to the localizations directory
|
||||
define('LOCALIZATIONS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'localizations');
|
||||
|
||||
// Initiailizing telegram data
|
||||
require(SETTINGS . DIRECTORY_SEPARATOR . 'telegram.php');
|
||||
|
||||
// Initializing dependencies
|
||||
require ROOT . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
|
||||
|
||||
// Initializing the message model
|
||||
$message_model = new message();
|
||||
|
||||
// Searching for the message
|
||||
$message = $message_model->database->read(
|
||||
filter: fn(record $record) => $record->sended === 1 && $record->identifier_gammu === 21,
|
||||
amount: 3,
|
||||
offset: 0
|
||||
);
|
||||
|
||||
var_dump($message);
|
||||
@@ -7,11 +7,7 @@ namespace garden\campanula\models;
|
||||
// Files of the project
|
||||
use garden\campanula\models\core,
|
||||
garden\campanula\models\authorizations,
|
||||
garden\campanula\models\chat,
|
||||
garden\campanula\models\settings,
|
||||
garden\campanula\models\tariff,
|
||||
garden\campanula\models\code,
|
||||
garden\campanula\models\enumerations\tariff as tariff_type;
|
||||
garden\campanula\models\settings;
|
||||
|
||||
// The library for languages support
|
||||
use mirzaev\languages\language;
|
||||
@@ -84,6 +80,7 @@ final class account extends core implements record_interface
|
||||
new column('language', type::string, ['length' => 2]),
|
||||
new column('robot', type::char),
|
||||
/* new column('', type::), */
|
||||
new column('active', type::char),
|
||||
new column('updated', type::integer_unsigned),
|
||||
new column('created', type::integer_unsigned)
|
||||
)
|
||||
@@ -115,8 +112,7 @@ final class account extends core implements record_interface
|
||||
if (
|
||||
$account->domain !== (string) $telegram->getUsername() ||
|
||||
$account->name_first !== (string) $telegram->getFirstName() ||
|
||||
$account->name_second !== (string) $telegram->getLastName() ||
|
||||
$account->language !== (string) $telegram->getLanguageCode()
|
||||
$account->name_second !== (string) $telegram->getLastName()
|
||||
) {
|
||||
// The telegram account was updated
|
||||
|
||||
@@ -128,7 +124,6 @@ final class account extends core implements record_interface
|
||||
$record->domain = (string) $telegram->getUsername();
|
||||
$record->name_first = (string) $telegram->getFirstName();
|
||||
$record->name_second = (string) $telegram->getLastName();
|
||||
$record->language = (string) $telegram->getLanguageCode();
|
||||
$record->updated = svoboda::timestamp();
|
||||
},
|
||||
amount: 1
|
||||
@@ -211,7 +206,7 @@ final class account extends core implements record_interface
|
||||
$record = $this->write(
|
||||
telegram_identifier: (int) $telegram->getId(),
|
||||
name_first: (string) $telegram->getFirstName(),
|
||||
name_last: (string) $telegram->getLastName(),
|
||||
name_second: (string) $telegram->getLastName(),
|
||||
domain: (string) $telegram->getUsername(),
|
||||
language: (string) $telegram->getLanguageCode(),
|
||||
robot: (bool) $telegram->isBot()
|
||||
@@ -232,18 +227,6 @@ final class account extends core implements record_interface
|
||||
// Creating the account settings
|
||||
$settings->write(account: $record->identifier);
|
||||
|
||||
// Initializing the chat model
|
||||
$chat = new chat();
|
||||
|
||||
// Creating the account chat
|
||||
$record->chat = $chat->write(account: $record->identifier, network: NETWORK_DEFAULT);
|
||||
|
||||
// Initializing the tariff model
|
||||
$tariff = new tariff();
|
||||
|
||||
// Creating the tariff record
|
||||
$record->tariff = $tariff->write(account: $record->identifier, invoice: 0, active: 1, type: TARIFF_DEFAULT ?? tariff_type::free);
|
||||
|
||||
// Writing the record into the database
|
||||
$record = $this->database->read(
|
||||
filter: fn(record $_record) => $_record->identifier === $record->identifier,
|
||||
@@ -264,10 +247,11 @@ final class account extends core implements record_interface
|
||||
*
|
||||
* @param int $telegram_identifier The telegram account identifier
|
||||
* @param string $name_first
|
||||
* @param string $name_last
|
||||
* @param string $name_second
|
||||
* @param string $domain
|
||||
* @param language|string $language
|
||||
* @param bool $robot Is a robot?
|
||||
* @param bool $active Is the record active?
|
||||
*
|
||||
* @return record|false The record, if created
|
||||
*/
|
||||
@@ -275,9 +259,10 @@ final class account extends core implements record_interface
|
||||
int $telegram_identifier,
|
||||
string $domain = '',
|
||||
string $name_first = '',
|
||||
string $name_last = '',
|
||||
string $name_second = '',
|
||||
language|string $language = LANGUAGE_DEFAULT ?? language::en,
|
||||
bool $robot = false,
|
||||
bool $active = true,
|
||||
): record|false {
|
||||
// Initializing the record
|
||||
$record = $this->database->record(
|
||||
@@ -285,10 +270,11 @@ final class account extends core implements record_interface
|
||||
(int) $telegram_identifier,
|
||||
$domain,
|
||||
$name_first,
|
||||
$name_last,
|
||||
$name_second,
|
||||
$language instanceof language ? $language->name : (string) $language,
|
||||
(int) $robot,
|
||||
/* */
|
||||
(int) $active,
|
||||
svoboda::timestamp(),
|
||||
svoboda::timestamp()
|
||||
);
|
||||
@@ -309,6 +295,8 @@ final class account extends core implements record_interface
|
||||
{
|
||||
// Serializing the record parameters
|
||||
$this->record->language = $this->record->language->name;
|
||||
$this->record->robot = (int) $this->record->robot;
|
||||
$this->record->active = (int) $this->record->active;
|
||||
|
||||
// Exit (success)
|
||||
return $this;
|
||||
@@ -323,6 +311,8 @@ final class account extends core implements record_interface
|
||||
{
|
||||
// Deserializing the record parameters
|
||||
$this->record->language = language::{$this->record->language} ?? LANGUAGE_DEFAULT ?? language::en;
|
||||
$this->record->robot = (bool) $this->record->robot;
|
||||
$this->record->active = (bool) $this->record->active;
|
||||
|
||||
// Exit (success)
|
||||
return $this;
|
||||
@@ -374,4 +364,3 @@ final class account extends core implements record_interface
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,9 +71,9 @@ final class authorizations extends core implements record_interface
|
||||
new column('account', type::long_long_unsigned),
|
||||
new column('system', type::char),
|
||||
new column('settings', type::char),
|
||||
new column('chat', type::char),
|
||||
/* new column('', type::char), */
|
||||
new column('system_settings', type::char),
|
||||
new column('active', type::char),
|
||||
new column('updated', type::integer_unsigned),
|
||||
new column('created', type::integer_unsigned)
|
||||
)
|
||||
@@ -87,25 +87,27 @@ final class authorizations extends core implements record_interface
|
||||
* Write
|
||||
*
|
||||
* @param int $account The account identifier
|
||||
* @param int $system
|
||||
* @param int $settings
|
||||
* @param int $system_settings
|
||||
* @param bool $system
|
||||
* @param bool $settings
|
||||
* @param bool $system_settings
|
||||
* @param bool $active Is the record active?
|
||||
*
|
||||
* @return int|false The record identifier, if created
|
||||
*/
|
||||
public function write(
|
||||
int $account,
|
||||
int $system = 1,
|
||||
int $settings = 1,
|
||||
int $system_settings = 0,
|
||||
): int|false
|
||||
{
|
||||
bool $system = true,
|
||||
bool $settings = true,
|
||||
bool $system_settings = false,
|
||||
bool $active = true,
|
||||
): int|false {
|
||||
$record = $this->database->record(
|
||||
$this->database->count() + 1,
|
||||
$account,
|
||||
$system,
|
||||
$settings,
|
||||
$system_settings,
|
||||
(int) $system,
|
||||
(int) $settings,
|
||||
(int) $system_settings,
|
||||
(int) $active,
|
||||
svoboda::timestamp(),
|
||||
svoboda::timestamp()
|
||||
);
|
||||
@@ -116,5 +118,38 @@ final class authorizations extends core implements record_interface
|
||||
// Exit (success)
|
||||
return $created ? $record->identifier : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize
|
||||
*
|
||||
* @return self The instance from which the method was called (fluent interface)
|
||||
*/
|
||||
public function serialize(): self
|
||||
{
|
||||
// Serializing the record parameters
|
||||
$this->record->system = (int) $this->record->system;
|
||||
$this->record->settings = (int) $this->record->settings;
|
||||
$this->record->system_settings = (int) $this->record->system_settings;
|
||||
$this->record->active = (int) $this->record->active;
|
||||
|
||||
// Exit (success)
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize
|
||||
*
|
||||
* @return self The instance from which the method was called (fluent interface)
|
||||
*/
|
||||
public function deserialize(): self
|
||||
{
|
||||
// Deserializing the record parameters
|
||||
$this->record->system = (bool) $this->record->system;
|
||||
$this->record->settings = (bool) $this->record->settings;
|
||||
$this->record->system_settings = (bool) $this->record->system_settings;
|
||||
$this->record->active = (bool) $this->record->active;
|
||||
|
||||
// Exit (success)
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
145
garden/campanula/system/models/message.php
Normal file
145
garden/campanula/system/models/message.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace garden\campanula\models;
|
||||
|
||||
// Files of the project
|
||||
use garden\campanula\models\core;
|
||||
|
||||
// Baza database
|
||||
use mirzaev\baza\database,
|
||||
mirzaev\baza\column,
|
||||
mirzaev\baza\record,
|
||||
mirzaev\baza\enumerations\encoding,
|
||||
mirzaev\baza\enumerations\type;
|
||||
|
||||
// Active Record pattern
|
||||
use mirzaev\record\interfaces\record as record_interface,
|
||||
mirzaev\record\traits\record as record_trait;
|
||||
|
||||
// Svoboda time
|
||||
use svoboda\time\statement as svoboda;
|
||||
|
||||
// Built-in libraries
|
||||
use Exception as exception,
|
||||
RuntimeException as exception_runtime;
|
||||
|
||||
/**
|
||||
* Settings
|
||||
*
|
||||
* @package garden\campanula\models
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
final class message extends core implements record_interface
|
||||
{
|
||||
use record_trait;
|
||||
|
||||
/**
|
||||
* File
|
||||
*
|
||||
* @var string $database Path to the database file
|
||||
*/
|
||||
protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'messages.baza';
|
||||
|
||||
/**
|
||||
* Database
|
||||
*
|
||||
* @var database $database The database
|
||||
*/
|
||||
public protected(set) database $database;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @method record|null $record The record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(?record $record = null)
|
||||
{
|
||||
// Initializing the database
|
||||
$this->database = new database()
|
||||
->encoding(encoding::utf8)
|
||||
->columns(
|
||||
new column('identifier', type::long_long_unsigned),
|
||||
new column('identifier_gammu', type::long_long_unsigned),
|
||||
new column('sender', type::string, ['length' => 20]),
|
||||
new column('date', type::string, ['length' => 32]),
|
||||
new column('text', type::string, ['length' => 128]),
|
||||
new column('sended', type::char),
|
||||
new column('updated', type::integer_unsigned),
|
||||
new column('created', type::integer_unsigned)
|
||||
)
|
||||
->connect($this->file);
|
||||
|
||||
// Initializing the record
|
||||
$record instanceof record and $this->record = $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write
|
||||
*
|
||||
* @param int $identifier_gammu The gammu sms identifier
|
||||
* @param string $sender
|
||||
* @param string $date Timestamp
|
||||
* @param string $text
|
||||
* @param bool $sended Is the message was sended?
|
||||
*
|
||||
* @return int|false The record identifier, if created
|
||||
*/
|
||||
public function write(
|
||||
int $identifier_gammu,
|
||||
string $sender = '',
|
||||
string $date = '',
|
||||
string $text = '',
|
||||
bool $sended = false
|
||||
): int|false {
|
||||
$record = $this->database->record(
|
||||
$this->database->count() + 1,
|
||||
$identifier_gammu,
|
||||
$sender,
|
||||
$date,
|
||||
$text,
|
||||
(int) $sended,
|
||||
svoboda::timestamp(),
|
||||
svoboda::timestamp()
|
||||
);
|
||||
|
||||
// Writing the record into the database
|
||||
$created = $this->database->write($record);
|
||||
|
||||
// Exit (success)
|
||||
return $created ? $record->identifier : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize
|
||||
*
|
||||
* @return self The instance from which the method was called (fluent interface)
|
||||
*/
|
||||
public function serialize(): self
|
||||
{
|
||||
// Serializing the record parameters
|
||||
$this->record->sended = (int) $this->record->sended;
|
||||
|
||||
// Exit (success)
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize
|
||||
*
|
||||
* @return self The instance from which the method was called (fluent interface)
|
||||
*/
|
||||
public function deserialize(): self
|
||||
{
|
||||
// Deserializing the record parameters
|
||||
$this->record->sended = (bool) $this->record->sended;
|
||||
|
||||
// Exit (success)
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,7 @@ declare(strict_types=1);
|
||||
namespace garden\campanula\models;
|
||||
|
||||
// Files of the project
|
||||
use garden\campanula\models\core,
|
||||
garden\campanula\models\tariff,
|
||||
garden\campanula\models\enumerations\tariff as tariff_type,
|
||||
garden\campanula\models\enumerations\acquiring as acquiring;
|
||||
use garden\campanula\models\core;
|
||||
|
||||
// Baza database
|
||||
use mirzaev\baza\database,
|
||||
@@ -70,6 +67,7 @@ final class settings extends core implements record_interface
|
||||
new column('identifier', type::long_long_unsigned),
|
||||
new column('account', type::long_long_unsigned),
|
||||
/* new column('', type::), */
|
||||
new column('active', type::char),
|
||||
new column('updated', type::integer_unsigned),
|
||||
new column('created', type::integer_unsigned)
|
||||
)
|
||||
@@ -82,16 +80,19 @@ final class settings extends core implements record_interface
|
||||
/**
|
||||
* Write
|
||||
*
|
||||
* @param int $account The account identifier (0 for disable)
|
||||
* @param int $account The account identifier
|
||||
* @param int $active Is the record active?
|
||||
*
|
||||
* @return int|false The record identifier, if created
|
||||
*/
|
||||
public function write(
|
||||
int $account = 0,
|
||||
int $account,
|
||||
bool $active = true,
|
||||
): int|false {
|
||||
$record = $this->database->record(
|
||||
$this->database->count() + 1,
|
||||
$account,
|
||||
(int) $active,
|
||||
svoboda::timestamp(),
|
||||
svoboda::timestamp()
|
||||
);
|
||||
@@ -102,5 +103,32 @@ final class settings extends core implements record_interface
|
||||
// Exit (success)
|
||||
return $created ? $record->identifier : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize
|
||||
*
|
||||
* @return self The instance from which the method was called (fluent interface)
|
||||
*/
|
||||
public function serialize(): self
|
||||
{
|
||||
// Serializing the record parameters
|
||||
$this->record->active = (int) $this->record->active;
|
||||
|
||||
// Exit (success)
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize
|
||||
*
|
||||
* @return self The instance from which the method was called (fluent interface)
|
||||
*/
|
||||
public function deserialize(): self
|
||||
{
|
||||
// Deserializing the record parameters
|
||||
$this->record->active = (bool) $this->record->active;
|
||||
|
||||
// Exit (success)
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ namespace garden\campanula\models\telegram;
|
||||
use garden\campanula\models\core,
|
||||
garden\campanula\models\account,
|
||||
garden\campanula\models\settings,
|
||||
garden\campanula\models\telegram\settings as telegram_settings,
|
||||
garden\campanula\models\telegram\processes\language\select as process_language_select;
|
||||
|
||||
// Library for languages support
|
||||
@@ -78,46 +77,10 @@ final class commands extends core
|
||||
// Initializing the title
|
||||
$title = '📋 *' . $localization['menu_title'] . '*';
|
||||
|
||||
// Initializing accounts
|
||||
/* $accounts_message = '*' . $localization['menu_accounts'] . ':* ' . ((new account)->database->count() ?? 0); */
|
||||
|
||||
// Initializing the account tariff
|
||||
$tariff = $account->tariff();
|
||||
|
||||
// Declaring the tariff button
|
||||
$tariff_button = [];
|
||||
|
||||
if ($tariff instanceof tariff) {
|
||||
// Initialized the account tariff
|
||||
|
||||
// Initializing the tariff button
|
||||
$tariff_button = [
|
||||
'text' => '🔐 ' . $tariff->type->label($language) . ' (' . $tariff->used . '/' . $tariff->tokens . ')',
|
||||
'callback_data' => 'tariffs'
|
||||
];
|
||||
} else {
|
||||
|
||||
// Initialized the account tariff
|
||||
|
||||
// Initializing the tariff button
|
||||
$tariff_button = [
|
||||
'text' => '⚠️ ' . $localization['menu_tariff_empty'],
|
||||
'callback_data' => 'tariffs'
|
||||
];
|
||||
}
|
||||
|
||||
// Initializing the account chat
|
||||
$chat = $account->chat();
|
||||
|
||||
// Initializing the chto text
|
||||
$howto = $localization['menu_howto'];
|
||||
|
||||
// Sending the message
|
||||
$context->sendMessage(
|
||||
<<<TXT
|
||||
$title
|
||||
|
||||
$howto
|
||||
TXT,
|
||||
[
|
||||
'reply_markup' => [
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user