10000 Generalist support for real-time messages · Issue #2407 · shlinkio/shlink · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
8000

Generalist support for real-time messages #2407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
2Friendly4You opened this issue Mar 30, 2025 · 8 comments
Open

Generalist support for real-time messages #2407

2Friendly4You opened this issue Mar 30, 2025 · 8 comments
Labels
Milestone

Comments

@2Friendly4You
Copy link

Summary

It would be cool if Shlink could use Apprise (https://github.com/caronc/apprise) to send notifications straight to places like Discord, Slack, Telegram, etc., whenever something happens (like a new link is made). This would be another way to get updates, besides the Mercure, RabbitMQ, and Redis stuff it already has.

Use case

So, Shlink already has ways to send updates in real-time using Mercure, RabbitMQ, and Redis. That's probably great if you're a fancy developer building another app that needs to react to Shlink stuff.

But honestly, sometimes I just want a simple notification. Like, I want a message in my Discord server or a Slack channel when someone creates a new short URL, or maybe when one of my links suddenly gets a bunch of visits.

Right now, getting that kind of simple message seems complicated. I think I'd have to set up another program just to listen to RabbitMQ or Redis, and then have that program send the message to Discord/Slack. That sounds like a lot of work just for a notification.

It would be way easier if Shlink could just talk to Apprise directly. Apprise is awesome because it already knows how to send messages to tons of different services (Discord, Slack, Telegram, email, push notifications, like everything).

If Shlink could use Apprise, I could just give it my Apprise notification URL, and boom – Shlink sends the update right to my chat app when something happens.

Why this would be nice:

  1. Easy Notifications: Get messages right where I want them without needing extra steps.
  2. Less Hassle: Don't need to set up some extra listener program just for alerts.
  3. Works Everywhere: Apprise supports pretty much any notification service I'd want to use.
  4. Just Another Option: It wouldn't break the other ways Shlink sends updates (Mercure, RabbitMQ, Redis). It's just an extra, simpler choice for people who want direct messages.

Basically, adding Apprise would make it super simple to get quick updates from Shlink on my phone or computer, which would be really useful.

@acelaya
Copy link
Member
acelaya commented Mar 31, 2025

In essence this makes sense, as it would be something definitely useful to have. However, I have some comments and thoughts about Apprise specifically:

Third party coupling

My first concern is with the election of a particular tool. RabbitMQ and Redis are well established technologies that many people use, and even though Mercure is not as much, I was not able to find anything else as powerful for the use-case it covers (real-time updates in the browser using web-socket-like technologies).

Making Shlink support a more generalist approach in which updates can be sent to different messaging systems is good, but ideally this should be done in an as agnostic as possible way. Apprise has a lot of stars and seems to be very active, so I guess it would be a reasonable choice, but some investigation is needed here to see if there are alternatives, or even if there's a way to do this transparently so that it doesn't require you to use any other particular technology or know what Shlink is doing under the hood.

Integration

My next concern is the lower-level integration with third parties. Shlink's core is written in PHP, so integrating with something that requires Python is tricky.

RabbitMQ, Mercure and Redis have very good integration libraries in PHP. I have always wanted to support Kafka as well, and if I haven't done it is because there are no good ways to do in in PHP.

Apprise seems to expose two ways to interact with it, a Python API and a CLI. Python is not an option, and integrating via a CLI is very brittle and error-prone.

On top of that, if the CLI assumes you are running it in the same host where Apprise is, it might not work in many of the scenarios for which Shlink is designed.

Ideally, the integration should be done via some network protocol (HTTP, TCP, socket, etc.), as all currently supported technologies do.

Apprise seems to have some kind of web interface you can install separately https://github.com/caronc/apprise-api, but I don't know if that would add more friction to the whole thing.

Architecture

This is a bit related with previous point. In order to integrate with a particular service, I first need to fully understand how it is architected.

In Apprise docs they always talk about a "library", so I suppose this is just a "binary" you have somewhere? If that's the case, there's a question on how is people supposed to make Shlink aware of it. Should it just ship a copy of the library? Seems a bit overkill, as most people won't be using it.

@acelaya acelaya changed the title Apprise support for real-time notifications Generalist support for real-time messages Mar 31, 2025
@2Friendly4You
Copy link
Author

Okay, thank you for the detailed feedback and for outlining the potential challenges. These are valid points, and I appreciate you taking the time to consider the implications. Let me try to address each concern based on my understanding of Apprise and the proposed use case:

  1. Third-Party Coupling:

    • I understand the hesitation to couple Shlink tightly with one specific tool. However, I see Apprise less as a competitor to RabbitMQ/Redis/Mercure and more as filling a different niche: user-facing notifications.
    • RabbitMQ/Redis/Mercure are excellent for inter-service communication or real-time data streams for other applications. Apprise is specifically designed as a notification dispatcher – its core value is its ability to abstract away the specifics of dozens of notification services (Discord, Slack, Telegram, Pushover, email, etc.).
    • Instead of Shlink needing to implement support for Discord, then Slack, then Telegram individually (which would be tight coupling and a maintenance burden), it would only need to support sending a notification payload to one target: Apprise. Apprise then handles the fan-out to the user's chosen service(s). In this sense, Apprise acts as an abstraction layer itself, potentially reducing the coupling Shlink would need if it were to support multiple notification endpoints directly.
    • While investigating alternatives is always wise, Apprise seems uniquely positioned and well-maintained for this specific "dispatch to many notification services" task.
  2. Integration:

    • You're absolutely right that integrating via a Python library is not feasible, and a CLI integration is brittle and problematic, especially regarding deployment assumptions.
    • However, the key here is the apprise-api (https://github.com/caronc/apprise-api) you mentioned. This is a separate, lightweight web service that exposes Apprise's functionality via a RESTful HTTP API.
    • This completely bypasses the Python dependency and CLI issues. Shlink (in PHP) would only need to make simple HTTP POST requests to the apprise-api endpoint.
    • The interaction would look something like this:
      • An event occurs in Shlink (e.g., new short URL).
      • Shlink constructs a JSON payload with the notification details.
      • Shlink sends an HTTP POST request to the configured apprise-api URL, including the target Apprise service URL(s) (e.g., discord://..., slack://...) in the request.
      • The apprise-api service receives the request and uses the underlying Apprise library to send the notification to the specified destination(s).
    • This HTTP-based approach fits perfectly with the preference for network protocols and avoids the pitfalls of CLI interaction.
  3. Architecture:

    • Regarding how Shlink becomes aware of Apprise: Shlink would not ship with Apprise or apprise-api. That would indeed be overkill.
    • The architecture would be similar to how users currently use RabbitMQ or Redis with Shlink:
      • The user who wants Apprise notifications is responsible for setting up and running the apprise-api service separately. This could be a Docker container, a small VM, or just running it on a server they manage.
      • Shlink's configuration would simply need fields to:
        • Enable/disable Apprise notifications.
        • Specify the URL of the running apprise-api instance (e.g., http://apprise-api.local:8000/notify).
        • Potentially, specify one or more default Apprise service URLs to send notifications to (though often the target URL is part of the payload sent to apprise-api).
    • This way, Shlink only needs a lightweight HTTP client implementation. The burden of running the notification dispatcher service lies with the user who opts into using this feature, just like they manage their own message queues or Mercure hubs.

In summary, by leveraging the apprise-api component, the integration becomes much cleaner:

  • It uses a standard HTTP protocol, avoiding PHP/Python and CLI issues.
  • It doesn't require bundling Apprise; the user runs apprise-api as a separate service.
  • It provides a powerful abstraction for sending notifications to a vast array of services without Shlink needing to support each one natively.
  • It directly addresses the use case of simple, user-facing notifications, complementing the existing real-time/inter-service mechanisms.

I believe this approach addresses the valid concerns raised and offers a robust, flexible way to add significant value for users wanting direct notifications.

@acelaya
Copy link
Member
acelaya commented Mar 31, 2025

Yep, if using apprise-api is reasonable, that would also be my preferred approach.

Do you, as an Apprise user, be ok on having to deal with it? Are you already using it for other integrations?

As per choosing Apprise over other options:

I understand the hesitation to couple Shlink tightly with one specific tool. However, I see Apprise less as a competitor to RabbitMQ/Redis/Mercure and more as filling a different niche: user-facing notifications.

Oh, definitely. My point here is, we integrate Shlink with Apprise specifically to resolve user-facing notifications. Right after releasing it, someone comes to ask if I can integrate with some other tool that does the same because it's their favorite tool for that.

I would like to investigate alternatives to Apprise, or even find a way to abstract it to users.

I understand it covers a different use case than RabbitMQ, Redis pub/sub and Mercure. This could even end-up being a different feature. For example, Shlink also supports sending visits to a Matomo instance, and it does not use the real-time updates mechanism for this, as it does not fit 1-to-1.

Instead of Shlink needing to implement support for Discord, then Slack, then Telegram individually (which would be tight coupling and a maintenance burden), it would only need to support sending a notification payload to one target: Apprise

If this was implemented, it would definitely be through some abstraction. The question is, is Apprise the right one?

@2Friendly4You
Copy link
Author

Using apprise-api definitely seems like the cleanest path forward.

And yes, absolutely. As someone who wants this feature, I'd be perfectly fine setting up and running the separate apprise-api service alongside Shlink.
I personally already use apprise for some private projects.

Regarding alternatives and the concern about choosing just one tool: Honestly, I'm not aware of any other single tool that does exactly what Apprise does – acting as a central dispatcher to so many different notification services (Discord, Slack, Telegram, email, Pushover, Gotify, Matrix, etc.).

There are individual notification tools or protocols, like ntfy.sh for example. But the great thing about Apprise is that it usually supports those tools as well. You can configure Apprise to send notifications to an ntfy server, just like you can configure it to send to Email.

So, rather than being just another endpoint, Apprise acts more like a universal translator or aggregator for notifications. It seems uniquely positioned to handle this specific "send a simple notification to wherever the user wants" job without requiring Shlink to implement support for every possible service individually. It feels like the right abstraction for this particular need.

@acelaya
Copy link
Member
acelaya commented Mar 31, 2025

This is an interesting alternative to consider https://symfony.com/doc/current/notifier.html

It's a component from a well established PHP framework (Shlink already uses some of their other components) to send notifications to many services. It acts as the abstraction, but with the benefit of not having to set-up anything else. Just enable it and Shlink will send the notifications for you, without having to maintain every individual integration.

I see it supports a lot of services, but not all that Apprise supports. On the other hand, it supports some that Apprise doesn't.

The most common ones are supported by both (Slack, discord, telegram, email, bluesky, mastodon, twitter, etc.)

@acelaya acelaya added this to the 4.6.0 milestone Mar 31, 2025
@2Friendly4You
Copy link
Author

Okay, I see what you mean. The Symfony Notifier component is an interesting alternative. I wasn't aware of it, but it definitely has some compelling points, especially being a native PHP solution and already integrating with the Symfony ecosystem, which Shlink already uses.

Since I haven't used Symfony Notifier myself, I'm not in the best position to compare it directly with Apprise based on personal experience. Both seem to offer a similar kind of abstraction for sending notifications to multiple services, but with different strengths in terms of the services they support and their integration approach.

Given that we have two viable options Apprise (via apprise-api) and Symfony Notifier (or maybe more, that I am not aware of) – each with its own set of advantages, perhaps the best way forward would be to gauge community interest. A survey could help understand which solution would be more appealing and useful to Shlink users.

That way, we can make sure, that the best notification system is implemented that will serve the needs of the Shlink user base.

@acelaya
Copy link
Member
acelaya commented Apr 2, 2025

Given that we have two viable options Apprise (via apprise-api) and Symfony Notifier (or maybe more, that I am not aware of) – each with its own set of advantages, perhaps the best way forward would be to gauge community interest. A survey could help understand which solution would be more appealing and useful to Shlink users.

That way, we can make sure, that the best notification system is implemented that will serve the needs of the Shlink user base.

I usually gather community feedback, but in this context it doesn't really make sense, considering one of the options is completely transparent for users. It would be like asking the community what database abstraction should be used. They don't (and shouldn't) care about that as long as they don't need to touch the internals.

The only thing that would make sense is to ask what messaging services are more useful to people. If there's a strong preference towards a service that only one of the abstractions support, that could influence the decision.

As things are now, I think the balance is clearly in favor of using symfony/notifier, simply because it's going to be way more convenient for users. They would just need to provide messaging platform config options to Shlink and that's it.

With Apprise they need to provide that same config to Apprise, then provide connection options to Shlink so that it can communicate with Apprise, and ultimately they need to maintain and host their Apprise "instance".

I'll gather some extra information when the work on this starts, and see if there's anything else that would favor Apprise, but if nothing else comes up, it's unlikely that's the chosen abstraction.

@2Friendly4You
Copy link
Author

Okay, I understand your perspective. It makes sense to prioritize a solution that's as seamless as possible for the end-user, and the Symfony Notifier component definitely seems to offer that by being a native PHP solution that integrates directly into Shlink without requiring users to set up and maintain a separate service.

I agree that a survey about the specific notification services users want makes more sense than asking about the underlying abstraction. That way, you can ensure that the chosen solution covers the most important use cases for the Shlink community.

If Symfony Notifier covers the most popular services and provides a simpler setup experience for users, it sounds like a very reasonable choice. I trust your judgment and appreciate you taking the time to carefully consider the options. I'm happy to hear you will gather some extra information, and I'm eager to see how this evolves!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: No status
Development

No branches or pull requests

2 participants
0