diff --git a/lib/Notification/Listener.php b/lib/Notification/Listener.php index f622dd865ca..123de1b6f51 100644 --- a/lib/Notification/Listener.php +++ b/lib/Notification/Listener.php @@ -41,10 +41,12 @@ use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventDispatcher; use OCP\EventDispatcher\IEventListener; +use OCP\IConfig; use OCP\IDBConnection; use OCP\IUser; use OCP\IUserSession; use OCP\Notification\IManager; +use OCP\Notification\INotification; use Psr\Log\LoggerInterface; /** @@ -53,10 +55,14 @@ class Listener implements IEventListener { protected bool $shouldSendCallNotification = false; + /** @var array $preparedCallNotifications Map of language => parsed notification in that language */ + protected array $preparedCallNotifications = []; public function __construct( + protected IConfig $serverConfig, protected IDBConnection $connection, protected IManager $notificationManager, + protected Notifier $notificationProvider, protected ParticipantService $participantsService, protected IEventDispatcher $dispatcher, protected IUserSession $userSession, @@ -290,7 +296,24 @@ protected function sendCallNotifications(Room $room): void { return; } + $this->preparedCallNotifications = []; $userIds = $this->participantsService->getParticipantUserIdsForCallNotifications($room); + // Room name depends on the notification user for one-to-one, + // so we avoid preparsing it there. Also, it comes with some base load, + // so we only do it for "big enough" calls. + $preparseNotificationForPush = count($userIds) > 10; + if ($preparseNotificationForPush) { + $fallbackLang = $this->serverConfig->getSystemValue('force_language', null); + if (is_string($fallbackLang)) { + /** @psalm-var array $userLanguages */ + $userLanguages = []; + } else { + $fallbackLang = $this->serverConfig->getSystemValueString('default_language', 'en'); + /** @psalm-var array $userLanguages */ + $userLanguages = $this->serverConfig->getUserValueForUsers('core', 'lang', $userIds); + } + } + $this->connection->beginTransaction(); try { foreach ($userIds as $userId) { @@ -298,6 +321,22 @@ protected function sendCallNotifications(Room $room): void { continue; } + if ($preparseNotificationForPush) { + // Get the settings for this particular user, then check if we have notifications to email them + $languageCode = $userLanguages[$userId] ?? $fallbackLang; + + if (!isset($this->preparedCallNotifications[$languageCode])) { + $translatedNotification = clone $notification; + + $this->notificationManager->setPreparingPushNotification(true); + $this->preparedCallNotifications[$languageCode] = $this->notificationProvider->prepare($translatedNotification, $languageCode); + $this->notificationManager->setPreparingPushNotification(false); + $notification = $translatedNotification; + } else { + $notification = $this->preparedCallNotifications[$languageCode]; + } + } + try { $notification->setUser($userId); $this->notificationManager->notify($notification);