Skip to content

Instantly share code, notes, and snippets.

@jkotchoff
Created November 29, 2016 00:23
Show Gist options
  • Save jkotchoff/34fba5c6df03a5caadad286b80c97b96 to your computer and use it in GitHub Desktop.
Save jkotchoff/34fba5c6df03a5caadad286b80c97b96 to your computer and use it in GitHub Desktop.
Rails example of how to connect to the Gmail API using Ruby and download a Zip File attachment and then unzip contents from the zip archive
class EmailedZipFileExtractor
# This class downloads an email from gmail and extracts a file out of a .zip attachment
require 'google/apis/gmail_v1'
require 'googleauth'
require 'zip'
# These credentials come from creating an OAuth Web Application client ID
# in the Google developer console
#
# refer: https://www.youtube.com/watch?v=hfWe1gPCnzc
#
# ie.
# > visit http://console.developers.google.com
# > API Manager
# > Credentials
# > Create Credentials (OAuth client ID)
# > Application type: Web Application
# > Authorised redirect URIs: https://developers.google.com/oauthplayground
# * the resultant client ID / client secret goes in the following GOOGLE_KEY / GOOGLE_SECRET variables
# > visit: https://developers.google.com/oauthplayground/
# > Click the settings icon to show the OAuth 2.0 configuration
# > Tick 'Use your own OAuth credentials'
# > Enter the OAuth Client ID and OAuth Client secret that you have just created
# > Check the entry for 'Google Play Developer API v2' in the scopes field and click 'Authorize APIs'
# > Click 'Allow'
# > Click 'Exchange authorization code for tokens'
# * the resultant Refresh token and Access token go in the following REFRESH_TOKEN / ACCESS_TOKEN variables
GOOGLE_KEY = 'xxxcc.apps.googleusercontent.com'
GOOGLE_SECRET = 'abcd'
ACCESS_TOKEN = 'abcd'
REFRESH_TOKEN = 'abcd'
TMP_DIR = "#{Rails.root.to_s}/tmp/list"
APPLICATION_NAME = 'Rails App'
EMAIL_ADDRESS = "[email protected]"
GMAIL_QUERY = "from:[email protected] has:attachment subject:Email+Subject"
Gmail = Google::Apis::GmailV1
def initialize
FileUtils.rm_r(TMP_DIR) if File.directory?(TMP_DIR)
FileUtils.mkdir_p(TMP_DIR)
end
def fetch
File.read(file_path)
end
private
def file_path
"#{TMP_DIR}/file.txt".tap do |path|
Zip::File.open(zip_file_path) do |zip_file|
# Match the required file
entry = zip_file.glob('full_list/_reliable_list.txt').first
entry.extract(path)
end
end
end
def zip_file_path
"#{TMP_DIR}/archive.zip".tap do |path|
File.open(path, "wb"){|f| f.puts attachment.data }
end
end
def attachment
gmail.get_user_message_attachment(EMAIL_ADDRESS, message_id, attachment_id)
end
def attachment_id
email.payload.parts.find{|p| p.mime_type == 'application/zip'}.body.attachment_id
end
def email
gmail.get_user_message(EMAIL_ADDRESS, message_id)
end
def message_id
# Get the latest email that matches the query
@message_id ||= gmail.list_user_messages(EMAIL_ADDRESS, q: GMAIL_QUERY).messages.first.id
end
def gmail
@gmail ||= Gmail::GmailService.new.tap do |publisher|
publisher.authorization = client
publisher.client_options.application_name = APPLICATION_NAME
end
end
def client(scopes = [Google::Apis::GmailV1::AUTH_GMAIL_READONLY])
Signet::OAuth2::Client.new(
authorization_uri: 'https://accounts.google.com/o/oauth2/auth',
token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
client_id: GOOGLE_KEY,
client_secret: GOOGLE_SECRET,
access_token: ACCESS_TOKEN,
refresh_token: REFRESH_TOKEN,
scope: Google::Apis::GmailV1::AUTH_GMAIL_READONLY,
)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment