Curl request in Ruby for Facebook Api - ruby-on-rails

I'm trying to make a curl call with curb gem equivalent to:
curl \
-F 'name=My new CA' \
-F 'subtype=CUSTOM' \
-F 'description=People who bought from my website' \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.5/act_<AD_ACCOUNT_ID>/customaudiences
So far my code looks like:
cr = Curl::Easy.http_post("https://graph.facebook.com/v2.5/act_XXXXXXXXXXXXXXX/customaudiences?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") do |curl|
curl.headers['name']='My new CA'
curl.headers['subtype']='CUSTOM'
curl.headers['description']='People who bought from my website'
curl.headers['access_token']='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
end
pp cr.body_str
However, as a response I get this:
=> "{\"error\":{\"message\":\"(#100) Missing parameter(s): subtype\",\"type\":\"OAuthException\",\"code\":100,\"fbtrace_id\":\"BOd\\/mmhQkkP\"}}"
Could someone explain me what am I doing wrong?
Thank you!

You can also just use a system call like this:
name = "something"
url = "http://www.example.com"
result = `curl -F 'name=#{name}' #{url}`
result will hold the output of your system call. For more sophisticated http requests, you probably want to take a look at faraday (https://github.com/lostisland/faraday)

Related

Parse curl information in Rails application

This is my first time using curl in my Rails 4 App. I am trying to use Plaid with Stripe. I am able to successful exchange the public token for the stripe bank account token.
Stripe with Plaid ACH
Here's my controller action.
def create
results = `curl https://tartan.plaid.com/exchange_token \
-d client_id="CLIENT_ID" \
-d secret="SECRET_KEY" \
-d public_token="#{params[:public_token]}" \
-d account_id="#{params[:meta][:account_id]}"`
end
In Terminal with JSON.parse(results)
{"account_id"=>"ACCOUNT_ID", "stripe_bank_account_token"=>"12345678abcd", "sandbox"=>true, "access_token"=>"test_citi"}
How does one get the stripe_bank_account_token into the controller?
UPDATE
I am using the Figaro Gem to hide the params/credentials..
results =
`curl https://tartan.plaid.com/exchange_token \
-d client_id="#{ ENV['PLAID_CLIENT_ID'] }" \
-d secret="#{ ENV['PLAID_SECRET_KEY'] }" \
-d public_token="#{params[:public_token]}" \
-d account_id="#{params[:meta][:account_id]}"`
# here's how I get the stripe_bank_account_token
break_down = JSON.parse(results)
x = break_down.select { |key, val| key == "stripe_bank_account_token" }
You shouldn't pipe to curl from Ruby code especially when it involves user input.
Rather you should use the built in Ruby HTTP Client, a gem like RestClient, or even better the Plaid Ruby Gem.
gem install plaid
then just
require 'Plaid'
Plaid.config do |p|
p.client_id = '<<< Plaid provided client ID >>>'
p.secret = '<<< Plaid provided secret key >>>'
p.env = :tartan # or :api for production
end
user = Plaid::User.exchange_token(params[:public_token], params[:meta][:account_id], product: :auth)
user.stripe_bank_account_token
Just create new method for plaid, smth like below.
Also, Good to use HTTP client or REST client
HTTP client
REST client
def create
res = plain_curl(params)
puts res.inspect #there you will see your respond json obj in rails console.
end
private
def plain_curl(params)
#it should return you json object, if not just add return before result.
results = `curl https://tartan.plaid.com/exchange_token \
-d client_id="CLIENT_ID" \
-d secret="SECRET_KEY" \
-d public_token="#{params[:public_token]}" \
-d account_id="#{params[:meta][:account_id]}"`
end

Erlang hackney : send a mail in mailgun.com using attachement

I'm trying to send an email via mailgun.com using the hackney and I have some issues sending attachments (which requires multipart).
https://documentation.mailgun.com/api-sending.html#sending
Basically my interest fields are:
from
to
subject
text
attachment File attachment. You can post multiple attachment values. Important: You must use multipart/form-data encoding when sending attachments.
I tried the following:
PayloadBase =[
{<<"from">>, From},
{<<"to">>, To},
{<<"subject">>, Subject},
{<<"text">>, TextBody},
{<<"html">>, HtmlBody}
],
Payload = case Attachment of
null ->
{form, PayloadBase};
_->
{multipart, PayloadBase ++ [{file, Attachment}]}
end,
But for some reason the attachment is not sent.. Everything else works as expected.
I don't see how I can set the filed name to "attachment" as required by mailgun .. at this this is what I suspect beeing wrong
I haven't used mailgun but I believe that you would need to put attachment as the field name. See examples at the bottom of the page you posted:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
-F from='Excited User <YOU#YOUR_DOMAIN_NAME>' \
-F to='foo#example.com' \
-F cc='bar#example.com' \
-F bcc='baz#example.com' \
-F subject='Hello' \
-F text='Testing some Mailgun awesomness!' \
--form-string html='<html>HTML version of the body</html>' \
-F attachment=#files/cartman.jpg \
-F attachment=#files/cartman.png
It will be easier if you make it working with curl first, then you can debug what headers curl sends to the server. And then you can mimic that in Erlang.
This post explains what multipart/form-data is and points to the W3 document that provides examples how the data should be encoded.
The following code will fix the problem:
Payload2 = case Attachment of
null ->
{form, PayloadBase};
_->
FName = hackney_bstr:to_binary(filename:basename(Attachment)),
MyName = <<"attachment">>,
Disposition = {<<"form-data">>, [{<<"name">>, <<"\"", MyName/binary, "\"">>}, {<<"filename">>, <<"\"", FName/binary, "\"">>}]},
ExtraHeaders = [],
{multipart, PayloadBase ++ [{file, Attachment, Disposition, ExtraHeaders}]}
end,
Silviu

Cron-like application of groovy script with console plugin environment?

We have an application that we would like to run a script on just like we do in the console window with access to the applications libraries and context, but we need to run it periodically like a cron job.
While the permanent answer is obviously a Quartz job, we need to the do this before we are able to patch the application.
Is there something available that gives us the same environment as the console-plugin but can be run via command-line or without a UI?
you can run a console script like the web interface does but just with a curl like this:
curl -F 'code=
class A {
def name
}
def foo = new A(name: "bar")
println foo.name
' localhost:8080/console/execute
You'll get the response as the console would print below.
With regard to #mwaisgold 's solution above, I made a couple of quick additions that helped. I added a little bit more to the script to handle authentication, plus the -F flag for curl caused an ambiguous method overloading error with the GroovyShell's evaluate method, so I addressed that by using the -d instead:
#/bin/bash
curl -i -H "Content-type: application/x-www-form-urlencoded" -c cookies.txt -X POST localhost:8080/myapp/j_spring_security_check -d "j_username=admin&j_password=admin"
curl -i -b cookies.txt -d 'code=
int iterations = 0
while (iterations < 10) {
log.error "********** Console Cron Test ${iterations++} ***********"
}
log.error "********** Console Cron Test Complete ***********"
' localhost:8080/myapp/console/execute

How to send file contents as body entity using cURL

I am using cURL command line utility to send HTTP POST to a web service. I want to include a file's contents as the body entity of the POST. I have tried using -d </path/to/filename> as well as other variants with type info like --data </path/to/filename> --data-urlencode </path/to/filename> etc... the file is always attached. I need it as the body entity.
I believe you're looking for the #filename syntax, e.g.:
strip new lines
curl --data "#/path/to/filename" http://...
keep new lines
curl --data-binary "#/path/to/filename" http://...
curl will strip all newlines from the file. If you want to send the file with newlines intact, use --data-binary in place of --data
I know the question has been answered, but in my case I was trying to send the content of a text file to the Slack Webhook api and for some reason the above answer did not work. Anywho, this is what finally did the trick for me:
curl -X POST -H --silent --data-urlencode "payload={\"text\": \"$(cat file.txt | sed "s/\"/'/g")\"}" https://hooks.slack.com/services/XXX
In my case, # caused some sort of encoding problem, I still prefer my old way:
curl -d "$(cat /path/to/file)" https://example.com
curl https://upload.box.com/api/2.0/files/3300/content -H "Authorization: Bearer $access_token" -F file=#"C:\Crystal Reports\Crystal Reports\mysales.pdf"

Special characters like # and & in cURL POST data

How do I include special characters like # and & in the cURL POST data? I'm trying to pass a name and password like:
curl -d name=john passwd=#31&3*J https://www.mysite.com
This would cause problems as # is used for loading files and & for specifying more than one key/value. Is there some way I can escape these characters? \# and \& don't seem to work.
cURL > 7.18.0 has an option --data-urlencode which solves this problem. Using this, I can simply send a POST request as
curl -d name=john --data-urlencode passwd=#31&3*J https://www.example.com
Summarizing the comments, in case of mixed "good" and "bad" data and exclamation marks inside we can use on Windows:
curl -d "grant_type=client_credentials&client_id=super-client&acr_values=tenant:TNT123" --data-urlencode "client_secret=XxYyZ21D8E&%fhB6kq^mXQDovSZ%Q*!ipINme" https://login.example.com/connect/token
How about using the entity codes...
# = %40
& = %26
So, you would have:
curl -d 'name=john&passwd=%4031%263*J' https://www.mysite.com
Double quote (" ") the entire URL .It works.
curl "http://www.mysite.com?name=john&passwd=#31&3*J"
Just found another solutions worked for me. You can use '\' sign before your one special.
passwd=\#31\&3*J
Try this:
export CURLNAME="john:#31&3*J"
curl -d -u "${CURLNAME}" https://www.example.com
If password has the special characters in it, just round the password with the single quote it will work.
curl -u username:'this|!Pa&*12' --request POST https://www.example.com
I did this
~]$ export A=g
~]$ export B=!
~]$ export C=nger
curl http://<>USERNAME<>1:$A$B$C#<>URL<>/<>PATH<>/

Resources