How to integrate SoundCloud in Ruby on Rails? - ruby-on-rails

I am new to RubyOnRails and SoundCloud.
I want to integrate SoundCloud API in my ruby on rails application.
For this I have registered on SoundCloud And I got the ClientID and ClientSecret. Also I have downloaded the SDK.
Now I have copied the files and folders from lib and spec directory to my applications lib and spec directory. Also I have added gem 'soundcloud' in the Gemfile.
After this I made simple code (copied from doc) in My Interactor:
# register a client with YOUR_CLIENT_ID as client_id_
client = SoundCloud.new(:client_id => YOUR_CLIENT_ID)
# get 10 hottest tracks
tracks = client.get('/tracks', :limit => 10, :order => 'hotness')
# print each link
tracks.each do |track|
puts track.permalink_url
end
But here I'm getting the error -
uninitialized constant MyApp::Interactors::MyInteractor::MyAction::SoundCloud
I followed the steps from APIDoc. Is there any step by step example for integrating SoundCloud in Ruby on Rails so that I can follow?
How can I resolve this error?
MyInteracor.rb
module MyApp
module Interactors
module MyInteractor
class MyAction < Struct.new(:user, :params)
def run
# SoundCloud
# register a client with YOUR_CLIENT_ID as client_id_
client = SoundCloud.new(:client_id => 'my-client-id')
# get 10 hottest tracks
tracks = client.get('/tracks', :limit => 10, :order => 'hotness')
# print each link
tracks.each do |track|
puts track.permalink_url
end
end
end
end
end
end

There's a typo in the soundcloud github page change the line:
client = SoundCloud.new(:client_id => 'my-client-id')
to
client = Soundcloud.new(:client_id => 'my-client-id')
[notice the lowercase c in Soundcloud]

Also you are going to need your client secret for SoundCloud's API to verify you.
Perhaps put client method and in it have client = SoundCloud.new(your-client-id,your-secret-key-your-redirect-uri) in a controller or helper with your client_id, client_secret, and redirect uri values protected in a .env file.
I think by leaving out your redirect_uri and client secret you might be getting this error in MyInteractor.rb
Hope this helps

Related

Undefined method `escape' for URI:Module

I'm a noob studying Ruby on Rails. I am trying to integrate my ruby on rails app to Quickbooks. I'm following the steps of this video. And I am stuck when I try to authenticate by pressing the "Connect to QuickBooks" button.
I get this error;
I did a little research and found out that this error was about the URI.escape() command. I think they removed it in Ruby 3. How can I resolve this issue? I can't even figure out where this URI.escape() command is located.
This is from vendors_controller.rb
def authenticate
callback = oauth_callback_vendors_url
token = $qb_oauth_consumer.get_request_token(:oauth_callback => callback)
session[:qb_request_token] = token
# If Rails >= 4.1 you need to do this => session[:qb_request_token] = Marshal.dump(token)
redirect_to("https://appcenter.intuit.com/Connect/Begin?oauth_token=#{token.token}") and return
end
def oauth_callback
at = session[:qb_request_token].get_access_token(:oauth_verifier => params[:oauth_verifier])
# If Rails >= 4.1 you need to do this => at = Marshal.load(session[:qb_request_token]).get_access_token(:oauth_verifier => params[:oauth_verifier])
session[:token] = at.token
session[:secret] = at.secret
session[:realm_id] = params['realmId']
redirect_to root_url, notice: "Your QuickBooks account has been successfully linked."
end
My initializer quickbooks.rb
QB_KEY = "I PASTED MY CLIENT ID KEY HERE"
QB_SECRET = "I PASTED MY CLIENT SECRET HERE"
$qb_oauth_consumer = OAuth::Consumer.new(QB_KEY, QB_SECRET, {
:site => "https://oauth.intuit.com",
:request_token_path => "/oauth/v1/get_request_token",
:authorize_url => "https://appcenter.intuit.com/Connect/Begin",
:access_token_path => "/oauth/v1/get_access_token"
})
My rails version Rails 6.1.4
My ruby version ruby 3.0.1p64
Thank you for your time.
I know many people say that URI.escape wasn't good, but it was good enough for me when all I wanted from it is to escape urls with non-English characters.
So I just monkey patched it
Add the following under /config/initializers/functions_overrides.rb
(the file name can be anything you want)
require 'uri'
module URI
class << self
def escape(str)
alpha = "a-zA-Z"
alnum = "#{alpha}\\d"
unreserved = "\\-_.!~*'()#{alnum}"
reserved = ";/?:#&=+$,\\[\\]"
unsafe = Regexp.new("[^#{unreserved}#{reserved}]")
str.gsub(unsafe) do
us = $&
tmp = ''
us.each_byte do |uc|
tmp << sprintf('%%%02X', uc)
end
tmp
end.force_encoding(Encoding::US_ASCII)
end
end
end
Use the https://developer.intuit.com/app/developer/qbo/docs/develop/sdks-and-samples-collections/ruby
OAuth Ruby Client
Intuit offers an OAuth 2.0 Client which provides a set of methods that make it easier to work with Intuit’s OAuth and OpenID implementation.
Community Supported Ruby SDK
The Community Supported Ruby SDK makes it easy to integrate your web app with the QuickBooks Online API. This guide assumes that you have an existing web app that you want to integrate with QuickBooks Online.
URI#escape was deprecated and later removed - https://github.com/ruby/uri/commit/61c6a47ebf1f2726b60a2bbd70964d64e14b1f98
From the commit :
# This method is obsolete and should not be used. Instead, use
# CGI.escape, URI.encode_www_form or URI.encode_www_form_component
# depending on your specific use case.
Ruby 3.0.0 onwards URI#escape does not work.
Use CGI.escape or URI.encode_www_form as mentioned in the deprecation warning

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 %>

Unsupported get request - Facebook Marketing API won't authenticate for me

I'm setting up an API integration in my rails application with the Facebook Ads/Marketing API. I'm attempting to test very basic options with my Sandbox Ad Account and cannot seem to get them to work. This is error I keep getting:
FacebookAds::ClientError: Unsupported post request.
Object with ID '119033245616727' does not exist, cannot be loaded due
to missing permissions, or does not support this operation.
Please read the Graph API documentation at
https://developers.facebook.com/docs/graph-api: (fbtrace_id: GyiFjx24NY/)
from /Users/kelly/.rvm/gems/ruby-2.3.0/gems/facebookads-0.2.11.0/lib/facebook_ads/api_request.rb:67:in `create_response'
To run the test, I used their Marketing API quickstart to get my access token, app secret and ad account id.
This is my rails config:
Gemfile:
gem 'facebookads' #https://github.com/facebook/facebook-ruby-ads-sdk
My Test Module:
module Advertising
module Facebook
class API
attr_accessor :access_token
attr_accessor :app_secret
attr_accessor :ad_account_id
def initialize
#access_token = 'EAAYVZBezhACwBAKwMk7fhAJO2WFlUeUaCcASveD9gb6ZCKBzEAJIzDToagt4Vy5n6Ue9QpOwyb0SWYCSHHf4A2jbdTOb99GTBjhSOu5WnU03mnKymd2YgmquOJHg4lPx3iZBonYTzriU27OnlBXDMXdIZApwt45SSqQ8SLs5xaMM3lVEsm0r6WXSoos5yiOiqfMB83SfnntzUzqkEywQ'
#app_secret = '15326d2073b04504ef72267bf36a8bd4'
#ad_account_id = '119033245616727'
end
def test1
FacebookAds.configure do |config|
config.access_token = #access_token
config.app_secret = #app_secret
end
ad_account = FacebookAds::AdAccount.get(ad_account_id)
ad_account.campaigns.create(
objective: 'LINK_CLICKS',
status: 'PAUSED',
buying_type: 'AUCTION',
name: 'My Campaign'
)
end
def test2
# With session
session = FacebookAds::Session.new(access_token: #access_token, app_secret: #app_secret)
ad_account = FacebookAds::AdAccount.get(ad_account_id, session)
puts "This is my account name: #{ad_account.name}"
end
end
end
end
Then I'm running this in the rails console:
ad = Advertising::Facebook::API.new()
ad.test1
# OR
ad.test2
This is a newly created facebook app. These are the settings:
Status: In Development
App ID: 1713013025472556
App Secret: 15326d2073b04504ef72267bf36a8bd4
I added the Marketing API to the products section and created a Sandbox Ad Account called T2 Sandbox (119033245616727).
When setting your ad_account_id, add 'act_' in front of the ID. As the SDK will not do this for you.

"Missing authorization code" error when trying to use Google Calendar API

The following is the code I am using to allow users to allow users to authorise my app to access their Google Calendar via OAuth. I based it off this sample code.
It works most of the time, but sometimes, there is an ArgumentError: Missing authorization code error on the client.authorization.fetch_access_token! line in the create_google_calendar action in the services controller. If I comment out that line, all of the client.authorization attributes are null.
I am using Rails 3.2.0 and Ruby 1.9.2.
What is causing this?
Gemfile
gem 'google-api-client', :require => 'google/api_client'
service.rb
def self.google_calendar_client google_calendar_service=nil
client = Google::APIClient.new
client.authorization.client_id = xxx
client.authorization.client_secret = xxx
client.authorization.scope = 'https://www.googleapis.com/auth/calendar'
url_prefix = Rails.env.production? ? xxx : 'http://localhost:3000'
client.authorization.redirect_uri = "#{url_prefix}/create_google_calendar"
if google_calendar_service.present?
client.authorization.update_token! :access_token => google_calendar_service.token, :refresh_token => google_calendar_service.google_calendar_refresh_token, :expires_in => google_calendar_service.google_calendar_expires_in, :issued_at => Time.at(google_calendar_service.google_calendar_issued_at)
client.authorization.fetch_access_token! if client.authorization.expired?
end
client
end
services_controller.rb
def connect_google_calendar
#google_calendar_url = Service.google_calendar_client.authorization.authorization_uri.to_s
end
def create_google_calendar
client = Service.google_calendar_client
client.authorization.code = params[:code]
client.authorization.fetch_access_token!
current_user.services.create :provider => 'google_calendar', :token => client.authorization.access_token, :google_calendar_refresh_token => client.authorization.refresh_token, :google_calendar_expires_in => client.authorization.expires_in, :google_calendar_issued_at => client.authorization.issued_at
end
The truth is, I don't know. Your code looks right to me. But I can at least tell you what the error means. Missing authorization code means that it thinks you're trying to do an "authorization code" grant type when you fetch the access token. If you're actually trying to obtain an access token off a refresh token as opposed to doing it on the first pass after obtaining authorization from the user, then you may not have correctly set up the authorization object.
You can check this by inspecting the client.authorization.grant_type value. In very recent versions of the client you can manually set the grant_type value to force a particular mode, which may give you more informative error messages, depending on what the actual issue is.

Dropbox Ruby API

I want to use Dropbox Ruby API, I installed the gem and when I want to create a dropbox session I got this message:
uninitialized constant DropboxController::Dropbox
Is there anything to do if I want to use this api except install the gem?
The code is:
def authorize
if params[:oauth_token] then
dropbox_session = Dropbox::Session.deserialize(session[:dropbox_session])
dropbox_session.authorize(params)
session[:dropbox_session] = dropbox_session.serialize # re-serialize the authenticated session
redirect_to :action => 'upload'
else
dropbox_session = Dropbox::Session.new('your_consumer_key', 'your_consumer_secret')
session[:dropbox_session] = dropbox_session.serialize
redirect_to dropbox_session.authorize_url(:oauth_callback => url_for(:action => 'authorize'))
end
end
This is a rails controller not for ruby.
For ruby you may refer to this tutorial and here is the DOCs for Ruby
Require the dropbox file in your current file.

Resources