Rails: Server side Google Analytics all trafic in 'Direct' source - ruby-on-rails

I tried several gems for use Server Side GA.
=> Stacato
=> Gabba
=> ...
But I have always the same problem, in google analytics the SOURCE of all my events are in "Direct" (direct traffic), even if i use utm_source, ...
I remarked, each time I trigger an event, Google analytics create a new session with source "Direct" (and a location in United states), and I think the event is attributed to this session and no to my effective session.
My config (with the gem Gem Gabba https://github.com/hybridgroup/gabba ):
View application.html.erb
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-1', 'auto');
ga('send', 'pageview');
</script>
Model User
Gabba::Gabba.new("UA-XXXXXX-1", "mysite.com").event('User', 'Signup', 'Profile completed')
I have a doubt if it's a configuration problem or if it's a recurrent problem when you use a Server Side GA?

Thx #eike & #RaV, you help me to find a solution.
I removed the gabba gem and added staccato gem instead.
The problem was the same (staccato generated a new client_id by default, that's why I had a duplicate), but I figured out how to fix it.
1.Just save the client_id from in the google analytics cookie in your application controller:
before_action :tacking_ga
def client_id
cookies["_ga"].split(".").last(2).join(".")
end
private
def tacking_ga
#tracker = Staccato.tracker('UA-XXXXXXXXX-1', client_id, ssl: true) if Rails.env == "production"
end
2.After that in my controller (example user_controller) I just had to add my event at the right place:
#tracker.event(category: 'User', action: 'Signup', label: "Profile completed", value: nil)
Thx for your help

Related

Getting authorization from iNaturalist for API

I'm trying to use iNaturalist's API via Ruby on Rails. I'm new to Ruby and iNaturalist's documentation is pretty sparse. As a first step, I need to figure out how to get authorization from their site.
iNaturalist provides the sample code below. I set up a project with iNaturalist and tried running the sample code in Rails Console with my credentials. #{url} in the following line is replaced with a url that the user is supposed to go to in order to log in to iNat:
puts "Go to #{url}, approve the app, and you should be redirected to your " +
"redirect_uri. Copy and paste the 'code' param here."
I went to the resulting url and logged in:
https://www.inaturalist.org/oauth/authorize?client_id=[my client id]&redirect_uri=https://ruby_on_rails--timrobinson41199691.codeanyapp.com/login/&response_type=code
iNaturalist responds with "The redirect uri included is not valid."
If I leave off &response_type=code, it responds with "The authorization server does not support this response type."
My website is on codeanywhere.com. The url of the main page is "https://ruby_on_rails--timrobinson41199691.codeanyapp.com/". Part of the problem is that I don't understand what kind of page I'm supposed to create for redirect_uri, since I'm still kind of new at this.
require 'rubygems'
require 'rest_client'
require 'json'
site = "https://www.inaturalist.org"
app_id = 'YOUR APP ID'
app_secret = 'YOUR APP SECRET'
redirect_uri = 'YOUR APP REDIRECT URI' # you can set this to some URL you control for testing
# REQUEST AN AUTHORIZATION CODE
# Your web app should redirect the user to this url. They should see a screen
# offering them the choice to authorize your app. If they aggree, they will be
# redirected to your redirect_uri with a "code" parameter
url = "#{site}/oauth/authorize?client_id=#{app_id}&redirect_uri=#{redirect_uri}&response_type=code"
# REQUEST AN AUTH TOKEN
# Once your app has that code parameter, you can exchange it for an access token:
puts "Go to #{url}, approve the app, and you should be redirected to your " +
"redirect_uri. Copy and paste the 'code' param here."
print "Code: "
auth_code = gets.strip
puts
payload = {
:client_id => app_id,
:client_secret => app_secret,
:code => auth_code,
:redirect_uri => redirect_uri,
:grant_type => "authorization_code"
}
puts "POST #{site}/oauth/token, payload: #{payload.inspect}"
puts response = RestClient.post("#{site}/oauth/token", payload)
puts
# response will be a chunk of JSON looking like
# {
# "access_token":"xxx",
# "token_type":"bearer",
# "expires_in":null,
# "refresh_token":null,
# "scope":"write"
# }
# Store the token (access_token) in your web app. You can now use it to make authorized
# requests on behalf of the user, like retrieving profile data:
token = JSON.parse(response)["access_token"]
headers = {"Authorization" => "Bearer #{token}"}
puts "GET /users/edit.json, headers: #{headers.inspect}"
puts RestClient.get("#{site}/users/edit.json", headers)
puts
After the user logs in to iNat, he should be redirected back to my website with the authorization code provided in the data. In routes.rb, my login route is set as:
post '/login', to: 'organisms#login'
I've tried using get, as well.
iNat is returned the error mentioned above and not redirecting back to my site.
OAuth can be a bit daunting at first. And that guide really just shows the equivalent of using cURL to test your API.
In an actual application redirect_uri is whatever endpoint in your application that handles the response when the provider redirects back from authorization.
So lets setup a minimal real rails app.
1. Register your app
Register a new application or edit your existing app.
Use http://localhost:3000/oauth/inaturalist/callback for the callback url (adjust the host as needed).
Keep the window open as you will need the client_id and secret in a moment.
2. Setup your routes
# /config/routes.rb
Rails.application.routes.draw do
# just make sure you have a root path defined.
root to: 'pages#home'
namespace :oauth do
namespace :inaturalist, controller: :callbacks do
# This is just a simple redirect route
get '/', action: :passthru, as: :authorize
# This is the route that handles the actual callback
get 'callback'
end
end
end
You can actually do this without the redirect route and just plant a link to the https://www.inaturalist.org/oauth/authorize... url in your view. But having it isolates your application against the craziness that is OAuth and its how OmniAuth does it.
3. Add your credentials to the Rails app.
In Rails 5 use the encrypted credentials to store your client_id and secret.
Run $ bin/rails credentials:edit from your shell.
inaturalist:
client_id: <from the inaturalist site>
secret: <from the inaturalist site>
In earlier versions use ENV vars instead.
4. Install the oauth2 gem
# Place this in your gemfile outside any groups
gem 'oauth2', '~> 1.4', '>= 1.4.1'
Then run bundle install.
4. Setup the controller
# app/controllers/oauth/inaturalist/callbacks_controller.rb
require 'oauth2'
module Oauth
module Inaturalist
class CallbacksController < ::ActionController::Base
# GET /oauth/inaturalist
def passthru
redirect_to client.auth_code.authorize_url
end
# This endpoint is where the provider redirects the user back to
# after authorization.
# GET /oauth/inaturalist/callback
def callback
# Fetch an auth token from the access code
token = client.auth_code.get_token(params[:code])
# Perform an authenticated request to get the users data
api_response = token.get("/users/edit.json")
#user_data = JSON.parse(api_response.body)
# This is just an example of how you can use the user data from
# the provider
#user = {
uid: #user_data["id"],
nickname: #user_data["nickname"]
}
session[:user_id] = #user[:uid]
session[:token] = token.to_hash
redirect_to root_path, success: "Hello #{#user[:nickname]}"
end
private
# Change this if you are not using Rails 5 credentials.
def client
OAuth2::Client.new(
credentials.fetch(:client_id),
credentials.fetch(:secret),
site: "https://www.inaturalist.org",
redirect_uri: oauth_inaturalist_callback_url
)
end
def credentials
Rails.application.credentials.fetch(:inaturalist)
end
end
end
end
token here is actually a new OAuth2::AccessToken instance that can be called to call endpoints with the fetched credentials.
This example stores the token in the session. You can retrieve it in subsequent requests with:
token = OAuth2::AccessToken.from_hash( session[:token] )
The docs kind of mention trading the oauth access token for an api token for api.inaturalist.org. But the details are kind of sparse.
5 Add a link to sign in:
<%= link_to 'Sign in to iNaturalist.org', oauth_inaturalist_authorize_path %>

Tracking with google analytics sign up page in Rails with Devise

I am trying to track each page of my Rails application, rendering this partial on the layout:
var analyticsId = '<%= Settings.env.app.analytics_id %>';
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r; i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];
a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', '<%= Settings.env.app.analytics_id %>', 'auto', 'trackEvent: true');
ga('send', 'pageview');
After adding the Google Analytics ID to the settings, I can see in my Google Analytics dashboard the visits to my users#sign_in page but not the visits to my users#sign_up page.
Inspecting both pages through the firebug console I see the spected result in the html code:
var analyticsId = 'UA-XXXXXXXX-X';
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;
i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g
m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-X', 'auto', 'trackEvent: true');
ga('send', 'pageview');
With 'UA-XXXXXXXX-X' = Settings.env.app.analytics_id which is defined in config/settings/app.yml under analytics_id.
We use devise to handle the signin/signup proccess and this is the part related to devise in the routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: {
confirmations: 'users/confirmations',
registrations: 'users/registrations'
}
ActiveAdmin.routes(self)
authenticated :user do
devise_scope :user do
root to: redirect("/home")
end
end
unauthenticated do
devise_scope :user do
root to: redirect("users/sign_in"), as: "unauthenticated_index"
get '/pages/:page', to: 'pages#show', as: "pages_show"
end
end
It seems that the problem was related to the fact that:
Rails 4.0 introduced a feature named Turbolinks to increase the
perceived speed of a website.
Google Analytics doesn’t work for a Rails 4.0 or newer web
applications. To be more precise, it won’t work for all pages. It can
be made to work with a workaround to accommodate Turbolinks.
Making the long story short I have applied a workaround based on the answer in this post:
Google analytics with rails 4

OmniAuth OAuth 1 strategy for upwork API error

I'm using OmniAuth gem along with the specific provider gems for FB, Linkedin and G+, both for login, registration and information retrieval. I want to offer further integration with other API's in this case with Upwork's api, that uses OAuth 1.
I've set the App with Upwork and have working key and secret. I've set the loader to load my custom strategy (since it's not a gem) and it loads. I've set the provider to pass the key and secret which are stored in an env file.
All of that seems to be working now, after many hours into it.
I tried reading through the sparse information contained in OmniAuth's strategy guide, along with OAuth wiki, and looked into the gem files of other providers. I ended up copying a bit of the code I thought would be enough to work through this, at least, for login but I'm messing something up.
Whenever I go to the callback path for upwork, set automatically by omniauth I get an error.
Started GET "/auth/upwork" for ::1 at 2015-07-29 00:08:12 +0800
ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations".* FROM "schema_migrations"
I, [2015-07-29T00:08:12.169605 #24517] INFO -- omniauth: (upwork) Request phase initiated.
OAuth::Unauthorized (405 Method Not Allowed):
lib/omniauth/strategies/upwork.rb:18:in `request_phase'
Rendered /Users/mnussbaumer/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.1/lib/action_dispatch/middleware/templates/rescues/_source.erb (5.1ms)
By the documentation this seems to be when I either try a GET to a POST only, or a POST to a GET only endpoint.
In Upwork's API reference they explicitly say that:
Get request token
Endpoint
POST /api/auth/v1/oauth/token/request
My strategy is currently as this:
require 'json'
require 'omniauth-oauth'
module OmniAuth
module Strategies
class Upwork < OmniAuth::Strategies::OAuth
option :client_options, {
:site => "https://www.upwork.com/api",
:request_token_path => "/api/auth/v1/oauth/token/request",
:authorize_url => "/services/api/auth",
:access_token_path => "api/auth/v1/oauth/token/access",
}
uid { request.params['user_id'] }
def request_phase
request_token = consumer.get_request_token(:oauth_callback => callback_url)
session['oauth'] ||= {}
session['oauth'][name.to_s] = {'callback_confirmed' => request_token.callback_confirmed?, 'request_token' => request_token.token, 'request_secret' => request_token.secret}
if request_token.callback_confirmed?
redirect request_token.authorize_url(options[:authorize_params].merge(:oauth_consumer_key => consumer.key))
else
redirect request_token.authorize_url(options[:authorize_params].merge(:oauth_callback => callback_url, :oauth_consumer_key => consumer.key))
end
rescue ::Timeout::Error => e
fail!(:timeout, e)
rescue ::Net::HTTPFatalError, ::OpenSSL::SSL::SSLError => e
fail!(:service_unavailable, e)
end
def raw_info
#raw_info ||= JSON.load(access_token.get('/me.json')).body
end
end
end
end
I tried changing "consumer.get_request_token" to "consumer.post_request_token" but I think that has nothing to do with it.
The request_phase was ripped off of a gem I found and the JSON.load from a different one. I thought it would work with only these 2 but it seems not. I'm learning slowly how to use all this and would like to build first a usable strategy and then provide it as a public gem for omniauth.
UpWork has an API documentation, and they even have a gem for ruby, but I would like to use OmniAuth for everything, plus, I'll need to figure out other API's in the future so I would like to know how to do this well.
https://developers.upwork.com/?lang=ruby#authentication_oauth-10
Anybody can help with this? Or with creating an OmniAuth gem for Upwork.
Thanks!
(edited to change the error - now it's much thinner output but it's the same error)
The request_phase method is actually a method that belongs to omniauth-oauth which you required on top of the upwork.rb and your class Upwork inherits it (OmniAuth::Strategies::OAuth). you don't have to override it.

Omniauth facebook - fetch friends

I am trying to configure omniauth-facebook to fetch user friends.
This is my configuration:
ActionController::Dispatcher.middleware.use OmniAuth::Builder do
provider :facebook, "xxxxxx", "xxxxxxxx",
:info_fields => 'friends'
end
I am using Rails 2.3.
I am using this code in view:
<div id="contacts">
</div>
<script type="text/javascript" charset="utf-8">
$('contacts').innerHTML = '<%= request.env['omniauth.auth'].keys %>';
</script>
I am not sure why the script is not being executed, but when I copy:
$('contacts').innerHTML = 'infouidcredentialsextraprovider';
in console after page has loaded it works replacing content of div with that text.
There is no error message in browser console.
Why script does not get executed? I tried with console.log too, and I had no luck.
The info_fields option is still new and so you will have to wait for a new release of the omniauth-facebook gem.
In the meantime, you can try using the master branch by changing your Gemfile to:
gem 'omniauth-facebook', :github => 'mkdynamic/omniauth-facebook'
As for debugging, you can get the information returned from facebook by adding the following as the first line of your callback controller:
raise request.env["omniauth.auth"].to_yaml
Now try to login and you'll be able to take a good look at the hash of nested hashes returned.

cannot make API call on paymill - 302 found as a response - rails

I used the examples on the paymill page to get the token with no problem. I'm passing the token using an ajax call. But I cannot make the API to make the final call. I cannot really understand how to use the code from the paymill-ruby or paymill-rails code at github, so I went trough the code and found the API call -which is what I'm missing-, but cannot make it work. All I want to do is a simple payment. No subscription, no user. Just a credit card payment. Here is the code from my controller:
token = params[:token]
params = {'amount' => '#{##amount}', 'currency' => 'EUR', 'token' => '#{token}', 'description' => 'description'}
https = Net::HTTP.new('api.paymill.de', 80)
https.use_ssl = false
https.start do |connection|
url = "/v2/transactions"
https_request = Net::HTTP::Post.new(url)
https_request.basic_auth(Paymill.api_key,"")
https_request.set_form_data(params)
#response = https.request(https_request)
end
puts #response.body
puts #response.header
render :action => "confirm"
The response is
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
#<Net::HTTPFound:0x00000004a98400>
And I cannot figure out what's wrong... a few weeks ago I didn't know what ajax was... can anybody give a hand?
I'm not a rails expert but ...
... you are connecting to our API at port 80 without using SSL. We only allow SSL requests to the api so you'll have to connect using port 443 and having SSL enabled.
Hope that solves your issues.

Resources