In this tutorial, we’ll show you how to send a message to a Slack channel whenever a user fills out an online form, using just a few lines of code hosted on the cloud.

Maintenance Request Form with Emergency Slack Notification

We’ve made a property maintenance request form for this demonstration. This form lets users choose a priority level for their request. Upon submission, FormSmarts notifies the property maintenance team by email. In addition, if the user indicates that the maintenance request is “urgent” or “critical”, we’ll use a webhook to send a message to a Slack channel.

About Webhooks

A webhook is computing code that executes outside FormSmarts whenever a form is submitted. FormSmarts triggers the code’s execution by sending an HTTP request to a callback URL you’ve configured. The code receives the form data from the HTTP request, allowing you to perform useful actions with it.

Prerequisites

You will need both a FormSmarts account and an AWS account.

This tutorial requires little coding skills (the Python code provided should run as is) and the AWS services needed for this tutorial are configured online via the AWS Console. If you think you would benefit from integrating your forms with a webhook but don't have the technical skills, please contact us for advice.

If you want to create a working webhook, replicate this form in your own FormSmarts account.

The Python Code


import os
import json
import urllib3
import logging
from formsmarts_api import WebhookAuthenticator, FormEntry, AuthenticationError

logger = logging.getLogger()

class SlackSender:

    def __init__(self, event):
        self._event = event
        self._au = WebhookAuthenticator(os.environ['FORMSMARTS_WEBHOOK_KEY'])
        self._entry = None

    def create_message(self):
        entry = self._entry
        # Retrieve an input field by name
        msg = dict(text=entry.fields_by_name('subject')[0].value)
        msg['attachments'] = [dict(color='danger')]
        msg['attachments'][0]['fields'] = [
            # The 'Message' field is the sixth one on the form
            dict(title='Message', value=entry.fields[5].value, short=False),
            # Look up fields with the "phone" and "email" datatypes
            dict(title='Client Phone', value=entry.fields_by_type('phone')[0].value, short=True),
            dict(title='Client Email', value=entry.fields_by_type('email')[0].value, short=True),
            dict(title='Priority Level', value=entry.fields_by_name('Priority')[0].value, short=True),
            # We can also locate a field by its Field ID
            dict(title='Client Name', value=entry.field_by_id(830211).value, short=True),
        ]
        return msg

    def send_to_slack(self):
        try:
            # Verify request is from FormSmarts
            if self._au.verify_request(self._event['headers']['authorization']):
                # Create a FormEntry object from the webhook message
                self._entry = FormEntry.create(json.loads(self._event['body']))
                # Only send urgent maintenance requests to Slack
                if self._entry.fields_by_name('Priority')[0].value in ('Urgent', 'Critical'):
                    try:
                        resp = urllib3.request('POST', os.environ['SLACK_HOOK_URL'], json=self.create_message())
                        if resp.status not in (200, 201, 202, 204):
                            logger.warning('Slack message delivery failed.')
                    except urllib3.exceptions.HTTPError as err:
                        logger.warning(err)
        except AuthenticationError as err:
            logger.warning(err)
            return {
                'statusCode': 401,
                'body': json.dumps('Invalid webhook signature.')
            }

def lambda_handler(event, context):
    SlackSender(event).send_to_slack()

Create a Slack Message

The create_message() function formats data from the form submission into a Slack message. We use a FormEntry object provided by the FormSmarts API & Webhook Client to get input fields by name, datatype or Field ID.

Note how we can retrieve a field:

  • With its name: entry.fields_by_name('Priority')[0]. Field names aren't necessarily unique, so the function returns a list.
  • With its datatype: entry.fields_by_type('email')[0]. This is especially convenient when you know there is only one input field of that type, like email address and phone number fields.
  • Sequentially, in the order fields appear on the form: entry.fields[5] returns the sixth field.
  • With the field's unique ID: entry.field_by_id(830211)

Send a Slack Message, Conditionally

The send_to_slack() function first verifies that the request was sent by FormSmarts. It takes advantage of the WebhookAuthenticator object to check the cryptographic signature in the header of the HTTP request. We then create a FormEntry object from the request's payload and send a message to Slack if the value of the Priority field is Urgent or Critical.

Downloads

The Lambda deployment package for this tutorial includes both the code above and the FormSmarts API & Webhook Client for Python.

Deployment to AWS Cloud

We're not quite done yet. We still need to create and configure the cloud resources that will run the code.

Deploy the Code to Lambda

Lambda is a service that runs code when an event occurs. To create a Lambda function, log in to the AWS Console and click Create Function. Choose the Author from scratch option.

  • Set the name as FormSmartsSlackSender
  • Select a Python 3.x runtime (Python 3.13 at the time of writing)
  • Hit the Create function button.

Create a Function

Scroll down to the Create a function section and select Upload a .ZIP file as the Code entry type. Upload the deployment package for this tutorial.

Set Environment Variables

Scroll down to the Environment variables section and set the FORMSMARTS_WEBHOOK_KEY environment variable to your FormSmarts Webhook Key. You can find your Webhook Key in the Security Settings of your account.

Also set the SLACK_HOOK_URL environment variable to the webhook URL of your Slack channel (something like https://hooks.slack.com/services/***/***/***).

Save changes.

Create a Function URL

Lambda runs code when an internal or external event happens. To trigger an event when an HTTP request is received, we need to create a Function URL.

Select Function URL in the Configuration tab and create a new URL. Choose the NONE Authentication type. The code authenticates the request with the FormSmarts cryptographic signature in the header, not with AWS authentication.

Note the function's URL, you'll need it to set up the webhook callback URL on FormSmarts.

Set Up the Webhook on FormSmarts

Follow the instructions in the webhook documentation to register the callback URL for the form you've created earlier.