Ad Widget

Collapse

Zabbix vs Mattermost

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jbrveen
    Junior Member
    • Oct 2020
    • 1

    #1

    Zabbix vs Mattermost

    Hi there guys! We are using Zabbix for our monitoring and we want to have an automated message to our MatterMost instance. We can't get this to work: it constantly gives an Mattermost notification failed: SyntaxError: invalid json (at offset 1).

    I've been searchin'everywhere, including here, to find a solution. I'm using the MatterMost integration shipped within Zabbix. I can see on my MatterMost server that the identification goes correctly (to say: if I'm using a wrong bot_token it gives a warning in my MatterMost log, if I'm using the correct bot_token it doesn't say anything).

    This is the configuration shipped within Zabbix. Anyone? Cause I've been trying to debug this for hours and hours and it's driving me crazy. I do have a working connection with Slack, so I can connect Zabbix to Slack and use Matterbridge to connect Slack to Mattermost, but that seems a bit... bloated.

    Code:
    var SEVERITY_COLORS = [
    '#97AAB3', '#7499FF', '#FFC859',
    '#FFA059', '#E97659', '#E45959'
    ];
    
    var RESOLVE_COLOR = '#009900';
    
    var SEND_MODE_HANDLERS = {
    alarm: handlerAlarm,
    event: handlerEvent
    };
    
    if (!String.prototype.format) {
    String.prototype.format = function() {
    var args = arguments;
    
    return this.replace(/{(\d+)}/g, function(match, number) {
    return number in args
    ? args[number]
    : match
    ;
    });
    };
    }
    
    function isEventProblem(params) {
    return params.event_value == 1
    && params.event_update_status == 0
    ;
    }
    
    function isEventUpdate(params) {
    return params.event_value == 1
    && params.event_update_status == 1
    ;
    }
    
    function isEventResolve(params) {
    return params.event_value == 0;
    }
    
    function getPermalink(mattermost_url, team_name, postid) {
    return '{0}/{1}/pl/{2}'.format(
    mattermost_url.replace(/\/+$/, ''),
    team_name,
    postid
    );
    }
    
    function getChannel(send_to) {
    switch (true) {
    case /.+\/#.+/.test(send_to):
    return getChannelByName(send_to);
    
    case /@.+/.test(send_to):
    return getDirectChannel(send_to);
    
    default:
    return getChannelByID(send_to);
    }
    }
    
    function getChannelByName(send_to) {
    var team_chan = send_to
    .trim()
    .split('/#');
    
    var resp = JSON.parse(req.Get(
    Mattermost.channel_byname.format(team_chan[0], team_chan[1]),
    JSON.stringify(fields)
    )
    );
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function getDirectChannel(send_to) {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var teamUser = send_to
    .trim()
    .split('/@'),
    bot = getBotUser(),
    user = getUserByName(teamUser[1]);
    
    var resp = JSON.parse(req.Post(
    Mattermost.direct_channel,
    JSON.stringify([bot.id, user.id])
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    resp.team_name = teamUser[0];
    
    return resp;
    }
    
    function getChannelByID(channelID) {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var resp = JSON.parse(req.Get(
    Mattermost.get_channel.format(channelID),
    JSON.stringify(fields)
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function getBotUser() {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var resp = JSON.parse(req.Get(
    Mattermost.bot_user,
    JSON.stringify(fields)
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function getUserByName(userName) {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var resp = JSON.parse(req.Get(
    Mattermost.user_byname.format(userName),
    JSON.stringify(fields)
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function getTeamByID(teamID) {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var resp = JSON.parse(req.Get(
    Mattermost.get_team.format(teamID),
    JSON.stringify(fields)
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function createProblemURL(zabbix_url, triggerid, eventid, event_source) {
    var problem_url = '';
    if (event_source === '0') {
    problem_url = '{0}/tr_events.php?triggerid={1}&eventid={2}'
    .format(
    zabbix_url,
    triggerid,
    eventid
    );
    }
    else {
    problem_url = zabbix_url;
    }
    
    return problem_url;
    }
    
    function getTagValue(event_tags, key) {
    var pattern = new RegExp('(' + key + ':.+)');
    var tagValue = event_tags
    .split(',')
    .filter(function (v) {
    return v.match(pattern);
    })
    .map(function (v) {
    return v.split(':')[1];
    })[0]
    || 0;
    
    return tagValue;
    }
    
    function handlerAlarm(req, params) {
    var channel = getChannel(params.send_to);
    var fields = {
    channel_id: channel.id,
    props: {}
    };
    
    if (isEventProblem(params)) {
    var team_name = channel.team_name
    ? channel.team_name
    : getTeamByID(channel.team_id).name;
    
    fields.props.attachments = [
    createMessage(
    SEVERITY_COLORS[params.event_nseverity] || 0,
    params.event_date,
    params.event_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
    )
    ];
    
    var resp = JSON.parse(req.Post(
    Mattermost.post_message,
    JSON.stringify(fields)
    )
    );
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    result.tags.__mattermost_post_id = resp.id;
    result.tags.__mattermost_channel_id = channel.id;
    result.tags.__mattermost_channel_name = channel.name;
    result.tags.__mattermost_message_link = getPermalink(
    params.mattermost_url,
    team_name,
    resp.id
    );
    
    }
    else if (isEventUpdate(params)) {
    fields.root_id = getTagValue(params.event_tags, 'mattermost_post_id');
    
    if (params.event_source === '0') {}
    fields.props.attachments = [
    createMessage(
    SEVERITY_COLORS[params.event_nseverity] || 0,
    params.event_update_date,
    params.event_update_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),
    true
    )
    ];
    
    resp = JSON.parse(req.Post(
    Mattermost.post_message, JSON.stringify(fields)
    )
    );
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    }
    else if (isEventResolve(params)) {
    fields.channel_id = getTagValue(params.event_tags, 'mattermost_channel_id');
    fields.id = getTagValue(params.event_tags, 'mattermost_post_id');
    fields.props.attachments = [
    createMessage(
    RESOLVE_COLOR,
    params.event_date,
    params.event_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
    )
    ];
    
    var post_id = getTagValue(params.event_tags, 'mattermost_post_id');
    
    resp = JSON.parse(req.Put(
    Mattermost.chat_update.format(post_id),
    JSON.stringify(fields)
    )
    );
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    }
    }
    
    function handlerEvent(req, params) {
    var channel = getChannel(params.send_to);
    var fields = {
    channel_id: channel.id,
    props: {}
    };
    
    if (isEventProblem(params)) {
    var team_name = channel.team_name
    ? channel.team_name
    : getTeamByID(channel.team_id).name;
    
    fields.props.attachments = [
    createMessage(
    SEVERITY_COLORS[params.event_nseverity] || 0,
    params.event_date,
    params.event_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
    )
    ];
    
    var resp = JSON.parse(req.Post(Mattermost.post_message, JSON.stringify(fields)));
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    result.tags.__mattermost_channel_name = channel.name;
    result.tags.__mattermost_message_link = getPermalink(
    params.mattermost_url,
    team_name,
    resp.id
    );
    
    }
    else if (isEventUpdate(params)) {
    fields.props.attachments = [
    createMessage(
    SEVERITY_COLORS[params.event_nseverity] || 0,
    params.event_update_date,
    params.event_update_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),
    false
    )
    ];
    
    resp = JSON.parse(req.Post(Mattermost.post_message, JSON.stringify(fields)));
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    }
    else if (isEventResolve(params)) {
    fields.props.attachments = [
    createMessage(
    RESOLVE_COLOR,
    params.event_recovery_date,
    params.event_recovery_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
    )
    ];
    
    resp = JSON.parse(req.Post(Mattermost.post_message, JSON.stringify(fields)));
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    }
    }
    
    function createMessage(
    event_severity_color,
    event_date,
    event_time,
    problem_url,
    isShort
    ) {
    var message = {
    fallbac: params.alert_subject,
    title: params.alert_subject,
    color: event_severity_color,
    title_link: problem_url,
    footer: problem_url,
    
    fields: [
    {
    title: 'Host',
    value: '{0} [{1}]'.format(params.host_name, params.host_ip),
    short: true
    },
    {
    title: 'Event time',
    value: '{0} {1}'.format(event_date, event_time),
    short: true
    }
    ],
    };
    
    
    if (params.event_source === '0') {
    message.fields.push(
    {
    title: 'Severity',
    value: params.event_severity,
    short: true
    },
    {
    title: 'Opdata',
    value: params.event_opdata,
    short: true
    }
    );
    }
    
    if (!isShort && params.event_source === '0') {
    message.fields.push(
    {
    title: 'Event tags',
    value: '`{0}`'.format(params.event_tags.replace(/__.+?:(.+?,|.+)/g, '') || 'None'),
    short: true
    },
    {
    title: 'Trigger description',
    value: params.trigger_description,
    short: true
    }
    );
    }
    
    if (params.event_source !== '0' || params.event_update_status === '1') {
    message.fields.push(
    {
    title: 'Details',
    value: params.alert_message,
    short: false
    }
    );
    }
    
    return message;
    }
    
    function validateParams(params) {
    if (typeof params.bot_token !== 'string' || params.bot_token.trim() === '') {
    throw 'Field "bot_token" cannot be empty';
    }
    
    if (isNaN(params.event_id)) {
    throw 'Field "event_id" is not a number';
    }
    
    if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {
    throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.';
    }
    
    if (params.event_source !== '0') {
    params.event_nseverity = '0';
    params.event_severity = 'Not classified';
    params.event_update_status = '0';
    params.send_mode = 'event';
    }
    
    if (params.event_source === '1' || params.event_source === '2') {
    params.event_value = '1';
    }
    
    if (params.event_source === '1') {
    params.host_name = params.discovery_host_dns;
    params.host_ip = params.discovery_host_ip;
    }
    
    if ([0, 1, 2, 3, 4, 5].indexOf(parseInt(params.event_nseverity)) === -1) {
    throw 'Incorrect "event_nseverity" parameter given: ' + params.event_nseverity + '\nMust be 0-5.';
    }
    
    if (typeof params.event_severity !== 'string' || params.event_severity.trim() === '') {
    throw 'Field "event_severity" cannot be empty';
    }
    
    if (params.event_update_status !== '0' && params.event_update_status !== '1') {
    throw 'Incorrect "event_update_status" parameter given: ' + params.event_update_status + '\nMust be 0 or 1.';
    }
    
    if (params.event_value !== '0' && params.event_value !== '1') {
    throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';
    }
    
    if (typeof params.host_ip !== 'string' || params.host_ip.trim() === '') {
    throw 'Field "host_ip" cannot be empty';
    }
    
    if (typeof params.host_name !== 'string' || params.host_name.trim() === '') {
    throw 'Field "host_name" cannot be empty';
    }
    
    if (typeof params.mattermost_url !== 'string' || params.mattermost_url.trim() === '') {
    throw 'Field "mattermost_url" cannot be empty';
    }
    
    if (!/^(http|https):\/\/.+/.test(params.mattermost_url)) {
    throw 'Field "mattermost_url" must contain a schema';
    }
    
    if (['alarm', 'event'].indexOf(params.send_mode) === -1) {
    throw 'Incorrect "send_mode" parameter given: ' + params.send_mode + '\nMust be "alarm" or "event".';
    }
    
    if (typeof params.send_to !== 'string' || params.send_to.trim() === '') {
    throw 'Field "send_to" cannot be empty';
    }
    
    if (isNaN(params.trigger_id) && params.event_source === '0') {
    throw 'field "trigger_id" is not a number';
    }
    
    if (typeof params.zabbix_url !== 'string' || params.zabbix_url.trim() === '') {
    throw 'Field "zabbix_url" cannot be empty';
    }
    
    if (!/^(http|https):\/\/.+/.test(params.zabbix_url)) {
    throw 'Field "zabbix_url" must contain a schema';
    }
    
    }
    
    try {
    var params = JSON.parse(value);
    
    validateParams(params);
    
    var req = new CurlHttpRequest(),
    fields = {},
    result = {tags: {}};
    
    if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
    req.SetProxy(params.HTTPProxy);
    }
    
    req.AddHeader('Content-Type: application/json; charset=utf-8');
    req.AddHeader('Authorization: Bearer ' + params.bot_token);
    
    params.mattermost_url = params.mattermost_url.replace(/\/+$/, '');
    params.zabbix_url = params.zabbix_url.replace(/\/+$/, '');
    
    var APIEndpoint = params.mattermost_url + '/api/v4/';
    
    var Mattermost = {
    post_message: APIEndpoint + 'posts',
    get_channel: APIEndpoint + 'channels/{0}',
    get_team: APIEndpoint + 'teams/{0}',
    chat_update: APIEndpoint + 'posts/{0}',
    direct_channel: APIEndpoint + 'channels/direct',
    channel_byname: APIEndpoint + 'teams/name/{0}/channels/name/{1}',
    user_byname: APIEndpoint + 'users/username/{0}',
    bot_user: APIEndpoint + 'users/me'
    
    };
    
    params.send_mode = params.send_mode.toLowerCase();
    params.send_mode = params.send_mode in SEND_MODE_HANDLERS
    ? params.send_mode
    : 'alarm';
    
    SEND_MODE_HANDLERS[params.send_mode](req, params);
    
    if (params.event_source === '0') {
    return JSON.stringify(result);
    }
    else {
    return 'OK';
    }
    }
    catch (error) {
    Zabbix.Log(4, '[ Mattermost Webhook ] Mattermost notification failed: ' + error);
    throw 'Mattermost notification failed: ' + error;
    }
  • vincent1890
    Junior Member
    • Nov 2020
    • 11

    #2
    Originally posted by jbrveen
    Hi there guys! We are using Zabbix for our monitoring and we want to have an automated message to our MatterMost instance. We can't get this to work: it constantly gives an Mattermost notification failed: SyntaxError: invalid json (at offset 1).

    I've been searchin'everywhere, including here, to find a solution. I'm using the MatterMost integration shipped within Zabbix. I can see on my MatterMost server that the identification goes correctly (to say: if I'm using a wrong bot_token it gives a warning in my MatterMost log, if I'm using the correct bot_token it doesn't say anything).

    This is the configuration shipped within Zabbix. Anyone? Cause I've been trying to debug this for hours and hours and it's driving me crazy. I do have a working connection with Slack, so I can connect Zabbix to Slack and use Matterbridge to connect Slack to Mattermost, but that seems a bit... bloated.

    Code:
    var SEVERITY_COLORS = [
    '#97AAB3', '#7499FF', '#FFC859',
    '#FFA059', '#E97659', '#E45959'
    ];
    
    var RESOLVE_COLOR = '#009900';
    
    var SEND_MODE_HANDLERS = {
    alarm: handlerAlarm,
    event: handlerEvent
    };
    
    if (!String.prototype.format) {
    String.prototype.format = function() {
    var args = arguments;
    
    return this.replace(/{(\d+)}/g, function(match, number) {
    return number in args
    ? args[number]
    : match
    ;
    });
    };
    }
    
    function isEventProblem(params) {
    return params.event_value == 1
    && params.event_update_status == 0
    ;
    }
    
    function isEventUpdate(params) {
    return params.event_value == 1
    && params.event_update_status == 1
    ;
    }
    
    function isEventResolve(params) {
    return params.event_value == 0;
    }
    
    function getPermalink(mattermost_url, team_name, postid) {
    return '{0}/{1}/pl/{2}'.format(
    mattermost_url.replace(/\/+$/, ''),
    team_name,
    postid
    );
    }
    
    function getChannel(send_to) {
    switch (true) {
    case /.+\/#.+/.test(send_to):
    return getChannelByName(send_to);
    
    case /@.+/.test(send_to):
    return getDirectChannel(send_to);
    
    default:
    return getChannelByID(send_to);
    }
    }
    
    function getChannelByName(send_to) {
    var team_chan = send_to
    .trim()
    .split('/#');
    
    var resp = JSON.parse(req.Get(
    Mattermost.channel_byname.format(team_chan[0], team_chan[1]),
    JSON.stringify(fields)
    )
    );
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function getDirectChannel(send_to) {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var teamUser = send_to
    .trim()
    .split('/@'),
    bot = getBotUser(),
    user = getUserByName(teamUser[1]);
    
    var resp = JSON.parse(req.Post(
    Mattermost.direct_channel,
    JSON.stringify([bot.id, user.id])
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    resp.team_name = teamUser[0];
    
    return resp;
    }
    
    function getChannelByID(channelID) {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var resp = JSON.parse(req.Get(
    Mattermost.get_channel.format(channelID),
    JSON.stringify(fields)
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function getBotUser() {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var resp = JSON.parse(req.Get(
    Mattermost.bot_user,
    JSON.stringify(fields)
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function getUserByName(userName) {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var resp = JSON.parse(req.Get(
    Mattermost.user_byname.format(userName),
    JSON.stringify(fields)
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function getTeamByID(teamID) {
    Zabbix.Log(5, '[ Mattermost Webhook ] Call {0}({1})'.format(
    arguments.callee.name,
    JSON.stringify(arguments)
    ));
    
    var resp = JSON.parse(req.Get(
    Mattermost.get_team.format(teamID),
    JSON.stringify(fields)
    )
    );
    
    Zabbix.Log(5, '[ Mattermost Webhook ] Result {0}: {1}'.format(
    arguments.callee.name,
    JSON.stringify(resp)
    ));
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    return resp;
    }
    
    function createProblemURL(zabbix_url, triggerid, eventid, event_source) {
    var problem_url = '';
    if (event_source === '0') {
    problem_url = '{0}/tr_events.php?triggerid={1}&eventid={2}'
    .format(
    zabbix_url,
    triggerid,
    eventid
    );
    }
    else {
    problem_url = zabbix_url;
    }
    
    return problem_url;
    }
    
    function getTagValue(event_tags, key) {
    var pattern = new RegExp('(' + key + ':.+)');
    var tagValue = event_tags
    .split(',')
    .filter(function (v) {
    return v.match(pattern);
    })
    .map(function (v) {
    return v.split(':')[1];
    })[0]
    || 0;
    
    return tagValue;
    }
    
    function handlerAlarm(req, params) {
    var channel = getChannel(params.send_to);
    var fields = {
    channel_id: channel.id,
    props: {}
    };
    
    if (isEventProblem(params)) {
    var team_name = channel.team_name
    ? channel.team_name
    : getTeamByID(channel.team_id).name;
    
    fields.props.attachments = [
    createMessage(
    SEVERITY_COLORS[params.event_nseverity] || 0,
    params.event_date,
    params.event_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
    )
    ];
    
    var resp = JSON.parse(req.Post(
    Mattermost.post_message,
    JSON.stringify(fields)
    )
    );
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    result.tags.__mattermost_post_id = resp.id;
    result.tags.__mattermost_channel_id = channel.id;
    result.tags.__mattermost_channel_name = channel.name;
    result.tags.__mattermost_message_link = getPermalink(
    params.mattermost_url,
    team_name,
    resp.id
    );
    
    }
    else if (isEventUpdate(params)) {
    fields.root_id = getTagValue(params.event_tags, 'mattermost_post_id');
    
    if (params.event_source === '0') {}
    fields.props.attachments = [
    createMessage(
    SEVERITY_COLORS[params.event_nseverity] || 0,
    params.event_update_date,
    params.event_update_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),
    true
    )
    ];
    
    resp = JSON.parse(req.Post(
    Mattermost.post_message, JSON.stringify(fields)
    )
    );
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    }
    else if (isEventResolve(params)) {
    fields.channel_id = getTagValue(params.event_tags, 'mattermost_channel_id');
    fields.id = getTagValue(params.event_tags, 'mattermost_post_id');
    fields.props.attachments = [
    createMessage(
    RESOLVE_COLOR,
    params.event_date,
    params.event_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
    )
    ];
    
    var post_id = getTagValue(params.event_tags, 'mattermost_post_id');
    
    resp = JSON.parse(req.Put(
    Mattermost.chat_update.format(post_id),
    JSON.stringify(fields)
    )
    );
    
    if (req.Status() != 200) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    }
    }
    
    function handlerEvent(req, params) {
    var channel = getChannel(params.send_to);
    var fields = {
    channel_id: channel.id,
    props: {}
    };
    
    if (isEventProblem(params)) {
    var team_name = channel.team_name
    ? channel.team_name
    : getTeamByID(channel.team_id).name;
    
    fields.props.attachments = [
    createMessage(
    SEVERITY_COLORS[params.event_nseverity] || 0,
    params.event_date,
    params.event_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
    )
    ];
    
    var resp = JSON.parse(req.Post(Mattermost.post_message, JSON.stringify(fields)));
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    result.tags.__mattermost_channel_name = channel.name;
    result.tags.__mattermost_message_link = getPermalink(
    params.mattermost_url,
    team_name,
    resp.id
    );
    
    }
    else if (isEventUpdate(params)) {
    fields.props.attachments = [
    createMessage(
    SEVERITY_COLORS[params.event_nseverity] || 0,
    params.event_update_date,
    params.event_update_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),
    false
    )
    ];
    
    resp = JSON.parse(req.Post(Mattermost.post_message, JSON.stringify(fields)));
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    
    }
    else if (isEventResolve(params)) {
    fields.props.attachments = [
    createMessage(
    RESOLVE_COLOR,
    params.event_recovery_date,
    params.event_recovery_time,
    createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
    )
    ];
    
    resp = JSON.parse(req.Post(Mattermost.post_message, JSON.stringify(fields)));
    
    if (req.Status() != 201) {
    throw '[{0}] {1}'.format(resp.status_code, resp.message);
    }
    }
    }
    
    function createMessage(
    event_severity_color,
    event_date,
    event_time,
    problem_url,
    isShort
    ) {
    var message = {
    fallbac: params.alert_subject,
    title: params.alert_subject,
    color: event_severity_color,
    title_link: problem_url,
    footer: problem_url,
    
    fields: [
    {
    title: 'Host',
    value: '{0} [{1}]'.format(params.host_name, params.host_ip),
    short: true
    },
    {
    title: 'Event time',
    value: '{0} {1}'.format(event_date, event_time),
    short: true
    }
    ],
    };
    
    
    if (params.event_source === '0') {
    message.fields.push(
    {
    title: 'Severity',
    value: params.event_severity,
    short: true
    },
    {
    title: 'Opdata',
    value: params.event_opdata,
    short: true
    }
    );
    }
    
    if (!isShort && params.event_source === '0') {
    message.fields.push(
    {
    title: 'Event tags',
    value: '`{0}`'.format(params.event_tags.replace(/__.+?:(.+?,|.+)/g, '') || 'None'),
    short: true
    },
    {
    title: 'Trigger description',
    value: params.trigger_description,
    short: true
    }
    );
    }
    
    if (params.event_source !== '0' || params.event_update_status === '1') {
    message.fields.push(
    {
    title: 'Details',
    value: params.alert_message,
    short: false
    }
    );
    }
    
    return message;
    }
    
    function validateParams(params) {
    if (typeof params.bot_token !== 'string' || params.bot_token.trim() === '') {
    throw 'Field "bot_token" cannot be empty';
    }
    
    if (isNaN(params.event_id)) {
    throw 'Field "event_id" is not a number';
    }
    
    if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {
    throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.';
    }
    
    if (params.event_source !== '0') {
    params.event_nseverity = '0';
    params.event_severity = 'Not classified';
    params.event_update_status = '0';
    params.send_mode = 'event';
    }
    
    if (params.event_source === '1' || params.event_source === '2') {
    params.event_value = '1';
    }
    
    if (params.event_source === '1') {
    params.host_name = params.discovery_host_dns;
    params.host_ip = params.discovery_host_ip;
    }
    
    if ([0, 1, 2, 3, 4, 5].indexOf(parseInt(params.event_nseverity)) === -1) {
    throw 'Incorrect "event_nseverity" parameter given: ' + params.event_nseverity + '\nMust be 0-5.';
    }
    
    if (typeof params.event_severity !== 'string' || params.event_severity.trim() === '') {
    throw 'Field "event_severity" cannot be empty';
    }
    
    if (params.event_update_status !== '0' && params.event_update_status !== '1') {
    throw 'Incorrect "event_update_status" parameter given: ' + params.event_update_status + '\nMust be 0 or 1.';
    }
    
    if (params.event_value !== '0' && params.event_value !== '1') {
    throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';
    }
    
    if (typeof params.host_ip !== 'string' || params.host_ip.trim() === '') {
    throw 'Field "host_ip" cannot be empty';
    }
    
    if (typeof params.host_name !== 'string' || params.host_name.trim() === '') {
    throw 'Field "host_name" cannot be empty';
    }
    
    if (typeof params.mattermost_url !== 'string' || params.mattermost_url.trim() === '') {
    throw 'Field "mattermost_url" cannot be empty';
    }
    
    if (!/^(http|https):\/\/.+/.test(params.mattermost_url)) {
    throw 'Field "mattermost_url" must contain a schema';
    }
    
    if (['alarm', 'event'].indexOf(params.send_mode) === -1) {
    throw 'Incorrect "send_mode" parameter given: ' + params.send_mode + '\nMust be "alarm" or "event".';
    }
    
    if (typeof params.send_to !== 'string' || params.send_to.trim() === '') {
    throw 'Field "send_to" cannot be empty';
    }
    
    if (isNaN(params.trigger_id) && params.event_source === '0') {
    throw 'field "trigger_id" is not a number';
    }
    
    if (typeof params.zabbix_url !== 'string' || params.zabbix_url.trim() === '') {
    throw 'Field "zabbix_url" cannot be empty';
    }
    
    if (!/^(http|https):\/\/.+/.test(params.zabbix_url)) {
    throw 'Field "zabbix_url" must contain a schema';
    }
    
    }
    
    try {
    var params = JSON.parse(value);
    
    validateParams(params);
    
    var req = new CurlHttpRequest(),
    fields = {},
    result = {tags: {}};
    
    if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
    req.SetProxy(params.HTTPProxy);
    }
    
    req.AddHeader('Content-Type: application/json; charset=utf-8');
    req.AddHeader('Authorization: Bearer ' + params.bot_token);
    
    params.mattermost_url = params.mattermost_url.replace(/\/+$/, '');
    params.zabbix_url = params.zabbix_url.replace(/\/+$/, '');
    
    var APIEndpoint = params.mattermost_url + '/api/v4/';
    
    var Mattermost = {
    post_message: APIEndpoint + 'posts',
    get_channel: APIEndpoint + 'channels/{0}',
    get_team: APIEndpoint + 'teams/{0}',
    chat_update: APIEndpoint + 'posts/{0}',
    direct_channel: APIEndpoint + 'channels/direct',
    channel_byname: APIEndpoint + 'teams/name/{0}/channels/name/{1}',
    user_byname: APIEndpoint + 'users/username/{0}',
    bot_user: APIEndpoint + 'users/me'
    
    };
    
    params.send_mode = params.send_mode.toLowerCase();
    params.send_mode = params.send_mode in SEND_MODE_HANDLERS
    ? params.send_mode
    : 'alarm';
    
    SEND_MODE_HANDLERS[params.send_mode](req, params);
    
    if (params.event_source === '0') {
    return JSON.stringify(result);
    }
    else {
    return 'OK';
    }
    }
    catch (error) {
    Zabbix.Log(4, '[ Mattermost Webhook ] Mattermost notification failed: ' + error);
    throw 'Mattermost notification failed: ' + error;
    }
    Hello
    Did you manage to find the problem I use Zabbix 5.2 and I have the same behavior as you?
    Thank you and have a good day

    Comment

    • jaayb
      Junior Member
      • Jan 2024
      • 1

      #3
      Had the same problem. Solution was that I was using the Token ID instead of the access token in the mattermost template. I also changed the zabbix username to zabbix-alerter vs "zabbix alerter" as the documentation said. Finally the mattermost url is just the fqdn of the server vs the web hook url which is what I was using. You have to copy the access token as mattermost indicates that it won't be shown again after the first time it is created. I thought the token id shown in the bot settings was the access token. Had to delete and recreate the token to get the access token value.

      Comment

      Working...