diff --git a/.env.example b/.env.example
index 7a44f3e42..838583efe 100644
--- a/.env.example
+++ b/.env.example
@@ -55,3 +55,8 @@ SCOUT_DRIVER=meilisearch
SCOUT_QUEUE=true
MEILISEARCH_HOST=
MEILISEARCH_KEY=
+
+# Notification channels
+TELEGRAM_BOT_TOKEN=
+TELEGRAM_BOT_URL=
+TELEGRAM_BOT_WEBHOOK_URL=
diff --git a/.env.testing b/.env.testing
new file mode 100644
index 000000000..fe5d0ee9d
--- /dev/null
+++ b/.env.testing
@@ -0,0 +1,27 @@
+APP_NAME=Monica
+APP_ENV=local
+APP_KEY=base64:G7wjzcmJ8lVlpDtY1LRYxQvCt7HeKXhkiUc2314OeUQ=
+APP_DEBUG=true
+APP_URL=https://ross.test
+
+LOG_CHANNEL=daily
+LOG_DEPRECATIONS_CHANNEL=null
+LOG_LEVEL=debug
+
+# Used for SQLite testing
+DB_TEST_DRIVER=sqlite
+DB_TEST_DATABASE=public/css/sqlite_test
+DB_TEST_HOST=127.0.0.1
+DB_TEST_USERNAME=root
+DB_TEST_PASSWORD=root
+
+BROADCAST_DRIVER=log
+CACHE_DRIVER=file
+FILESYSTEM_DRIVER=local
+QUEUE_CONNECTION=database
+SESSION_DRIVER=file
+SESSION_LIFETIME=120
+
+TELEGRAM_BOT_TOKEN=123
+TELEGRAM_BOT_URL=https://t.me/randombot
+TELEGRAM_BOT_WEBHOOK_URL=123
diff --git a/app/Console/Commands/TestReminders.php b/app/Console/Commands/TestReminders.php
index 5fb35b83a..829fc615b 100644
--- a/app/Console/Commands/TestReminders.php
+++ b/app/Console/Commands/TestReminders.php
@@ -3,11 +3,15 @@
namespace App\Console\Commands;
use App\Contact\ManageReminders\Services\RescheduleContactReminderForChannel;
-use App\Jobs\Notifications\SendEmailNotification;
+use App\Helpers\NameHelper;
+use App\Models\ContactReminder;
use App\Models\UserNotificationChannel;
+use App\Notifications\ReminderTriggered;
use Illuminate\Console\Command;
+use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Notification;
class TestReminders extends Command
{
@@ -43,18 +47,25 @@ class TestReminders extends Command
foreach ($scheduledContactReminders as $scheduledReminder) {
$channel = UserNotificationChannel::findOrFail($scheduledReminder->user_notification_channel_id);
- if ($channel->type == UserNotificationChannel::TYPE_EMAIL) {
- SendEmailNotification::dispatch(
- $scheduledReminder->user_notification_channel_id,
- $scheduledReminder->contact_reminder_id
- )->onQueue('low');
+ if ($channel->type == UserNotificationChannel::TYPE_EMAIL && $channel->active) {
+ $contactReminder = ContactReminder::findOrFail($scheduledReminder->contact_reminder_id);
+
+ $contact = $contactReminder->contact;
+ $contactName = NameHelper::formatContactName($channel->user, $contact);
+
+ Notification::route('mail', $channel->content)
+ ->notify(new ReminderTriggered($channel, $contactReminder->label, $contactName));
}
- (new RescheduleContactReminderForChannel())->execute([
- 'contact_reminder_id' => $scheduledReminder->contact_reminder_id,
- 'user_notification_channel_id' => $scheduledReminder->user_notification_channel_id,
- 'contact_reminder_scheduled_id' => $scheduledReminder->id,
- ]);
+ try {
+ (new RescheduleContactReminderForChannel())->execute([
+ 'contact_reminder_id' => $scheduledReminder->contact_reminder_id,
+ 'user_notification_channel_id' => $scheduledReminder->user_notification_channel_id,
+ 'contact_reminder_scheduled_id' => $scheduledReminder->id,
+ ]);
+ } catch (ModelNotFoundException) {
+ continue;
+ }
}
}
}
diff --git a/app/Helpers/NameHelper.php b/app/Helpers/NameHelper.php
index 1db0ae578..4b52da241 100644
--- a/app/Helpers/NameHelper.php
+++ b/app/Helpers/NameHelper.php
@@ -2,6 +2,7 @@
namespace App\Helpers;
+use Illuminate\Support\Str;
use App\Models\Contact;
use App\Models\User;
@@ -48,6 +49,12 @@ class NameHelper
}
}
+ // in some cases, the user will add parenthesis to add, for instance,
+ // the nickname, but if the nickname is not set, we need to remove them
+ // from being displayed
+ $completeName = str_replace('()', '', $completeName);
+ $completeName = Str::of($completeName)->rtrim();
+
return $completeName;
}
}
diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php
index 0c13b8548..4fd16238f 100644
--- a/app/Http/Middleware/VerifyCsrfToken.php
+++ b/app/Http/Middleware/VerifyCsrfToken.php
@@ -12,6 +12,6 @@ class VerifyCsrfToken extends Middleware
* @var array
*/
protected $except = [
- //
+ '/telegram/webhook/*',
];
}
diff --git a/app/Jobs/Notifications/SendEmailNotification.php b/app/Jobs/Notifications/SendEmailNotification.php
deleted file mode 100644
index 0a0a4ff47..000000000
--- a/app/Jobs/Notifications/SendEmailNotification.php
+++ /dev/null
@@ -1,62 +0,0 @@
-userNotificationChannel = UserNotificationChannel::findOrFail($userNotificationChannelId);
- $this->contactReminder = ContactReminder::findOrFail($contactReminderId);
- }
-
- /**
- * Execute the job.
- *
- * @return void
- */
- public function handle()
- {
- $emailAddress = $this->userNotificationChannel->content;
- $user = $this->userNotificationChannel->user;
-
- Mail::to($emailAddress)
- ->queue(
- (new SendReminder($this->contactReminder, $user))
- ->onQueue('low')
- );
-
- UserNotificationSent::create([
- 'user_notification_channel_id' => $this->userNotificationChannel->id,
- 'sent_at' => Carbon::now(),
- 'subject_line' => $this->contactReminder->label,
- ]);
- }
-}
diff --git a/app/Mail/SendReminder.php b/app/Mail/SendReminder.php
deleted file mode 100644
index f845d9bd4..000000000
--- a/app/Mail/SendReminder.php
+++ /dev/null
@@ -1,50 +0,0 @@
-contactReminder = $contactReminder;
- $this->user = $user;
- }
-
- /**
- * Build the message.
- *
- * @return $this
- */
- public function build()
- {
- $contact = $this->contactReminder->contact;
- $contactName = NameHelper::formatContactName($this->user, $contact);
-
- $reason = $this->contactReminder->label;
-
- return $this->subject(trans('email.notification_reminder_email', ['name' => $contactName]))
- ->markdown('emails.notifications.reminder', [
- 'name' => $this->user->name,
- 'reason' => $reason,
- 'contactName' => $contactName,
- ]);
- }
-}
diff --git a/app/Mail/UserNotificationChannelEmailCreated.php b/app/Mail/UserNotificationChannelEmailCreated.php
index c1132c1e6..bee0cdd5b 100644
--- a/app/Mail/UserNotificationChannelEmailCreated.php
+++ b/app/Mail/UserNotificationChannelEmailCreated.php
@@ -33,7 +33,10 @@ class UserNotificationChannelEmailCreated extends Mailable
{
return $this->subject('Please validate your email address')
->markdown('emails.notifications.validate-email', [
- 'url' => $this->channel->email_verification_link,
+ 'url' => route('settings.notifications.verification.store', [
+ 'notification' => $this->channel->id,
+ 'uuid' => $this->channel->verification_token,
+ ]),
]);
}
}
diff --git a/app/Models/UserNotificationChannel.php b/app/Models/UserNotificationChannel.php
index 43162df4d..cdcb320d7 100644
--- a/app/Models/UserNotificationChannel.php
+++ b/app/Models/UserNotificationChannel.php
@@ -18,6 +18,7 @@ class UserNotificationChannel extends Model
* Possible type.
*/
public const TYPE_EMAIL = 'email';
+ public const TYPE_TELEGRAM = 'telegram';
/**
* The attributes that are mass assignable.
@@ -32,7 +33,7 @@ class UserNotificationChannel extends Model
'active',
'verified_at',
'preferred_time',
- 'email_verification_link',
+ 'verification_token',
];
/**
diff --git a/app/Notifications/ReminderTriggered.php b/app/Notifications/ReminderTriggered.php
new file mode 100644
index 000000000..bfe7713d5
--- /dev/null
+++ b/app/Notifications/ReminderTriggered.php
@@ -0,0 +1,92 @@
+content = $content;
+ $this->contactName = $contactName;
+ $this->channel = $channel;
+ }
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ * @return array
+ */
+ public function via($notifiable)
+ {
+ return ['mail', 'telegram'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ UserNotificationSent::create([
+ 'user_notification_channel_id' => $this->channel->id,
+ 'sent_at' => Carbon::now(),
+ 'subject_line' => $this->content,
+ ]);
+
+ return (new MailMessage())
+ ->subject(trans('email.notification_reminder_email', ['name' => $this->contactName]))
+ ->line(trans('email.reminder_triggered_intro'))
+ ->line($this->content)
+ ->line(trans('email.reminder_triggered_for'))
+ ->line($this->contactName)
+ ->line(trans('email.reminder_triggered_signature'));
+ }
+
+ public function toTelegram($notifiable)
+ {
+ UserNotificationSent::create([
+ 'user_notification_channel_id' => $this->channel->id,
+ 'sent_at' => Carbon::now(),
+ 'subject_line' => $this->content,
+ ]);
+
+ return TelegramMessage::create()
+ ->to($this->channel->content)
+ ->content($this->content);
+ }
+
+ /**
+ * Get the array representation of the notification.
+ *
+ * @param mixed $notifiable
+ * @return array
+ */
+ public function toArray($notifiable)
+ {
+ return [
+ //
+ ];
+ }
+}
diff --git a/composer.json b/composer.json
index ad8ca44cc..f89b1cb0f 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"http-interop/http-factory-guzzle": "^1.2",
"inertiajs/inertia-laravel": "^0.6.2",
"itsgoingd/clockwork": "^5.1",
- "laravel-notification-channels/telegram": "^2.0",
+ "laravel-notification-channels/telegram": "^2.1",
"laravel/framework": "^9.0",
"laravel/sanctum": "^2.6",
"laravel/scout": "^9.4",
diff --git a/composer.lock b/composer.lock
index 023e01b6c..0967566b5 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "efc65da104294a065a51d76bff968d03",
+ "content-hash": "7b49550f8e7a6f67670354298f2dfbfb",
"packages": [
{
"name": "asm89/stack-cors",
@@ -1154,16 +1154,16 @@
},
{
"name": "inertiajs/inertia-laravel",
- "version": "v0.6.2",
+ "version": "v0.6.3",
"source": {
"type": "git",
"url": "https://github.com/inertiajs/inertia-laravel.git",
- "reference": "75859fb1586c3d37ed8705500b5f43e87eee3cb2"
+ "reference": "540b953ec383364264f9bd633849db16560a4461"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/inertiajs/inertia-laravel/zipball/75859fb1586c3d37ed8705500b5f43e87eee3cb2",
- "reference": "75859fb1586c3d37ed8705500b5f43e87eee3cb2",
+ "url": "https://api.github.com/repos/inertiajs/inertia-laravel/zipball/540b953ec383364264f9bd633849db16560a4461",
+ "reference": "540b953ec383364264f9bd633849db16560a4461",
"shasum": ""
},
"require": {
@@ -1211,7 +1211,7 @@
],
"support": {
"issues": "https://github.com/inertiajs/inertia-laravel/issues",
- "source": "https://github.com/inertiajs/inertia-laravel/tree/v0.6.2"
+ "source": "https://github.com/inertiajs/inertia-laravel/tree/v0.6.3"
},
"funding": [
{
@@ -1219,7 +1219,7 @@
"type": "github"
}
],
- "time": "2022-05-25T02:00:06+00:00"
+ "time": "2022-06-27T23:21:15+00:00"
},
{
"name": "itsgoingd/clockwork",
@@ -1291,16 +1291,16 @@
},
{
"name": "laravel-notification-channels/telegram",
- "version": "2.0.0",
+ "version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/laravel-notification-channels/telegram.git",
- "reference": "63f6727c3f9953e11ee9a690c29ce0db456d69a1"
+ "reference": "76299fa06f48cb175e17ea951ccf3b185329a1ac"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel-notification-channels/telegram/zipball/63f6727c3f9953e11ee9a690c29ce0db456d69a1",
- "reference": "63f6727c3f9953e11ee9a690c29ce0db456d69a1",
+ "url": "https://api.github.com/repos/laravel-notification-channels/telegram/zipball/76299fa06f48cb175e17ea951ccf3b185329a1ac",
+ "reference": "76299fa06f48cb175e17ea951ccf3b185329a1ac",
"shasum": ""
},
"require": {
@@ -1351,22 +1351,22 @@
],
"support": {
"issues": "https://github.com/laravel-notification-channels/telegram/issues",
- "source": "https://github.com/laravel-notification-channels/telegram/tree/2.0.0"
+ "source": "https://github.com/laravel-notification-channels/telegram/tree/2.1.0"
},
- "time": "2022-02-10T19:29:50+00:00"
+ "time": "2022-07-01T02:14:31+00:00"
},
{
"name": "laravel/framework",
- "version": "v9.18.0",
+ "version": "v9.19.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "93a1296bca43c1ca8dcb5df8f97107e819a71499"
+ "reference": "bbce25bd823133f6a5a724f2d62680b711f1d0df"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/93a1296bca43c1ca8dcb5df8f97107e819a71499",
- "reference": "93a1296bca43c1ca8dcb5df8f97107e819a71499",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/bbce25bd823133f6a5a724f2d62680b711f1d0df",
+ "reference": "bbce25bd823133f6a5a724f2d62680b711f1d0df",
"shasum": ""
},
"require": {
@@ -1532,7 +1532,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
- "time": "2022-06-21T14:40:11+00:00"
+ "time": "2022-06-28T14:33:19+00:00"
},
{
"name": "laravel/sanctum",
@@ -1988,16 +1988,16 @@
},
{
"name": "league/flysystem",
- "version": "3.0.21",
+ "version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
- "reference": "8f1fcf9d2304ff77a006aa36dd2cb5f236999b12"
+ "reference": "34a68067b7ae3b836ea5e57e1fc432478372a4f5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8f1fcf9d2304ff77a006aa36dd2cb5f236999b12",
- "reference": "8f1fcf9d2304ff77a006aa36dd2cb5f236999b12",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/34a68067b7ae3b836ea5e57e1fc432478372a4f5",
+ "reference": "34a68067b7ae3b836ea5e57e1fc432478372a4f5",
"shasum": ""
},
"require": {
@@ -2058,7 +2058,7 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
- "source": "https://github.com/thephpleague/flysystem/tree/3.0.21"
+ "source": "https://github.com/thephpleague/flysystem/tree/3.1.0"
},
"funding": [
{
@@ -2074,7 +2074,7 @@
"type": "tidelift"
}
],
- "time": "2022-06-12T17:54:28+00:00"
+ "time": "2022-06-29T17:29:54+00:00"
},
{
"name": "league/mime-type-detection",
@@ -2305,16 +2305,16 @@
},
{
"name": "nesbot/carbon",
- "version": "2.58.0",
+ "version": "2.59.1",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
- "reference": "97a34af22bde8d0ac20ab34b29d7bfe360902055"
+ "reference": "a9000603ea337c8df16cc41f8b6be95a65f4d0f5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/97a34af22bde8d0ac20ab34b29d7bfe360902055",
- "reference": "97a34af22bde8d0ac20ab34b29d7bfe360902055",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/a9000603ea337c8df16cc41f8b6be95a65f4d0f5",
+ "reference": "a9000603ea337c8df16cc41f8b6be95a65f4d0f5",
"shasum": ""
},
"require": {
@@ -2329,11 +2329,12 @@
"doctrine/orm": "^2.7",
"friendsofphp/php-cs-fixer": "^3.0",
"kylekatarnls/multi-tester": "^2.0",
+ "ondrejmirtes/better-reflection": "*",
"phpmd/phpmd": "^2.9",
"phpstan/extension-installer": "^1.0",
- "phpstan/phpstan": "^0.12.54 || ^1.0",
- "phpunit/php-file-iterator": "^2.0.5",
- "phpunit/phpunit": "^7.5.20 || ^8.5.23",
+ "phpstan/phpstan": "^0.12.99 || ^1.7.14",
+ "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20",
"squizlabs/php_codesniffer": "^3.4"
},
"bin": [
@@ -2390,15 +2391,19 @@
},
"funding": [
{
- "url": "https://opencollective.com/Carbon",
- "type": "open_collective"
+ "url": "https://github.com/sponsors/kylekatarnls",
+ "type": "github"
},
{
- "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
+ "url": "https://opencollective.com/Carbon#sponsor",
+ "type": "opencollective"
+ },
+ {
+ "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme",
"type": "tidelift"
}
],
- "time": "2022-04-25T19:31:17+00:00"
+ "time": "2022-06-29T21:43:55+00:00"
},
{
"name": "nette/schema",
@@ -2680,16 +2685,16 @@
},
{
"name": "php-http/discovery",
- "version": "1.14.2",
+ "version": "1.14.3",
"source": {
"type": "git",
"url": "https://github.com/php-http/discovery.git",
- "reference": "c8d48852fbc052454af42f6de27635ddd916b959"
+ "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-http/discovery/zipball/c8d48852fbc052454af42f6de27635ddd916b959",
- "reference": "c8d48852fbc052454af42f6de27635ddd916b959",
+ "url": "https://api.github.com/repos/php-http/discovery/zipball/31d8ee46d0215108df16a8527c7438e96a4d7735",
+ "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735",
"shasum": ""
},
"require": {
@@ -2741,9 +2746,9 @@
],
"support": {
"issues": "https://github.com/php-http/discovery/issues",
- "source": "https://github.com/php-http/discovery/tree/1.14.2"
+ "source": "https://github.com/php-http/discovery/tree/1.14.3"
},
- "time": "2022-05-25T07:26:05+00:00"
+ "time": "2022-07-11T14:04:40+00:00"
},
{
"name": "php-http/httplug",
@@ -3429,16 +3434,16 @@
},
{
"name": "psy/psysh",
- "version": "v0.11.5",
+ "version": "v0.11.7",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
- "reference": "c23686f9c48ca202710dbb967df8385a952a2daf"
+ "reference": "77fc7270031fbc28f9a7bea31385da5c4855cb7a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/bobthecow/psysh/zipball/c23686f9c48ca202710dbb967df8385a952a2daf",
- "reference": "c23686f9c48ca202710dbb967df8385a952a2daf",
+ "url": "https://api.github.com/repos/bobthecow/psysh/zipball/77fc7270031fbc28f9a7bea31385da5c4855cb7a",
+ "reference": "77fc7270031fbc28f9a7bea31385da5c4855cb7a",
"shasum": ""
},
"require": {
@@ -3499,9 +3504,9 @@
],
"support": {
"issues": "https://github.com/bobthecow/psysh/issues",
- "source": "https://github.com/bobthecow/psysh/tree/v0.11.5"
+ "source": "https://github.com/bobthecow/psysh/tree/v0.11.7"
},
- "time": "2022-05-27T18:03:49+00:00"
+ "time": "2022-07-07T13:49:11+00:00"
},
{
"name": "ralouphie/getallheaders",
@@ -3722,16 +3727,16 @@
},
{
"name": "symfony/console",
- "version": "v6.1.1",
+ "version": "v6.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "6187424023fbffcd757789aeb517c9161b1eabee"
+ "reference": "7a86c1c42fbcb69b59768504c7bca1d3767760b7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/6187424023fbffcd757789aeb517c9161b1eabee",
- "reference": "6187424023fbffcd757789aeb517c9161b1eabee",
+ "url": "https://api.github.com/repos/symfony/console/zipball/7a86c1c42fbcb69b59768504c7bca1d3767760b7",
+ "reference": "7a86c1c42fbcb69b59768504c7bca1d3767760b7",
"shasum": ""
},
"require": {
@@ -3798,7 +3803,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v6.1.1"
+ "source": "https://github.com/symfony/console/tree/v6.1.2"
},
"funding": [
{
@@ -3814,7 +3819,7 @@
"type": "tidelift"
}
],
- "time": "2022-06-08T14:02:09+00:00"
+ "time": "2022-06-26T13:01:30+00:00"
},
{
"name": "symfony/css-selector",
@@ -3883,7 +3888,7 @@
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.1.0",
+ "version": "v3.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
@@ -3930,7 +3935,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.0"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1"
},
"funding": [
{
@@ -4104,7 +4109,7 @@
},
{
"name": "symfony/event-dispatcher-contracts",
- "version": "v3.1.0",
+ "version": "v3.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
@@ -4163,7 +4168,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.0"
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.1"
},
"funding": [
{
@@ -4247,16 +4252,16 @@
},
{
"name": "symfony/http-foundation",
- "version": "v6.1.1",
+ "version": "v6.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "a58dc88d56e04e57993d96c1407a17407610e1df"
+ "reference": "86119d294e51afe4d8e07da96b63332bd1f3f52c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a58dc88d56e04e57993d96c1407a17407610e1df",
- "reference": "a58dc88d56e04e57993d96c1407a17407610e1df",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/86119d294e51afe4d8e07da96b63332bd1f3f52c",
+ "reference": "86119d294e51afe4d8e07da96b63332bd1f3f52c",
"shasum": ""
},
"require": {
@@ -4299,7 +4304,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-foundation/tree/v6.1.1"
+ "source": "https://github.com/symfony/http-foundation/tree/v6.1.2"
},
"funding": [
{
@@ -4315,20 +4320,20 @@
"type": "tidelift"
}
],
- "time": "2022-05-31T14:28:03+00:00"
+ "time": "2022-06-19T13:21:48+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v6.1.1",
+ "version": "v6.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "86c4d6f6c5b6cd012df41e3b950c924b3ffdc019"
+ "reference": "8aaede489900dda61aee208557f63bfa1bca0877"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/86c4d6f6c5b6cd012df41e3b950c924b3ffdc019",
- "reference": "86c4d6f6c5b6cd012df41e3b950c924b3ffdc019",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8aaede489900dda61aee208557f63bfa1bca0877",
+ "reference": "8aaede489900dda61aee208557f63bfa1bca0877",
"shasum": ""
},
"require": {
@@ -4409,7 +4414,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-kernel/tree/v6.1.1"
+ "source": "https://github.com/symfony/http-kernel/tree/v6.1.2"
},
"funding": [
{
@@ -4425,20 +4430,20 @@
"type": "tidelift"
}
],
- "time": "2022-06-09T17:31:33+00:00"
+ "time": "2022-06-26T17:06:14+00:00"
},
{
"name": "symfony/mailer",
- "version": "v6.1.1",
+ "version": "v6.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
- "reference": "db6a19a5c896139901c2de59fc9849379e0ff3b6"
+ "reference": "8fa150355115ea09238858ae3cfaf249fd1fd5ed"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mailer/zipball/db6a19a5c896139901c2de59fc9849379e0ff3b6",
- "reference": "db6a19a5c896139901c2de59fc9849379e0ff3b6",
+ "url": "https://api.github.com/repos/symfony/mailer/zipball/8fa150355115ea09238858ae3cfaf249fd1fd5ed",
+ "reference": "8fa150355115ea09238858ae3cfaf249fd1fd5ed",
"shasum": ""
},
"require": {
@@ -4483,7 +4488,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/mailer/tree/v6.1.1"
+ "source": "https://github.com/symfony/mailer/tree/v6.1.2"
},
"funding": [
{
@@ -4499,7 +4504,7 @@
"type": "tidelift"
}
],
- "time": "2022-06-06T19:15:01+00:00"
+ "time": "2022-06-19T13:21:48+00:00"
},
{
"name": "symfony/mime",
@@ -5455,16 +5460,16 @@
},
{
"name": "symfony/service-contracts",
- "version": "v3.1.0",
+ "version": "v3.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "d66cd8ab656780f62c4215b903a420eb86358957"
+ "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d66cd8ab656780f62c4215b903a420eb86358957",
- "reference": "d66cd8ab656780f62c4215b903a420eb86358957",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/925e713fe8fcacf6bc05e936edd8dd5441a21239",
+ "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239",
"shasum": ""
},
"require": {
@@ -5520,7 +5525,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.1.0"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.1.1"
},
"funding": [
{
@@ -5536,20 +5541,20 @@
"type": "tidelift"
}
],
- "time": "2022-05-07T08:07:09+00:00"
+ "time": "2022-05-30T19:18:58+00:00"
},
{
"name": "symfony/string",
- "version": "v6.1.0",
+ "version": "v6.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "d3edc75baf9f1d4f94879764dda2e1ac33499529"
+ "reference": "1903f2879875280c5af944625e8246d81c2f0604"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/d3edc75baf9f1d4f94879764dda2e1ac33499529",
- "reference": "d3edc75baf9f1d4f94879764dda2e1ac33499529",
+ "url": "https://api.github.com/repos/symfony/string/zipball/1903f2879875280c5af944625e8246d81c2f0604",
+ "reference": "1903f2879875280c5af944625e8246d81c2f0604",
"shasum": ""
},
"require": {
@@ -5605,7 +5610,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v6.1.0"
+ "source": "https://github.com/symfony/string/tree/v6.1.2"
},
"funding": [
{
@@ -5621,7 +5626,7 @@
"type": "tidelift"
}
],
- "time": "2022-04-22T08:18:23+00:00"
+ "time": "2022-06-26T16:35:04+00:00"
},
{
"name": "symfony/translation",
@@ -5721,16 +5726,16 @@
},
{
"name": "symfony/translation-contracts",
- "version": "v3.1.0",
+ "version": "v3.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation-contracts.git",
- "reference": "bfddd2a1faa271b782b791c361cc16e2dd49dfaa"
+ "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/bfddd2a1faa271b782b791c361cc16e2dd49dfaa",
- "reference": "bfddd2a1faa271b782b791c361cc16e2dd49dfaa",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/606be0f48e05116baef052f7f3abdb345c8e02cc",
+ "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc",
"shasum": ""
},
"require": {
@@ -5782,7 +5787,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/translation-contracts/tree/v3.1.0"
+ "source": "https://github.com/symfony/translation-contracts/tree/v3.1.1"
},
"funding": [
{
@@ -5798,7 +5803,7 @@
"type": "tidelift"
}
],
- "time": "2022-04-22T07:30:54+00:00"
+ "time": "2022-06-27T17:24:16+00:00"
},
{
"name": "symfony/var-dumper",
@@ -6602,16 +6607,16 @@
},
{
"name": "brianium/paratest",
- "version": "v6.5.1",
+ "version": "v6.6.0",
"source": {
"type": "git",
"url": "https://github.com/paratestphp/paratest.git",
- "reference": "41fc4cc01422dae2d6bf6a0ce39756f57ac7d8a9"
+ "reference": "bce7b965a5fe5028a53c3151042ca12777600acd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paratestphp/paratest/zipball/41fc4cc01422dae2d6bf6a0ce39756f57ac7d8a9",
- "reference": "41fc4cc01422dae2d6bf6a0ce39756f57ac7d8a9",
+ "url": "https://api.github.com/repos/paratestphp/paratest/zipball/bce7b965a5fe5028a53c3151042ca12777600acd",
+ "reference": "bce7b965a5fe5028a53c3151042ca12777600acd",
"shasum": ""
},
"require": {
@@ -6626,18 +6631,18 @@
"phpunit/php-timer": "^5.0.3",
"phpunit/phpunit": "^9.5.21",
"sebastian/environment": "^5.1.4",
- "symfony/console": "^5.4.9 || ^6.1.1",
+ "symfony/console": "^5.4.9 || ^6.1.2",
"symfony/process": "^5.4.8 || ^6.1.0"
},
"require-dev": {
"doctrine/coding-standard": "^9.0.0",
"ext-pcov": "*",
"ext-posix": "*",
- "infection/infection": "^0.26.12",
+ "infection/infection": "^0.26.13",
"malukenho/mcbumpface": "^1.1.5",
"squizlabs/php_codesniffer": "^3.7.1",
"symfony/filesystem": "^5.4.9 || ^6.1.0",
- "vimeo/psalm": "^4.23.0"
+ "vimeo/psalm": "^4.24.0"
},
"bin": [
"bin/paratest",
@@ -6678,7 +6683,7 @@
],
"support": {
"issues": "https://github.com/paratestphp/paratest/issues",
- "source": "https://github.com/paratestphp/paratest/tree/v6.5.1"
+ "source": "https://github.com/paratestphp/paratest/tree/v6.6.0"
},
"funding": [
{
@@ -6690,7 +6695,7 @@
"type": "paypal"
}
],
- "time": "2022-06-24T16:02:27+00:00"
+ "time": "2022-07-12T07:15:58+00:00"
},
{
"name": "composer/package-versions-deprecated",
@@ -7835,16 +7840,16 @@
},
{
"name": "laravel/breeze",
- "version": "v1.9.4",
+ "version": "v1.10.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/breeze.git",
- "reference": "98c79a68ae53c2193367238c019a2f988be44f4f"
+ "reference": "e98e855ab4bde5bf0083c4a4d73c0f5b474241ae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/breeze/zipball/98c79a68ae53c2193367238c019a2f988be44f4f",
- "reference": "98c79a68ae53c2193367238c019a2f988be44f4f",
+ "url": "https://api.github.com/repos/laravel/breeze/zipball/e98e855ab4bde5bf0083c4a4d73c0f5b474241ae",
+ "reference": "e98e855ab4bde5bf0083c4a4d73c0f5b474241ae",
"shasum": ""
},
"require": {
@@ -7888,7 +7893,7 @@
"issues": "https://github.com/laravel/breeze/issues",
"source": "https://github.com/laravel/breeze"
},
- "time": "2022-06-13T18:41:50+00:00"
+ "time": "2022-06-28T11:52:06+00:00"
},
{
"name": "laravel/pint",
@@ -7957,16 +7962,16 @@
},
{
"name": "laravel/sail",
- "version": "v1.14.11",
+ "version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/sail.git",
- "reference": "6edf45a247b3688e0d07e149570a62fd9bc11c73"
+ "reference": "676e1ff33c1b8af657779f62f57360c376cba666"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/sail/zipball/6edf45a247b3688e0d07e149570a62fd9bc11c73",
- "reference": "6edf45a247b3688e0d07e149570a62fd9bc11c73",
+ "url": "https://api.github.com/repos/laravel/sail/zipball/676e1ff33c1b8af657779f62f57360c376cba666",
+ "reference": "676e1ff33c1b8af657779f62f57360c376cba666",
"shasum": ""
},
"require": {
@@ -8013,7 +8018,7 @@
"issues": "https://github.com/laravel/sail/issues",
"source": "https://github.com/laravel/sail"
},
- "time": "2022-06-13T18:32:48+00:00"
+ "time": "2022-06-24T13:56:11+00:00"
},
{
"name": "mockery/mockery",
@@ -8199,16 +8204,16 @@
},
{
"name": "nunomaduro/collision",
- "version": "v6.2.0",
+ "version": "v6.2.1",
"source": {
"type": "git",
"url": "https://github.com/nunomaduro/collision.git",
- "reference": "c379636dc50e829edb3a8bcb944a01aa1aed8f25"
+ "reference": "5f058f7e39278b701e455b3c82ec5298cf001d89"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nunomaduro/collision/zipball/c379636dc50e829edb3a8bcb944a01aa1aed8f25",
- "reference": "c379636dc50e829edb3a8bcb944a01aa1aed8f25",
+ "url": "https://api.github.com/repos/nunomaduro/collision/zipball/5f058f7e39278b701e455b3c82ec5298cf001d89",
+ "reference": "5f058f7e39278b701e455b3c82ec5298cf001d89",
"shasum": ""
},
"require": {
@@ -8220,6 +8225,7 @@
"require-dev": {
"brianium/paratest": "^6.4.1",
"laravel/framework": "^9.7",
+ "laravel/pint": "^0.2.1",
"nunomaduro/larastan": "^1.0.2",
"nunomaduro/mock-final-classes": "^1.1.0",
"orchestra/testbench": "^7.3.0",
@@ -8282,7 +8288,7 @@
"type": "patreon"
}
],
- "time": "2022-04-05T15:31:38+00:00"
+ "time": "2022-06-27T16:11:16+00:00"
},
{
"name": "nunomaduro/larastan",
@@ -8848,16 +8854,16 @@
},
{
"name": "phpstan/phpstan",
- "version": "1.7.15",
+ "version": "1.8.1",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "cd0202ea1b1fc6d1bbe156c6e2e18a03e0ff160a"
+ "reference": "8dbba631fa32f4b289404469c2afd6122fd61d67"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/cd0202ea1b1fc6d1bbe156c6e2e18a03e0ff160a",
- "reference": "cd0202ea1b1fc6d1bbe156c6e2e18a03e0ff160a",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8dbba631fa32f4b289404469c2afd6122fd61d67",
+ "reference": "8dbba631fa32f4b289404469c2afd6122fd61d67",
"shasum": ""
},
"require": {
@@ -8883,7 +8889,7 @@
"description": "PHPStan - PHP Static Analysis Tool",
"support": {
"issues": "https://github.com/phpstan/phpstan/issues",
- "source": "https://github.com/phpstan/phpstan/tree/1.7.15"
+ "source": "https://github.com/phpstan/phpstan/tree/1.8.1"
},
"funding": [
{
@@ -8903,7 +8909,7 @@
"type": "tidelift"
}
],
- "time": "2022-06-20T08:29:01+00:00"
+ "time": "2022-07-12T16:08:06+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -10686,16 +10692,16 @@
},
{
"name": "vimeo/psalm",
- "version": "4.23.0",
+ "version": "4.24.0",
"source": {
"type": "git",
"url": "https://github.com/vimeo/psalm.git",
- "reference": "f1fe6ff483bf325c803df9f510d09a03fd796f88"
+ "reference": "06dd975cb55d36af80f242561738f16c5f58264f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/vimeo/psalm/zipball/f1fe6ff483bf325c803df9f510d09a03fd796f88",
- "reference": "f1fe6ff483bf325c803df9f510d09a03fd796f88",
+ "url": "https://api.github.com/repos/vimeo/psalm/zipball/06dd975cb55d36af80f242561738f16c5f58264f",
+ "reference": "06dd975cb55d36af80f242561738f16c5f58264f",
"shasum": ""
},
"require": {
@@ -10787,9 +10793,9 @@
],
"support": {
"issues": "https://github.com/vimeo/psalm/issues",
- "source": "https://github.com/vimeo/psalm/tree/4.23.0"
+ "source": "https://github.com/vimeo/psalm/tree/4.24.0"
},
- "time": "2022-04-28T17:35:49+00:00"
+ "time": "2022-06-26T11:47:54+00:00"
},
{
"name": "webmozart/path-util",
diff --git a/config/services.php b/config/services.php
index 7c6ec9824..720277d66 100644
--- a/config/services.php
+++ b/config/services.php
@@ -31,7 +31,9 @@ return [
],
'telegram-bot-api' => [
- 'token' => env('TELEGRAM_BOT_TOKEN', 'YOUR BOT TOKEN HERE'),
+ 'token' => env('TELEGRAM_BOT_TOKEN', null),
+ 'bot_url' => env('TELEGRAM_BOT_URL'),
+ 'webhook' => env('TELEGRAM_BOT_WEBHOOK_URL'),
],
];
diff --git a/database/migrations/2022_02_18_215852_create_reminders_table.php b/database/migrations/2022_02_18_215852_create_reminders_table.php
index 1306021ee..7bb6c2c86 100644
--- a/database/migrations/2022_02_18_215852_create_reminders_table.php
+++ b/database/migrations/2022_02_18_215852_create_reminders_table.php
@@ -34,12 +34,12 @@ return new class () extends Migration {
$table->id();
$table->unsignedBigInteger('user_id')->nullable();
$table->string('type');
- $table->string('label');
+ $table->string('label')->nullable();
$table->text('content');
$table->time('preferred_time')->nullable();
$table->boolean('active')->default(false);
$table->datetime('verified_at')->nullable();
- $table->string('email_verification_link')->nullable();
+ $table->string('verification_token')->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
diff --git a/domains/Contact/ManageReminders/Jobs/ProcessScheduledContactReminders.php b/domains/Contact/ManageReminders/Jobs/ProcessScheduledContactReminders.php
index 99643bae8..de7a821ec 100644
--- a/domains/Contact/ManageReminders/Jobs/ProcessScheduledContactReminders.php
+++ b/domains/Contact/ManageReminders/Jobs/ProcessScheduledContactReminders.php
@@ -3,8 +3,11 @@
namespace App\Contact\ManageReminders\Jobs;
use App\Contact\ManageReminders\Services\RescheduleContactReminderForChannel;
-use App\Jobs\Notifications\SendEmailNotification;
+use App\Helpers\NameHelper;
+use App\Models\ContactReminder;
use App\Models\UserNotificationChannel;
+use App\Models\UserNotificationSent;
+use App\Notifications\ReminderTriggered;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
@@ -12,6 +15,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Notification;
class ProcessScheduledContactReminders implements ShouldQueue
{
@@ -51,10 +55,18 @@ class ProcessScheduledContactReminders implements ShouldQueue
$channel = UserNotificationChannel::findOrFail($scheduledReminder->user_notification_channel_id);
if ($channel->type == UserNotificationChannel::TYPE_EMAIL) {
- SendEmailNotification::dispatch(
- $scheduledReminder->user_notification_channel_id,
- $scheduledReminder->contact_reminder_id
- )->onQueue('low');
+ $contactReminder = ContactReminder::find($scheduledReminder->contact_reminder_id);
+ $contact = $contactReminder->contact;
+ $contactName = NameHelper::formatContactName($channel->user, $contact);
+
+ Notification::route('mail', $channel->content)
+ ->notify(new ReminderTriggered($channel, $contactReminder->label, $contactName));
+
+ UserNotificationSent::create([
+ 'user_notification_channel_id' => $channel->id,
+ 'sent_at' => Carbon::now(),
+ 'subject_line' => $contactReminder->label,
+ ]);
}
$this->updateScheduledContactReminderTriggeredAt($scheduledReminder->id);
diff --git a/domains/Settings/ManageNotificationChannels/Services/CreateUserNotificationChannel.php b/domains/Settings/ManageNotificationChannels/Services/CreateUserNotificationChannel.php
index 1b7f65faa..1c6edf69f 100644
--- a/domains/Settings/ManageNotificationChannels/Services/CreateUserNotificationChannel.php
+++ b/domains/Settings/ManageNotificationChannels/Services/CreateUserNotificationChannel.php
@@ -85,16 +85,8 @@ class CreateUserNotificationChannel extends BaseService implements ServiceInterf
'preferred_time' => $this->data['preferred_time'],
]);
- // add a verification link if the channel is email
- if ($this->data['verify_email']) {
- $uuid = Str::uuid();
-
- $this->userNotificationChannel->email_verification_link = route('settings.notifications.verification.store', [
- 'notification' => $this->userNotificationChannel->id,
- 'uuid' => $uuid,
- ]);
- $this->userNotificationChannel->save();
- }
+ $this->userNotificationChannel->verification_token = (string) Str::uuid();
+ $this->userNotificationChannel->save();
}
private function verifyChannel(): void
diff --git a/domains/Settings/ManageNotificationChannels/Services/SendTestEmail.php b/domains/Settings/ManageNotificationChannels/Services/SendTestEmail.php
index 589047bb0..d83c2ff1b 100644
--- a/domains/Settings/ManageNotificationChannels/Services/SendTestEmail.php
+++ b/domains/Settings/ManageNotificationChannels/Services/SendTestEmail.php
@@ -4,7 +4,6 @@ namespace App\Settings\ManageNotificationChannels\Services;
use App\Interfaces\ServiceInterface;
use App\Mail\TestEmailSent;
-use App\Models\User;
use App\Models\UserNotificationChannel;
use App\Models\UserNotificationSent;
use App\Services\BaseService;
diff --git a/domains/Settings/ManageNotificationChannels/Services/SendTestTelegramNotification.php b/domains/Settings/ManageNotificationChannels/Services/SendTestTelegramNotification.php
new file mode 100644
index 000000000..e6a3a3b43
--- /dev/null
+++ b/domains/Settings/ManageNotificationChannels/Services/SendTestTelegramNotification.php
@@ -0,0 +1,80 @@
+ 'required|integer|exists:accounts,id',
+ 'author_id' => 'required|integer|exists:users,id',
+ 'user_notification_channel_id' => 'required|integer|exists:user_notification_channels,id',
+ ];
+ }
+
+ /**
+ * Get the permissions that apply to the user calling the service.
+ *
+ * @return array
+ */
+ public function permissions(): array
+ {
+ return [
+ 'author_must_belong_to_account',
+ ];
+ }
+
+ /**
+ * Send a test notification to Telegram.
+ *
+ * @param array $data
+ * @return UserNotificationChannel
+ */
+ public function execute(array $data): UserNotificationChannel
+ {
+ $this->data = $data;
+ $this->validate();
+ $this->send();
+
+ return $this->userNotificationChannel;
+ }
+
+ private function validate(): void
+ {
+ $this->validateRules($this->data);
+
+ $this->userNotificationChannel = UserNotificationChannel::where('user_id', $this->data['author_id'])
+ ->findOrFail($this->data['user_notification_channel_id']);
+
+ if ($this->userNotificationChannel->type !== UserNotificationChannel::TYPE_TELEGRAM) {
+ throw new Exception('Only telegram messages can be sent.');
+ }
+ }
+
+ private function send(): void
+ {
+ $content = trans('settings.notification_channels_telegram_test_notification', ['name' => $this->author->name]);
+
+ Notification::route('telegram', $this->userNotificationChannel->content)
+ ->notify(new ReminderTriggered($this->userNotificationChannel, $content, 'Test'));
+ }
+}
diff --git a/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsController.php b/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsController.php
index 9f6d1f5b2..3e91e6149 100644
--- a/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsController.php
+++ b/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsController.php
@@ -39,7 +39,7 @@ class NotificationsController extends Controller
$channel = (new CreateUserNotificationChannel())->execute($data);
return response()->json([
- 'data' => NotificationsIndexViewHelper::dtoEmail($channel, Auth::user()),
+ 'data' => NotificationsIndexViewHelper::dtoEmail($channel),
], 200);
}
diff --git a/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsTestController.php b/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsTestController.php
index 1f7e4d648..4f8bc63c5 100644
--- a/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsTestController.php
+++ b/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsTestController.php
@@ -3,7 +3,9 @@
namespace App\Settings\ManageNotificationChannels\Web\Controllers;
use App\Http\Controllers\Controller;
+use App\Models\UserNotificationChannel;
use App\Settings\ManageNotificationChannels\Services\SendTestEmail;
+use App\Settings\ManageNotificationChannels\Services\SendTestTelegramNotification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@@ -17,7 +19,15 @@ class NotificationsTestController extends Controller
'user_notification_channel_id' => $userNotificationChannelId,
];
- (new SendTestEmail())->execute($data);
+ $channel = UserNotificationChannel::find($userNotificationChannelId);
+
+ if ($channel->type == UserNotificationChannel::TYPE_EMAIL) {
+ (new SendTestEmail())->execute($data);
+ }
+
+ if ($channel->type == UserNotificationChannel::TYPE_TELEGRAM) {
+ (new SendTestTelegramNotification())->execute($data);
+ }
return response()->json([
'data' => true,
diff --git a/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsToggleController.php b/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsToggleController.php
index d0f62ea3f..b6fa0a2d9 100644
--- a/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsToggleController.php
+++ b/domains/Settings/ManageNotificationChannels/Web/Controllers/NotificationsToggleController.php
@@ -21,7 +21,7 @@ class NotificationsToggleController extends Controller
$channel = (new ToggleUserNotificationChannel())->execute($data);
return response()->json([
- 'data' => NotificationsIndexViewHelper::dtoEmail($channel, Auth::user()),
+ 'data' => NotificationsIndexViewHelper::dtoEmail($channel),
], 200);
}
}
diff --git a/domains/Settings/ManageNotificationChannels/Web/Controllers/TelegramNotificationsController.php b/domains/Settings/ManageNotificationChannels/Web/Controllers/TelegramNotificationsController.php
new file mode 100644
index 000000000..d32a7ceb7
--- /dev/null
+++ b/domains/Settings/ManageNotificationChannels/Web/Controllers/TelegramNotificationsController.php
@@ -0,0 +1,34 @@
+input('hours').':'.$request->input('minutes');
+
+ $data = [
+ 'account_id' => Auth::user()->account_id,
+ 'author_id' => Auth::user()->id,
+ 'label' => 'Telegram',
+ 'type' => UserNotificationChannel::TYPE_TELEGRAM,
+ 'content' => 'tbd',
+ 'verify_email' => false,
+ 'preferred_time' => $time,
+ ];
+
+ $channel = (new CreateUserNotificationChannel())->execute($data);
+
+ return response()->json([
+ 'data' => NotificationsIndexViewHelper::dtoTelegram($channel),
+ ], 200);
+ }
+}
diff --git a/domains/Settings/ManageNotificationChannels/Web/Controllers/TelegramWebhookController.php b/domains/Settings/ManageNotificationChannels/Web/Controllers/TelegramWebhookController.php
new file mode 100644
index 000000000..151d8f7eb
--- /dev/null
+++ b/domains/Settings/ManageNotificationChannels/Web/Controllers/TelegramWebhookController.php
@@ -0,0 +1,53 @@
+message['text'];
+ } catch (Exception $e) {
+ return response()->json([
+ 'code' => $e->getCode(),
+ 'message' => 'Accepted with error: \'' . $e->getMessage() . '\'',
+ ], 202);
+ }
+
+ // check if the message matches the expected pattern.
+ // if the message does not match the pattern, then we return a 202 response
+ // so telegram will stop trying to send the message.
+ if (! Str::of($messageText)->test('/^\/start\s[A-Za-z0-9-]{36}$/')) {
+ return response('Accepted', 202);
+ }
+
+ // Cleanup the string
+ $verificationKey = Str::of($messageText)->remove('/start ')->rtrim();
+
+ // Get Telegram ID from the request.
+ $chatId = $request->message['chat']['id'];
+
+ // Get the User ID from the cache using the temp code as key.
+ $channel = UserNotificationChannel::where('verification_token', $verificationKey)->first();
+
+ // Update user with the Telegram Chat ID
+ $channel->content = $chatId;
+ $channel->active = true;
+ $channel->save();
+
+ return response('Success', 200);
+ }
+}
diff --git a/domains/Settings/ManageNotificationChannels/Web/ViewHelpers/NotificationsIndexViewHelper.php b/domains/Settings/ManageNotificationChannels/Web/ViewHelpers/NotificationsIndexViewHelper.php
index 72f3c667c..b6feb76c7 100644
--- a/domains/Settings/ManageNotificationChannels/Web/ViewHelpers/NotificationsIndexViewHelper.php
+++ b/domains/Settings/ManageNotificationChannels/Web/ViewHelpers/NotificationsIndexViewHelper.php
@@ -19,17 +19,27 @@ class NotificationsIndexViewHelper
return self::dtoEmail($channel, $user);
});
+ // telegram
+ $telegram = $channels->filter(function ($channel) {
+ return $channel->type === 'telegram';
+ })->first();
+
return [
'emails' => $emailsCollection,
+ 'telegram' => [
+ 'data' => $telegram ? self::dtoTelegram($telegram) : null,
+ 'telegram_env_variable_set' => config('services.telegram-bot-api.token'),
+ ],
'url' => [
'settings' => route('settings.index'),
'back' => route('settings.index'),
'store' => route('settings.notifications.store'),
+ 'store_telegram' => route('settings.notifications.telegram.store'),
],
];
}
- public static function dtoEmail(UserNotificationChannel $channel, User $user): array
+ public static function dtoEmail(UserNotificationChannel $channel): array
{
return [
'id' => $channel->id,
@@ -56,4 +66,30 @@ class NotificationsIndexViewHelper
],
];
}
+
+ public static function dtoTelegram(UserNotificationChannel $channel): array
+ {
+ return [
+ 'id' => $channel->id,
+ 'type' => $channel->type,
+ 'active' => $channel->active,
+ 'verified_at' => $channel->verified_at ? $channel->verified_at->format('Y-m-d H:i:s') : null,
+ 'preferred_time' => $channel->preferred_time->format('H:i'),
+ 'url' => [
+ 'open' => config('services.telegram-bot-api.bot_url').'?start='.$channel->verification_token,
+ 'send_test' => route('settings.notifications.test.store', [
+ 'notification' => $channel->id,
+ ]),
+ 'toggle' => route('settings.notifications.toggle.update', [
+ 'notification' => $channel->id,
+ ]),
+ 'logs' => route('settings.notifications.log.index', [
+ 'notification' => $channel->id,
+ ]),
+ 'destroy' => route('settings.notifications.destroy', [
+ 'notification' => $channel->id,
+ ]),
+ ],
+ ];
+ }
}
diff --git a/domains/Settings/ManageNotificationChannels/Web/ViewHelpers/NotificationsLogIndexViewHelper.php b/domains/Settings/ManageNotificationChannels/Web/ViewHelpers/NotificationsLogIndexViewHelper.php
index 348176b44..d2dd6ea54 100644
--- a/domains/Settings/ManageNotificationChannels/Web/ViewHelpers/NotificationsLogIndexViewHelper.php
+++ b/domains/Settings/ManageNotificationChannels/Web/ViewHelpers/NotificationsLogIndexViewHelper.php
@@ -23,7 +23,7 @@ class NotificationsLogIndexViewHelper
return [
'channel' => [
'id' => $channel->id,
- 'type' => trans('app.notification_channel_type_'.$channel->type),
+ 'type' => trans('settings.notification_channel_type_'.$channel->type),
'label' => $channel->label,
],
'notifications' => $notificationsCollection,
diff --git a/lang/en/app.php b/lang/en/app.php
index 52b6b8d89..2e62e9950 100644
--- a/lang/en/app.php
+++ b/lang/en/app.php
@@ -93,5 +93,4 @@ return [
'emotion_negative' => 'đĄ Negative',
'notification_channel_email' => 'My email',
- 'notification_channel_type_email' => 'Email',
];
diff --git a/lang/en/email.php b/lang/en/email.php
index b1061e657..66abe63d3 100644
--- a/lang/en/email.php
+++ b/lang/en/email.php
@@ -3,4 +3,9 @@
return [
'notification_test_email' => 'Test email for Monica',
'notification_reminder_email' => 'Reminder for :name',
+
+ // reminder triggered
+ 'reminder_triggered_intro' => 'You wanted to be reminded of the following:',
+ 'reminder_triggered_for' => 'for',
+ 'reminder_triggered_signature' => 'Have a great day',
];
diff --git a/lang/en/settings.php b/lang/en/settings.php
index 79b19034e..ad847de83 100644
--- a/lang/en/settings.php
+++ b/lang/en/settings.php
@@ -50,6 +50,8 @@ return [
* NOTIFICATION CHANNELS
**************************************************************/
+ 'notification_channel_type_email' => 'Email',
+ 'notification_channel_type_telegram' => 'Telegram',
'notification_channels_title' => 'Configure how we should notify you',
'notification_channels_description' => 'You can be notified through different channels: emails, a Telegram message, on Facebook. You decide.',
'notification_channels_email_title' => 'Via email',
@@ -77,6 +79,17 @@ return [
'notification_channels_log_label' => 'Label:',
'notification_channels_log_help' => 'This page shows all the notifications that have been sent in this channel in the past. It primeraly serves as a way to debug in case you donât receive the notification youâve set up.',
'notification_channels_log_blank' => 'You havenât received a notification in this channel yet.',
+ 'notification_channels_telegram_title' => 'Via Telegram',
+ 'notification_channels_telegram_cta' => 'Setup Telegram',
+ 'notification_channels_telegram_blank' => 'You havenât setup Telegram yet.',
+ 'notification_channels_telegram_delete_confirm' => 'Are you sure? You can always add Telegram back later on if you want.',
+ 'notification_channels_telegram_not_set' => 'You have not setup Telegram in your environment variables yet.',
+ 'notification_channels_telegram_test_notification' => 'This is a test notification for :name',
+ 'notification_channels_telegram_test_notification_sent' => 'Notification sent',
+ 'notification_channels_telegram_destroy_success' => 'The Telegram channel has been deleted',
+ 'notification_channels_telegram_added' => 'The Telegram channel has been added',
+ 'notification_channels_telegram_linked' => 'Your account is linked',
+ 'notification_channels_test_success_telegram' => 'The notification has been sent',
/***************************************************************
* USER MANAGEMENT
diff --git a/lang/fr/app.php b/lang/fr/app.php
index 43ccbfb88..8d72f2b15 100644
--- a/lang/fr/app.php
+++ b/lang/fr/app.php
@@ -93,5 +93,4 @@ return [
'emotion_negative' => 'đĄ NĂ©gatif',
'notification_channel_email' => 'Mon courriel',
- 'notification_channel_type_email' => 'Courriel',
];
diff --git a/lang/fr/settings.php b/lang/fr/settings.php
index a20379b32..b980cd737 100644
--- a/lang/fr/settings.php
+++ b/lang/fr/settings.php
@@ -50,6 +50,8 @@ return [
* NOTIFICATION CHANNELS
**************************************************************/
+ 'notification_channel_type_email' => 'Courriel',
+ 'notification_channel_type_telegram' => 'Telegram',
'notification_channels_title' => 'Configurer comment nous devons vous notifier',
'notification_channels_description' => 'Vous pouvez ĂȘtre notifiĂ© Ă travers plusieurs canaux : courriels, Telegram, Facebook. Vous dĂ©cidez.',
'notification_channels_email_title' => 'Par courriel',
@@ -77,6 +79,17 @@ return [
'notification_channels_log_label' => 'Libellé :',
'notification_channels_log_help' => 'Cette page montre toutes les notifications qui ont Ă©tĂ© envoyĂ©s via ce canal par le passĂ©. Cela sert principalement comme une façon de dĂ©boguer dans le cas oĂč vous ne recevez pas les notifications que vous avez programmĂ©es.',
'notification_channels_log_blank' => 'Vous nâavez pas encore reçu de notifications dans ce canal.',
+ 'notification_channels_telegram_title' => 'Par Telegram',
+ 'notification_channels_telegram_cta' => 'Configurer Telegram',
+ 'notification_channels_telegram_blank' => 'Vous nâavez pas encore configurĂ© Telegram.',
+ 'notification_channels_telegram_delete_confirm' => 'Ătes-vous sĂ»r ? Vous pourrez toujours rajouter Telegram plus tard si vous le voulez.',
+ 'notification_channels_telegram_not_set' => 'Vous nâavez pas encore configurĂ© Telegram dans vos variables dâenvironnement.',
+ 'notification_channels_telegram_test_notification' => 'Ceci est une notification de test pour :name',
+ 'notification_channels_telegram_test_notification_sent' => 'Notification envoyée',
+ 'notification_channels_telegram_destroy_success' => 'Le canal Telegram a été supprimé',
+ 'notification_channels_telegram_added' => 'Le canal Telegram a été ajouté',
+ 'notification_channels_telegram_linked' => 'Votre compte est lié',
+ 'notification_channels_test_success_telegram' => 'La notification a été envoyée',
/***************************************************************
* USER MANAGEMENT
diff --git a/resources/js/Pages/Settings/Notifications/Index.vue b/resources/js/Pages/Settings/Notifications/Index.vue
index b06e61c85..59702f24e 100644
--- a/resources/js/Pages/Settings/Notifications/Index.vue
+++ b/resources/js/Pages/Settings/Notifications/Index.vue
@@ -58,6 +58,9 @@
â ïž {{ $t('settings.notification_channels_email_help') }}
+â ïž {{ $t('settings.notification_channels_email_help') }}
{{ $t('settings.notification_channels_telegram_not_set') }}
+{{ $t('settings.notification_channels_telegram_blank') }}
+