I would create a class somewhere called NotificationService with methods that handle the scenarios you mentioned.
This service can then be used wherever you need it, like in controllers, actions, queued jobs, or event listeners.
If a Controller needs to use the service, you can just add it to the constructor (Dependency Injection) and Laravel will take care of the rest.
class SomeController extends Controller
{
private $notificationService;
public function __contruct(NotificationService $notificationService)
{
$this->notificationService = $notificationService;
}
public function someMethod(Request $request)
{
// Use the service
}
}
In some cases, like when you want to be able to switch between different "versions" of the same Service (meaning the perform the same tasks, but do it in different ways), it's a good idea to create a common Interface, and inject that instead of a concrete class. This way, the "consumer" - in this case a controller - doesn't really know or care which "version" of the service it's talking to.
I only mention this because you'll probably come across it a lot when you're googling about the Service Pattern, and it can be confusing and make things unnecessarily complicated. Keep it simple, and just create a single class and start injecting that. You can always refactor later if the need arises.