Correct way to get response from Slack API - ruby

I want to move this code from the console:
curl --data "token=TOKEN_NO&email=USER#EXAMPLE.COM" https://slack.com/api/users.lookupByEmail
to the class method and get response from Slack (user details) exactly like from the console. I was trying to do something like this, but I don't see any results:
require 'net/http'
module Slack
class GetUserID
SLACK_API_ENDPOINT = 'https://slack.com/api/users.lookupByEmail'
def call
escaped_address = URI.decode_www_form_component(SLACK_API_ENDPOINT)
uri = URI.parse(escaped_address)
puts Net::HTTP.post(uri, params)
end
private
def params
{
token: 'TOKEN_NO',
email: 'USER#EXAMPLE.COM'
}
end
end
end
Right now I have an error:
send_request_with_body': undefined methodbytesize' for #Hash:0x00007f9d85093100> (NoMethodError)
Where am I wrong? Should I use HTTParty instead?

The second argument passed to Net::HTTP.post should be a string, read more about the method signature here.
You will need to convert the params hash into a query string format that looks like:
token=TOKEN_NO&email=USER#EXAMPLE.COM

Related

Httparty - appending to url and adding headers to get request via Ruby class

I'm currently working with Httparty to make a GET Seamless.giv API which returns field from a form. In the requests there are Authentication headers that need to be passed in order to access the API. But the request has to be made to a specific form. Thats where the issue lays should this be in the base URI or appended?
Here is the curl example of the request:
curl -X GET -H "AuthDate: 1531236159"\
-H "Authorization: HMAC-SHA256 api_key=XXXXXXXX nonce=12345 Signature=XXXXXXXXXXX"\
-d 'false' https://nycopp.seamlessdocs.com/api/form/:form_id/elements
and this is the approach im currently taking:
class SeamlessGov
include HTTParty
base_uri "https://nycopp.seamlessdocs.com/api"
def initialize(args={})
#api_key = args[:api_key]
#nonce = args[:nonce]
#signature = generate_signature
end
def form(form_id)
#form = form_id
end
def headers(headers={})
#headers = headers
end
def generate_signature
# bash command
end
end
Is the best practice to append it or put it in the base_uri for example:
base_uri "https://nycopp.seamlessdocs.com/api/form/:form_id/elements" or created a method to append to the base_uri for example:
def append_form(form)
"/form/#{form}/elements"
end
What would the best approach be? So that when I call
#form = SeamlessGov.new(params, headers) works.
If I understand what you're asking correctly, you would write a method like:
def create_form
get("/form/#{form_id}/elements", headers)
end
Which you can then call like:
#form = SeamlessGov.new(params, headers).create_form

Httparty request query not parsed properly

I would like to pass some query parameters to HTTParty.get. I have a helper method to handle requests
def handle_request
begin
response = yield
if response['Success']
response['Payload']
else
raise Bondora::Error::ApiError, "#{response['Errors'][0]['Code']}: #{response['Errors'][0]['Message']}"
end
rescue Net::OpenTimeout, Net::ReadTimeout
{}
end
end
And another method to to make the request:
def investments(*params)
handle_request do
url = '/account/investments'
self.class.get(url, :query => params)
end
end
When I call this method like investments({"User" => "test"}) I should end up with a GET request to /account/investments?User=test.
Unfortunately the request params are not parsed properly and the resulting request looks like this: /account/balance?[{%22User%22=%3E%22test%22}]
Any clue why this happens? I think it has something to do with the methods I wrote.
When you declare the method as def investments(*params), params will contain an array of arguments, and want to pass a hash to your get call. So, either drop the asterisk and simply say def investments(params), or use query: params.first later in the method.

get response of grape endpoint with def after

I'm using Grape. I want to define a method that runs after the response value has been calculated for a request, I tried following this:
http://www.sinatrarb.com/intro.html#Filters
and ended up with:
after do
puts response
end
however response is not defined. Apparently within this block, self refers to Grape::Endpoint, since after runs after the endpoint handler, I should be able to find the response value, right? I tried self.body however this returns nothing - it does, however, let me change the value of the response, but I want to retrieve the response value that was generated by my handler.
Ahh, so I solved this using rack middleware:
class CaptureResponse < Grape::Middleware::Base
def call!(env)
#env = env
#app_response = #app.call(#env)
body = #app_response[2]
body = body.body if body.kind_of? Rack::BodyProxy
puts body
#app_response
end
end
use CaptureResponse
I have no idea why just slapping in use CaptureResponse in config.ru works but it does!

valid_json? check in ruby is not working

I am trying to check whether the response is valid JSON. I am making HTTParty or Restclient request to some urls and checking whether the responses returned are valid JSON?
I referred the link here. This is not working.
My code:
require 'json'
def get_parsed_response(response)
if not response.is_a? String or not response.valid_json?
# code
end
end
Error:
/home/user/.rvm/gems/ruby-2.1.0/gems/httparty-0.13.1/lib/httparty/response.rb:66:in `method_missing': undefined method `valid_json?' for #<HTTParty::Response:0x00000002497918> (NoMethodError)
More specifically than in my comment, I suggest you use something like this:
value = nil
begin
value = JSON.parse(response)
# do whatever you do when not error
rescue JSON::ParserError, TypeError => e
puts "Not a string, or not a valid JSON"
# do whatever you do when error
end
You should be calling response.body.
response is an HTTParty::Response object. What you really want to be working with is the String object that represents the HTTP response body.

How to get ALL of the URL parameters in a Sinatra app

Using the following Sinatra app
get '/app' do
content_type :json
{"params" => params}.to_json
end
Invoking:
/app?param1=one&param2=two&param2=alt
Gives the following result:
{"params":{"param1":"one","param2":"alt"}}
Params has only two keys, param1 & param2.
I understand Sinatra is setting params as a hash, but it does not represent all of the URL request.
Is there a way in Sinatra to get a list of all URL parameters sent in the request?
Any request in rack
get '/app' do
params = request.env['rack.request.query_hash']
end
I believe by default params of the same name will be overwritten by the param that was processed last.
You could either setup params2 as an array of sorts
...&param2[]=two&param2[]=alt
Or parse the query string vs the Sinatra provided params hash.
kwon suggests to parse the query string.
You can use CGI to parse it as follows:
require 'cgi'
get '/app' do
content_type :json
{"params" => CGI::parse(request.query_string)}.to_json
end
Invoking:
/app?param1=one&param2=two&param2=alt
Gives the following result:
{"params":{"param1":["one"],"param2":["two","alt"]}}
You can create a helper to make the process more friendly:
require 'cgi'
helpers do
def request_params_repeats
params = {}
request.env["rack.input"].read.split('&').each do |pair|
kv = pair.split('=').map{|v| CGI.unescape(v)}
params.merge!({kv[0]=> kv.length > 1 ? kv[1] : nil }) {|key, o, n| o.is_a?(Array) ? o << n : [o,n]}
end
params
end
end
You can then access the parameters in your get block:
get '/app' do
content_type :json
request_params_repeats.to_json
end

Resources