Repository: louislam/uptime-kuma
File: server/notification-providers/discord.js (JavaScript)

Code before:
                if (notification.discordChannelType === "createNewForumPost") {
                    discorddowndata.thread_name = notification.postName;
                }
                if (notification.discordPrefixMessage) {
                    discorddowndata.content = notification.discordPrefixMessage;
                }
                if (notification.discordSuppressNotifications) {
                    discorddowndata.flags = SUPPRESS_NOTIFICATIONS_FLAG;
                }

                await axios.post(webhookUrl.toString(), discorddowndata, config);
                return okMsg;
            } else if (heartbeatJSON["status"] === UP) {
                // Format timestamp for Discord using Discord's timestamp format
                const backOnlineTimestamp = Math.floor(new Date(heartbeatJSON["time"]).getTime() / 1000);
                const backOnlineFormatted = `<t:${backOnlineTimestamp}:F>`;

                // Calculate downtime duration by finding the last DOWN heartbeat
                let downtimeDuration = null;
                let wentOfflineFormatted = null;
                try {
                    if (monitorJSON && monitorJSON.id) {
                        const lastDownHeartbeat = await R.getRow(
                            "SELECT time FROM heartbeat WHERE monitor_id = ? AND status = ? ORDER BY time DESC LIMIT 1",
                            [monitorJSON.id, DOWN]
                        );

                        if (lastDownHeartbeat && lastDownHeartbeat.time) {
                            const wentOfflineTimestamp = Math.floor(new Date(lastDownHeartbeat.time).getTime() / 1000);
                            wentOfflineFormatted = `<t:${wentOfflineTimestamp}:F>`;

                            // Calculate downtime duration in seconds
                            const downtimeSeconds = backOnlineTimestamp - wentOfflineTimestamp;
                            // Format as relative time using Discord's relative timestamp (R format)
                            downtimeDuration = `<t:${wentOfflineTimestamp}:R>`;
                        }
                    }
                } catch (error) {
                    // If we can't calculate downtime, just continue without it
                    // Silently fail to avoid disrupting notification sending
                }

                let discordupdata = {
                    username: discordDisplayName,
                    embeds: [
                        {
                            title: "✅ Your service " + monitorJSON["name"] + " is up! ✅",
                            color: 65280,
                            timestamp: heartbeatJSON["time"],
                            fields: [
                                {

Review comment (suggestion):
Notification providers are never allowed to do database queries.
This is really bad since if this is done and we change the schema a bit, we would need to test that this still works.

I don't have contribution capacity for this.

Please move the downtime tracking outside, to make it avaliable to all notifications

Code after:
                if (notification.discordPrefixMessage) {
                    discorddowndata.content = notification.discordPrefixMessage;
                }
                if (notification.discordSuppressNotifications) {
                    discorddowndata.flags = SUPPRESS_NOTIFICATIONS_FLAG;
                }

                await axios.post(webhookUrl.toString(), discorddowndata, config);
                return okMsg;
            } else if (heartbeatJSON["status"] === UP) {
                const backOnlineTimestamp = Math.floor(new Date(heartbeatJSON["time"]).getTime() / 1000);
                let downtimeDuration = null;
                let wentOfflineTimestamp = null;
                if (heartbeatJSON["lastDownTime"]) {
                    wentOfflineTimestamp = Math.floor(new Date(heartbeatJSON["lastDownTime"]).getTime() / 1000);
                    downtimeDuration = this.formatDuration(backOnlineTimestamp - wentOfflineTimestamp);
                }

                let discordupdata = {
                    username: discordDisplayName,
                    embeds: [
                        {
                            title: "✅ Your service " + monitorJSON["name"] + " is up! ✅",
                            color: 65280,
                            timestamp: heartbeatJSON["time"],
                            fields: [
                                {
                                    name: "Service Name",
                                    value: monitorJSON["name"],
                                },
                                ...(!notification.disableUrl && addess
                                    ? [
                                          {
                                              name: monitorJSON["type"] === "push" ? "Service Type" : "Service URL",
                                              value: addess,
                                          },
                                      ]
                                    : []),
                                ...(wentOfflineTimestamp
                                    ? [
                                          {
                                              name: "Went Offline",
                                              // F for full date/time
                                              value: `<t:${wentOfflineTimestamp}:F>`,
                                          },
                                      ]
                                    : []),
                                ...(downtimeDuration
                                    ? [
                                          {
                                              name: "Downtime Duration",