Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
POST a JSON payload to a Slack Incoming Webhook using Python requests
'''
This is an example of how to send data to Slack webhooks in Python with the
requests module.
Detailed documentation of Slack Incoming Webhooks:
https://api.slack.com/incoming-webhooks
'''
import json
import requests
# Set the webhook_url to the one provided by Slack when you create the webhook at https://my.slack.com/services/new/incoming-webhook/
webhook_url = 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'
slack_data = {'text': "Sup! We're hacking shit together @HackSussex :spaghetti:"}
response = requests.post(
webhook_url, data=json.dumps(slack_data),
headers={'Content-Type': 'application/json'}
)
if response.status_code != 200:
raise ValueError(
'Request to slack returned an error %s, the response is:\n%s'
% (response.status_code, response.text)
)
@Parkham

This comment has been minimized.

Copy link

Parkham commented Sep 2, 2016

I take the exact same information that works in slack_data= and then put it into a text file. I then do:

e = open('export.txt', 'r')
slack_data = e.readline()

But I get error 400, invalid_payload. I do a print to compare, and the information is exactly the same. Any ideas why it doesn't work?

@Parkham

This comment has been minimized.

Copy link

Parkham commented Sep 2, 2016

Since I already had the data preformatted in the file as JSON already, it was just a matter of removing json.dumps out of the code.

OLD:

#response = requests.post(webhook_url, data=json.dumps(slack_data), headers={'Content-Type': 'application/json'})
NEW:

response = requests.post(webhook_url, data=slack_data, headers={'Content-Type': 'application/json'})

Once I did that, everything worked like a charm.

@mrooney

This comment has been minimized.

Copy link

mrooney commented Jan 30, 2017

Thanks! FWIW requests has a 'json' parameter that encodes and handles the content type for you, so you can simply do response = requests.post(webhook_url, json=slack_data)

@BHushanRathod

This comment has been minimized.

Copy link

BHushanRathod commented Nov 11, 2017

Thanks man. Now i can send my daily reports to the channel directly..

@bbkane

This comment has been minimized.

Copy link

bbkane commented Dec 18, 2017

Thanks! This worked when using a dict as the data argument didn't!

@jhonatancasale

This comment has been minimized.

Copy link

jhonatancasale commented Jan 30, 2018

Thanks, worked on the first run!

@ControlX

This comment has been minimized.

Copy link

ControlX commented Feb 27, 2018

Just posting as it might help somebody. For me the below snippet worked:

data = json.dumps(slack_data)
    response = requests.post(
        URL, json={"text": data},
        headers={'Content-Type': 'application/json'}
    )

the final payload that we are going to send should have keyword "text", else it will fail.

Moreover, in post method I have to replace data= with json= else it kept throwing error for invalid payload with 400

@renaecarr

This comment has been minimized.

Copy link

renaecarr commented Aug 15, 2018

This worked for the newer urllib3 library:

import json
import urllib3
import certifi

http = urllib3.ProxyManager(proxy_url=proxy, cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())

def post_to_slack(message):
    slack_url = "https://hooks.slack.com/services/Your/Slack/Hook"
    
    encoded_data = json.dumps({'text': message}).encode('utf-8')
    response = http.request("POST", slack_url, body=encoded_data, headers={'Content-Type': 'application/json'})
    print(str(response.status) + str(response.data))

post_to_slack("Testing")

Note the encoding and the use of the "body" parameter. If not using a proxy, use the urllib3.PoolManager instead of ProxyManager.

@Soteark

This comment has been minimized.

Copy link

Soteark commented Nov 4, 2018

im running into socket errors, any chance someone can tell me what firewall rules should be setup to allow for this funcctionality

@ralston3

This comment has been minimized.

Copy link

ralston3 commented Nov 6, 2018

Works for me using requests futures (via requests-futures). Caveat here is that you have to json encode the entire payload, and send that as your data, as opposed to just sending a dict (which this tutorial successfully shows)

@yazinsai

This comment has been minimized.

Copy link

yazinsai commented May 8, 2019

Content-Type is optional when you use the json= param in requests. I'm using this:

requests.post(webhook_url, json={'text': 'Hello from Python!'})
@guymorrell

This comment has been minimized.

Copy link

guymorrell commented Jul 29, 2019

If you are using the newer Block Kit Builder to format your text, you'll produce an array. There is an example array in the link.
To post it to Slack, do the following:

def post_to_slack(message):
    webhook_url = 'https://hooks.slack.com/services/MY/WEBHOOK/URL'
    slack_data = json.dumps({'blocks': message})
    response = requests.post(
        webhook_url, data=slack_data,
        headers={'Content-Type': 'application/json'}
    )
    if response.status_code != 200:
        raise ValueError(
            'Request to slack returned an error %s, the response is:\n%s'
            % (response.status_code, response.text)
        )

post_to_slack(data)
@chankongching

This comment has been minimized.

Copy link

chankongching commented Sep 4, 2019

Really helpful. Thanks

@NandanSatheesh

This comment has been minimized.

Copy link

NandanSatheesh commented Sep 9, 2019

Really helpful. Thanks a lot.
But I had a question. How can I post a Block Kit Message using Web Hooks? Is it possible? If so how?
Please let me know.
Thanks.

@guymorrell

This comment has been minimized.

Copy link

guymorrell commented Sep 10, 2019

Really helpful. Thanks a lot.
But I had a question. How can I post a Block Kit Message using Web Hooks? Is it possible? If so how?
Please let me know.
Thanks.

The example I gave will post a block kit message via webhook. Store the block kit built array as the variable 'data' to make it work. Good luck!

@NandanSatheesh

This comment has been minimized.

Copy link

NandanSatheesh commented Sep 10, 2019

Really helpful. Thanks a lot.
But I had a question. How can I post a Block Kit Message using Web Hooks? Is it possible? If so how?
Please let me know.
Thanks.

The example I gave will post a block kit message via webhook. Store the block kit built array as the variable 'data' to make it work. Good luck!

I tried the above example. But it gave me the below error. Please help.
ValueError: Request to slack returned an error 400, the response is:invalid_blocks
The variable data had the following

 [
    {
        "type": "section",
        "text": {
            "type": "mrkdwn",
            "text": "Hello, Assistant to the Regional Manager Dwight! *Michael Scott* wants to know where you'd like to take the Paper Company investors to dinner tonight.\n\n *Please select a restaurant:*"
        }
    },
    {
        "type": "divider"
    },
    {
        "type": "section",
        "text": {
            "type": "mrkdwn",
            "text": "*Farmhouse Thai Cuisine*\n:star::star::star::star: 1528 reviews\n They do have some vegan options, like the roti and curry, plus they have a ton of salad stuff and noodles can be ordered without meat!! They have something for everyone here"
        },
        "accessory": {
            "type": "image",
            "image_url": "https://s3-media3.fl.yelpcdn.com/bphoto/c7ed05m9lC2EmA3Aruue7A/o.jpg",
            "alt_text": "alt text for image"
        }
    },
    {
        "type": "section",
        "text": {
            "type": "mrkdwn",
            "text": "*Kin Khao*\n:star::star::star::star: 1638 reviews\n The sticky rice also goes wonderfully with the caramelized pork belly, which is absolutely melt-in-your-mouth and so soft."
        },
        "accessory": {
            "type": "image",
            "image_url": "https://s3-media2.fl.yelpcdn.com/bphoto/korel-1YjNtFtJlMTaC26A/o.jpg",
            "alt_text": "alt text for image"
        }
    },
    {
        "type": "section",
        "text": {
            "type": "mrkdwn",
            "text": "*Ler Ros*\n:star::star::star::star: 2082 reviews\n I would really recommend the  Yum Koh Moo Yang - Spicy lime dressing and roasted quick marinated pork shoulder, basil leaves, chili & rice powder."
        },
        "accessory": {
            "type": "image",
            "image_url": "https://s3-media2.fl.yelpcdn.com/bphoto/DawwNigKJ2ckPeDeDM7jAg/o.jpg",
            "alt_text": "alt text for image"
        }
    },
    {
        "type": "divider"
    },
    {
        "type": "actions",
        "elements": [
            {
                "type": "button",
                "text": {
                    "type": "plain_text",
                    "text": "Farmhouse",
                    "emoji": "true"
                },
                "value": "click_me_123"
            },
            {
                "type": "button",
                "text": {
                    "type": "plain_text",
                    "text": "Kin Khao",
                    "emoji": "true"
                },
                "value": "click_me_123"
            },
            {
                "type": "button",
                "text": {
                    "type": "plain_text",
                    "text": "Ler Ros",
                    "emoji": "true"
                },
                "value": "click_me_123"
            }
        ]
    }
]
@guymorrell

This comment has been minimized.

Copy link

guymorrell commented Sep 11, 2019

Okay, so you're trying to post the Farmhouse Thai Cuisine example to Slack via Webhook from the api.slack.com Block Kit Builder.

I've done something similar here. In that example, I use OATH as I also wanted to upload an image but have a variable which can be set to use webhooks instead. The Block Kit is built on the fly by the script.

Why not try something simpler like this:

data = []
data.append({"type": "section","text": {"type": "mrkdwn","text": "I'm posting to Slack via webhook"}})

def post_to_slack(message):
    webhook_url = 'https://hooks.slack.com/services/MY/WEBHOOK/URL'
    slack_data = json.dumps({'blocks': message})
    response = requests.post(
        webhook_url, data=slack_data,
        headers={'Content-Type': 'application/json'}
    )
    if response.status_code != 200:
        raise ValueError(
            'Request to slack returned an error %s, the response is:\n%s'
            % (response.status_code, response.text)
        )

post_to_slack(data)

Then you can build up your Block Kit as you wish.

@johannesber

This comment has been minimized.

Copy link

johannesber commented Sep 12, 2019

@guymorrell Using this approach, I get a notification that the sent content can't be displayed. If I open the Slack Channel, the provided text is shown without any formatting.

@guymorrell

This comment has been minimized.

Copy link

guymorrell commented Sep 25, 2019

@johannesber and @NandanSatheesh try putting the content directly into a separate json file then loading it into a variable as follows:

import slack
import json
import requests

with open("block.json", "rt") as block_f:
    data = json.load(block_f)

def post_to_slack(message):
    webhook_url = 'https://hooks.slack.com/services/MY/WEBHOOK/URL'
    slack_data = json.dumps({'blocks': message})
    response = requests.post(
        webhook_url, data=slack_data,
        headers={'Content-Type': 'application/json'}
    )
    if response.status_code != 200:
        raise ValueError(
            'Request to slack returned an error %s, the response is:\n%s'
            % (response.status_code, response.text)
        )

post_to_slack(data)

image

I've put this up here: https://github.com/guymorrell/slack-webhooks-blockkit

@johannesber

This comment has been minimized.

Copy link

johannesber commented Sep 27, 2019

@guymorrell now this works like a charm! Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.