Nextcloud Talk Transport

It would be nice for LibreNMS to have a Nextcloud Talk transport.

See below for code that could be used as-is or as a starting point.

I do not consider myself a PHP expert and I have relatively little experience with Nextcloud APIs, but this seems to work on two Nextcloud installations, one of which has had the URL shortened.

<?php
/**
 * LibreNMS Nextcloud Talk alerting transport
 * 
 * Copyright (c) 2023 Dan Mahn
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

namespace LibreNMS\Alert\Transport;

use LibreNMS\Alert\Transport;
use LibreNMS\Util\Proxy;

class Nextcloudtalk extends Transport
{
    protected $name = 'Nextcloud Talk';

    public function deliverAlert($obj, $opts)
    {
        $link = $this->config['nextcloudtalk-link'];
        $username = $this->config['nextcloudtalk-username'];
        $password = $this->config['nextcloudtalk-password'];

        return $this->contactNextcloudtalk($obj, $link, $username, $password);
    }

    public static function contactNextcloudtalk($obj, $link, $username, $password)
    {

        $json_data = [
            'message' => strip_tags($obj['msg']),
        ];
        $json_payload = json_encode($json_data);

        $callapi = ['/index.php/call/', '/call/'];
        $chatapi = '/ocs/v2.php/apps/spreed/api/v1/chat/';
        $url = str_replace($callapi, $chatapi, $link);

        // cURL resource ...
        $ch = curl_init($url);
        Proxy::applyToCurl($ch);

        curl_setopt($ch, CURLOPT_POSTFIELDS, $json_payload);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json', 'OCS-APIRequest: true']);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");

        // POST request
        $result = curl_exec($ch);

        // Get result code
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        // ... cURL resource
        curl_close($ch);

        if ($code != 201) {
            return 'HTTP(S) Status code ' . $code;
        }

        return true;
    }


    public static function configTemplate()
    {
        return [
            'config' => [
                [
                    'title' => 'Conversation Link',
                    'name' => 'nextcloudtalk-link',
                    'descr' => 'Nextcloud conversation link, e.g. https://cloud.somewhere.tld/call/{token}',
                    'type' => 'text'
                ],
                [
                    'title' => 'Username',
                    'name' => 'nextcloudtalk-username',
                    'descr' => 'Nextcloud username',
                    'type' => 'text',
                ],
                [
                    'title' => 'App Password',
                    'name' => 'nextcloudtalk-password',
                    'descr' => 'Nextcloud app password',
                    'type' => 'password',
                ],
            ],
            'validation' => [
                'nextcloudtalk-link' => 'required|string',
                'nextcloudtalk-username' => 'required|string',
                'nextcloudtalk-password' => 'required|string',
            ],
        ];
    }
}

1 Like