Deform smart hooks

In Docast team we love to be notified about some things happening in our projects.

This post is about a webhook which triggers a webhook which triggers Slack integration :D

The Problem

We need to get a notification every time new user starts using our service.

Slack has a Incoming WebHooks feature which allows us to send a json with notification contents.

It has an interface:

{
    "text": "Here is your notification", 
    "channel": "#yourchannel"
}

So, we need to send a document with a root property named text.

Use Deform.io hooks

The Deform.io has a great feature which can help us - hooks.

The hook is being triggered when a document sends event which matches the hook's triggers property.

These is how we do it:

  • create a collection for users
  • create a collection for slack notification ( something like a log of messages we've sent to Slack )
  • add a hook user > slack_notification
  • add a hook slack_notification > Slack

Let's code it

In this example we will use deform-python library to code with ease.

Create a collection for users

Store user in a collection users. Every time our service has a new user - store it here.

deform.collection.save(  
    data={
        "_id": "users", 
        "name":"users", 
        "schema": {
            "type": "object",
            "properties": {
                "username": {
                    "type": "string"
                },
                "email": {
                    "type": "string"
                },
                "avatar": {
                    "type": "string"
                }
            }
        }
    }
)

This will be a storage for user's profiles and data.

Create a collection for slack notifications

Our notifications to slack will be stored in a collection slack_notifications

deform.collection.save(  
    data={
        "_id": "slack_notifications",
        "name": "Slack Notifications",
        "schema": {
            "title": "Slack specific hook wrapper",
            "type": "object",
            "properties": {
                "text": {
                    "type": "string",
                    "processors": [
                        {
                            "name": "template",
                            "in": {
                                "context": {
                                    "profile": {
                                        "property": "user"
                                    }
                                },
                                "syntax": {
                                    "value": "handlebars"
                                },
                                "template_string": {
                                    "value": "{{#if profile}} Welcome {{profile.username}} {{profile.email}} {{/if}}"
                                }
                            }
                        }
                    ]
                },
                "user": {
                    "type": "object",
                    "properties": {
                        "username": {
                            "type": "string"
                        }
                    },
                    "additionalProperties": true
                }
            }
        }
    }
)

Even if user will be created multiple times this collection will contain one notification. You will get exactly one created event and one hook.

Note the property text. This is required because slack hooks has interface:

{
    "text": "Here is your notification", 
    "channel": "#yourchannel"
}

The hook will have this property in a document it PUT.

Add a hook: user > slack_notification
deform.document.save(  
    collection="_hooks",
    identity="user_registered",
    data={
        "name": "User joined",
        "url": "https://yourproject.deform.io/api/collections/slack_notifications/documents/",
        "method": "PUT",
        "triggers": ["created"],
        "collection": "users",
        "headers": {
            "Authorization": "Token YOUR_TOKEN"
        }
    }
)

This hook will be triggered by created documents inside of users collection.

Add a hook slack_notification > Slack
deform.document.save(  
    collection="_hooks",
    identity="sent_slack_notification",
    data={
        "name": "Slack notification",
        "url": "https://hooks.slack.com/services/YOUR_SLACK_HOOK_DETAILS",
        "method": "POST",
        "triggers": [
            "created"
        ],
        "collection": "slack_notifications"
    }
)

This hook will send created notifications directly to Slack service.

The result

The hook triggered to Slack will look like this

This is how notification looks in slack:

Hope you succeeded with webhooks in Deform :D