Sending alarm event notifications to Slack channels using Incoming Webhook URLs

Here are some quick and easy instructions for sending alarm event notifications to Slack channels, using Slack's Incoming Webhook URLs...

Note, the implementation described here directs event notifications to one or more slack channels and does not integrate directly with Ignition's user, schedules and roster configurations. If you want "first-class integration" with alarm pipeline notification blocks take a look at at the linked forum post instead:

...and when you figure it out please add a step-by-step guide for that to the Ignition forums. While looking into that I came across the method below as an easier and potentially more versatile option that met the need I had. Sharing it here for the benefit of others, please point out corrections and/or potential improvements.

Instructions to create a slack webhook URL:
Reference: https://api.slack.com/messaging/webhooks

  • Using a web browser open: https://slack.com/signin
    • Ensure you are signed into the correct slack workspace.
  • On another tab in the same browser open: https://api.slack.com/apps
  • Click the Create New App button, and follow prompts as outlined below
    • Select the From scratch option
    • App name: choose your bot name
    • Pick a workspace to develop your app in:
  • You should now be on the Basic Information page for the newly created App.
  • Enable incoming webhooks…
    • Select Incoming webhooks from the left navigation menu.
    • Click the Activate Incoming Webhooks toggle to switch it on (if not already on).
  • Create an Incoming Webhook…
    • Click the Add New Webhook to Workspace button, and follow prompts…
      • Select the channel:
      • Then, click the Allow button.
  • You should now see an updated Incoming Webhooks page with a new entry under the Webhook URLs for Your Workspace section, associated with the specified channel.
  • Copy the Webhook URL for the channel to use in integrating slack notifications in SCADA.

To post alarm event notifications from Ignition to the slack channel for which you created the incoming webhook, add a script block to a notification pipleline and use the system.net.httpPost() function specifying the webhook URL as the url parameter of the function.

Simple 'Hello World' example:

def handleAlarm(event):
	webhookURL = 'https://hooks.slack.com/services/youneedyourownwebhookURL'
	jsonData = system.util.jsonEncode({"text":Hello World'})
	system.net.httpPost(url=webhookURL, contentType="application/json", postData=jsonData)

Another example:

Here is a more complex example. Slack specific information on message composition can be found here:
https://api.slack.com/messaging/composing

def handleAlarm(event):
# Purpose: Used to send alarm event notification content to one or more slack channels
# Notes: For each targeted slack channel a Webhook URL must be created and included in the list of Webhook URLs
	
	# Define a list of Slack API Webhook URLs that that are to receive the alarm event notification	
	# https://api.slack.com/messaging/webhooks
	webhookURLs= [
		  'https://hooks.slack.com/services/youneedyourownwebhookURL1'   # Slack Channel #1
		, 'https://hooks.slack.com/services/youneedyourownwebhookURL2'   # Slack Channel #2
	]

	# Determine the plain text version of the notification subject line 
	subjectPlain = '{} {} - {} - {}'.format(event['projectName'], str(event['pipelineName']).upper(), event['label'], event['eventState'])

	# Determine the formatted (mrkdown) version of the notification subject line
	# https://api.slack.com/messaging/composing/layouts
 	# https://app.slack.com/block-kit-builder 
	subjectMrkdwn = '{} {} - {} - *{}*'.format(event['projectName'], str(event['pipelineName']).upper(), event['label'], event['eventState'])

	# Determine the plain text version of the notification body 				
	bodyPlain = (
	         "Label:       " + str(event['label'])
	+ "\n" + "Name:        " + str(event['name'])
	+ "\n" + "State:       " + str(event['state'])
	+ "\n" + "Priority:    " + str(event['priority'])
	+ "\n" + "Path:        " + str(event['displayPathOrSource'])
	+ "\n" + "Notes:       " + str(event['notes'])	
	+ "\n" + "---" 
	+ "\n" + "Event State: " + str(event['eventState'])
	+ "\n" + "Event Time:  " + str(event['eventTime'])
	+ "\n" + "Event Value: " + str(event['eventValue'])
	+ "\n" + "---"
	+ "\n" + "Active Time: " + str(event['activeTime'])
	+ "\n" + "Clear Time:  " + str(event['clearTime'])
	+ "\n" + "Ack Time:    " + str(event['ackTime'])
	+ "\n" + "Acked by:    " + str(event['ackUserName'])
	+ "\n" + "---"
	+ "\n" + "Project:     " + event['projectName']
	+ "\n" + "Pipeline:    " + event['pipelineName']	
	)

	# Determine the formatted (mrkdwn) version of the notification body 
	bodyMrkdwn = "```" + bodyPlain + "```"

	# Prepare notification content to be sent via slack.  	
	text = subjectPlain + "\n" + bodyPlain
	blocks = [ {'type':'section', 'text':{'type':'mrkdwn', 'text':subjectMrkdwn + "\n" + bodyMrkdwn }} ]
	postData = system.util.jsonEncode({"text":text, 'blocks': blocks})

	# Send to each slack webhook URL (slack channel)					
	for url in webhookURLs:
		system.net.httpPost(url=url, contentType="application/json", postData=postData)
2 Likes

Nice writeup!
For posterity, the instructions for the SDK example you linked would be basically your first steps, to get a webhook from Slack.
Then in Ignition, you go to each user you created a webhook for (or create a fake user for each channel you want to notify), and set the webhook URL in their "contact info".

Then the rest of the alarming system "just works" - you can add users to rosters, use rosters in notification blocks, etc.

1 Like