-
-
Save devStepsize/b1b795309a217d24566dcc0ad136f784 to your computer and use it in GitHub Desktop.
''' | |
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) | |
) |
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
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.
im running into socket errors, any chance someone can tell me what firewall rules should be setup to allow for this funcctionality
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)
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!'})
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)
Really helpful. Thanks
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.
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!
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"
}
]
}
]
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.
@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.
@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)
I've put this up here: https://github.com/guymorrell/slack-webhooks-blockkit
@guymorrell now this works like a charm! Thanks for your help!
Hi, is there away you can use the same method but posting in a thread instead of the channel on Slack?
Hi @guymorrell I am trying to publish cucumber report (Cucumber.json) from Jenkins to slack using slak-notifier-plugin but I got the below error
java.lang.RuntimeException: Received HTTP Status code [400] while posting to slack
at org.jenkinsci.plugins.slacknotifier.SlackClient.postToSlack(SlackClient.java:62)
at org.jenkinsci.plugins.slacknotifier.SlackClient.postToSlack(SlackClient.java:54)
at org.jenkinsci.plugins.slacknotifier.SlackClient.postToSlack(SlackClient.java:41)
at org.jenkinsci.plugins.slacknotifier.CucumberSlackService.sendCucumberReportToSlack(CucumberSlackService.java:33)
at org.jenkinsci.plugins.slacknotifier.CucumberSlackPostBuildNotifier.perform(CucumberSlackPostBuildNotifier.java:67)
at hudson.tasks.BuildStepMonitor$2.perform(BuildStepMonitor.java:32)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:741)
at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
at hudson.model.Build$BuildExecution.post2(Build.java:186)
at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
at hudson.model.Run.execute(Run.java:1878)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:428)
Build step 'Send Cucumber Report to Slack' marked build as failure
I could not be able to send the json which is made with Block Kit too. Can you please help me here?
Hi @Udhay1316, can you post trivial messages to slack? See https://github.com/guymorrell/slack-post-oath
Digging the history up but this seems to not work as intended anymore.
What I get as a result is no_text
when I try to post a message. If I add the text
field, it ignores the blocks
.
Have you seen this issue before?
Hi @guymorrell
A simple text worked fine , but I'm trying to send this payload :
{
"Title": "Resources in AWS ~> eng-sbx",
"icon_emoji": ":money:",
"Resource_Count": {
"CloudFormationStack": "259",
"CloudWatchLog Group": "4319",
"DynamoDBTable": "119",
"EC2Address": "7",
"EC2Instance": "34",
"EC2Security Group": "877",
"GlueDatabase": "14",
"LambdaFunction": "831",
"ECRRepository": "117",
"ECRImage": "6602",
"ELBLoad Balancer": "34",
"EMRCluster": "1",
"ElastiCacheCluster": "20",
"ElastiCacheReplication Group": "5",
"GlueCrawler": "10",
"KinesisStream": "24",
"EFSFile System": "9",
"EKSNode Group": "13",
"EKSCluster": "5",
"SageMakerApp": "7",
"SageMakerNotebook Instance": "2",
"RedshiftSnapshot": "2",
"RDSInstance": "18",
"RDSSnapshot": "3",
"EC2Snapshot": "40",
"EC2Volume": "224",
"S3Bucket": "123",
"IAMPolicy": "157",
"IAMRole": "359"
}
}
I keep having error 400 . Can you help me please ?
Traceback (most recent call last):
File "testing.py", line 183, in
print(test())
File "testing.py", line 179, in test
response = post_slack(result)
File "testing.py", line 160, in post_slack
raise ValueError(
ValueError: Request to slack returned an error 400, the response is:
missing_text_or_fallback_or_attachments
json={"text": data}
Amazing! Working like a charm!
@rafaelnpaiva - I have this problem also.
You need to use the block strucutre that Slack is expecting: (found here)
{
"blocks": [
{
"type": "section",
"text": {
"type": "plain_text",
"text": "This is a plain text section block.",
"emoji": true
}
}
]
}
I also need to send a simple JSON payload, and I really don't understand why there isn't a way to send our own key:value JSON block...I get that it won't nessasarily be pretty like Slack likes things to be... but sometimes we just need payloads.
@guymorrell do you have any ideas?
Hi, this is working example:
import requests
def send_slack_notif():
url = 'YOUR_SLACK_WEBHOOK_URL'
payload = {
"blocks": [
{
"type": "section",
"text": {
"type": "plain_text",
"text": ":red_circle: This is a plain text section block.",
"emoji": True
}
}
]
}
r = requests.post(url, json=payload)
send_slack_notif()
I want to format the code in the form of code.
```
slack_data = {
"text": "```\n" + message + "\n```"
}
response = requests.post(
url,
proxies={
"http_proxy": <proxy>,
},
json=slack_data,
headers={"Content-Type": "application/json"},
timeout=5,
)
print(response.text)
```
This does not format my code.
Thanks, worked on the first run!