google-gmail-api 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/TODO.md ADDED
@@ -0,0 +1,3 @@
1
+ # TODO
2
+
3
+ *proper errors handling
@@ -0,0 +1,17 @@
1
+ # Auth Method
2
+ google_api_auth_method: ENV['GOOGLE_API_AUTH_METHOD']
3
+
4
+ #App Info
5
+ application_name: ENV['APP_NAME']
6
+ application_version: ENV['APP_VERSION']
7
+
8
+ # Web Application Auth
9
+ client_id: ENV['GOOGLE_API_CLIENT_ID']
10
+ client_secret: ENV['GOOGLE_API_CLIENT_SECRET']
11
+ refresh_token: ENV['GOOGLE_API_REFRESH_TOKEN']
12
+
13
+ # Service Account Auth
14
+ google_api_key: ENV['GOOGLE_API_KEY']
15
+ google_api_email: ENV['GOOGLE_API_EMAIL']
16
+ email_account: ENV['GOOGLE_ACCOUNT']
17
+ auth_scopes: ENV['GOOGLE_AUTH_SCOPES']
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path('../lib', __FILE__)
4
+ require 'gmail/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "google-gmail-api"
8
+ s.summary = "A Ruby interface to Gmail API (NO IMAP, NO SMTP), with all the tools you will need."
9
+ s.description = "A Ruby interface to Gmail API (NO IMAP, NO SMTP).
10
+ Search, read and send multipart emails; archive, mark as read/unread,
11
+ delete emails; and manage labels. Everything is done through the Gmail API without going through IMAP or SMTP Protocol
12
+ "
13
+ s.version = Gmail::VERSION
14
+ s.platform = Gem::Platform::RUBY
15
+ s.authors = ["Julien Hobeika","Keiran Betteley", 'Evaldas Grudzinskas']
16
+ s.homepage = "https://github.com/evaldasg/google-gmail-api"
17
+ s.licenses = ['MIT']
18
+
19
+ # runtime dependencies
20
+ s.required_ruby_version = '>= 1.9.3'
21
+ s.add_dependency "mime", ">= 0.1"
22
+ s.add_dependency "mail", ">= 2.2.1"
23
+ s.add_dependency "activesupport"
24
+ s.add_dependency 'google-api-client', "0.8.6"
25
+ s.add_dependency "hooks", ">=0.4.0"
26
+ s.add_dependency "hashie", ">=3.3.2"
27
+ s.add_dependency "stringex"
28
+
29
+ # development dependencies
30
+ s.add_development_dependency "rake"
31
+ s.add_development_dependency "test-unit"
32
+ s.add_development_dependency('mocha', '~> 1.0.0')
33
+ s.add_development_dependency('shoulda', '~> 3.5.0')
34
+
35
+ s.add_development_dependency "gem-release"
36
+
37
+ s.files = `git ls-files`.split("\n")
38
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
39
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
40
+ s.require_paths = ["lib"]
41
+ end
@@ -0,0 +1,159 @@
1
+ require 'mail'
2
+ require 'hashie'
3
+ require 'hooks'
4
+ require 'google/api_client'
5
+ require 'gmail/gmail_object'
6
+ require 'gmail/api_resource'
7
+ #base
8
+ require 'gmail/base/create'
9
+ require 'gmail/base/delete'
10
+ require 'gmail/base/get'
11
+ require 'gmail/base/list'
12
+ require 'gmail/base/update'
13
+ require 'gmail/base/modify'
14
+ require 'gmail/base/trash'
15
+
16
+ #object
17
+ require 'gmail/util'
18
+ require 'gmail/message'
19
+ require 'gmail/draft'
20
+ require 'gmail/thread'
21
+ require 'gmail/label'
22
+
23
+ module Gmail
24
+
25
+ class << self
26
+ attr_accessor :auth_method, :client_id, :client_secret,
27
+ :refresh_token, :auth_scopes, :email_account, :application_name, :application_version
28
+ attr_reader :service, :client, :mailbox_email
29
+ def new hash
30
+ [:auth_method, :client_id, :client_secret, :refresh_token, :auth_scopes, :email_account, :application_name, :application_version].each do |accessor|
31
+ Gmail.send("#{accessor}=", hash[accessor.to_s])
32
+ end
33
+ end
34
+ end
35
+
36
+ Google::APIClient.logger.level = 3
37
+ @service = Google::APIClient.new.discovered_api('gmail', 'v1')
38
+ Google::APIClient.logger.level = 2
39
+
40
+ begin
41
+ Gmail.new YAML.load_file("account.yml") # for development purpose
42
+ rescue
43
+
44
+ end
45
+
46
+ def self.request(method, params={}, body={}, auth_method=@auth_method)
47
+
48
+ params[:userId] ||= "me"
49
+ case auth_method
50
+ when "web_application"
51
+ if @client.nil?
52
+ self.connect
53
+ end
54
+ when "service_account"
55
+ if @client.nil?
56
+ self.service_account_connect
57
+ elsif self.client.authorization.principal != @email_account
58
+ self.service_account_connect
59
+ end
60
+ end
61
+
62
+ if body.empty?
63
+ response = @client.execute(
64
+ :api_method => method,
65
+ :parameters => params,
66
+
67
+ :headers => {'Content-Type' => 'application/json'})
68
+ else
69
+
70
+ response = @client.execute(
71
+ :api_method => method,
72
+ :parameters => params,
73
+ :body_object => body,
74
+ :headers => {'Content-Type' => 'application/json'})
75
+ end
76
+ parse(response)
77
+
78
+ end
79
+
80
+ def self.mailbox_email
81
+ @mailbox_email ||= self.request(@service.users.to_h['gmail.users.getProfile'])[:emailAddress]
82
+ end
83
+
84
+
85
+
86
+ def self.connect(client_id=@client_id, client_secret=@client_secret, refresh_token=@refresh_token)
87
+ unless client_id
88
+ raise 'No client_id specified'
89
+ end
90
+
91
+ unless client_secret
92
+ raise 'No client_secret specified'
93
+ end
94
+
95
+ unless refresh_token
96
+ raise 'No refresh_token specified'
97
+ end
98
+
99
+ @client = Google::APIClient.new(
100
+ application_name: @application_name,
101
+ application_version: @application_version
102
+ )
103
+ @client.authorization.client_id = client_id
104
+ @client.authorization.client_secret = client_secret
105
+ @client.authorization.refresh_token = refresh_token
106
+ @client.authorization.grant_type = 'refresh_token'
107
+ @client.authorization.fetch_access_token!
108
+ @client.auto_refresh_token = true
109
+
110
+ #@service = @client.discovered_api('gmail', 'v1')
111
+
112
+ end
113
+
114
+ def self.service_account_connect(
115
+ client_id=@client_id, client_secret=@client_secret,
116
+ email_account=@email_account, auth_scopes=@auth_scopes,
117
+ application_name=@application_name, application_version=@application_version
118
+ )
119
+ puts "Authenticating service account - #{email_account}"
120
+
121
+
122
+ @client = Google::APIClient.new(application_name: application_name, application_version: application_version)
123
+
124
+
125
+
126
+ key = Google::APIClient::KeyUtils.load_from_pem(
127
+ client_secret,
128
+ 'notasecret')
129
+ asserter = Google::APIClient::JWTAsserter.new(
130
+ client_id,
131
+ auth_scopes,
132
+ key
133
+ )
134
+ @client.authorization = asserter.authorize(email_account)
135
+
136
+ end
137
+
138
+ def self.parse(response)
139
+ begin
140
+
141
+ if response.body.empty?
142
+ return response.body
143
+ else
144
+ response = JSON.parse(response.body)
145
+ end
146
+
147
+ rescue JSON::ParserError
148
+ raise "error code: #{response.error},body: #{response.body})"
149
+ end
150
+
151
+ r = Gmail::Util.symbolize_names(response)
152
+ if r[:error]
153
+ raise "#{r[:error]}"
154
+ end
155
+ r
156
+ end
157
+
158
+
159
+ end # Gmail
@@ -0,0 +1,12 @@
1
+ module Gmail
2
+ class APIResource < GmailObject
3
+ def self.class_name
4
+ self.name.split('::')[-1]
5
+ end
6
+
7
+ def self.base_method
8
+ Gmail.service.users.send("#{class_name.downcase}s")
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Gmail
2
+ module Base
3
+ module Create
4
+ module ClassMethods
5
+ def create(body, opts={})
6
+ response = Gmail.request(base_method.send("create"), {}, body)
7
+ Util.convert_to_gmail_object(response, class_name.downcase)
8
+ end
9
+ end
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ module Gmail
2
+ module Base
3
+ module Delete
4
+ def delete(opts={})
5
+ response = Gmail.request(self.class.base_method.send("delete"),{id: id})
6
+ if response == ""
7
+ true
8
+ else
9
+ false
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def delete(id, opts={})
15
+ response = Gmail.request(base_method.send("delete"),{id: id})
16
+ if response == ""
17
+ true
18
+ else
19
+ false
20
+ end
21
+ end
22
+ end
23
+
24
+ def self.included(base)
25
+ base.extend(ClassMethods)
26
+ end
27
+
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ module Gmail
2
+ module Base
3
+ module Get
4
+ module ClassMethods
5
+ def get(id)
6
+ response = Gmail.request(base_method.send("get"), {id: id})
7
+ Util.convert_to_gmail_object(response, class_name.downcase)
8
+
9
+ end
10
+ end
11
+
12
+ def self.included(base)
13
+ base.extend(ClassMethods)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,54 @@
1
+ module Gmail
2
+ module Base
3
+ module List
4
+ module ClassMethods
5
+ def all(filters={}, opts={})
6
+ max_results = filters[:maxResults] || 100
7
+ opts[:items] ||= []
8
+
9
+ if max_results == -1
10
+ filters.merge!({maxResults: 100})
11
+ end
12
+ response = Gmail.request(base_method.send("list"), filters)
13
+ items = response["#{class_name.downcase}s".to_sym] || []
14
+ next_page_token = response[:nextPageToken]
15
+ opts[:items] = opts[:items] + items
16
+
17
+ if items.count < 100 || items.count < max_results
18
+ Util.convert_to_gmail_object(opts[:items], class_name.downcase)
19
+ else
20
+ max_results = (max_results == -1)?-1:max_results-items.count
21
+ all(filters.merge({maxResults: max_results, pageToken: next_page_token}), opts)
22
+ end
23
+ end
24
+
25
+ def search(q={})
26
+ if q.is_a? String
27
+ all({q: q})
28
+ else
29
+ query = ""
30
+ [:from, :to, :subject].each do |prop|
31
+ query += "#{prop.to_s}:(#{q[prop].downcase}) " unless q[prop].nil?
32
+ q.delete(prop)
33
+ end
34
+ [:in, :before, :after].each do |prop|
35
+ query += "#{prop.to_s}:#{q[prop]} " unless q[prop].nil?
36
+ q.delete(prop)
37
+ end
38
+
39
+ query += "#{q[:has_words]} " unless q[:has_words].nil?
40
+ query += "-{#{q[:has_not_words]}}" unless q[:has_not_words].nil?
41
+ q.delete(:has_words)
42
+ q.delete(:has_not_words)
43
+
44
+ all(q.merge({q: query}))
45
+ end
46
+ end
47
+ end
48
+
49
+ def self.included(base)
50
+ base.extend(ClassMethods)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,66 @@
1
+ module Gmail
2
+ module Base
3
+ module Modify
4
+ def modify!(addLabelIds=[], removeLabelIds=[])
5
+ response = Gmail.request(self.class.base_method.send("modify"),{id: id}, {addLabelIds: addLabelIds, removeLabelIds: removeLabelIds})
6
+ d = Util.convert_to_gmail_object(response, self.class.class_name.downcase)
7
+ @values = d.values
8
+ self
9
+ end
10
+
11
+ def modify(addLabelIds=[], removeLabelIds=[])
12
+ response = Gmail.request(self.class.base_method.send("modify"),{id: id}, {addLabelIds: addLabelIds, removeLabelIds: removeLabelIds})
13
+ d = Util.convert_to_gmail_object(response, self.class.class_name.downcase)
14
+ end
15
+
16
+ def archive
17
+ modify([], ["INBOX"])
18
+ end
19
+
20
+ def archive!
21
+ modify!([], ["INBOX"])
22
+ end
23
+
24
+ def unarchive
25
+ modify(["INBOX"], [] )
26
+ end
27
+
28
+ def unarchive!
29
+ modify!(["INBOX"], [] )
30
+ end
31
+
32
+ def star
33
+ modify(["STARRED"], [] )
34
+ end
35
+
36
+ def star!
37
+ modify!(["STARRED"], [] )
38
+ end
39
+
40
+ def unstar
41
+ modify([],["STARRED"] )
42
+ end
43
+
44
+ def unstar!
45
+ modify!([],["STARRED"] )
46
+ end
47
+
48
+ def mark_as_read
49
+ modify([],["UNREAD"] )
50
+ end
51
+
52
+ def mark_as_read!
53
+ modify!([],["UNREAD"] )
54
+ end
55
+
56
+ def mark_as_unread
57
+ modify(["UNREAD"],[] )
58
+ end
59
+
60
+ def mark_as_unread!
61
+ modify!(["UNREAD"],[] )
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,33 @@
1
+ module Gmail
2
+ module Base
3
+ module Trash
4
+ def trash(opts={})
5
+ response = Gmail.request(self.class.base_method.send("trash"),{id: id})
6
+ Util.convert_to_gmail_object(response, self.class.class_name.downcase)
7
+ end
8
+
9
+ def untrash(opts={})
10
+ response = Gmail.request(self.class.base_method.send("untrash"),{id: id})
11
+ Util.convert_to_gmail_object(response, self.class.class_name.downcase)
12
+ end
13
+
14
+ module ClassMethods
15
+ def trash(id, opts={})
16
+ response = Gmail.request(base_method.send("trash"),{id: id})
17
+ Util.convert_to_gmail_object(response, class_name.downcase)
18
+ end
19
+
20
+ def untrash(id, opts={})
21
+ response = Gmail.request(base_method.send("untrash"),{id: id})
22
+ Util.convert_to_gmail_object(response, class_name.downcase)
23
+ end
24
+ end
25
+
26
+ def self.included(base)
27
+ base.extend(ClassMethods)
28
+ end
29
+
30
+
31
+ end
32
+ end
33
+ end