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

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.

Related

Data sent with the requests.delete method is disregarded

While trying to connect to an API from Alpaca (a broker that accepts automated orders), I found that I was unable to send data with the requests.delete method. Here is some code:
def close_position(symbol, percentage, api_key=api_key, secret_key=secret_key, base_url=base_url):
data = {"percentage": percentage}
headers = {
"APCA-API-KEY-ID": api_key,
"APCA-API-SECRET-KEY": secret_key
}
url = f"{base_url}/v2/positions/{symbol}"
order = requests.delete(url, json=data, headers=headers)
return order.json()
This code is supposed to close (i.e., liquidate) a specified percentage of a position. However, it seems that the data sent using the delete method is disregarded; this function always closes my entire position instead of the specified percentage. Here is the documentation for the Alpaca API: https://alpaca.markets/docs/api-references/trading-api/positions/#close-a-position
I have also tried the data and params parameter and json.dumps(data), but to no avail.
Any idea how to send data with the requests.delete method would be appreciated.

Imgur Auth via API

First and foremost, thank you for taking the time to read this.
The Ask
I am attempting to connect to Imgur's API and need to pass the authentication steps. I admit, Oauth has been a struggle for me and I welcome any help.
Current Code Block
from Auth import *
from datetime import datetime
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
print("Current Time =", current_time)
response = []
api_variable = f""
api_auth_url = f"https://api.imgur.com/oauth2/authorize"
headers = {f"Authorization" : f"Client-ID {imgur_client_id}"}
response_api_url = requests.post(api_auth_url,headers=headers)
response_api_url.json()
response_api_url.status_code
response.append(response_api_url.json())
print(response)
Response
[{'data': {'error': 'client_id and response_type are required', 'request': '/oauth2/authorize', 'method': 'POST'}, 'success': False, 'status': 400}]
I have tried adding multiple different headers / parameters though I must admit I am not sure what the next steps are. I am following the following documentation.
https://apidocs.imgur.com/#authorization-and-oauth
I have registered 2 applications, one with the postman call back (which fails) and one without.
Might Be Relevant
When it comes to api's like twitter / twitch to name a couple, I was able to auth without needing to solve for a user logging in, is that possible here via headers as well?
Thanks if you managed to make it this far, really appreciate it!

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)

requests.post only accepts "text" dictionary values

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.

Needed advice to automate REST services test

I am kind of newbie to REST and testing dept. I needed to write automation scripts to test our REST services.We are planning to run these scripts from a Jenkins CI job regularly. I prefer writing these in python as we already have UI functionality testing scripts in python generated by selenium IDE, but I am open to any good solution.I checked httplib,simplejson and Xunit, but looking for better solutions available out there.
And also, I would prefer to write a template and generate actual script for each REST API by reading api info from xml or something. Advance thanks to all advices.
I usually use Cucumber to test my restful APIs. The following example is in Ruby, but could easily be translated to python using either the rubypy gem or lettuce.
Start with a set of RESTful base steps:
When /^I send a GET request for "([^\"]*)"$/ do |path|
get path
end
When /^I send a POST request to "([^\"]*)" with the following:$/ do |path, body|
post path, body
end
When /^I send a PUT request to "([^\"]*)" with the following:$/ do |path, body|
put path, body
end
When /^I send a DELETE request to "([^\"]*)"$/ do |path|
delete path
end
Then /^the response should be "([^\"]*)"$/ do |status|
last_response.status.should == status.to_i
end
Then /^the response JSON should be:$/ do |body|
JSON.parse(last_response.body).should == JSON.parse(body)
end
And now we can write features that test the API by actually issuing the requests.
Feature: The users endpoints
Scenario: Creating a user
When I send a POST request to "/users" with the following:
"""
{ "name": "Swift", "status": "awesome" }
"""
Then the response should be "200"
Scenario: Listing users
Given I send a POST request to "/users" with the following:
"""
{ "name": "Swift", "status": "awesome" }
"""
When I send a GET request for "/users"
Then the response should be "200"
And the response JSON should be:
"""
[{ "name": "Swift", "status": "awesome" }]
"""
... etc ...
These are easy to run on a CI system of your choice. See these links for references:
http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test/
http://jeffkreeftmeijer.com/2011/the-pain-of-json-api-testing/
http://www.cheezyworld.com/2011/08/09/running-your-cukes-in-jenkins/
import openpyxl
import requests
import json
from requests.auth import HTTPBasicAuth
urlHead='https://IP_ADDRESS_HOST:PORT_NUMBER/'
rowStartAt=2
apiColumn=2
#payloadColumn=3
responseBodyColumn=12
statusCodeColumn=13
headerTypes = {'Content-Type':'application/json',
'Accept':'application/json',
'Authorization': '23324'
}
wb = openpyxl.load_workbook('Excel_WORKBOOK.xlsx')
# PROCESS EACH SHEET
for sheetName in (wb.get_sheet_names()):
print ('Sheet Name = ' + sheetName)
flagVar = input('Enter N To avoid APIs Sheets')
if (flagVar=='N'):
print ('Sheet got skipped')
continue
#get a sheet
sheetObj = wb.get_sheet_by_name(sheetName)
#for each sheet iterate the API's
for i in range(2, sheetObj.max_row+1):
#below is API with method type
apiFromSheet = (sheetObj.cell(row=i, column=apiColumn).value)
if apiFromSheet is None:
continue
#print (i, apiFromSheet)
#Let's split the api
apiType = apiFromSheet.split()[0]
method = apiFromSheet.split()[1]
if (apiType!='GET'):
continue
#lets process GET API's
absPath = urlHead + method
print ("REQUESTED TYPE AND PATH = ", apiType, absPath)
print('\n')
res = requests.get(absPath, auth=HTTPBasicAuth(user, pwd), verify=False, headers=headerTypes)
#LET's write res body into relevant cell
sheetObj.cell(row=i, column=responseBodyColumn).value = (res.text)
sheetObj.cell(row=i, column=statusCodeColumn).value = (res.status_code)
wb.save('Excel_WORKBOOK.xlsx')
`#exit(0)`

Categories

Resources