Allow administrators to use JSON MessageCard in Msteams transport rather than just markdown

Currently, the Msteams transport is rather limited given that the $obj[‘msg’] is entered into the “text” field at the top of the JSON hierarchy:

Excerpt from /opt/librenms/LibreNMS/Alert/Transport/Msteams.php

 $data  = array(
    'title' => $obj['title'],
    'themeColor' => self::getColorForState($obj['state']),
    'text' => strip_tags($obj['msg'], "<strong><em><h1><h2><h3><strike><ul><ol><li><pre><blockquote><a><img><p>")
    ...
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));

This limits the capability of the text entered into the template to be in either HTML or Markdown (Microsoft recommends Markdown and discourages HTML in this case, but the LibreNMS example currently uses HTML so the documentation should probably be updated to use markdown). There are a lot more features to the JSON MessageCard and without the ability to format the JSON oneself, administrators are severely limited in the functionality of this alert format. I think it would greatly benefit admins to have the ability to manually format the card themselves as they would be able to take advantage of all of the additional features of MessageCards such as buttons that would acknowledge the alert or add a comment using the LibreNMS API. As time goes on this could be converted into fancy buttons and such, but initially it would be nice to at least have the option to use the JSON directly. Example:

{
    "@context": "https://schema.org/extensions",
    "@type": "MessageCard",
    "title": "{{ $alert->title }}",z
@if ($alert->state != 0)
    "themeColor": "FF0000",
@else
    "themeColor": "00FF00",
@endif
    "summary": "LibreNMS",
    "sections": [
        {
@if ($alert->name)
            "text": "**Rule:** [{{ $alert->name }}](https://your-librenms-url/device/device={{ $alert->device_id > }}/tab=alert/)  
@else
            "text": "**Rule:** [{{ $alert->rule }}](https://your-librenms-url/device/device={{ $alert->device_id > }}/tab=alert/)  
@endif
            **Severity:** {{ $alert->severity }}  
            **Unique-ID:** {{ $alert->uid }}  
            **Timestamp:** {{ $alert->timestamp }}  
@if ($alert->state == 0)
            **Time elapsed:** {{ $alert->elapsed }}  
@endif
            **Hostname:** [{{ $alert->hostname }}](https://your-librenms-url/device/device={{ $alert->device_id }}/)  
            **Hardware:** {{ $alert->hardware }}  
            **IP:** {{ $alert->ip }}  
            **Faults:**  
@if ($alert->faults)
@foreach ($alert->faults as $key => $value)
            **Port:** [{{ $value['ifName'] }}](https://your-librenms-url/device/device={{ $alert->device_id }}/tab=port/port={{ $value['port_id'] }}/)  
            **Description:** {{ $value['ifAlias'] }}  
@if ($alert->state != 0)
            **Status:** down",
@else
            **Status:** up",
@endif
@endforeach
@endif
        }
    ]
}

Could be as simple as:

Adding to /opt/librenms/LibreNMS/Alert/Transport/Msteams.php:

    public function contactMsteams($obj, $opts)
    {
        ...
        if ($this->config['use-json'] === 'on') {
            curl_setopt($curl, CURLOPT_POSTFIELDS, $obj['msg']);
        } else {
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
        }
        ...
    public static function configTemplate()
    {
        return [
            'config' => [
                ...
                [
                    'title' => 'Use JSON?',
                    'name' => 'use-json',
                    'descr' => 'Use JSON when sending the alert',
                    'type' => 'checkbox',
                    'default' => false,
                ]
                ...
1 Like

You should submit a pull request.