Search code examples
devisegoogle-drive-apiruby-on-rails-5omniauthgoogle-sheets-api

using devise+omniauth access_token to pull from Google Sheets


I'd like to pull data from the Google Sheets spreadsheet of a logged-in user for some processing. I've set up an app in the Google Console with:

  • Google Drive API
  • Contacts API
  • Google+ API
  • Google Sheets API

I've also hooked up devise/oauth so that it can successfully log in. However, whenever I try to use the access_token received in my from_omniauth method, I get:

dailyLimitExceededUnreg: Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.

What am I doing wrong?

My code (using the google-api-client) is as follows:

# frozen_string_literal: true
require 'google/apis/drive_v2'

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, omniauth_providers: [:google_oauth2]
  has_many :datasets, inverse_of: :user

  # Omniauth support
  def self.from_omniauth(access_token)
    #session = GoogleDrive::Session.new( access_token )
    drive = Google::Apis::DriveV2::DriveService.new
    files = drive.list_files(
      fields: "nextPageToken, files(id, name)",
      q: "mimeType = 'application/vnd.google-apps.spreadsheet' AND trashed != true",
    )


    data = access_token.info
    user = User.where(email: data['email']).first

    unless user
      user = User.create(
        email: data['email'],
        password: Devise.friendly_token[0, 20]
      )
    end
    user
  end
end

For the record, I also tried using the google-drive gem and met with the same response.


Solution

  • While @pinyyid didn't have the complete answer in itself, it confirmed that I'd not been passing the credentials correctly (I'd tried previously, but not got it right). Ultimately, the following changes were necessary to make it work using the google-drive gem:

    config.omniauth :google_oauth2, '<CLIENT_ID>', '<SECRET_KEY', scope: 'https://www.googleapis.com/auth/drive,https://spreadsheets.google.com/feeds/,https://www.googleapis.com/auth/plus.login,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/userinfo.profile'
    

    The key here was to add the scopes I needed to the devise request.

    Then, in my user object, I used the following:

    def self.from_omniauth(access_token)
       session = GoogleDrive::Session.from_access_token(access_token[:credentials][:token])
       x = session.spreadsheet_by_title '<a spreadsheet title>' #or any call, really
    

    I hope this helps someone!