在Ruby中为macOS桌面应用程序访问Google工作区表的Oauth示例(无效授权类型)



我正在尝试使用macOS上的Ruby客户端更新谷歌工作空间表。我找不到一个目前有效的样本。我目前正在尝试以下,这显然是不正确的!执行时:

user_credentials.fetch_access_token!

我得到错误:

ERROR Signet::AuthorizationError: Authorization failed.  Server message:n{n  "error": "unsupported_grant_type",n  "error_description": "Invalid grant_type: "n}
/Users/jtosey/.rbenv/versions/3.1.3/lib/ruby/gems/3.1.0/gems/signet-0.17.0/lib/signet/oauth_2/client.rb:1028:in `fetch_access_token'

这是我当前的认证码:

require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'launchy'
require 'webrick'
# Configuration
secrets = ENV['HOME'] + '/.secrets'
credentials_file = secrets + '/google_workspace_client_secret.json'
token_store_file = secrets + '/google_workspace_token.yaml'
# Authorization
scopes = ['https://www.googleapis.com/auth/spreadsheets']
client_id = Google::Auth::ClientId.from_file(credentials_file)
token_store = Google::Auth::Stores::FileTokenStore.new(file: token_store_file)
authorizer = Google::Auth::UserAuthorizer.new(client_id, scopes, token_store)
user_credentials = Google::Auth::UserRefreshCredentials.new(client_id: client_id.id, scope: scopes, token_store: token_store)
if user_credentials.refresh_token.nil?
auth_uri = user_credentials.authorization_uri(
access_type: 'offline',
prompt: 'select_account consent',
redirect_uri: 'http://localhost:8080'
)
Launchy.open(auth_uri)
root = File.expand_path '~/public_html'
server = WEBrick::HTTPServer.new Port: 8080, DocumentRoot: root
server.mount_proc '/' do |req, res|
code = req.query['code']
if code.nil?
[200, {'Content-Type' => 'text/html'}, [%(<html><body><h2>Authorization required</h2><p>Click <a href="#{auth_uri}">here</a> to authorize the application.</p></body></html>)]]
else
user_credentials.code = code
user_credentials.fetch_access_token!
user_credentials.store(token_store)
[200, {'Content-Type' => 'text/html'}, ['<html><body><h2>Authorization successful!</h2></body></html>']]
# TODO: stop server
end
end
server.start
end

建议吗?

这对我来说是有效的,从2023-04-05开始:

require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'google/apis/sheets_v4'
require 'launchy'
require 'webrick'
# Configuration
secrets = ENV['HOME'] + '/.secrets'
CREDENTIALS_FILE = secrets + '/google_workspace_client_secret.json'
TOKEN_STORE_FILE = secrets + '/google_workspace_token.yaml'
BASE_URL = 'http://localhost:8080'.freeze
CREDENTIALS_PATH = "credentials.json".freeze
SCOPES = [
Google::Apis::SheetsV4::AUTH_DRIVE,
Google::Apis::SheetsV4::AUTH_DRIVE_FILE,
Google::Apis::SheetsV4::AUTH_DRIVE_READONLY,
Google::Apis::SheetsV4::AUTH_SPREADSHEETS,
Google::Apis::SheetsV4::AUTH_SPREADSHEETS_READONLY
]
def authorize
client_id = Google::Auth::ClientId.from_file(CREDENTIALS_FILE)
token_store = Google::Auth::Stores::FileTokenStore.new(file: TOKEN_STORE_FILE)
authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPES, token_store)
user_id = "default"
credentials = authorizer.get_credentials user_id
if credentials.nil?
auth_uri = authorizer.get_authorization_url(base_url: BASE_URL)
Launchy.open(auth_uri)
root = File.expand_path(ENV['HOME'] + '/public_html')
server = WEBrick::HTTPServer.new(Port: 8080, DocumentRoot: root)
server.mount_proc '/oauth2callback' do |request, response|
code = request.query['code']
response.status = 200
response['Content-Type'] = 'text/html'
response.body = if code.nil?
%(<html><body><h2>Authorization required</h2><p>Click <a href="#{auth_uri}">here</a> to authorize the application.</p></body></html>)
else
credentials = authorizer.get_and_store_credentials_from_code(user_id: user_id, code: code, base_url: BASE_URL)
server.shutdown
'<html><body><h2>Authorization successful!</h2></body></html>'
end
end
server.start
end
credentials
end
spreadsheet_id = 'your spreadsheet ID'
range = 'Sheet1!A1' # The range of the cell to write to
# Google Sheets API
service = Google::Apis::SheetsV4::SheetsService.new
service.client_options.application_name = 'Your Application Name'
service.authorization = authorize
# Write the value to the cell
value_range = Google::Apis::SheetsV4::ValueRange.new
value_range.range = range
value_range.values = [['Hello, World!']]
result = service.update_spreadsheet_value(spreadsheet_id, range, value_range, value_input_option: 'USER_ENTERED')
puts "#{result.updated_cells} cells updated."

最新更新