Issues (2963)

LibreNMS/Alert/Transport/Discord.php (1 issue)

1
<?php
2
/**
3
 * Discord.php
4
 *
5
 * LibreNMS Discord API Tranport
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
 *
20
 * @link       https://www.librenms.org
21
 *
22
 * @copyright  2018 Ryan Finney
23
 * @author     https://github.com/theherodied/
24
 * @contributer f0o, sdef2
25
 * Thanks to F0o <[email protected]> for creating the Slack transport which is the majority of this code.
26
 * Thanks to sdef2 for figuring out the differences needed to make Discord work.
27
 */
28
29
namespace LibreNMS\Alert\Transport;
30
31
use LibreNMS\Alert\Transport;
32
33
class Discord extends Transport
34
{
35
    const ALERT_FIELDS_TO_DISCORD_FIELDS = [
36
        'timestamp' => 'Timestamp',
37
        'severity' => 'Severity',
38
        'hostname' => 'Hostname',
39
        'name' => 'Rule Name',
40
        'rule' => 'Rule',
41
    ];
42
43
    public function deliverAlert($obj, $opts)
44
    {
45
        $discord_opts = [
46
            'url' => $this->config['url'],
47
            'options' => $this->parseUserOptions($this->config['options']),
48
        ];
49
50
        return $this->contactDiscord($obj, $discord_opts);
51
    }
52
53
    public function contactDiscord($obj, $discord_opts)
54
    {
55
        $host = $discord_opts['url'];
56
        $curl = curl_init();
57
        $discord_title = '#' . $obj['uid'] . ' ' . $obj['title'];
58
        $discord_msg = strip_tags($obj['msg']);
59
        $color = self::getColorForState($obj['state']);
60
61
        // Special handling for the elapsed text in the footer if the elapsed is not set.
62
        $footer_text = $obj['elapsed'] ? 'alert took ' . $obj['elapsed'] : '';
63
64
        $data = [
65
            'embeds' => [
66
                [
67
                    'title' => $discord_title,
68
                    'color' => hexdec($color),
69
                    'description' => $discord_msg,
70
                    'fields' => $this->createDiscordFields($obj, $discord_opts),
71
                    'footer' => [
72
                        'text' => $footer_text,
73
                    ],
74
                ],
75
            ],
76
        ];
77
        if (! empty($discord_opts['options'])) {
78
            $data = array_merge($data, $discord_opts['options']);
79
        }
80
81
        $alert_message = json_encode($data);
82
        curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
83
        set_curl_proxy($curl);
84
        curl_setopt($curl, CURLOPT_URL, $host);
85
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
86
        curl_setopt($curl, CURLOPT_POST, true);
87
        curl_setopt($curl, CURLOPT_POSTFIELDS, $alert_message);
88
89
        $ret = curl_exec($curl);
90
        $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
91
        if ($code != 204) {
92
            var_dump("API '$host' returned Error"); //FIXME: propper debuging
0 ignored issues
show
Security Debugging Code introduced by
var_dump('API ''.$host.'' returned Error') looks like debug code. Are you sure you do not want to remove it?
Loading history...
93
            var_dump('Params: ' . $alert_message); //FIXME: propper debuging
94
            var_dump('Return: ' . $ret); //FIXME: propper debuging
95
96
            return 'HTTP Status code ' . $code;
97
        }
98
99
        return true;
100
    }
101
102
    public function createDiscordFields($obj, $discord_opts)
103
    {
104
        $result = [];
105
106
        foreach (self::ALERT_FIELDS_TO_DISCORD_FIELDS as $objKey => $discordKey) {
107
            // Skip over keys that do not exist so Discord does not give us a 400.
108
            if (! $obj[$objKey]) {
109
                continue;
110
            }
111
112
            array_push($result, [
113
                'name' => $discordKey,
114
                'value' => $obj[$objKey],
115
            ]);
116
        }
117
118
        return $result;
119
    }
120
121
    public static function configTemplate()
122
    {
123
        return [
124
            'config' => [
125
                [
126
                    'title' => 'Discord URL',
127
                    'name' => 'url',
128
                    'descr' => 'Discord URL',
129
                    'type' => 'text',
130
                ],
131
                [
132
                    'title' => 'Options',
133
                    'name' => 'options',
134
                    'descr' => 'Enter the config options (format: option=value separated by new lines)',
135
                    'type' => 'textarea',
136
                ],
137
            ],
138
            'validation' => [
139
                'url' => 'required|url',
140
            ],
141
        ];
142
    }
143
}
144