requests.post only accepts "text" dictionary values - python

I'm attempting to make post requests to slack from a requests.post() call. Here is an example of the code that I've made to do this:
fields = {
'sender': message['From'],
'subject': message['Subject'],
}
url = 'https://hooks.slack.com/services/XXXXXX'
print(fields)
return requests.post(url, json=fields)
The issue seems to be that the requests.post(url, json=fields) command only seems to respond to the fields command if I change the key value(s) to "text". I have no idea what is not allowing the requests.post command to use other key values (such as sender or subject) that I have defined here.
I have been able to fix this by doing a terrible workaround of calling two separate requests.post commands and setting sender/subject as their own variables with json formatted dictionaries:
sender = {'text': message['From']}
subject = {'text': message['Subject']}
Just a side-note I'm gathering these message handlers from aiosmtpd.handlers which allows me to parse smtp messages that come in.

Related

Code does not post all output using jira-python in Jira

So I’m having some difficulty with my code. The code works but for some reason it only post one string instead of having all the strings posted in Jira. for example, up to the point that you see the #print(username, response), in the terminal I see all responses being printed in on screen. So it works great up to that point but the moment I send the same variable such as response through the Jira Dictionary called issue_dict, it creates the Jira but with only one of the responses and not all. I’ve tried doing something like response[x] but it just gives me an error that string indices must be integers. I’m not quite sure what else to do to be able to iterate through this so I can post all the results in the Description/body of a Jira ticket.
Ideally I would love to have both the user and the response in the description part. I’ve tried to do this with a List but I seem to get the same results where only one string gets printed. Anyone have done anything similar to post results in Jira?
Here is the code:
import jira from JIRA
for i in range(1,3):
user = os.getenv(‘USER’ + str(i))
pass = os.getenv(‘PASS’+ str(i))
headers = {
'X-Requested-With': 'Curl',
}
response =requests post('https://API-Address', headers=headers, auth=(USER,PASS))
root = ET.fromString(response.text) # Parses the JSON into text
for x in root.iter(’text’): #all this is doing is iterating through the file root and finding the text and saving the substring in response.
response = x[2].text
#print(username, response)
issue_dict = {
'project': {'id': 123},
'summary’:’My Jira Using Py',
'description': response, #This is the current issue!
'issuetype': {'name': 'Bug'},
}
new_issue = jira.create_issue(fields=issue_dict)

How to forward webhook data from JIRA using Google Cloud Functions?

I want to make a simple middle-man script which receives data from a JIRA webhook and then parses it and sends it over (to Discord, but that's not important).
From the looks of it, Cloud Functions was a perfect match, so I made a short script which just forwards the request json to a message on Discord to see what data it sends.
import requests
import json
def forward(request):
data = request.json
#tried:
#data = request.get_json()
#data = request.data
#data = request.values
url = 'discord webhook receiver url'
myobj = {'content': str(data)}
requests.post(url, data = myobj)
return '', 200
Set up the webhook on the JIRA side and it kinda works, but not really. First of all it doesn't trigger on some events, like adding a comment or editing a task, only for important(?) events, like adding a new task.
And secondly, it doesn't even send the right looking data for it. This is all i'm getting
{'timestamp': 1609851709546, 'webhookEvent': 'issuelink_created', 'issueLink': {'id': 10016, 'sourceIssueId': 10007, 'destinationIssueId': 10022, 'issueLinkType': {'id': 10004, 'name': 'jira_subtask_link', 'outwardName': 'jira_subtask_outward', 'inwardName': 'jira_subtask_inward', 'style': 'jira_subtask', 'isSubTaskLinkType': True, 'isSystemLinkType': True}, 'sequence': 12, 'systemLink': True}}
And I know those 2 things are wrong because while testing it I've also set up another webhook for Pipedream, where it reacts to all changes, and the data contains names of issues, avatars, links. Everything that's needed for what I'm trying to do. And there aren't any differences between those 2 webhook settings, I have them both with all events selected.
So I've been at it for 2 days now with no breakthrough. Maybe I'm misunderstanding how webhooks work, or maybe cloud functions isn't the service to use for this. So while the question is how to do it in cloud functions, I'm also open to alternatives. (not the ones which do the formatting for you, as that's why I started making this in the first place)
Apparently Jira sends 2 requests on webhook trigger and the one containing all the useful info was just over the limit to be put into a Discord message so it never sent it.
That's what I get for using it for logging.
If anyone is also on the same dumbass path, then what I did to find that out is to save all the request data into a hastebin and send the link to it, like so.
#pack it all into a hastebin
everything = str(request.headers) + "\n" + str(request.data) + "\n" + str(request.args) + "\n" + str(request.form) + "\n" + str(request.method) + "\n" + str(request.remote_addr)
req = requests.post('https://hastebin.com/documents', data=everything)
#send the link id to discord
myobj = {'content': req.text}
x = requests.post(url, data = myobj)
All that's left is to parse and format the json.

Mapbox API PUT Datasets Feature return "Provide a single Feature to insert"

I am trying to add a feature to the Dataset via Mapbox API using Python. I'm following this instruction https://docs.mapbox.com/api/maps/#update-a-dataset but keep getting this error:
{'message': 'Provide a single Feature to insert'}
The code looks like this:
rs = []
dictionary = {
"id":1,
"type":"Feature",
"properties":{},
"geometry":{"coordinates":[-83.750246, 42.269375],"type":"Point"}}
url = "https://api.mapbox.com/datasets/v1/voratima/"+dataset+"/features/1?access_token="+access_token
rs.append(grequests.put(url, data=dictionary, hooks = {'response' : do_something}))
grequests.map(rs, exception_handler=exception_handler)
I've tried the following but none of them work:
using requests instead of grequests
wrapping the dictionary with json.dumps()
changing the put parameter from data=dictionary to json=dictionary
Making sure the id for both data and URL are set to 1.
Postman of the exact same request does not have the error. What am I missing?
Given a dataset with dataset ID dataset exists, your request body looks ok.
Please add the header
headers = {'Content-type': 'application/json'}
Also can you check if you meet these specs:
This should be one individual GeoJSON feature, not a GeoJSON
FeatureCollection. If the GeoJSON feature has a top-level id property,
it must match the feature_id you use in the URL endpoint.
It turns out I forgot the header. Thanks to Mortiz for pointing that out. After the update I got
<Response [400]> {'message': 'Unexpected token i'}
That's because I need to wrap the dictionary inside json.dumps(). Then the error became
<Response [422]> {'message': 'Request URI does not match feature id'}
That's because the id in the dictionary has to be a string i.e. "id":"1" not "id":1. Here's the code that works:
rs = []
dictionary = {
"id":"1",
"type":"Feature",
"properties":{},
"geometry":{"coordinates":[-83.750246, 42.269375],"type":"Point"}}
headers = {'Content-type': 'application/json'}
url = "https://api.mapbox.com/datasets/v1/voratima/"+dataset+"/features/1?access_token="+access_token
rs.append(grequests.put(url, data=json.dumps(dictionary), headers=headers, hooks = {'response' : do_something}))
grequests.map(rs, exception_handler=exception_handler)

Onesignal notification template, Tags are not working

The same code without the tags (in the payload) succeeds with default template values, when adding the tags the message is getting 200-ok but on the onesignal dashboard - messages -delivery page i see NO RECIPIENTS status.
what am i doing wrong ?
import json
import requests
headers = {'Authorization': 'Basic mykey',
'Content-Type': 'application/json'}
payload = {'app_id': 'myapp_id',
'include_player_ids': ['my_player_id'],
'tags': [{'key': 'full_name', 'relation': '=', 'value': 'MOSHOE'}],
'template_id': 'my_template id'}
req = requests.post('ONESIGNAL_URL',headers=headers,data=json.dumps(payload))
You cannot add custom variables to notifications sent from OneSignal. You need to tag user devices first, then use the tag key within the template directly or API call and the OneSignal servers will substitute that tag key with the value you set on each device.
For example, I tagged a user's device with the sendTag method with key:value pair "full_name": "Bob Odenkirk"
Within my API call, I want the message to say "Hey Bob Odenkirk, you are awesome!"
Then my contents property within the API call will look like:
"contents": {"en": "Hey {{ full_name }}, you are awesome!"}
OneSignal Tagging Guide:https://documentation.onesignal.com/docs/add-user-data-tags
OneSignal Tag Substitution Guide: https://documentation.onesignal.com/docs/personalization
Which API endpoint are you calling? I'm assuming https://onesignal.com/api/v1/notifications.
It looks like the key should be 'tag' not 'tags'. If the key is wrong you should get a 400 or it should be ignored.
Also, assuming you're using the right tag key, isn't it possible that the tag filters out all possible recipients? The docs show returning 200 in two cases: 1) invalid player ids and 2) no subscribed players
Not sure if those apply

Blockchain info wallet check payment

i am trying to create bill for payment and send to my customer via telegram bot:
i am using blockchain API V2-https://blockchain.info/api/api receive .my code is:
xpub='***'
keyk='02e57f1***'
url='https://api.blockchain.info/v2/receive?xpub='+str(xpub)+'&callback=https%3A%2F%2Fdoors03.ru&key='+keyk
x=requests.get(url)
r=x.json()
r=r['address']
r -is an adress wich was made.
i am sending it to my costumer(by the way is there any way to send adress with exact sum for pay ) . After i want to check is payment was recieved:
data={ "Content-Type": "text/plain","key":keyk,"addr":r,"callback":"https%3A%2F%2Fdoors03.ru","onNotification":"KEEP", "op":"RECEIVE"}
r = requests.post(url, data=data)
and this is the response - u'{\n "message" : "Internal handlers error"\n}'
what i am doing wrong ? how to check payments ? how to send address with exact sum of btc or ethereum ?
Sorry, i don't have enough reputation to post a comment, so this is
the only option i have. #egorkh have you solved this problem? Maybe
you have received explanation from blockchain.info support? I have
sent them a question about that, but they are answering for too long.
UPDATE: Finally, i have found solution.
In my case, reason of "Internal handlers error" message is in a wrong interpretation of their API.
As they haven't implemented balance_update request in their java-api, i did it on my own and i did it in wrong way.
I have put this parameters:
{"key":keyk,"addr":r,"callback":"https%3A%2F%2Fdoors03.ru","onNotification":"KEEP", "op":"RECEIVE"}
as post parameters, like in other methods they have provided in api. In those methods parameters are URLEncoded like you did with callback link. But...
In this HTML request they must be sent as plain text in json format without any special encoding, like that:
Map<String, String> params = new HashMap<String, String>();
params.put("addr", address);
params.put("callback", callbackUrl);
params.put("key", apiCode);
params.put("onNotification", keepOnNotification? "KEEP" : "DELETE");
params.put("confs", Integer.toString(confirmationCount));
params.put("op", StringUtils.isBlank(operationType) ? "ALL" : operationType);
//parse parameters map to json string(that's optional: you can write it directly as string)
String body = new Gson().toJson(params);
if (requestMethod.equals("POST")) {
byte[] postBytes = body.getBytes("UTF-8");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "text/plain");
conn.setRequestProperty("Content-Length", String.valueOf(postBytes.length));
conn.getOutputStream().write(postBytes);
conn.getOutputStream().close();
}
The main reason of your error may be that you put "Content-Type": "text/plain" in data object (, and maybe encoded callback url) .

Categories

Resources