How to get personal slack notifications from UptimeRobot
kosar
TL; DR:
- The service accepts a Slack workflow hook URL, a Slack bot token, an UptimeRobot API key, a MongoDB URI, and Azure App registration data.
- Using the UptimeRobot API key, the service retrieves all websites from UptimeRobot and displays them. The UI includes "request add" and "request delete" options that allow users to submit requests for adding or deleting websites.
- User authorization is handled via Azure Entra using an App registration.
- For each website, two dropdowns are available: one for Slack users and another for Slack channels. Data for these dropdowns is fetched using the Slack bot token. Selected users and channels are subscribed to notifications.
- A webhook with pre-defined token authentication is implemented in the service.
- The service webhook is configured in UptimeRobot and applied to all websites.
- In-memory cache is utilized to store Slack users, Slack channels, and UptimeRobot website data, reducing the number of API calls.
- When a subscription for a website is created, a record is stored in MongoDB, associating the website with its subscribers (users and channels). If no subscriptions are present, no record is created.
- When an UptimeRobot event occurs, UptimeRobot sends a notification to the default Slack channel (as a fallback) and to the service webhook. The service checks MongoDB to determine if a subscription exists for the website associated with the event. If a subscription exists, notifications are sent to all subscribers. If not, no further action is taken.
- Upon submission of add/delete request for a website, the service automatically creates a task in Slack List, including details such as the website name/URL and the user who submitted the request.
- Specific Slack channels (e.g., "general" and "random") can be hidden from the subscription list to prevent accidental selection. This can be configured by providing the channel names.
If you are still reading
In my work, I use UptimeRobot to monitor websites. There are quite a lot of them — enough to clutter up the general notifications channels and make them unreadable. Naturally, neither developers nor managers read these notifications in the general monitoring channels. Why? Well, I think we all know the reasons — there are plenty of them.
UptimeRobot can send notifications to Slack, but they all go to a single channel. There’s no option for personalized notifications. At some point, I decided my team shouldn’t be the only ones responsible for monitoring clients’ websites.
I’d been wanting to implement personalized Slack notifications for a while, so that each developer and manager would receive alerts for the projects they work on. It’s a way to share responsibility, and so on. Along the way, I realized that I had never actually written code in Next.js. Of course, I had worked with it, definitely, but within the scope of my responsibilities. Setting up a project, configuring the pipeline, deploying it, writing a Dockerfile — that's all familiar territory. But coding? I hadn’t had the chance to do that before.
Sooooo.... From a high-level perspective, the service has the next technologies:
- Next.js on Vercel for the user interface and API routes
- Azure Entra (App Registration) for secure authentication
- Slack for messaging, user lookups, and tasks (Slack Lists)
- MongoDB Atlas for storing subscription details
- UptimeRobot for monitoring websites
As already said, I have UptimeRobot. Essentially, it contains a list of all the websites I want to monitor in this situation. In this case, it can be viewed as both a data source and notifications producer. The challenge is to somehow link these notifications to specific recipients. The first idea that comes to mind is subscription-based notifications. Users and channels can be fetched from Slack and subscriptions can be stored in a separate MongoDB database. The algorithm works as follows: if there is a subscription for a specific website, the service sends a message in Slack to those who have subscribed to the notifications. These could be either individual users or channels. And if there are no subscriptions? Well, there’s nothing to do — the notification will still be sent to the general channel by UptimeRobot itself.
Identifier is the UptimeRobot monitor ID. Why? We can get it from uptimerobot, we can use it in future. Of course we also can use url
value as unique, but we already have id, so why not.
Of course, to receive notifications from UptimeRobot, a webhook is needed. From the Next.js perspective, it's a simple API endpoint that accepts a POST payload.
Naturally, I don’t want anyone other than UptimeRobot to trigger this webhook, so it’s protected by an API token. Yes, the token is simply set via an environment file — so what?
In my opinion, the output of head -c 64 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9'
is enough for this purpose.
Something like this:
Fetching all websites from UptimeRobot is straightforward — it’s just a single API request. Displaying them as a list, adding an "Add", "Delete" and "Edit" buttons are all pretty straightforward. I believe these aspects don’t require further clarification.
The "Edit" button simply opens a page where user can select users and channels for sending notifications.
Of course, users need to be authorized. First, for security reasons, and second, to extract their email from the authentication data. This email can then be used to find the corresponding user in Slack for sending personalized notifications. I chose Azure Entra for authentication just because it’s widely used. There’s nothing extraordinary about the implementation — it’s a standard setup easily found by googling next-auth Azure Entra integration.
To reduce the number of requests to Slack and UptimeRobot, an in-memory cache with a TTL of one hour is used. This ensures efficient performance while keeping the system responsive.
Direct access to UptimeRobot isn’t granted to all users. Instead, when someone clicks the "Add" or "Delete" buttons, a hook creates a task in a Slack List. his task contains the email of the authorized user and the website they want to add or delete. This approach ensures all necessary details for the request are available: what needs to be done and who requested it.
Why not use the functionality of adding and deleting records directly through the UptimeRobot API? Because, in addition to monitoring uptime, we also monitor SSL certificates and domain expiration dates. Firstly, UptimeRobot does not have the necessary fields in its API (at least at the time of writing this article), and secondly, it does not automatically include domain and SSL checks in some cases. I’m not entirely sure about all the cases, but I suspect one example is when the site is behind a Cloudflare proxy. It seems logical not to check the certificate if Cloudflare is handling it, but no — Cloudflare is also configured by people, and people can make mistakes.
About Slack List... Well, I created a workflow that is triggered by a webhook and creates a task in the Slack List based on the payload data. It looks something like this:
From the service side there's the next code:
That's it. Key takeaways:
- Distributed Ownership. By enabling developers and managers to self-service their website monitoring needs, reaction times decrease, and DevOps teams have more bandwidth for strategic work.
- Slack Integration. Notifications are sent directly to chosen users or channels, ensuring updates land in front of the right people.
- Possible Free Hosting. Deploying on Vercel and using MongoDB Atlas simplifies maintenance. Free plans can be used.