try {
    var params = JSON.parse(value),
        request = new CurlHttpRequest(),
        data,
        response,
        severities = [
            {name: 'not_classified', color: '#97AAB3'},
            {name: 'information', color: '#7499FF'},
            {name: 'warning', color: '#FFC859'},
            {name: 'average', color: '#FFA059'},
            {name: 'high', color: '#E97659'},
            {name: 'disaster', color: '#E45959'},
            {name: 'resolved', color: '#009900'},
            {name: 'default', color: '#000000'}
        ],
        priority;

    if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
        request.SetProxy(params.HTTPProxy);
    }

    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_value !== '0' && params.event_value !== '1'
        && (params.event_source === '0' || params.event_source === '3')) {
        throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';
    }

    if ([0, 1, 2, 3, 4, 5].indexOf(parseInt(params.event_nseverity)) === -1) {
        params.event_nseverity = '7';
    }

    if (params.event_value === '0') {
        params.event_nseverity = '6';
    }

    priority = params['priority_' + severities[params.event_nseverity].name] || params.priority_default;

    if (isNaN(priority) || priority < -2 || priority > 2) {
        throw '"priority" should be -2..2';
    }

    if (params.event_source === '0' && isNaN(params.triggerid)) {
        throw 'field "triggerid" is not a number';
    }

    if (isNaN(params.eventid)) {
        throw 'field "eventid" is not a number';
    }

    if (typeof params.message !== 'string' || params.message.trim() === '') {
        throw 'field "message" cannot be empty';
    }

    data = {
        token: params.token,
        user: params.user,
        title: params.title,
        message: params.message,
        url: (params.event_source === '0') 
            ? params.url + '/tr_events.php?triggerid=' + params.triggerid + '&eventid=' + params.eventid
            : params.url,
        url_title: params.url_title,
        priority: priority
    };

    if (priority == 2) {
        if (isNaN(params.retry) || params.retry < 30) {
            throw 'field "retry" should be a number with value of at least 30 if "priority" is set to 2';
        }

        if (isNaN(params.expire) || params.expire > 10800) {
            throw 'field "expire" should be a number with value of at most 10800 if "priority" is set to 2';
        }

        data.retry = params.retry;
        data.expire = params.expire;
    }

    data = JSON.stringify(data);
    Zabbix.Log(4, '[ Pushover Webhook ] Sending request: ' + params.endpoint + '\n' + data);

    request.AddHeader('Content-Type: application/json');
    response = request.Post(params.endpoint, data);

    Zabbix.Log(4, '[ Pushover Webhook ] Received response with status code ' + request.Status() + '\n' + response);

    if (response !== null) {
        try {
            response = JSON.parse(response);
        }
        catch (error) {
            Zabbix.Log(4, '[ Pushover Webhook ] Failed to parse response received from Pushover');
            response = null;
        }
    }

    if (request.Status() != 200 || response === null || typeof response !== 'object' || response.status !== 1) {
        if (response !== null && typeof response === 'object' && typeof response.errors === 'object'
                && typeof response.errors[0] === 'string') {
            throw response.errors[0];
        }
        else {
            throw 'Unknown error. Check debug log for more information.';
        }
    }

    return 'OK';
}
catch (error) {
    Zabbix.Log(4, '[ Pushover Webhook ] Pushover notification failed: ' + error);
    throw 'Pushover notification failed: ' + error;
}