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

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

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

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

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

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

commented Jan 30, 2018

Thanks, worked on the first run!

@ControlX

This comment has been minimized.

Copy link

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

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

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

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

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!'})
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.