Added database to keep track of videos already uploaded, so that only new videos send out notifications
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
This commit is contained in:
parent
803ad25cda
commit
c4afe6f08e
4
.gitignore
vendored
4
.gitignore
vendored
@ -6,3 +6,7 @@ config/config.yaml
|
|||||||
|
|
||||||
# PHP_Codesniffer cache
|
# PHP_Codesniffer cache
|
||||||
.phpcs-cache
|
.phpcs-cache
|
||||||
|
|
||||||
|
# database file
|
||||||
|
data/pigeon.db
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@
|
|||||||
"symfony/yaml": "^6.0",
|
"symfony/yaml": "^6.0",
|
||||||
"hassankhan/config": "^3.0",
|
"hassankhan/config": "^3.0",
|
||||||
"madcoda/php-youtube-api": "^1.2",
|
"madcoda/php-youtube-api": "^1.2",
|
||||||
"team-reflex/discord-php": "^7.0"
|
"team-reflex/discord-php": "^7.0",
|
||||||
|
"robmorgan/phinx": "^0.12.10",
|
||||||
|
"illuminate/database": "^9.3"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"squizlabs/php_codesniffer": "^3.6",
|
"squizlabs/php_codesniffer": "^3.6",
|
||||||
@ -22,5 +24,10 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"phpcs": "phpcs --standard=./phpcs.xml",
|
"phpcs": "phpcs --standard=./phpcs.xml",
|
||||||
"phpmd": "phpmd src/ text phpmd.xml"
|
"phpmd": "phpmd src/ text phpmd.xml"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Pigeon\\": "src"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1985
composer.lock
generated
1985
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,7 @@
|
|||||||
|
pigeon:
|
||||||
|
check_interval: 10
|
||||||
|
db_path: "data/pigeon.db"
|
||||||
|
|
||||||
youtube:
|
youtube:
|
||||||
api_key: "supersecretyoutubeapiky"
|
api_key: "supersecretyoutubeapiky"
|
||||||
channel_id: "mychannelid"
|
channel_id: "mychannelid"
|
||||||
|
0
data/.gitkeep
Normal file
0
data/.gitkeep
Normal file
29
db/migrations/20220308141532_add_videos_table.php
Normal file
29
db/migrations/20220308141532_add_videos_table.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class AddVideosTable extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
// create the table
|
||||||
|
$table = $this->table('videos');
|
||||||
|
$table->addColumn('video_id', 'string')
|
||||||
|
->addColumn('published_at', 'datetime')
|
||||||
|
->addTimestamps()
|
||||||
|
->addIndex(['video_id'], ['unique' => true])
|
||||||
|
->create();
|
||||||
|
}
|
||||||
|
}
|
28
phinx.php
Normal file
28
phinx.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return
|
||||||
|
[
|
||||||
|
'paths' => [
|
||||||
|
'migrations' => '%%PHINX_CONFIG_DIR%%/db/migrations',
|
||||||
|
'seeds' => '%%PHINX_CONFIG_DIR%%/db/seeds'
|
||||||
|
],
|
||||||
|
'environments' => [
|
||||||
|
'default_migration_table' => 'phinxlog',
|
||||||
|
'default_environment' => 'development',
|
||||||
|
'production' => [
|
||||||
|
'adapter' => 'sqlite',
|
||||||
|
'name' => './data/pigeon',
|
||||||
|
'suffix' => 'db',
|
||||||
|
],
|
||||||
|
'development' => [
|
||||||
|
'adapter' => 'sqlite',
|
||||||
|
'name' => './data/pigeon',
|
||||||
|
'suffix' => 'db',
|
||||||
|
],
|
||||||
|
'testing' => [
|
||||||
|
'adapter' => 'sqlite',
|
||||||
|
'memory' => true,
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'version_order' => 'creation'
|
||||||
|
];
|
10
src/Models/Video.php
Normal file
10
src/Models/Video.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pigeon\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Video extends Model {
|
||||||
|
// define SQL attributes that can be modified
|
||||||
|
protected $fillable = ['video_id', 'published_at'];
|
||||||
|
}
|
@ -5,12 +5,24 @@ include __DIR__ . '/../vendor/autoload.php';
|
|||||||
use Discord\Discord;
|
use Discord\Discord;
|
||||||
use Discord\Parts\Channel\Message;
|
use Discord\Parts\Channel\Message;
|
||||||
use Discord\WebSockets\Intents;
|
use Discord\WebSockets\Intents;
|
||||||
|
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||||
use Madcoda\Youtube\Youtube;
|
use Madcoda\Youtube\Youtube;
|
||||||
use Noodlehaus\Config;
|
use Noodlehaus\Config;
|
||||||
|
|
||||||
|
use Pigeon\Models\Video;
|
||||||
|
|
||||||
// load config file
|
// load config file
|
||||||
$config = new Config('config/config.yaml');
|
$config = new Config('config/config.yaml');
|
||||||
|
|
||||||
|
// create Eloquent connection object
|
||||||
|
$capsule = new Capsule;
|
||||||
|
$capsule->addConnection([
|
||||||
|
'driver' => 'sqlite',
|
||||||
|
'database' => $config->get('pigeon.db_path'),
|
||||||
|
]);
|
||||||
|
$capsule->setAsGlobal();
|
||||||
|
$capsule->bootEloquent();
|
||||||
|
|
||||||
// create YouTube API object
|
// create YouTube API object
|
||||||
$youtube = new Youtube(array('key' => $config->get('youtube.api_key')));
|
$youtube = new Youtube(array('key' => $config->get('youtube.api_key')));
|
||||||
// get channel
|
// get channel
|
||||||
@ -19,6 +31,21 @@ $yt_res = $youtube->getChannelById($config->get('youtube.channel_id'));
|
|||||||
$config->set('youtube.channel_name', $yt_res->snippet->title);
|
$config->set('youtube.channel_name', $yt_res->snippet->title);
|
||||||
$config->set('youtube.uploads_id', $yt_res->contentDetails->relatedPlaylists->uploads);
|
$config->set('youtube.uploads_id', $yt_res->contentDetails->relatedPlaylists->uploads);
|
||||||
|
|
||||||
|
// get the channel's uploads so we can seed the DB
|
||||||
|
$uploads = $youtube->getPlaylistItemsByPlaylistId($config->get('youtube.uploads_id'));
|
||||||
|
|
||||||
|
// create Video model objects with the above uploads
|
||||||
|
foreach ($uploads as $u) {
|
||||||
|
$video = new Video;
|
||||||
|
$video->video_id = $u->contentDetails->videoId;
|
||||||
|
$video->published_at = date($u->contentDetails->videoPublishedAt);
|
||||||
|
|
||||||
|
// create the table entry if it doesn't already exist
|
||||||
|
Video::where('video_id', $video->video_id)->firstOr(function() use ($video) {
|
||||||
|
$video->save();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// create our event loop
|
// create our event loop
|
||||||
$loop = React\EventLoop\Factory::create();
|
$loop = React\EventLoop\Factory::create();
|
||||||
|
|
||||||
@ -32,21 +59,31 @@ $discord = new Discord([
|
|||||||
// periodic youtube uploads check
|
// periodic youtube uploads check
|
||||||
$loop->addPeriodicTimer($config->get('pigeon.check_interval') * 60, function () use ($config, $discord, $youtube) {
|
$loop->addPeriodicTimer($config->get('pigeon.check_interval') * 60, function () use ($config, $discord, $youtube) {
|
||||||
// get latest video from uploads playlist
|
// get latest video from uploads playlist
|
||||||
$uploads = $youtube->getPlaylistItemsByPlaylistId($config->get('youtube.uploads_id'));
|
$uploads = $youtube->getPlaylistItemsByPlaylistId($config->get('youtube.uploads_id'), 1);
|
||||||
$latest_video_id = $uploads[0]->contentDetails->videoId;
|
$uploadDetails = $uploads[0]->contentDetails;
|
||||||
$latest_url = "https://youtu.be/$latest_video_id";
|
|
||||||
|
|
||||||
$message_text = str_replace('{link}', $latest_url, $config->get('discord.message_template'));
|
// search for the latest video in the DB
|
||||||
|
Video::where('video_id', $uploadDetails->videoId)->firstOr(function() use ($discord, $config, $uploadDetails) {
|
||||||
|
$latest_url = "https://youtu.be/$uploadDetails->videoId";
|
||||||
|
|
||||||
$discord->guilds->first()->channels->find(function ($channel) use ($config) {
|
$message_text = str_replace('{link}', $latest_url, $config->get('discord.message_template'));
|
||||||
return $channel->name === $config->get('discord.announcement_channel');
|
|
||||||
})->sendMessage($message_text)->done(function ($message) use ($discord) {
|
$discord->guilds->first()->channels->find(function ($channel) use ($config) {
|
||||||
echo 'Message sent!', PHP_EOL;
|
return $channel->name === $config->get('discord.announcement_channel');
|
||||||
|
})->sendMessage($message_text)->done(function ($message) use ($discord) {
|
||||||
|
echo 'Message sent!', PHP_EOL;
|
||||||
|
});
|
||||||
|
|
||||||
|
// add the video to the DB
|
||||||
|
$video = new Video;
|
||||||
|
$video->video_id = $uploadDetails->videoId;
|
||||||
|
$video->published_at = date($uploadDetails->videoPublishedAt);
|
||||||
|
$video->save();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// run tasks when Discord is ready
|
// run tasks when Discord is ready
|
||||||
$discord->on('ready', function (Discord $discord) use ($conf, $latest_url) {
|
$discord->on('ready', function (Discord $discord) {
|
||||||
echo "Bot is ready!", PHP_EOL;
|
echo "Bot is ready!", PHP_EOL;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user