← Script library

Business Rules

Integrate with External System (Webhook)

Send data to external systems via REST API webhooks when records are created or updated (e.g., Slack, Teams, third-party systems).

JavaScript
(function executeRule(current, previous /*null when async*/) {

  try {
    // Configuration: Define webhook settings
    var webhookUrl = gs.getProperty('integration.webhook.url');  // Store URL in system property
    var webhookEnabled = gs.getProperty('integration.webhook.enabled', 'false') === 'true';

    if (!webhookEnabled || !webhookUrl) {
      gs.info('Webhook integration disabled or URL not configured');
      return;
    }

    // Define conditions for sending webhook
    var shouldSendWebhook = false;

    // Example 1: Send webhook for high-priority incidents
    if (current.priority.toString() === '1') {  // Critical priority
      shouldSendWebhook = true;
    }

    // Example 2: Send webhook when incident is resolved
    if (current.state.changesTo('6')) {  // Resolved
      shouldSendWebhook = true;
    }

    // Example 3: Send webhook for new incidents
    if (current.isNewRecord()) {
      shouldSendWebhook = true;
    }

    if (!shouldSendWebhook) {
      return;
    }

    // Build payload
    var payload = {
      event_type: current.isNewRecord() ? 'incident.created' : 'incident.updated',
      timestamp: new GlideDateTime().getValue(),
      incident: {
        sys_id: current.sys_id.toString(),
        number: current.number.toString(),
        short_description: current.short_description.toString(),
        state: current.state.getDisplayValue(),
        priority: current.priority.getDisplayValue(),
        urgency: current.urgency.getDisplayValue(),
        impact: current.impact.getDisplayValue(),
        category: current.category.toString(),
        assignment_group: current.assignment_group.getDisplayValue(),
        assigned_to: current.assigned_to.getDisplayValue(),
        caller: {
          name: current.caller_id.getDisplayValue(),
          email: current.caller_id.email.toString(),
          phone: current.caller_id.phone.toString()
        },
        opened_at: current.opened_at.getDisplayValue(),
        url: gs.getProperty('glide.servlet.uri') + 'incident.do?sys_id=' + current.sys_id
      },
      metadata: {
        instance: gs.getProperty('instance_name'),
        updated_by: gs.getUserName()
      }
    };

    // Add change-specific data for updates
    if (!current.isNewRecord() && previous) {
      payload.changes = [];

      var trackedFields = ['priority', 'state', 'assignment_group', 'assigned_to'];
      trackedFields.forEach(function(field) {
        if (current[field].changes()) {
          payload.changes.push({
            field: field,
            old_value: previous[field].getDisplayValue(),
            new_value: current[field].getDisplayValue()
          });
        }
      });
    }

    // Create REST message
    var request = new sn_ws.RESTMessageV2();
    request.setEndpoint(webhookUrl);
    request.setHttpMethod('POST');

    // Set headers
    request.setRequestHeader('Content-Type', 'application/json');
    request.setRequestHeader('Accept', 'application/json');

    // Add authentication if required
    var apiKey = gs.getProperty('integration.webhook.api_key');
    if (apiKey) {
      request.setRequestHeader('Authorization', 'Bearer ' + apiKey);
    }

    // Set request body
    request.setRequestBody(JSON.stringify(payload));

    // Set timeout (30 seconds)
    request.setHttpTimeout(30000);

    // Execute request
    var response = request.execute();
    var statusCode = response.getStatusCode();
    var responseBody = response.getBody();

    // Log success
    if (statusCode >= 200 && statusCode < 300) {
      gs.info('Webhook sent successfully for incident ' + current.number +
              ', status: ' + statusCode);

      // Optional: Update custom field to track integration status
      // current.u_webhook_sent = true;
      // current.u_webhook_sent_at = new GlideDateTime();
      // current.update();
    } else {
      gs.error('Webhook failed for incident ' + current.number +
               ', status: ' + statusCode + ', response: ' + responseBody);
    }

  } catch (e) {
    gs.error('Error sending webhook for incident ' + current.number + ': ' + e.message);
  }

})(current, previous);

How to use it

1. Create system properties for webhook configuration: - integration.webhook.url (URL of external webhook) - integration.webhook.enabled (true/false) - integration.webhook.api_key (optional authentication) 2. Create an async Business Rule on your table 3. Check "Insert" and/or "Update" checkboxes 4. Customize the payload structure for your integration 5. Test with a webhook testing service (e.g., webhook.site) first 6. Implement error handling and retry logic as needed 7. Monitor system logs for integration errors

Adapt the table names, fields, and conditions to your instance. Test the behavior in a development environment before using it in production.