Splunk – Posting to Microsoft Teams via Webhooks

Using either the default webhook action or the Teams-specific webhook, Splunk searches can post data into Microsoft Teams. First, you need to get a webhook URL for your Teams channel. On the hamburger menu next to the channel, select “Connectors”. Select Webhook, provide a name for the webhook, and copy the webhook URL.

If you intend to use the generic webhook app, there is no need to install the Teams-specific one. The Teams-specific app gives you prettier output & a “view in splunk” button. Download the app tgz. To install the app, go into “Manage Apps” and select “Install app from file”.

Click ‘Browse…’ and find the tgz you downloaded. Click ‘Upload’ to install the app to Splunk.

Now create a search for which you want to post data into your Teams channel. Click “Save As” and select “Alert”

Provide a title for the alert — you can use real-time or scheduled alerts. Once you’ve got the alert sorted, select “Add Actions” and select the Teams webhook action (or the generic webhook action if you intend to use that one). Paste in the URL from your Teams channel webhook and click “Save”.

You”ll see a confirmation that the alert has been saved. Close this.

Now you would think you’d be ready to use it … but wait. Neither one works out of the box. In the Splunk log, you see error 400 “Bad data” reported.

For the default webhook app, edit the Python script (/opt/splunk/etc/apps/alert_webhook/bin/webhook.py in my case). Find the section where the JSON body is built. Teams requires a summary or title within the POST data. I just added a static summary, but you could do something fancier.

        body = OrderedDict(
            sid=settings.get('sid'),
            summary='LJRWebhook',
            search_name=settings.get('search_name'),
            app=settings.get('app'),
            owner=settings.get('owner'),
            results_link=settings.get('results_link'),
            result=settings.get('result')

For the Teams-specific webhook, edit the Python script (/opt/splunk/etc/apps/alert_msteams/bin/teams.py in my case) and find the section where the facts list is populated. There’s too much data being sent through. There’s probably a way to filter it out in Splunk, but I don’t know how 🙂

The right way to do it is select the most important items from settings.get(‘result’).items that you want to be displayed within Teams and populate facts with those elements. I used a new list, strWantedKeys, to determine which keys should be added to the facts list. The quick/ugly way is to just take the first n items from the result items (settings.get(‘results’).items()[:7] gets seven … 8 produced a ‘bad payload received by generic incoming webhook’ error from Teams.

try:
settings = json.loads(sys.stdin.read())
print >> sys.stderr, "DEBUG Settings: %s" % settings
url = settings['configuration'].get('url')
facts = []
strWantedKeys = ['sourcetype', '_raw', 'host', 'source']
for key,value in settings.get('result').items():
if key in strWantedKeys:
facts.append({"name":key, "value":value})
body = OrderedDict(

For reference, the original facts list was:

    "facts": [{
        "name": "index",
        "value": "history"
    }, {
        "name": "_raw",
        "value": "Test push to teams 555"
    }, {
        "name": "_eventtype_color",
        "value": ""
    }, {
        "name": "host",
        "value": "10.10.15.134:8088"
    }, {
        "name": "source",
        "value": "http:Sendmail testing"
    }, {
        "name": "_si",
        "value": ["49cgc3e5e52e", "history"]
    }, {
        "name": "sourcetype",
        "value": "mysourcetype"
    }, {
        "name": "_indextime",
        "value": "1544554125"
    }, {
        "name": "punct",
        "value": "___"
    }, {
        "name": "linecount",
        "value": ""
    }, {
        "name": "_time",
        "value": "1544554125"
    }, {
        "name": "eventtype",
        "value": ""
    }, {
        "name": "_sourcetype",
        "value": "mysourcetype"
    }, {
        "name": "_kv",
        "value": "1"
    }, {
        "name": "_serial",
        "value": "15"
    }, {
        "name": "_confstr",
        "value": "source::http:Sendmail testing|host::10.10.15.134:8088|mysourcetype"
    }, {
        "name": "splunk_server",
        "value": ""
    }]

Now generate a message that matches your search — you’ll see a post created in your Teams channel.

8 comments

  1. Avatar
    Spraight says:

    Thank you for the description.
    I changed the webhook.py script like you mentioned above but in my case it is not working. The sendemail is working but in teams I get no notification. Do you have an idea why?

    • Avatar
      Lisa says:

      Not sure — I had to look through my Splunk log to identify an error when the webhook posting was made. I then modified the python code to dump out everything it was posting so I could try posting that content directly to the webhook. I had a sample python script for sending cards to Teams using the webhook — so I added each component from *that* script into the Splunk content & removed them one at a time until I arrived at *the one* that generated an error when it was missing.

      The only other thing I could think of is that the host running the python script cannot actually *reach* the Teams webhook — something like nmap can be used to verify you’ve got connectivity to an endpoint.

  2. Avatar
    Santhosh says:

    Any idea how to embed the link to results under ‘View in Splunk’ tab?

    When I click on that, it takes me to ‘https://teams.microsoft.com/null’ which is non-existent.

    • Avatar
      Lisa says:

      The link is build from the “potentialAction” part of the message sent to Teams. In the teams.py file from the Teams/Splunk custom webhook, that’s

      potentialAction=[{
      “@context”:”http://schema.org”,
      “@type”:”ViewAction”,
      “name”:”View in Splunk”,
      “target”:[settings.get(‘results_link’)]
      }]

      I’d assume that there’s no results_link. Unfortunately, my Splunk knowledge is very much so on the “fumble through it” side of expertise. I’m not sure if you set the “include.results_link” to false in alert_actions.conf if that would filter results_link here. I’d start by adding some debugging to the generating script to dump out the entire “settings” json object to differentiate between the link value not being delivered from Splunk and the link getting malformed in the webhook generation script.

  3. Avatar
    Margarete says:

    Hi, just want to ask, is there an access configuration for the alerts to send to MS team? I am an admin and was able to send alert perfectly on the ms teams channel. But when the alert owner is a power user, the alert is not sending on the channel. Do you have something in mind? Thank you in advance.

  4. Avatar
    Gee says:

    in Splunk, you can use a “table” search command to filter down to a specific list of fields, e.g.
    (index=main OR index=summary) sourcetype=*mail*
    | table source host sourcetype _raw

Leave a Reply

Your email address will not be published. Required fields are marked *