sending messages!

This commit is contained in:
2026-01-07 16:43:47 +05:00
parent 3d4e1a9cd2
commit 7342cb7a0b
8 changed files with 448 additions and 3 deletions

View File

@@ -35,7 +35,8 @@
"twig/extra-bundle": "^3.7", "twig/extra-bundle": "^3.7",
"twig/intl-extra": "^3.10", "twig/intl-extra": "^3.10",
"nyholm/psr7": "^1.8", "nyholm/psr7": "^1.8",
"react/filesystem": "^0.1.2" "react/filesystem": "^0.1.2",
"react/async": "^4.3"
}, },
"suggest": { "suggest": {
"mirzaev/files": "Easy working with files", "mirzaev/files": "Easy working with files",

77
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "330a5fd85753f4fb8d74b9564bae298d", "content-hash": "f2c3677e133cdc48eb5a0ac9a778ed10",
"packages": [ "packages": [
{ {
"name": "badfarm/zanzara", "name": "badfarm/zanzara",
@@ -1695,6 +1695,81 @@
}, },
"time": "2021-05-03T11:20:27+00:00" "time": "2021-05-03T11:20:27+00:00"
}, },
{
"name": "react/async",
"version": "v4.3.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/async.git",
"reference": "635d50e30844a484495713e8cb8d9e079c0008a5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/async/zipball/635d50e30844a484495713e8cb8d9e079c0008a5",
"reference": "635d50e30844a484495713e8cb8d9e079c0008a5",
"shasum": ""
},
"require": {
"php": ">=8.1",
"react/event-loop": "^1.2",
"react/promise": "^3.2 || ^2.8 || ^1.2.1"
},
"require-dev": {
"phpstan/phpstan": "1.10.39",
"phpunit/phpunit": "^9.6"
},
"type": "library",
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"React\\Async\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Lück",
"email": "christian@clue.engineering",
"homepage": "https://clue.engineering/"
},
{
"name": "Cees-Jan Kiewiet",
"email": "reactphp@ceesjankiewiet.nl",
"homepage": "https://wyrihaximus.net/"
},
{
"name": "Jan Sorgalla",
"email": "jsorgalla@gmail.com",
"homepage": "https://sorgalla.com/"
},
{
"name": "Chris Boden",
"email": "cboden@gmail.com",
"homepage": "https://cboden.dev/"
}
],
"description": "Async utilities and fibers for ReactPHP",
"keywords": [
"async",
"reactphp"
],
"support": {
"issues": "https://github.com/reactphp/async/issues",
"source": "https://github.com/reactphp/async/tree/v4.3.0"
},
"funding": [
{
"url": "https://opencollective.com/reactphp",
"type": "open_collective"
}
],
"time": "2024-06-04T14:40:02+00:00"
},
{ {
"name": "react/cache", "name": "react/cache",
"version": "v1.2.0", "version": "v1.2.0",

View File

@@ -0,0 +1 @@
*/10 * * * * php /var/www/campanula/garden/campanula/system/public/telegram_week.php

View 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);

View 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;
}
}

View File

@@ -0,0 +1,153 @@
<?php
declare(strict_types=1);
namespace garden\campanula;
// Files of the project
use garden\campanula\models\account,
garden\campanula\models\message,
garden\campanula\models\telegram\middlewares,
garden\campanula\models\telegram\commands,
garden\campanula\models\telegram\settings;
// Library for languages support
use mirzaev\languages\language;
// Framework for PHP
use mirzaev\minimal\core,
mirzaev\minimal\route;
// Framework for Telegram
use Zanzara\Zanzara as zanzara,
Zanzara\Context as context,
Zanzara\Config as config;
// Baza database
use mirzaev\baza\database,
mirzaev\baza\column,
mirzaev\baza\record,
mirzaev\baza\enumerations\encoding,
mirzaev\baza\enumerations\type;
// The library for escaping all markdown symbols
use function mirzaev\unmarkdown;
// Framework for asynchronous PHP
use function React\Async\await;
// Built-in libraries
use pdo,
pdoexception;
// 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__);
// Initializing path to the project root directory
define('ROOT', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR);
// Initializing path to the directory of views
define('VIEWS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'views');
// Initializing path to the directory of settings
define('SETTINGS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'settings');
// Initializing system settings
require SETTINGS . DIRECTORY_SEPARATOR . 'system.php';
// Initializing path to the directory of the storage
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 chat-robot settings
require(SETTINGS . DIRECTORY_SEPARATOR . 'telegram.php');
// Initiailizing Gammu database connection data
require(SETTINGS . DIRECTORY_SEPARATOR . 'gammu.php');
// Initializing dependencies
require ROOT . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
// Initializing the gammu database connection
$gammu = new pdo(GAMMU['type'] . ':dbname=' . GAMMU['database'] . ';host=' . GAMMU['server'], GAMMU['name'], GAMMU['password']);
// Initializing the configuration
$config = new config();
$config->setParseMode(config::PARSE_MODE_MARKDOWN);
$config->useReactFileSystem(true);
// Initializing the robot
$robot = new Zanzara(ROBOT['key'], $config);
// Initializing the request
$request = $gammu->prepare('SELECT * FROM `' . GAMMU['table_inbox'] . '` WHERE `' . GAMMU['table_inbox'] . '`.`ReceivingDateTime` <= NOW() + interval 1 week ORDER BY `inbox`.`ReceivingDateTime` ASC');
// Initializing the request parameters
$parameters = [];
// Sending the request
$request->execute($parameters);
// Fetching the response
$response = (array) $request->fetchAll(pdo::FETCH_ASSOC);
foreach ($response as $message) {
// Iterating over messages from last week
// Searching for the message
$model = new message()->read(filter: fn(record $record) => $record->sended === 1 && $record->identifier_gammu === (int) $message['ID']);
if ($model instanceof message) {
// The message was sent
} else {
// The message was not send
// Initializing the message parameters
$sender = unmarkdown($message['SenderNumber']);
$date = unmarkdown($message['ReceivingDateTime']);
$text = unmarkdown($message['TextDecoded']);
// Sending the message
await($robot->getTelegram()->sendMessage(
<<<TXT
$text
**$sender**
`$date`
TXT,
[
'chat_id' => ROBOT['receiver'],
'link_preview_options' => [
'is_disabled' => true
],
'disable_notification' => false
]
)->then(function () use ($message, $sender, $date, $text) {
// Sended the message
// Initializing the model
$model = new message();
// Creating the message
$model->write(
identifier_gammu: $message['ID'],
sender: $sender,
date: $date,
text: $text,
sended: true
);
}));
sleep(1);
}
}

View File

@@ -0,0 +1,12 @@
<?php
// Robot
define('GAMMU', [
'type' => 'mysql',
'server' => 'localhost',
'database' => '',
'name' => '',
'password' => ''
'table_inbox' => 'inbox'
]);

View File

@@ -3,5 +3,6 @@
// Robot // Robot
define('ROBOT', [ define('ROBOT', [
'identifier' => null, 'identifier' => null,
'key' => '' 'key' => '',
'receivers' => '' // telegram identifier (example: '8138746766')
]); ]);