Generic webhook alerts (e.g. for Discord)

Problem/Justification
TrueNAS offers many notification services like Slack, Mattermost, Email and so on. I happen to be a happy user of Discord and sending messages to it is very simple, just a webhook. Even though TrueNAS uses webhooks for some of the preexisting services, a generic webhook service would be welcome.

Impact
Users could send alerts to arbitrary communication platforms supporting webhooks, on of which is Discord. Webhook consumers are also easy to set up, so making a custom service would be simple.

User Story
I am a long time user of unRAID, but when setting up a NAS for my friends company, I ventured into TrueNAS mainly for ZFS. I have a Discord server, where any server I maintain pings me, if anything goes wrong. I see UPS status, daily disk-array health reports and even when a new docker container version becomes available. I’d like to integrate the new server into this. A generic webhook would solve such problem.

2 Likes

Related: Add ntfy.sh and shoutrrr Alert services

It think it would be nice if we could allow users to

  1. Specify the webhook url;
  2. Specify request headers, if any;
  3. A request body template, e.g.,

JSON:

{"text": "${message:json}", "something": "else"}

XML:

<alert>${message:xml}</alert>

application/x-www-form-urlencoded:

text=${message:url}&something=else

Plaintext:

${message}

where ${message} is the alert message placeholder and :format escapes the message based on format.

1 Like

This is a great suggestion. This would help with a wide range of endpoints. As an example, I was a huge consumer of Teams and had a channel specifically for alerts at my previous org. This would have been really nice to have.

In fact I still use this at home. I have an o365 small business account and I have uptime-kuma send me alerts this way.

hello, I was looking for something similar and have found this works.
EDIT: May not be what your looking for though.
https://www.reddit.com/r/freenas/comments/bmbyk7/discord_notifications/


discord_server

2 Likes

Ahh thats an interesting work-around. Looks like Discord has “slack compatibility mode”
Discord Developer Portal — Documentation — Webhook

Using this trick, Teams does work (I did not have to append /slack) Perhaps this feature request should be to rename “Slack” to “Webhook”

@matesaktesak If this workaround is Ok for you, can we turn this into a documentation request?

No, I don’t think its enough… I have been using the workaroud…and it works but let me make a comparison of what a customized hook on unRAID looks like compared to the one provided for Slack:


TrueNAS slack notification

These are night and day. I don’t necessarly want the TrueNAS team to make the hooks preatty, but let me do it.

You may want verbose on a system with 5 drives, but the guy managing a 1,000 drive system probably doesn’t want verbose.

Yes, I mentioned the need for this feature a long time ago because I want to send my notifications to my WeChat above, and WeChat is the only place where I can be notified in time!

Yes, that is a very good point. I was talking more about the mesage using an embed. I chose to get the verbose drive reports, they can be turned off. The green strip on the left is red on error messages and errors ping me.

My request really is about the option to customize these to my liking, both the looks and the contents.

We generally prioritize based on community votes or customer pain.

If you can explain time wasted or technical problems, it helps. If others have the same issues, even better. If you want to develop a solution, we are usually glad of assistance.

I have an alternative way to implement it and it’s compatible with any project’s webhook, provided you need a little bit of programming knowledge, see my example which forwards to WeChat above. Just select “Slack” for the notification access and point the url to the php service you’re running and the path to it.

<?php

header('Content-Type: application/json');
date_default_timezone_set('Asia/Shanghai');

$postData = file_get_contents('php://input');
$data = json_decode($postData, true); 

$logMessage = "[" . date('Y-m-d H:i:s') . "] Received POST data: " . $postData . "\n";


if (!isset($data['text'])) {

    $logMessage .= "[" . date('Y-m-d H:i:s') . "] Error: Invalid input data\n";
    writeLog($logMessage);
    
    http_response_code(200);
    echo json_encode(['ok' => false]);
    exit;
}

$payload = json_encode([
    'msgtype' => 'text',
    'text' => ['content' => $data['text']."\n\n".date('Y-m-d H:i:s')]
]);

// Webhook URL
$url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=your KKKKKKKEY";

// POST JSON
$options = [
    'http' => [
        'header'  => "Content-type: application/json\r\n",
        'method'  => 'POST',
        'content' => $payload
    ]
];

$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);

if ($result === FALSE) {
    // Error
    $logMessage .= "[" . date('Y-m-d H:i:s') . "] Error: Failed to send data to WeChat\n";
    $response = ['ok' => false];
} else {
    // Success
    $response = json_decode($result, true);
    if ($response && $response['errcode'] === 0) {
        $logMessage .= "[" . date('Y-m-d H:i:s') . "] Success: Data sent to WeChat, response: " . $result . "\n";
        $response = ['ok' => true];
    } else {
        $logMessage .= "[" . date('Y-m-d H:i:s') . "] Error: WeChat response error: " . $result . "\n";
        $response = ['ok' => false];
    }
}

//  logs
writeLog($logMessage);

http_response_code(200);
echo json_encode($response);


function writeLog($message) {
    $logDir = __DIR__ . '/logs'; 
    if (!file_exists($logDir)) {
        mkdir($logDir, 0777, true); 
    }
    $logFile = $logDir . '/log_' . date('Y-m-d') . '.log';
    file_put_contents($logFile, $message, FILE_APPEND); 
}
?>