How to handle API callback response in Rails 3 app - ruby-on-rails-3

In a rails 3 app, I'm using a third party API to save webcam videos. When a video is saved to their server, they give an option to send you a callback to a url you specify. From their site:
Callback
Callbacks are for advanced users who wish to be notified when a video is finished processing on the Framey servers. If you choose to receive callbacks in your account settings Framey will POST video and thumbnail URLs to your server once conversion is complete.
Here's an example of the data that we post to your server:
"video": {
"name": "ecf7c330-549c-012e-9d34-7c6d628c53d4",
"filesize": 123456,
"duration": 15.62,
"state": "uploaded",
"views": 0,
"data": {
"my_user_id": 1,
"video_title": "Contest Submission"
},
"flv_url": "http://framey.com/videos/source/ecf7c330-549c-012e-9d34-7c6d628c53d4.flv",
"mp4_url": "http://framey.com/videos/source/ecf7c330-549c-012e-9d34-7c6d628c53d4.mp4",
"large_thumbnail_url": "http://framey.com/thumbnails/large/ecf7c330-549c-012e-9d34-7c6d628c53d4.jpg",
"medium_thumbnail_url": "http://framey.com/thumbnails/medium/ecf7c330-549c-012e-9d34-7c6d628c53d4.jpg",
"small_thumbnail_url": "http://framey.com/thumbnails/small/ecf7c330-549c-012e-9d34-7c6d628c53d4.jpg"
}
I'm working my way to understanding how to handle this, but I thought I could get proper direction from you good folks. They specify a POST method, so I have to set up a route. In my config/routes.rb file I have
post "framey/callback/"
In my app/controllers/framey_controller.rb file there is this:
class FrameyController < ApplicationController
def callback
end
end
Do I need to do something like
render :json =>????
I'm familiar with using POST via HTML forms and/or ajax. I'm not sure how to grab the JSON they send back to me.
Thanks in advance for the help and please let me know if you need more details.

In app/controllers/framey_controller.rb
class FrameyController < ApplicationController
def callback
v = Video.new
v.name = params[:video][:name]
v.user_id = params[:video][:data][:user_id]
v.question_id = params[:video][:data][:question_id]
v.save
end
end

Related

Interact with password protected Jupyter /api

A friend is trying to run a script to check which notebooks are using the most memory, but their server is password protected. I'm trying to figure out how to configure authentication using urllib2 since I don't believe there is a username, only a password.
The #aiguofer answer did not work for me because jupyter now uses '_xsrf' in cookie. The follwoing woked for me:
s = requests.Session()
url='http://127.0.0.1:8888/login/'
resp=s.get(url)
xsrf_cookie = resp.cookies['_xsrf']
params={'_xsrf':xsrf_cookie,'password': password}
s.post(url, data=params)
After that s can be used to call the apis.
After digging into the notebook code and through some trial and error, I figured out how to do this (and I switched to using requests).
I can't guarantee that this is the best way to do it, but it certainly worked for me. I actually set my vars elsewhere in the code but included here for completeness
import requests
hostname = '127.0.0.1'
port = '8888'
password = 'mypassword'
base_url = 'http://{0}:{1}/'.format(hostname, port)
h = {}
if password:
r = requests.post(base_url + 'login', params={
'password': password
})
h = r.request.headers
sessions = requests.get(base_url + 'api/sessions', headers=h).json()
I believe this works because when you hit the /login endpoint, it redirects you with the right headers set. I guess requests keeps the headers of the redirect, so we can reuse those for the other call. It might be better to extract only the cookies and use those, but this works for now :)
It seems there are some changes with new version. url '/login' does not work for me, I need to add next parameters
url='http://localhost:8050/login?next=%2F'
For the login request. The rest just like Hassan answer
i found when use jupyter put api upload file response 403,
need add "X-XSRFToken" header can solve it..
data= json.dumps({
"name": "test.jpg",
"path": "path",
"type":"file",
"format": "base64",
"content": "base64 data"
})
headers["X-XSRFToken"] = xsrf_cookie
s.put(url, data=data, headers=headers)

How to send pushes with "conditions" to pushwoosh with remote API?

I use the pushwoosh remote API and I can send pushes to all users and to just one device, good!
But now Im trying to be able to send pushes to different groups and Im trying to get "conditions" to work. But Im missing something and I don´t know what!
I have first created a tag called "Grupper" as a listtag at pushwoosh.
And it is registering the value "5A" at pushwoosh from the app.
And this is how I try to send a push from my server.
var tags="5A"
var data = {
"request": {
"application": applicationId,
"auth": authKey,
"notifications": [{
"send_date": "now",
"ignore_user_timezone": true,
"content": {
"en": pushtext
},
"conditions":["Grupper", "EQ", tags]
}]
}
};
And here its the "conditions" that is wrong somehow?
If I remove the row with "conditions" then it sends a push to all users, but if I use it, it sends nothing. No errors.
Any input really appreciated, after a couple of days trying, I still don´t know what Im missing :-)
A condition is always an array of arrays, therefore try this:
"conditions":[["Grupper", "EQ", tags]]
Also, since "Grupper" is a List-type tag, you can only use IN operator with it (see the docs here)

iOS app - Rails 4 and Devise as backend

I would like to know how to use rails as backend for my iOS app.
All I need is a User with email and password to authenticate using devise.
I already have a User created with devise and rails 4.
I did find this post http://jessewolgamott.com/blog/2012/01/19/the-one-with-a-json-api-login-using-devise/ explaining what I need, but some things are still missing.
When I try to do a POST via my iOS app, I get the message "Can't verify CSRF token authenticity". How do I solve that without skipping the filter verify_authenticity_token ?
How would the request code for the iOS look like? Right now I'm doing a POST to http://localhost:3000/api/users/sign_in.json and setting the HTTPBody = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:&jsonError], but the rails server is receiving only a string as key with the entire json dictionary, not an actual json dictionary.
params = {"{\"user\":{\"email\":\"qwe\",\"password\":\"123\"}}"=>nil, "action"=>"create", "controller"=>"api/sessions", "format"=>"json"}
How would I do an https request instead of http, so I can hide the password and email fields in case someone else tries to watch my internet traffic?
Thank you very much.
To use Rails Applications Mobile and Android and IOS, necessarily you have to use JSONP: example:
JS sample:
$.ajax({
url: '/api_mobile',
jsonp: "callback",
dataType: "jsonp",
cache: true,
data: {method: 'login', other_data ...},
success: function(res) {
// response object
console.log(res)
},
error: function(request, status, error) {
alert("Error server: " + request.status);
}
});
RAILS 4:
protect_from_forgery with: :exception, only: :api_mobile
# route /api_mobile
def api_mobile
json = {error: 'Not found Method'}
case params[:method]
when: 'login'
if User.login(params[:username], params[:password])
json = {notice: 'Login success'}
else
json = {error: 'Error Username or Password'}
end
end
render json: json, :callback => params[:callback]
end
All functions must be personalized and parameterized

tastypie post authentication issues

I'm having trouble with tastypie and posting data to it. I only am able to retrieve a 401 error code.
For clarification, I am able to successfully retrieve data from the tastypie api.
Attached are the code snippets, and maybe someone can help me out get behind this.
Before I get started, a little background: I am using a custom authorization class.
class CustomAuthorization(Authorization):
def is_authorized(self, request, object=None):
if request.user.username == 'custom_user':
return True
return False
Here is the actual resource:
class CustomObjectResource(ModelResource):
class Meta:
queryset = CustomObject.objects.all()
authentication = ApiKeyAuthentication()
authorization = CustomAuthorization()
list_allowed_methods = ['get', 'post', ]
detail_allowed_methods = ['get', 'post', 'put']
include_resource_uri = False
resource_name = 'customobject'
always_return_data = True
def obj_create(self, bundle, request=None, **kwargs):
try:
print "request"
except:
raise BadRequest('I couldnt save your information.')
return True
I know the obj_create method is bogus, but it should still be called and do something, or is this already the issue?
The following curl command is used to post the data to the tastypie API.
curl --dump-header - -H "Content-Type: application/json" -X POST --data '{"body": "This will prbbly be my lst post.", "pub_date": "2011-05-22T00:46:38", "slug": "another-post", "title": "Another Post"}' http://local.com:8000/api/v1/customobject/?format=json&username=custom_user&api_key=123456789012345
The api_key is correct, but bogus in this case!
As previously mentioned, the get method works but the post just wont work.
Anyone have an idea on how to solve this or have a workaround?
I would try a couple of things to debug this issue.
1) Try adding: allowed_methods = ['get', 'post', 'put']
2) Add print statements in the custom_authorization to check if that is causing the problems due to the request.user.username being different.
3) Do (2) in the source of APIKeyAuthentication too.
This should be sufficient for you to debug the issue.
Remember to remove the print statements once youre done!
Best of luck.
This is COULD be due to a known issue. On the background tastypie at the moment converts the POST to PUT and as Nikunj pointed since in list_allowed_methods you don't have PUT the POST gets blocked too... Not sure there though cause you should get method not allowed in that case. I would suggest debug in the method "is_authorized" and check what is happening there.

Posting to Facebook OG with HTTParty only works from the rails console?

I'm having a really weird problem with my rails app and facebook's open graph beta. Whenever I post an action to an object, Facebook returns an error that seems to indicate the URL of the object can't be reached, or the og scraper isn't scraping the URL correctly.
However, when I take the URL the app is generating for the post to Facebook and manually use the HTTParty gem to post it, it works.
Here's my code:
class Post < ActiveRecord::Base
FB_CONFIG = YAML.load_file("#{Rails.root}/config/initializers/facebook.yml")[Rails.env]
def self.to_facebook_og(obj, obj_id, verb, auth, extra)
#requires that a user has granted `publish_actions`
found_obj = obj.classify.constantize.find(obj_id) #find the actual object we're talking about
post_url = self.construct_facebook_action_url(obj, found_obj, verb, auth, extra) #create the URL
begin
ret = HTTParty.post(post_url)
logger.info "Facebook Post Action Response = #{ret}"
rescue HTTParty::ResponseError => e #handle any errors
logger.error {"FACEBOOK Response #{ret.code} / #{e.inspect}"}
flash.alert {"There was a Facebook problem. Please try again."}
return
end
end
def self.construct_facebook_action_url(obj, found_obj, verb, auth, extra)
base = 'https://graph.facebook.com/'
uid = auth.uid
namespace = FB_CONFIG['namespace']
token = "?access_token=#{auth.token}"
og_url = "#{obj}=http://theshortestfiction.com/#{obj.pluralize}/#{found_obj.id}"
fb_url = base + uid + '/' + namespace + ':' + verb + token + '&' + og_url + extra
logger.info fb_url
fb_url
end
def self.lint_og_object(obj_url)
lint_ret = HTTParty.post("https://developers.facebook.com/tools/lint/?url=#{obj_url}&format=json")
logger.info "Facebook Linter Response = #{lint_ret}"
end
end
When an object is read via its controller's show method, the app calls Post.to_facebook. From my logs, I can see that that Post.construct_facebook_action_url is constructing the proper url (because like I said, I can pull the URL from the logs and manually post it from the console). So, I'm assuming there's so problem with how I'm passing the URL to HTTParty? Facebook seems able to tell what object URL it should be looking at. Why does the code I've written not work, but manually in the console, it does?
Even weirder -- once there's been a sucessful post action on the object once, the code seems to work consistently. Facebook insists the problem is that the objects' URLs aren't reachable, but I can't understand how they're not, since I can browse to them.
I think this is actually a timeout issue.
I had the exact same issue as you, using HTTParty and getting the URL can't be reached error.
I moved the code to a background process using Resque and it fixed the problem.