HTTParty not sending data to API - ruby-on-rails

I am trying to call a Restful API (basically a third party application). Here is my code:
resp = HTTParty.post("http://example.com/test/api/url",
{
:query => {"id"=> 3, "example_payload"=> "test payload", "details"=> {}},
:headers => { 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'client_key' => "xxx-xxx-xxxxx" }
})
This is returning a response with status "200 ok". But I am not able to find the changes in my third party application.
I tried with "Rest-client" and "Net-http" as well. Both of them are also not working.
Thanks for helping in advance.

I assume that by
"not able to find the changes in my third party application"
, you mean that your not able to hit that third party url.
Solution:
You don't need to wrap the query and headers into a hash. Simply pass them as parameters like:
HTTParty.post(
"http://example.com/test/api/url",
query: {"id"=> 3, "example_payload"=> "test payload", "details"=> {}},
headers: { 'Content-Type' => 'application/json',
'Accept' => 'application/json',
'client_key' => "xxx-xxx-xxxxx"
}
)
This works for me.

Related

How can I log an HTTP POST response in React Native app?

I have a simple React Native app with a button. On press, it calls the following function which makes a POST request.
I have tested in POSTMAN and the request works. However, I want to test my app and I'm unable to log the response or any errors. Only the console.log statements for 'here' and 'done' are being printed (I see them in Chrome using remote debugger).
It seems like the fetch function is just being ignored, no warning/errors/logs.
What am I doing wrong here? Or what's the best way to make sure the Request is working?
_onPressButton() {
console.log('here');
fetch('http://passport.local/oauth/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
client_id: '2',
client_secret: 'value',
grant_type: 'password',
username: 'value',
password: 'value',
})
})
.then((response) => response.json())
.then((responseJson) => {
console.warn(xhr.responseText);
console.log(responseJson);
return responseJson;
})
.catch((error) => {
console.error(error);
});
console.log('done');
}
Seems like the virtual host wasn't being resolved. I used ngrok to tunnel the address "passport.local" into an ngrok URL and it worked.

POST request timing out on request to APN server

I'm trying to set up Apple Push Notifications through a Rails back-end. I'm using the NetHttp2 gem to create the connection and jwt to sign my tokens.
Here's a sample of the responses I get when trying various combinations of post requests. I get a quick response if I omit the "authorization" header, and similar if I give it garbage or a fake token. But if I use the actual token that I've encoded, the connection times out. I have no idea what Apple is doing on the back-end - I get no message at all.
[22] pry(main)> request = client.call(:post, '/3/device/adknerulkdf2345nl',
body: "{ 'aps' => { 'hello' => 'hello' }", headers: { "apns-topic" => "something" })
=> #<NetHttp2::Response:0x007fbee8226c90 #body="{\"reason\":\"MissingProviderToken\"}", #headers={":status"=>"403", "apns-id"=>"690A959F-27F0-5B5C-1173-0316D6CE4C91"}>
[23] pry(main)> request = client.call(:post, '/3/device/adknerulkdf2345nl',
body: "{ 'aps' => { 'hello' => 'hello' }", headers: { 'authorization' => "bearer garbage", "apns-topic" => "something" })
=> #<NetHttp2::Response:0x007fbeebbbf060 #body="{\"reason\":\"InvalidProviderToken\"}", #headers={":status"=>"403", "apns-id"=>"8EF335C7-1F05-1D99-5425-CCF200960626"}>
[24] pry(main)> request = client.call(:post, '/3/device/adknerulkdf2345nl',
body: "{ 'aps' => { 'hello' => 'hello' }", headers: { 'authorization' => "bearer snwekrwunlsdfu.sdlfknweru.awepi234np2", "apns-topic" => "something" })
=> #<NetHttp2::Response:0x007fbee7f38f88 #body="{\"reason\":\"InvalidProviderToken\"}", #headers={":status"=>"403", "apns-id"=>"C3B48281-C7F1-22B0-6159-0FD0B79C1D43"}>
[25] pry(main)> request = client.call(:post, '/3/device/adknerulkdf2345nl',
body: "{ 'aps' => { 'alert' => 'hello' }", headers: { 'authorization' => "bearer #{token}", "apns-topic" => "something" })
SocketError: Socket was remotely closed
How do I debug this? Is there a way to view what is happening on the Apple server?
If not, has anyone set this up and has some tips? Honestly, I am not at all sure I am properly encoding the JWT token. I am attempting to use my p8 token from Apple and am using the 'ES256' settings but I don't know how to validate it. If I make another request with my token + garbage, it also hangs forever.
Here's the rest of the relevant code:
client = NetHttp2::Client.new("https://api.development.push.apple.com:443",
{ connect_timeout: 100000})
token = JWT.encode({'alg': 'ES256', 'kid': APNS_KEY_ID},
(OpenSSL::PKey::EC.new #p8key), 'ES256',
{'iss': TEAM_ID, 'iat': DateTime.now().to_time.to_i})
After much heartache, the solution
I'm still not totally sure what was going on with Apple, but the answer was with my token encoding. The proper format is:
token = JWT.encode(
{
"iss": TEAM_ID,
"iat": DateTime.now().to_time.to_i
},
private_key,
ALGORITHM,
header_fields= {
"alg": ALGORITHM,
"kid": APNS_KEY_ID
}
)
It seems if you give Apple something with the format authorization => bearer WHATEVER it will hang forever trying to authenticate.
The JWT library is very particular about order and keys (as of 6/29/17).

Rails, RestClient pass binary font file

I'm trying to use restclient to do this CURL post
curl -v -i -X POST -H 'X-Api-Secret: ' -F font=#myraid.ttf APIURL
This is what I have so far
response = RestClient::Request.execute(
:method => :post,
:url => api_url,
:headers => {:content_type => 'multipart/form-data', :accept => 'application/json', :X_Api_Secret => "xxxxxxxxx"}
)
which works perfectly until I try to pass a file like this
response =RestClient::Request.execute(
:method => :post,
:url => api_url,
:headers => {:content_type => 'multipart/form-data', :accept => 'application/json', :X_Api_Secret => "xxxxxxxxxx"},
:upload => {
:file => File.new(params[:custom_font][:font].path, 'rb')
}
)
It then seems to ignore my headers and I get a 403 error, I've also tried a regular rest-client post request like
response = RestClient.post api_url, { :X_Api_Secret => "xxxxxx"}
But again it breaks when I try to introduce the data file.
Any help, pointers or advice would be greatly appreciated.
Ok after a couple of days of head banging, I ended up using unirest instead, after updating to the latest version it worked straight away.
response = Unirest.post api_key,
headers:{
"X-Api-Secret" => "xxxxx"
},
parameters:{
"data" => "ccc"
}

How to send data in a post request with RestClient

I'm trying to mimic a curl request using the RestClient Ruby gem, and so far, I've been having a lot of trouble trying to send in a payload. My curl request looks something like this
curl URL -X POST -u API_KEY -d '{"param_1": "1"}'
I've been trying to replicate this with RestClient using something like this:
RestClient::Request.execute(method: :post, url: URL, user: API_KEY, payload: {"param_1" => "1"})
Alas, I keep getting 400 - Bad Requests errors when doing this. Am I sending data over the wrong way? Should I be using something other than payload?
Change:
payload: {"param_1" => "1"})
To:
payload: '{"param_1": "1"})'
Also, specify the headers.
So, it becomes:
RestClient::Request.execute(method: :post,
url: 'your_url',
user: 'API_KEY',
payload: '{"param_1": "1"}',
headers: {"Content-Type" => "application/json"}
)
Just Change:
payload: {"param_1" => "1"}
To:
payload: {"param_1" => "1"}.to_json
So, then it becomes:
RestClient::Request.execute(method: :post,
url: 'your_url',
user: 'API_KEY',
payload: {"param_1" => "1"}.to_json,
headers: {"Content-Type" => "application/json"}
)
Turns out I had to add an argument to specify that my data was in a JSON format. The correct answer was something like this:
RestClient::Request.execute(method: :post, url: URL, user: API_KEY, payload: '{"param_1": "1"}', headers: {"Content-Type" => "application/json"})

Changing Content-Type to JSON using HTTParty

I am trying to use Ruby on Rails to communicate with the Salesforce API. I can fetch data easily enough but I am having problems posting data to the server. I am using HTTParty as per Quinton Wall's post here:
https://github.com/quintonwall/omniauth-rails3-forcedotcom/wiki/Build-Mobile-Apps-in-the-Cloud-with-Omniauth,-Httparty-and-Force.com
but all I seem to be able to get from the salesforce server is the error that I am submitting the body as html
{"message"=>"MediaType of 'application/x-www-form-urlencoded' is not supported by this resource", "errorCode"=>"UNSUPPORTED_MEDIA_TYPE"}
the responsible code looks like:
require 'rubygems'
require 'httparty'
class Accounts
include HTTParty
format :json
...[set headers and root_url etc]
def self.save
Accounts.set_headers
response = (post(Accounts.root_url+"/sobjects/Account/", :body => {:name => "graham"}.to_json))
end
end
anyone have an idea why the body should be being posted as html and how to change this so that it definitely goes as json so that salesforce doesn't reject it?
Any help would be appreciated. cheers
The Content-Type header needs to be set to "application/json". This can be done by inserting :headers => {'Content-Type' => 'application/json'} as a parameter to post, ie:
response = post(Accounts.root_url+"/sobjects/Account/",
:body => {:name => "graham"}.to_json,
:headers => {'Content-Type' => 'application/json'} )
You have to set the Content-Type header to application/json. I haven't used HTTParty, but it looks like you have to do something like
response = (post(Accounts.root_url+"/sobjects/Account/", :body => {:name => "graham"}.to_json) , :options => { :headers => { 'Content-Type' => 'application/json' } } )
I'm somewhat surpised that the format option doesn't do this automatically.

Resources