I am pretty new to ruby. To be honest its my first try doing a ruby script with an http connection. I am lost at one point. Sending data via POST to Jira6. Here is the code I use
# If issues_id.count != 0 make a transition of the issues
if issue_id.count > 0
issue_id.each do |id|
transition_data = '{"transition": {"id": "666"}}'
Net::HTTP.start(jira_domain, jira_port) do |http|
ap jira_transition + id + jira_transition_query
request = Net::HTTP::Post.new(jira_transition + id + jira_transition_query)
request.basic_auth jira_user, jira_pass
request["Content-Type"] = "application/json"
ap transition_data
request.set_form_data('data' => '{"transition": {"id": "841"}}');
response = http.request(request)
ap response.code
ap response
end
end
end
testing this results in the following error:
#<Net::HTTPUnsupportedMediaType 415 Unsupported Media Type readbody=true> error.
when I try the same with curl, it works just fine
curl -D- -u external_user:external_pass -X POST --data '{"transition": {"id": "841"}}' -H "Content-Type: application/json" http://jira.demo.com:80/rest/api/2/issue/17399/transitions\?expand\=transitions.fields
Just to be sure I don't get the same crap answers like on google groups:
Yes I reseted the issue after a sucessfull try :-)
Yes the transitionId 841 is correct :-)
Can someone please send me in the right direction howto send the data to Jira6 REST-API? I think its a marginal error, but I do not recognize it.
Thank you very very much.
I recommend you try the jira-ruby gem
I ran into the same issue. For some reason, you can not use 'request["Content-Type"] = "application/json"'. You must create a new header variable and then pass it as a second argument to Post.new. Then use request.body to include the update params.
if issue_id.count > 0
issue_id.each do |id|
transition_data = '{"transition": {"id": "666"}}'
Net::HTTP.start(jira_domain, jira_port) do |http|
ap jira_transition + id + jira_transition_query
header = {'Content-Type': 'application/json'}
request = Net::HTTP::Post.new(jira_transition + id + jira_transition_query, header)
request.basic_auth jira_user, jira_pass
#request["Content-Type"] = "application/json"
ap transition_data
#request.set_form_data('data' => '{"transition": {"id": "841"}}');
params = {transistion: {id: 841}}
request.body = params.to_json
response = http.request(request)
ap response.code
ap response
end
end
end
Related
I have making a post request in Ruby to a slack endpoint and its failing, here is my request, not sure what I'm missing:
#!/usr/bin/env ruby
#Notification Script Test
def send_slack_message
slack_rooms = [ '#test_channel_notify' ]
slack_token_file = (File.join(ENV['HOME'], '.slack_api_token'))
slack_api_token = (File.open(#slack_token_file).readlines)[0].chomp
msg = 'This is a test message send'
slack_url = "https://slack.com/api/chat.postMessage"
%x{curl -k -X POST -d"token=#{slack_api_token}\&channel=#{slack_rooms}\&text=#{msg}" '#{slack_url}'}
end
send_slack_message
I am getting the following error, not sure what I'm missing:
./cap2.rb:7:in `initialize': no implicit conversion of nil into String (TypeError)
from ./cap2.rb:7:in `open'
from ./cap2.rb:7:in `send_slack_message'
from ./cap2.rb:13:in `<main>'
I am a ruby novice so I may be missing everything would love some help!
The error says that you can't give nil to File.open. Make sure #slack_token_file exists and is not nil.
The slack API wants to receive the payload in this format: 'payload={"json": "data"}'
Using Net::HTTP you can make a POST request like this:
require 'net/http'
require 'uri'
def payload(message, channel)
{ channel: channel, username: 'your-username', text: message, icon_emoji: ':robot_face:' }
end
msg = 'This is a test message send'
body = payload(msg, '#test_channel_notify').to_json
url = URI("https://slack.com/api/chat.postMessage")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request.body = "payload=#{body}"
http.request(request)
While your original problem has been solved, I will provide an alternative solution which follows the more common practice of storing secret credentials as environment variables, not as files (which can, for example, more easily exfiltrated by accident, committed to source control, pasted to a presentation, etc).
Set SLACK_TOKEN in your environment, and then use:
#!/usr/bin/env ruby
#Notification Script Test
def send_slack_message
slack_rooms = [ '#test_channel_notify' ]
slack_api_token = ENV['SLACK_TOKEN']
msg = 'This is a test message send'
slack_url = "https://slack.com/api/chat.postMessage"
%x{curl -k -X POST -d"token=#{slack_api_token}\&channel=#{slack_rooms}\&text=#{msg}" '#{slack_url}'}
end
send_slack_message
I've been trying to make an API call to my server to delete a user record help on a dev database. When I use Fiddler to call the URL with the DELETE operation I am able to immediately delete the user record. When I call that same URL, again with the DELETE operation, from my script below, I get this error:
{"Message":"The requested resource does not support http method 'DELETE'."}
I have changed the url in my script below. The url I am using is definitely correct. I suspect that there is a logical error in my code that I haven't caught. My script:
require 'net/http'
require 'json'
require 'pp'
require 'uri'
def deleteUserRole
# prepare request
url= "http://my.database.5002143.access" # dev
uri = URI.parse(url)
request = Net::HTTP::Delete.new(uri.path)
http = Net::HTTP.new(uri.host, uri.port)
# send the request
response = http.request(request)
puts "response: \n"
puts response.body
puts "response code: " + response.code + "\n \n"
# parse response
buffer= response.body
result = JSON.parse(buffer)
status= result["Success"]
if status == true
then puts "passed"
else puts "failed"
end
end
deleteUserRole
It turns out that I was typing in the wrong command. I needed to change this line:
request = Net::HTTP::Delete.new(uri.path)
to this line:
request = Net::HTTP::Delete.new(uri)
By typing uri.path I was excluding part of the URL from the API call. When I was debugging, I would type puts uri and that would show me the full URL, so I was certain the URL was right. The URL was right, but I was not including the full URL in my DELETE call.
if you miss the parameters to pass while requesting delete, it won't work
you can do like this
uri = URI.parse('http://localhost/test')
http = Net::HTTP.new(uri.host, uri.port)
attribute_url = '?'
attribute_url << body.map{|k,v| "#{k}=#{v}"}.join('&')
request = Net::HTTP::Delete.new(uri.request_uri+attribute_url)
response = http.request(request)
where body is a hashmap where you can define query params as a hashmap.. while sending request it can be joined in the url by the code above.
ex:body = { :resname => 'res', :bucket_name => 'bucket', :uploaded_by => 'upload' }
I'm simply trying to get a response from the API that includes certain fields that I'm specifying in my uri string but I keep receiving an InvalidURIError. I've come here as a last resort, having spent hours trying to debug this.
I've already tried using the URI.encode() method on it as well, but only get the same error.
Here's my code:
url = params[:url]
uri = URI('https://graph.facebook.com/v2.3/?id=' + url + '&fields=share,og_object{id,url,engagement}&access_token=' + CONFIG['fb_access_token'])
req = Net::HTTP::Post.new(uri.path)
req.set_form_data('fields' => 'og_object[engagement]','access_token' => CONFIG['fb_access_token'])
res = Net::HTTP.new(uri.host, uri.port)
res.verify_mode = OpenSSL::SSL::VERIFY_NONE
res.use_ssl = true
response = nil
res.start do |http|
response = http.request(req)
end
response = http.request(req)
output = ""
output << "#{response.body} <br />"
return output
And the error I'm receiving:
URI::InvalidURIError - bad URI(is not URI?): https://graph.facebook.com/v2.3/?id=http://www.wikipedia.org&fields=share,og_object{id,url,engagement}&access_token=960606020650536|eJC0PoCARFaqKZWZHdwN5ogkhfs
I'm just exhausted at this point so if I left out any important information just let me know and I'll respond with it as soon as I can. Thank you!
The problem is you're just dumping strings into your URI without escaping them first.
Since you're using Sinatra you can use Rack::Utils.build_query to construct your URI's query component with the values correctly escaped:
uri = URI('https://graph.facebook.com/v2.3/')
uri.query = Rack::Utils.build_query(
id: url,
fields: 'share,og_object{id,url,engagement}',
access_token: CONFIG['fb_access_token']
)
I understand that you could use proxy in the ruby Net::HTTP. However, I have no idea how to do this with a bunch of proxy. I need the Net::HTTP to change to another proxy and send another post request after every post request. Also, is it possible to make the Net::HTTP to change to another proxy if the previous proxy is not working? If so, how?
Code I'm trying to implement the script in:
require 'net/http'
sleep(8)
http = Net::HTTP.new('URLHERE', 80)
http.read_timeout = 5000
http.use_ssl = false
path = 'PATHHERE'
data = '(DATAHERE)'
headers = {
'Referer' => 'REFERER HERE',
'Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8',
'User-Agent' => '(USERAGENTHERE)'}
resp, data = http.post(path, data, headers)
# Output on the screen -> we should get either a 302 redirect (after a successful login) or an error page
puts 'Code = ' + resp.code
puts 'Message = ' + resp.message
resp.each {|key, val| puts key + ' = ' + val}
puts data
end
Given an array of proxies, the following example will make a request through each proxy in the array until it receives a "302 Found" response. (This isn't actually a working example because Google doesn't accept POST requests, but it should work if you insert your own destination and working proxies.)
require 'net/http'
destination = URI.parse "http://www.google.com/search"
proxies = [
"http://proxy-example-1.net:8080",
"http://proxy-example-2.net:8080",
"http://proxy-example-3.net:8080"
]
# Create your POST request_object once
request_object = Net::HTTP::Post.new(destination.request_uri)
request_object.set_form_data({"q" => "stack overflow"})
proxies.each do |raw_proxy|
proxy = URI.parse raw_proxy
# Create a new http_object for each new proxy
http_object = Net::HTTP.new(destination.host, destination.port, proxy.host, proxy.port)
# Make the request
response = http_object.request(request_object)
# If we get a 302, report it and break
if response.code == "302"
puts "#{proxy.host}:#{proxy.port} responded with #{response.code} #{response.message}"
break
end
end
You should also probably do some error checking with begin ... rescue ... end each time you make a request. If you don't do any error checking and a proxy is down, control will never reach the line that checks for response.code == "302" -- the program will just fail with some type of connection timeout error.
See the Net::HTTPHeader docs for other methods that can be used to customize the Net::HTTP::Post object.
I have to send two XML documents in my request to the UPS API (here's my original question What is the root of this XML document? )
How would I do this?
def make_initial_request
uri = URI.parse(UPS_API['confirm_url'])
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
headers = {'Content-Type' => 'text/xml'}
request = Net::HTTP::Post.new(uri.path, headers)
request.body = xml_for_initial_request #<-- how do i split this into two documents?
#request.body = second_xml_document #<-- i want something like that. could i just use << ?
begin
response = https.request(request)
rescue
return nil
end
puts "response: #{response.code} #{response.message}: #{response.body}"
return nil if response.body.include?("Error")
end
You should use MIME Multipart messages if the API support them (ruby gem).
Otherwise just try to concatenate files' contents request.body = "#{xml_for_initial_request}\n#{second_xml_document}"