Post a hash using HTTParty to an api - ruby-on-rails

I'm trying to send a POST request to an api with a hash as the parameters of the request. The api in question is freshdesk's api. I'm using rails 4.
They require that i send a request in this form:
Code
{
"helpdesk_ticket":{
"description":"Some details on the issue ...",
"subject":"Support needed..",
"email":"hulk#outerspace.com",
"priority":1, "status":2
},
"cc_emails":"superman#marvel.com,avengers#marvel.com"
}
Sample Curl
curl -u user#yourcompany.com:test -H "Content-Type: application/json"
-d '{ "helpdesk_ticket": { "description": "Details about the issue...", "subject": "Support Needed...", "email":
"hulk#outerspace.com", "priority": 1, "status": 2 }, "cc_emails":
"superman#marvel.com,avengers#marvel.com" }' -X POST
http://domain.freshdesk.com/helpdesk/tickets.json
This is currently what I have
Controller
def create
email = params[:email]
description = params[:description]
subject = params[:subject]
payload = [{"helpdesk_ticket" => { 'email' => email, 'description' => description, 'subject' => subject, 'priority' => 1, 'status' => 2}}].to_json
trololol = Freshdesk.post('/helpdesk/tickets.json',
:body => payload
)
debugger
redirect_to "/support"
end
class Freshdesk
include HTTParty
#apikey = "Somethingladida"
format :json
base_uri "http://genericname.freshdesk.com/"
basic_auth #apikey, ""
end
View
=form_tag support_index_path do
=label_tag :email
=text_field_tag :email,params[:email]
=label_tag :description
=text_field_tag :description
=label_tag :subject
=text_field_tag :subject
=submit_tag "Submit", class:"button"
The main problem is this: I'm getting a 500 internal server error, so I'm presuming that the request that i'm trying to craft is not in the format that the freshdesk api requires
Cheers! :)

You can mirror that structure exactly by doing something like this:
def freshdesk_hash
{
"helpdesk_ticket":{
"description":"Some details on the issue ...",
"subject":"Support needed..",
"email":"hulk#outerspace.com",
"priority":1, "status":2
},
"cc_emails":"superman#marvel.com,avengers#marvel.com"
}
end
But to me it looks like you're putting the hash into an array ([{...).

Related

Sending the parent object to the Box File Upload API in Ruby on Rails

I'm attempting to use the Box File Upload API to send a file to Box.com from a Ruby on Rails application. However, I keep getting a bad request response that says parent is a missing parameter.
Here is their documentation:
https://developer.box.com/v2.0/reference#upload-a-file
Here is their curl example:
curl https://upload.box.com/api/2.0/files/content \
-H "Authorization: Bearer ACCESS_TOKEN" -X POST \
-F attributes='{"name":"tigers.jpeg", "parent":{"id":"11446498"}}' \
-F file=#myfile.jpg
I'm attempting to use RailsClient to do this in my app and here are the two ways I've tried:
RestClient.post(BASE_CONTENT_URL,{ :name => "randompdf.pdf", :parent => {:id => 0}, :myfile => file }, { :Authorization => "Bearer #{NEW_TOKEN}" })
&
#parent = Struct.new(:id)
#parent.id = 0
RestClient.post(BASE_CONTENT_URL,{ :name => "randompdf.pdf", :parent => #parent, :myfile => file }, { :Authorization => "Bearer #{NEW_TOKEN}" })
I get the same error attempting to do it via Postman as well. Box's Community Forum and Support resources haven't gotten back to me so I'm a little lost.
attributes = {name: #{unique_name}, parent: { id: 0 }}
box_response = RestClient::Request.execute(method: :post,
url: BASE_UPLOAD_URL + "/content",
payload: { attributes: attributes.to_json,
file: file},
headers: {Authorization: "Bearer #{NEW_TOKEN}"})

SendGrid add multiple email addresses to Marketing Email API

I'm having some real difficultly trying to send multiple email addresses in json to the sendgrid API.
Here is my code that works for one email address:
#result = HTTParty.post("https://api.sendgrid.com/api/newsletter/lists/email/add.json",
:body => { :list => "#{#survey.name}_#{#survey.id}", :data => '{ "name": "John Smith", "email": "john#smith.com" }', :api_user => 'XXXXX', :api_key => 'XXXXX'})
But in ruby using the :data post attribute how can I add another email address?
The following don't work - life would be too easy lol
:data => '[{"email" => "nick#sendgrid.com"},{"email" => "jane#example.com"}]'
OR
:data => '{[{"email" => "nick#sendgrid.com"},{"email" => "jane#example.com"}]}'
Apparently SendGrid expects the following....
data[]={"email" => "nick#sendgrid.com"}&data[]={"email" => "jane#example.com"}
How I can create a post parameter in rails that does this?!?
You could create your :data param as an array of JSONs, like so:
:data => ['{ "name" : "Foo Bar", "email" : "foo#bar.com" }','{ "name" : "Jon Snow", "email" : "jon#snow.com" }']

How to set Devise confirmable link on Mandrill template?

I know that with the Mandrill syntax that I can send in user specific info by doing something like this:
def confirmation_instructions(record, token, opts={})
options = {
:subject => 'Email confirmation',
:email => record.email,
:name => record.first_name,
:global_merge_vars => [
{
name: 'email',
content: record.email
},
{
name: 'confirmation_link',
content: record.confirmation_token
}
],
:template => 'confirm_email'
}
mandrill_send(options)
end
but how do I send the actual confirmation link that is in the devise confirmation instructions html.erb?
views/confirmable/mailer/confirmation_instructions.html.erb
<p><%= link_to 'Confirm my account', confirmation_url(#resource, confirmation_token: #token) %></p>
UPDATE
I edited so I send this link:
content: 'http://localhost:3000/users/confirmation?confirmation_token=' + record.confirmation_token
It still doesn't work, I think because the token is actually encrypted. I'm thinking this is the case because when I use the default mailer the token is a lot shorter than the token I get from record.confirmation_token.
Can someone let me know how to pass the correct token to Mandrill?
I had the same issue, what worked for me was using 'token' instead of 'record.confirmation_token'. It seems that Devise's latests updates changed some Mailer's methods config.
Instead of:
http://domain.com/users/confirmation?confirmation_token=' + record.confirmation_token
Use:
http://domain.com/users/confirmation?confirmation_token=' + token
Let me know if it helps you.

Ruby: POST data to a url

In a rails app I want to be able to post some information to another website inside a method without visiting the website. I'm fairly new to the topic so act as if I’m 5 years old.
My idea so far:
def create_button
button = {
:name => 'test',
:type => 'buy_now',
:callback_url => 'http://www.example.com/my_custom_button_callback',
:description => 'sample description',
:include_email => true
}
"https://thesite.com/api/v1" + button.to_query
# post logic here
end
Ruby ships with the Net::HTTP library for making HTTP requests. There are a lot of gems that wrap HTTP as well, my favorite is Faraday. Look into those libraries, it is pretty straightforward how to make a POST request with them.
There are a lots of gems that do this for free but if you only want to use the standard library, try something like this:
require "net/http"
require 'net/https'
require "uri"
uri = URI.parse("https://thesite.com/api/v1")
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
req = Net::HTTP::Post.new(uri.path)
# I'm unsure if symbols will work
button = {
"name" => 'test',
"type" => 'buy_now',
"callback_url" => 'http://www.example.com/my_custom_button_callback',
"description" => 'sample description',
"include_email" => true
}
req.set_form_data(button)
res = https.request(req)
Try: Net::HTTP
uri = URI.parse("https://thesite.com/api/v1")
button = {
:name => 'test',
:type => 'buy_now',
:callback_url => 'http://www.example.com/my_custom_button_callback',
:description => 'sample description',
:include_email => true
}
res = Net::HTTP.post_form(uri,button)
res.code
res.body # response from api

Ruby: HTTParty: can't format XML POST data correctly?

NOTE: "object" is a placeholder work, as I don't think I should be saying what the controller does specifically.
so, I have multiple ways of calling my apps API, the following works in the command line:
curl -H 'Content-Type: application/xml' -d '<object><name>Test API object</name><password>password</password><description>This is a test object</description></object>' "http://acme.example.dev/objects.xml?api_key=1234"
the above command generates the following request in the devlog:
Processing ObjectsController#create to xml (for 127.0.0.1 at 2011-07-07 09:17:51) [POST]
Parameters: {"format"=>"xml", "action"=>"create", "api_key"=>"1234", "controller"=>"objects",
"object"=>{"name"=>"Test API object", "description"=>"This is a test object", "password"=>"[FILTERED]"}}
Now, I'm trying to write tests for the actions using the API, to make sure the API works, as well as the controllers.
Here is my current (broken) httparty command:
response = post("create", :api_key => SharedTest.user_api_key, :xml => data, :format => "xml")
this command generates the following request in the testlog:
Processing ObjectsController#create to xml (for 0.0.0.0 at 2011-07-07 09:37:35) [POST]
Parameters: {
"xml"=>"<object><name><![CDATA[first post]]></name>
<description><![CDATA[Things are not as they used to be]]></description>
<password><![CDATA[WHEE]]></password>
</object>",
"format"=>"xml",
"api_key"=>"the_hatter_wants_to_have_tea1",
"action"=>"create",
"controller"=>"objects
So, as you can see, the command line command actually generates the object hash from the xml, whereas the httparty command ends up staying in xml, which causes problems for the create method, as it needs a hash.
Any ideas / proper documentation?
Current documentation says that post takes an url, and "options" and then never says what options are available
**EDIT:
as per #Casper's suggestion, my method now looks like this:
def post_through_api_to_url(url, data, api_key = SharedTest.user_api_key)
response = post("create", {
:query => {
:api_key => api_key
},
:headers => {
"Content-Type" => "application/xml"
},
:body => data
})
ap #request.env["REQUEST_URI"]
assert_response :success
return response
end
unfortunately, the assert_response fails, because the authentication via the api key fails.
looking at the very of of the request_uri, the api_key isn't being set properly... it shows:
api_key%5D=the_hatter_wants_to_have_tea1"
but it should just be equals, without the %5D (right square bracket)
I think this is how you're supposed to use it:
options = {
:query => {
:api_key => 1234
},
:headers => {
"Content-Type" => "application/xml"
},
:body => "<xmlcode>goes here</xmlcode>"
}
post("/create", options)
Forgive me for being basic about it but if you only want to send one variable as a parameter, why don't you do as Casper suggests, but just do:
post("/create?api_key=1234", options)
Or rather than testing HTTParty's peculiarities in accessing your API, perhaps write your tests using Rack::Test? Very rough example...
require "rack/test"
require "nokogiri"
class ObjectsTest < Test::Unit::TestCase
include Rack::Test::Methods
def app
MyApp.new
end
def create_an_object(o)
authorize "x", "1234" # or however you want to authenticate using query params
header 'Accept', 'text/xml'
header 'Content-Type', 'text/xml'
body o.to_xml
post "/create"
xml = Nokogiri::XML(last_response.body)
assert something_logic_about(xml)
end
end

Resources