i have use aws-sdk-core gem i am getting error during getting url form aws
following is my code
def initialize(bucket:, region:)
#bucket = bucket
client = Aws::S3::Client.new(region: region)
#signer = Aws::S3::Presigner.new(client: client)
end
def sign(key, expires_in: 3600)
#signer.presigned_url(:get_object, bucket: #bucket, key: key, expires_in: expires_in)
end
i am getting error
NoMethodError - undefined method `credentials' for nil:NilClass:
aws-sdk-core (2.1.15) lib/aws-sdk-core/signers/v4.rb:24:in `initialize'
aws-sdk-core (2.1.15) lib/aws-sdk-core/s3/presigner.rb:88:in `block in sign_but_dont_send'
If anyone known how get presigned url please lets us known
Thanks
The unhelpful error message indicates that you have not configured AWS credentials. These are need to generate the signature. If you had used the client to send a request you would have gotten a more helpful error message indicating that credentials were required.
def initialize(bucket:, region:)
#bucket = bucket
creds = Aws::Credentials.new('ACCESS_KEY', 'SECRET_ACCESS_KEY')
client = Aws::S3::Client.new(region: region, credentials, creds)
#signer = Aws::S3::Presigner.new(client: client)
end
def sign(key, expires_in: 3600)
#signer.presigned_url(:get_object, bucket: #bucket, key: key, expires_in: expires_in)
end
Not related to your problem, but you can use the resource interface for S3 which cleans up the code a bit.
def initialize(bucket:, region:)
#bucket = Aws::S3::Bucket.new(bucket, {
region: region,
credentials: Aws::Credentials.new('ACCESS_KEY', 'SECRET_ACCESS_KEY'),
})
end
def sign(key, expires_in: 3600)
#bucket.object(key).presigned_url(:get, expires_in: expires_in)
end
While I showed how to configure credentials in code, I strongly recommend against this. You should export credentials to ENV before launching your applications or put them in the shared credentials file.
$ export AWS_ACCESS_KEY_ID=...
$ export AWS_SECRET_ACCESS_KEY=...
Or put the following in ~/.aws/credentials
[default]
aws_access_key_id=...
aws_secret_access_key=...
If you use the ENV or shared credentials file, then you no longer need to configure them in code. The SDK will attempt to source these locations when they are not given to the client constructor.
Related
I have a Rails application using Active Storage, with some tasks that should run every day to attach images to a model and store them in a bucket in Google Cloud.
When I run the task "rake attach_image:attach_image_to_cloud" to attach the image, it shows:
Google::Cloud::PermissionDeniedError: forbidden: attach-images-app#attach-images.iam.gserviceaccount.com does not have storage.buckets.get access to the Google Cloud Storage bucket.
Caused by:
Google::Apis::ClientError: forbidden: attach-images-app#attach-images.iam.gserviceaccount.com does not have storage.buckets.get access to the Google Cloud Storage bucket.
I followed "Setting up Rails 5.2 Active Storage, using Google Cloud Storage and Heroku" and think I did everything right.
My Ruby version is 2.5.3 and Rails is 5.2.2.
My task is:
def download_data(download_url, datetime, json_data)
puts "Downloading fields"
#field = Field.new(datetime: datetime, json_data: json)
puts "Saving field, datetime: #{datetime}"
attach_image(download_url, datetime, #field)
#field.save
puts "Finished downloading #{datetime} field"
end
def attach_image(download_url, datetime, field)
link = download_url
field.image.attach(io: open(link), filename: "global_#{datetime}.png")
end
download_data(download_url, some_datetime, json_data)
This is my model field.rb:
class Field < ApplicationRecord
has_one_attached :image
end
This is my config.yml:
google:
service: GCS
project: attach-images
credentials: <%= ENV['GOOGLE_APPLICATION_CREDENTIALS'].as_json %>
bucket: fields
google_dev:
service: GCS
project: attach-images
credentials: <%= Rails.root.join("config/secrets/attach_images.json") %>
bucket: fields
These are on my development.rb and production.rb environment files:
config.active_storage.service = :google_dev
config.active_storage.service = :google
I ran bundle install with:
gem "google-cloud-storage", "~> 1.8", require: false
My bucket and my service account key were both created correctly and the credential has owner rule. The credential is a hash downloaded when it was created in Google Cloud's console and set correctly in my development and Heroku production environments.
I've found a solution for this issue. The problem was solved by using the gsutil cors command to configure CORS on a bucket.
gsutil cors set [JSON_FILE_NAME].json gs://[BUCKET_NAME]
And the content of the json file was:
[
{
"origin": ["*"],
"responseHeader": ["Content-Type", "Content-Md5", "Origin", "X-Requested-With", "Accept", "Authorization"],
"method": ["PUT", "GET", "HEAD", "DELETE", "OPTIONS"],
"maxAgeSeconds": 3600
}
]
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.
In rails 5, I need to configure the dynamodb feature. I have referred some blogs and tried to implement it. First in localhost it was running without any issue, but when I move to other new system or a server then it is showing an error like,
/home/NICHEPRO/shruthir/.rvm/gems/ruby-2.4.0/gems/aws-sdk-core-2.10.19/lib/aws-sdk-core/plugins/regional_endpoint.rb:34:in `after_initialize': missing region; use :region option or export region name to ENV['AWS_REGION'] (Aws::Errors::MissingRegionError)
from /home/NICHEPRO/shruthir/.rvm/gems/ruby-2.4.0/gems/aws-sdk-core-2.10.19/lib/seahorse/client/base.rb:84:in `block in after_initialize'
AWS gem is,
aws-sdk (2.10.19)
aws-sdk-core (2.10.19)
aws-sdk-resources (2.10.19)
Referred From:
https://assist-software.net/snippets/how-save-data-amazon-dynamodb-using-ruby-on-rails
Also I have tried to fix this by referring other blogs but I will get below error too,
Failed to open TCP connection to localhost:8080 (Connection refused - connect(2) for "localhost" port 8080)
How to solve this issue?
Hope you are using Dynamoid gem. In app/config/initializer add a new config file and add below code.
Dynamoid.configure do |config|
config.adapter = 'aws_sdk_v2' # This adapter establishes a connection to the DynamoDB servers using Amazon's own AWS gem.
config.access_key = (ENV['AWS_ACCESS_KEY_ID'] || APP_CONFIG[:aws_access_key_id])
config.secret_key = (ENV['AWS_SECRET_ACCESS_KEY'] || APP_CONFIG[:aws_secret_access_key])
config.region = (ENV['AWS_REGION'] || 'us-east-1')
config.namespace = nil # To namespace tables created by Dynamoid from other tables you might have. Set to nil to avoid namespacing.
config.warn_on_scan = true # Output a warning to the logger when you perform a scan rather than a query on a table.
config.read_capacity = 100 # Read capacity for your tables
config.write_capacity = 200 # Write capacity for your tables
config.endpoint = (ENV['DYNAMO_ENDPOINT'] || APP_CONFIG[:dynamo_endpoint]) # [Optional]. If provided, it communicates with the DB listening at the endpoint. This is useful for testing with [Amazon Local DB] (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tools.DynamoDBLocal.html).
end
Make sure you update your ENV variables. Or if you connect directly to AWS instead of Dynamoid gem just follow...
def client
#client ||= Aws::DynamoDB::Client.new(
access_key_id: (ENV['AWS_ACCESS_KEY_ID'] || APP_CONFIG[:aws_access_key_id]),
secret_access_key: (ENV['AWS_SECRET_ACCESS_KEY'] || APP_CONFIG[:aws_secret_access_key]),
region: (ENV['AWS_REGION'] || 'us-east-1'),
endpoint: (ENV['DYNAMO_ENDPOINT'] || APP_CONFIG[:dynamo_endpoint])
)
end
and do a query like this
client.query(
table_name: table_name,
select: 'COUNT',
expression_attribute_values: {
':v1' => index
},
key_condition_expression: 'user_id = :v1'
).count
For more info http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/DynamoDB.html
I am trying to access the gmail api for that I am using this rubygmail guide but everytime I am trying to run the code I am getting different errors I am using this code:
require 'google/apis/gmail_v1'
require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'fileutils'
OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
APPLICATION_NAME = 'Gmail API Ruby Quickstart'
CLIENT_SECRETS_PATH = 'client_secret.json'
CREDENTIALS_PATH = File.join(Dir.home, '.credentials',
"gmail-ruby-quickstart.yaml")
SCOPE = Google::Apis::GmailV1::AUTH_GMAIL_READONLY
##
# Ensure valid credentials, either by restoring from the saved credentials
# files or intitiating an OAuth2 authorization. If authorization is required,
# the user's default browser will be launched to approve the request.
#
# #return [Google::Auth::UserRefreshCredentials] OAuth2 credentials
def authorize
FileUtils.mkdir_p(File.dirname(CREDENTIALS_PATH))
client_id = Google::Auth::ClientId.from_file(CLIENT_SECRETS_PATH)
token_store = Google::Auth::Stores::FileTokenStore.new(:file => 'gmail-ruby-quickstart.yaml')
authorizer = Google::Auth::UserAuthorizer.new(
client_id, SCOPE, token_store)
user_id = 'me'
credentials = authorizer.get_credentials(user_id)
if credentials.nil?
url = authorizer.get_authorization_url(
base_url: OOB_URI)
puts "Open the following URL in the browser and enter the " +
"resulting code after authorization"
puts url
code = gets
credentials = authorizer.get_and_store_credentials_from_code(
user_id: user_id, code: code, base_url: OOB_URI)
end
credentials
end
# Initialize the API
service = Google::Apis::GmailV1::GmailService.new
service.client_options.application_name = APPLICATION_NAME
service.authorization = authorize
# Show the user's labels
user_id = 'me'
result = service.list_user_labels(user_id)
puts "Labels:"
puts "No labels found" if result.labels.empty?
result.labels.each { |label| puts "- #{label.name}" }
When I am running the ruby code I am getting this error:
nilay#nilay:~/gmail$ ruby quickstart.rb
/home/nilay/.rbenv/versions/2.3.1/lib/ruby/2.3.0/pstore.rb:414:in `load_data': PStore file seems to be corrupted. (PStore::Error)
from /home/nilay/.rbenv/versions/2.3.1/lib/ruby/2.3.0/pstore.rb:328:in `transaction'
from /home/nilay/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/googleauth-0.5.1/lib/googleauth/stores/file_token_store.rb:49:in `load'
from /home/nilay/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/googleauth-0.5.1/lib/googleauth/user_authorizer.rb:130:in `get_credentials'
from quickstart.rb:28:in `authorize'
from quickstart.rb:45:in `<main>'
How can I fix this please help me.
Use this gem
Gem gmail
Or Gem gmail-ruby-api
I'm trying to use the Ruby gem 'google_drive'. Before using that gem, I'm obtaining the user's token via the gem omniauth-google-oauth2.
When I try to use google_drive as follows:
def google_oauth2(current_user)
session = GoogleDrive.login_with_oauth(self.token)
# Gets list of remote files.
session.files.each do |file|
p file.title
end
end
I get the following error:
Sending HTTP get https://www.googleapis.com/drive/v3/files?fields=%2A
Caught error Authorization failed. Server message:
{
"error": "invalid_request",
"error_description": "Required parameter is missing: grant_type"
}
Error - #<Signet::AuthorizationError: Authorization failed. Server message:
{
"error": "invalid_request",
"error_description": "Required parameter is missing: grant_type"
}>
Completed 500 Internal Server Error in 128ms (ActiveRecord: 0.4ms)
How can I resolve this?
Update
Omniauth code being used to store the google oauth 2 tokens:
def google_oauth2
auth_hash = request.env['omniauth.auth']
#authentication = Authentication.find_or_create_by(
user_id: current_user.id,
provider: auth_hash["provider"],
uid: auth_hash["uid"]
)
#authentication.update_attributes(
:token => auth_hash['credentials']['token'],
:refresh_token => auth_hash['credentials']['refresh_token'],
:provider_description => auth_hash["info"].email
)
flash[:notice] = "google_oauth2 authed."
redirect_to '/'
end
Working solution to access google drive api without requiring a config.json. This solution uses the refresh token obtained from the google auth 2 omniauth strategy:
require 'google/apis/drive_v2'
auth = Signet::OAuth2::Client.new(
token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
client_id: "XXX-XXX",
client_secret: "XXX",
refresh_token: self.refresh_token # Get this from the omniauth strategy.
)
auth.fetch_access_token!
x = Google::Apis::DriveV2
drive = x::DriveService.new
drive.authorization = auth
files = drive.list_files
This took me .5 day. I hope it helps someone else out there! :)