Skip to content

Instantly share code, notes, and snippets.

@lnznt
Last active April 23, 2017 10:27
Show Gist options
  • Save lnznt/0d85b9dd8563d4e41565c94a17d78824 to your computer and use it in GitHub Desktop.
Save lnznt/0d85b9dd8563d4e41565c94a17d78824 to your computer and use it in GitHub Desktop.
[Ruby] sample: Send Mail Using the Gmail API
APP_NAME = 'Send Mail Using the Gmail API'
#
# To run this program, we need two files.
#
# 1. clent_secret.json
#
# Create credentials in your Google Developers Console and download it.
# Details for see 'Google Developers Console' web page.
#
# 2. credential.yaml
#
# When authorization is required, this program will get and store it.
# In that case, plese operate according to the message of this program.
#
#
require 'mail' # gem install mail
require 'google/apis/gmail_v1' # gem install google-api-client
require 'googleauth' # (same as above)
require 'googleauth/stores/file_token_store' # (same as above)
require 'zip' # gem install rubyzip
require 'find'
require 'tmpdir'
require 'pathname'
require 'optparse'
SCOPE = Google::Apis::GmailV1::AUTH_GMAIL_SEND
CHARSET = 'UTF-8'
OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
APP_HOME = Pathname.new(Dir.home) + ".#{APP_NAME.gsub(/\s+/){'_'}}"
CLIENT_SECRET = Pathname.new('client_secret.json')
CREDENTIALS = Pathname.new('credentials.yaml')
app = {
user: ENV['LOGNAME'] || `hostname`.chomp,
client_secret: APP_HOME + CLIENT_SECRET,
credentials: APP_HOME + CREDENTIALS,
}
message = Google::Apis::GmailV1::Message.new
Dir.mktmpdir do |tmpdir|
make_zip = -> path {
zip_path = Pathname.new(tmpdir) + "#{path.basename}.zip"
Zip::File.open(zip_path, Zip::File::CREATE) do |zip|
Dir.chdir(path.dirname) do
Find.find(path.basename) do |ent|
zip.add(ent, Pathname.new(ent).realpath)
end
end
end
zip_path.to_s
}
OptionParser.new.instance_eval do
mail = Mail.new(charset: CHARSET)
on('--to=TO' ) {|to | mail.to = to }
on('--cc=CC' ) {|cc | mail.cc = cc }
on('--subject=SUBJECT' ) {|text| mail.subject = text }
on('--body=BODY' ) {|text| mail.body = text }
on('--user=USER' ) {|user| app[:user ] = user }
on('--client_secret=PATH') {|path| app[:client_secret] = Pathname.new path }
on('--credentials=PATH' ) {|path| app[:credentials ] = Pathname.new path }
parse! ARGV
raise "Not specified 'to'" unless mail.to
ARGV.map{|f| Pathname.new f }.each do |path|
mail.add_file(path.to_s) if path.file?
mail.add_file(make_zip.(path)) if path.directory?
end
message.raw = mail.to_s
end
end
app[:credentials].dirname.mkpath
client_id = Google::Auth::ClientId.from_file(app[:client_secret])
token_store = Google::Auth::Stores::FileTokenStore.new(file: app[:credentials])
authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, token_store)
authorization = authorizer.instance_eval do
get_code = -> {
puts <<-ATTENTION
!!! NEEDS AUTHORIZATION !!!
1) At first, sign in with your Google account in your browser
2) then open the following URL and click 'Authorize' button.
3) At last, enter the resulting code that display on the browser.
--[URL]---------------------------------------------------------------
#{get_authorization_url base_url:OOB_URI}
----------------------------------------------------------------------
ATTENTION
print "[Enter the resulting code]==>> " ; gets
}
get_credentials(app[:user]) ||
get_and_store_credentials_from_code(user_id: app[:user],
code: get_code.(),
base_url: OOB_URI)
end
Google::Apis::GmailV1::GmailService.new.tap do |gmail|
gmail.client_options.application_name = APP_NAME
gmail.authorization = authorization
gmail.send_user_message(user_id='me', message)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment