ghost
11 months ago
6 changed files with 301 additions and 0 deletions
@ -1,2 +1,32 @@ |
|||||||
# twister-rss-bot-php |
# twister-rss-bot-php |
||||||
|
|
||||||
RSS Bot for Twister P2P |
RSS Bot for Twister P2P |
||||||
|
|
||||||
|
## Requirements |
||||||
|
|
||||||
|
* `php-8.2` |
||||||
|
* `php-curl` |
||||||
|
* `php-mbstring` |
||||||
|
* `php-pdo` |
||||||
|
* `php-sqlite3` |
||||||
|
|
||||||
|
## Install |
||||||
|
|
||||||
|
### Production |
||||||
|
|
||||||
|
* `composer create-project twisterarmy/twister-rss-bot` |
||||||
|
|
||||||
|
### Development |
||||||
|
|
||||||
|
* `git clone https://github.com/twisterarmy/twister-rss-bot-php.git` |
||||||
|
* `cd twister-rss-bot-php` |
||||||
|
* `composer install` |
||||||
|
|
||||||
|
## Config |
||||||
|
|
||||||
|
* `cp config.example.json config.json` |
||||||
|
* `nano config.json` add twister connection and RSS feeds |
||||||
|
|
||||||
|
## Usage |
||||||
|
|
||||||
|
* `@hourly php src/cli/bot.php` |
@ -0,0 +1,14 @@ |
|||||||
|
{ |
||||||
|
"name": "twisterarmy/twister-rss-bot", |
||||||
|
"description": "RSS Bot for Twister P2P", |
||||||
|
"type": "project", |
||||||
|
"license": "MIT", |
||||||
|
"autoload": { |
||||||
|
"psr-4": { |
||||||
|
"Twisterarmy\\TwisterRssBot\\": "src/" |
||||||
|
} |
||||||
|
}, |
||||||
|
"require": { |
||||||
|
"twisterarmy/twister": "^1.0" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
{ |
||||||
|
"_readme": [ |
||||||
|
"This file locks the dependencies of your project to a known state", |
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", |
||||||
|
"This file is @generated automatically" |
||||||
|
], |
||||||
|
"content-hash": "70fb72082709cc5f798645656e8c4865", |
||||||
|
"packages": [ |
||||||
|
{ |
||||||
|
"name": "twisterarmy/twister", |
||||||
|
"version": "1.0.0", |
||||||
|
"source": { |
||||||
|
"type": "git", |
||||||
|
"url": "https://github.com/twisterarmy/twister-php.git", |
||||||
|
"reference": "5761f1b90b25caf58fef7a1274b91af9c25a1831" |
||||||
|
}, |
||||||
|
"dist": { |
||||||
|
"type": "zip", |
||||||
|
"url": "https://api.github.com/repos/twisterarmy/twister-php/zipball/5761f1b90b25caf58fef7a1274b91af9c25a1831", |
||||||
|
"reference": "5761f1b90b25caf58fef7a1274b91af9c25a1831", |
||||||
|
"shasum": "" |
||||||
|
}, |
||||||
|
"type": "library", |
||||||
|
"autoload": { |
||||||
|
"psr-4": { |
||||||
|
"Twisterarmy\\Twister\\": "src/" |
||||||
|
} |
||||||
|
}, |
||||||
|
"notification-url": "https://packagist.org/downloads/", |
||||||
|
"license": [ |
||||||
|
"MIT" |
||||||
|
], |
||||||
|
"description": "PHP 8 / Composer Tools for Twister API", |
||||||
|
"support": { |
||||||
|
"issues": "https://github.com/twisterarmy/twister-php/issues", |
||||||
|
"source": "https://github.com/twisterarmy/twister-php/tree/1.0.0" |
||||||
|
}, |
||||||
|
"time": "2023-12-21T03:22:50+00:00" |
||||||
|
} |
||||||
|
], |
||||||
|
"packages-dev": [], |
||||||
|
"aliases": [], |
||||||
|
"minimum-stability": "stable", |
||||||
|
"stability-flags": [], |
||||||
|
"prefer-stable": false, |
||||||
|
"prefer-lowest": false, |
||||||
|
"platform": [], |
||||||
|
"platform-dev": [], |
||||||
|
"plugin-api-version": "2.3.0" |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
{ |
||||||
|
"twister": |
||||||
|
{ |
||||||
|
"protocol":"http", |
||||||
|
"host":"localhost", |
||||||
|
"port":28332, |
||||||
|
"username":"user", |
||||||
|
"password":"pwd" |
||||||
|
}, |
||||||
|
"sqlite": |
||||||
|
{ |
||||||
|
"database":"database.sqlite", |
||||||
|
"username":null, |
||||||
|
"password":null |
||||||
|
}, |
||||||
|
"feed": |
||||||
|
[ |
||||||
|
{ |
||||||
|
"source":"https://...", |
||||||
|
"target":"user1", |
||||||
|
"queue": |
||||||
|
{ |
||||||
|
"limit":5 |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"source":"https://...", |
||||||
|
"target":"user2", |
||||||
|
"queue": |
||||||
|
{ |
||||||
|
"limit":5 |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,169 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
// Load dependencies |
||||||
|
require __DIR__ . '/../../vendor/autoload.php'; |
||||||
|
|
||||||
|
// Load config |
||||||
|
$config = json_decode( |
||||||
|
file_get_contents( |
||||||
|
__DIR__ . '/../../config.json' |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
// Connect twister |
||||||
|
try |
||||||
|
{ |
||||||
|
$twister = new \Twisterarmy\Twister\Client( |
||||||
|
$config->twister->protocol, |
||||||
|
$config->twister->host, |
||||||
|
$config->twister->port, |
||||||
|
$config->twister->username, |
||||||
|
$config->twister->password |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
catch (Exception $e) |
||||||
|
{ |
||||||
|
var_dump( |
||||||
|
$e->getMessage() |
||||||
|
); |
||||||
|
|
||||||
|
exit; |
||||||
|
} |
||||||
|
|
||||||
|
// Connect DB |
||||||
|
try |
||||||
|
{ |
||||||
|
$database = new PDO( |
||||||
|
sprintf( |
||||||
|
'sqlite:%s', |
||||||
|
sprintf( |
||||||
|
'%s/../../storage/%s', |
||||||
|
__DIR__, |
||||||
|
$config->sqlite->database |
||||||
|
) |
||||||
|
), |
||||||
|
$config->sqlite->username, |
||||||
|
$config->sqlite->password |
||||||
|
); |
||||||
|
|
||||||
|
$database->setAttribute( |
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE, |
||||||
|
PDO::FETCH_OBJ |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
catch (Exception $e) |
||||||
|
{ |
||||||
|
var_dump( |
||||||
|
$e->getMessage() |
||||||
|
); |
||||||
|
|
||||||
|
exit; |
||||||
|
} |
||||||
|
|
||||||
|
// Collect feeds data |
||||||
|
foreach ($config->feed as $feed) |
||||||
|
{ |
||||||
|
// Create account database if not exists |
||||||
|
$database->query( |
||||||
|
sprintf( |
||||||
|
'CREATE TABLE IF NOT EXISTS "%s" |
||||||
|
( |
||||||
|
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id" >= 0), |
||||||
|
"hash" CHAR(32) NOT NULL, |
||||||
|
"message" VARCHAR(256) NOT NULL, |
||||||
|
"time" INTEGER NOT NULL, |
||||||
|
"sent" INTEGER NULL, |
||||||
|
CONSTRAINT "UNIQUE" |
||||||
|
UNIQUE("hash") |
||||||
|
)', |
||||||
|
$feed->target |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
// Save feed to the database pool |
||||||
|
foreach ((array) \Twisterarmy\Twister\Tools\Rss::feed($feed->source) as $data) |
||||||
|
{ |
||||||
|
// Generate record hash |
||||||
|
$hash = md5( |
||||||
|
$data['message'] |
||||||
|
); |
||||||
|
|
||||||
|
// Check record not exist |
||||||
|
$query = $database->prepare( |
||||||
|
sprintf( |
||||||
|
'SELECT COUNT(*) AS `total` FROM %s WHERE `hash` = ?', |
||||||
|
$feed->target |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
$query->execute( |
||||||
|
[ |
||||||
|
$hash |
||||||
|
] |
||||||
|
); |
||||||
|
|
||||||
|
if ($query->fetch()->total) |
||||||
|
{ |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
// Add new record |
||||||
|
$query = $database->prepare( |
||||||
|
sprintf( |
||||||
|
'INSERT INTO %s (`hash`, `message`, `time`) VALUES (?, ?, ?)', |
||||||
|
$feed->target |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
$query->execute( |
||||||
|
[ |
||||||
|
$hash, |
||||||
|
$data['message'], |
||||||
|
$data['time'], |
||||||
|
] |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// Process messages queue by time ASC |
||||||
|
$query = $database->query( |
||||||
|
sprintf( |
||||||
|
'SELECT `id`, `message` FROM %s WHERE `sent` IS NULL ORDER BY `time` ASC LIMIT %s', |
||||||
|
$feed->target, |
||||||
|
$feed->queue->limit, |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
// Send each message to the twister account |
||||||
|
foreach ($query->fetchAll() as $queue) |
||||||
|
{ |
||||||
|
$errors = []; |
||||||
|
|
||||||
|
$twister->newPostMessage( |
||||||
|
$feed->target, |
||||||
|
time(), //int $k, |
||||||
|
$queue->message, |
||||||
|
$errors |
||||||
|
); |
||||||
|
|
||||||
|
if ($errors) |
||||||
|
{ |
||||||
|
var_dump( |
||||||
|
$errors |
||||||
|
); |
||||||
|
|
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
// Update time sent on success |
||||||
|
$database->query( |
||||||
|
sprintf( |
||||||
|
'UPDATE %s SET `sent` = %s WHERE `id` = %s LIMIT 1', |
||||||
|
$feed->target, |
||||||
|
time(), |
||||||
|
$queue->id |
||||||
|
) |
||||||
|
); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue