diff --git a/.env.example b/.env.example
index be3e47d42..e07d8a7b9 100644
--- a/.env.example
+++ b/.env.example
@@ -33,3 +33,6 @@ TWITTER_ACCESS_SECRET=
FLARE_KEY=
MIX_FLARE_KEY="${FLARE_KEY}"
+
+TELEGRAM_BOT_TOKEN=
+TELEGRAM_CHANNEL=
diff --git a/app/Events/ArticleWasSubmittedForApproval.php b/app/Events/ArticleWasSubmittedForApproval.php
new file mode 100644
index 000000000..901096650
--- /dev/null
+++ b/app/Events/ArticleWasSubmittedForApproval.php
@@ -0,0 +1,18 @@
+article = $article;
+ }
+}
diff --git a/app/Jobs/CreateArticle.php b/app/Jobs/CreateArticle.php
index d05c030ee..235169ee8 100644
--- a/app/Jobs/CreateArticle.php
+++ b/app/Jobs/CreateArticle.php
@@ -2,6 +2,7 @@
namespace App\Jobs;
+use App\Events\ArticleWasSubmittedForApproval;
use App\Http\Requests\ArticleRequest;
use App\Models\Article;
use App\Models\User;
@@ -56,6 +57,10 @@ public function handle(): Article
$article->authoredBy($this->author);
$article->syncTags($this->tags);
+ if ($article->isAwaitingApproval()) {
+ event(new ArticleWasSubmittedForApproval($article));
+ }
+
return $article;
}
}
diff --git a/app/Jobs/UpdateArticle.php b/app/Jobs/UpdateArticle.php
index d1612df39..462e26cea 100644
--- a/app/Jobs/UpdateArticle.php
+++ b/app/Jobs/UpdateArticle.php
@@ -2,6 +2,7 @@
namespace App\Jobs;
+use App\Events\ArticleWasSubmittedForApproval;
use App\Http\Requests\ArticleRequest;
use App\Models\Article;
@@ -50,9 +51,15 @@ public function handle(): Article
'body' => $this->body,
'original_url' => $this->originalUrl,
'slug' => $this->title,
- 'submitted_at' => $this->shouldUpdateSubmittedAt() ? now() : $this->article->submittedAt(),
]);
+ if ($this->shouldUpdateSubmittedAt()) {
+ $this->article->submitted_at = now();
+ $this->article->save();
+
+ event(new ArticleWasSubmittedForApproval($this->article));
+ }
+
$this->article->syncTags($this->tags);
return $this->article;
diff --git a/app/Listeners/SendNewArticleNotification.php b/app/Listeners/SendNewArticleNotification.php
new file mode 100644
index 000000000..b41365245
--- /dev/null
+++ b/app/Listeners/SendNewArticleNotification.php
@@ -0,0 +1,20 @@
+notifiable->notify(new ArticleSubmitted($event->article));
+ }
+}
diff --git a/app/Notifications/ArticleSubmitted.php b/app/Notifications/ArticleSubmitted.php
new file mode 100644
index 000000000..89b4235fa
--- /dev/null
+++ b/app/Notifications/ArticleSubmitted.php
@@ -0,0 +1,45 @@
+article = $article;
+ }
+
+ public function via($notifiable)
+ {
+ return ['telegram'];
+ }
+
+ public function toTelegram($notifiable)
+ {
+ $url = route('articles.show', $this->article->slug());
+
+ return TelegramMessage::create()
+ ->to(config('services.telegram-bot-api.channel'))
+ ->content($this->content())
+ ->button('View Article', $url);
+ }
+
+ private function content(): string
+ {
+ $content = "*New Article Submitted!*\n\n";
+ $content .= 'Title: '.$this->article->title()."\n";
+ $content .= 'By: [@'.$this->article->author()->username().']('.route('profile', $this->article->author()->username()).')';
+
+ return $content;
+ }
+}
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index a0a24aaff..28d79a29c 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -3,9 +3,11 @@
namespace App\Providers;
use App\Events\ArticleWasApproved;
+use App\Events\ArticleWasSubmittedForApproval;
use App\Events\ReplyWasCreated;
use App\Listeners\MarkLastActivity;
use App\Listeners\SendArticleApprovedNotification;
+use App\Listeners\SendNewArticleNotification;
use App\Listeners\SendNewReplyNotification;
use App\Listeners\StoreTweetIdentifier;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@@ -23,6 +25,9 @@ class EventServiceProvider extends ServiceProvider
MarkLastActivity::class,
SendNewReplyNotification::class,
],
+ ArticleWasSubmittedForApproval::class => [
+ SendNewArticleNotification::class,
+ ],
ArticleWasApproved::class => [
SendArticleApprovedNotification::class,
],
diff --git a/composer.json b/composer.json
index 0bd83e9c6..012a7b270 100644
--- a/composer.json
+++ b/composer.json
@@ -17,6 +17,7 @@
"guzzlehttp/guzzle": "^7.0.1",
"intervention/image": "^2.5",
"intervention/imagecache": "^2.5",
+ "laravel-notification-channels/telegram": "^0.9.0",
"laravel-notification-channels/twitter": "^5.0",
"laravel/framework": "8.66.0",
"laravel/horizon": "^5.2",
diff --git a/composer.lock b/composer.lock
index 2a88c038e..497ea03ac 100644
--- a/composer.lock
+++ b/composer.lock
@@ -2384,6 +2384,72 @@
},
"time": "2017-11-25T19:51:26+00:00"
},
+ {
+ "name": "laravel-notification-channels/telegram",
+ "version": "0.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel-notification-channels/telegram.git",
+ "reference": "a941130a555908dc16b119b4f8c99b5f3605bf25"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel-notification-channels/telegram/zipball/a941130a555908dc16b119b4f8c99b5f3605bf25",
+ "reference": "a941130a555908dc16b119b4f8c99b5f3605bf25",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "guzzlehttp/guzzle": "^6.2 || ^7.0",
+ "illuminate/contracts": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "illuminate/notifications": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0",
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.3",
+ "phpunit/phpunit": "^7.0 || ^8.5.21 || ^9.0"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "NotificationChannels\\Telegram\\TelegramServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "NotificationChannels\\Telegram\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Irfaq Syed",
+ "email": "syed@lukonet.com",
+ "homepage": "https://lukonet.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "Telegram Notifications Channel for Laravel",
+ "homepage": "https://github.com/laravel-notification-channels/telegram",
+ "keywords": [
+ "laravel",
+ "notification",
+ "telegram",
+ "telegram notification",
+ "telegram notifications channel"
+ ],
+ "support": {
+ "issues": "https://github.com/laravel-notification-channels/telegram/issues",
+ "source": "https://github.com/laravel-notification-channels/telegram/tree/0.9.0"
+ },
+ "time": "2021-11-24T12:19:23+00:00"
+ },
{
"name": "laravel-notification-channels/twitter",
"version": "v5.1.0",
diff --git a/config/services.php b/config/services.php
index a59a428cb..586e80d8b 100644
--- a/config/services.php
+++ b/config/services.php
@@ -51,4 +51,9 @@
'access_secret' => env('TWITTER_ACCESS_SECRET'),
],
+ 'telegram-bot-api' => [
+ 'token' => env('TELEGRAM_BOT_TOKEN'),
+ 'channel' => env('TELEGRAM_CHANNEL'),
+ ],
+
];
diff --git a/phpunit.xml b/phpunit.xml
index 476245d85..daabbf7bd 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -25,5 +25,7 @@
+
+
diff --git a/tests/Feature/ArticleTest.php b/tests/Feature/ArticleTest.php
index e61dee483..c85b06bdd 100644
--- a/tests/Feature/ArticleTest.php
+++ b/tests/Feature/ArticleTest.php
@@ -1,9 +1,11 @@
see('Awaiting approval');
});
+test('articles submitted for approval send telegram notification', function () {
+ Event::fake();
+ $this->login();
+
+ $this->post('/articles', [
+ 'title' => 'Using database migrations',
+ 'body' => 'This article will go into depth on working with database migrations.',
+ 'submitted' => '1',
+ ]);
+
+ Event::assertDispatched(ArticleWasSubmittedForApproval::class);
+});
+
test('users can create a draft article', function () {
$this->login();
@@ -71,6 +86,19 @@
->see('Draft');
});
+test('draft articles do not send telegram notification', function () {
+ Event::fake();
+ $this->login();
+
+ $this->post('/articles', [
+ 'title' => 'Using database migrations',
+ 'body' => 'This article will go into depth on working with database migrations.',
+ 'submitted' => '0',
+ ]);
+
+ Event::assertNotDispatched(ArticleWasSubmittedForApproval::class);
+});
+
test('users cannot create an article with a title that is too long', function () {
$this->login();
@@ -132,6 +160,28 @@
->assertSessionHas('success', 'Article successfully updated!');
});
+test('editing a draft article does not send telegram notification', function () {
+ Event::fake();
+ $user = $this->createUser();
+ $tag = Tag::factory()->create(['name' => 'Test Tag']);
+
+ Article::factory()->create([
+ 'author_id' => $user->id(),
+ 'slug' => 'my-first-article',
+ ]);
+
+ $this->loginAs($user);
+
+ $this->put('/articles/my-first-article', [
+ 'title' => 'Using database migrations',
+ 'body' => 'This article will go into depth on working with database migrations.',
+ 'tags' => [$tag->id()],
+ 'submitted' => '0',
+ ]);
+
+ Event::assertNotDispatched(ArticleWasSubmittedForApproval::class);
+});
+
test('user gets submitted message when submitting existing article for approval', function () {
$user = $this->createUser();
@@ -173,6 +223,27 @@
->dontSee('Draft');
});
+test('notification is sent to telegram when existing article is submitted for approval', function () {
+ Event::fake();
+ $user = $this->createUser();
+
+ Article::factory()->create([
+ 'author_id' => $user->id(),
+ 'slug' => 'my-first-article',
+ ]);
+
+ $this->loginAs($user);
+
+ $this->put('/articles/my-first-article', [
+ 'title' => 'Using database migrations',
+ 'body' => 'This article will go into depth on working with database migrations.',
+ 'tags' => [],
+ 'submitted' => '1',
+ ]);
+
+ Event::assertDispatched(ArticleWasSubmittedForApproval::class);
+});
+
test('users cannot edit an article with a title that is too long', function () {
$user = $this->createUser();
Article::factory()->create([