gmail-api-ruby 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -4
- data/CHANGELOG.md +1 -1
- data/README.md +65 -11
- data/Rakefile +6 -9
- data/TODO.md +1 -2
- data/account.yml.example +5 -0
- data/gmail.gemspec +3 -2
- data/lib/gmail.rb +20 -14
- data/lib/gmail/api_resource.rb +0 -1
- data/lib/gmail/base/delete.rb +6 -2
- data/lib/gmail/base/list.rb +6 -2
- data/lib/gmail/draft.rb +6 -1
- data/lib/gmail/gmail_object.rb +11 -2
- data/lib/gmail/label.rb +2 -2
- data/lib/gmail/message.rb +23 -5
- data/lib/gmail/thread.rb +10 -4
- data/lib/gmail/version.rb +1 -1
- data/test/gmail/api_resource_test.rb +47 -0
- data/test/gmail/draft_test.rb +104 -0
- data/test/gmail/gmail_object_test.rb +45 -0
- data/test/gmail/label_test.rb +129 -0
- data/test/gmail/message_test.rb +266 -0
- data/test/gmail/thread_test.rb +184 -0
- data/test/gmail/util_test.rb +18 -0
- data/test/test_data.rb +175 -0
- data/test/test_helper.rb +33 -0
- metadata +45 -12
- data/.rspec +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03481cc395ab2eb88fa4f90aef5ac3e5368ad2fc
|
4
|
+
data.tar.gz: cbf0ec27698b435a7ddd72c8f70c47f51b74bff0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 257b9bbb2719a1260d9023e9508cbeac3a670f7875afbd9eb3e41affd32d64ec66c60c4addfdd44c426312536ff7b746da3ab98755b8fc9b8b27bc547672b55f
|
7
|
+
data.tar.gz: 3047e7203b0ba52a79fffec5fc2a8d986690bc1823e3027d8a295c836ff4e30542561c9e0155c617a133a7193ea97fd331ffbcd402bb5d2bc450cd20035ed0c7
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -8,38 +8,47 @@ and manage labels. Everything goes through Gmail API (and not throught IMAP or S
|
|
8
8
|
|
9
9
|
If for your usecase, the gem is too limited there are two solutions for you:
|
10
10
|
|
11
|
-
1
|
12
|
-
2
|
13
|
-
*Do custom query by adding parameters I didn't talk about in my doc
|
14
|
-
*If for some reason I forgot to build some methods, note that you can call fully custom request via Gmail.client (Standard Google Api Client)
|
11
|
+
1. Contribute ;)
|
12
|
+
2. Look at [Gmail Api doc](https://developers.google.com/gmail/api/v1/reference) to:
|
13
|
+
* Do custom query by adding parameters I didn't talk about in my doc
|
14
|
+
* If for some reason I forgot to build some methods, note that you can call fully custom request via Gmail.client (Standard Google Api Client)
|
15
15
|
|
16
16
|
# To Do
|
17
17
|
|
18
|
-
|
19
|
-
write proper error handling
|
18
|
+
* write proper error handling
|
20
19
|
|
21
20
|
## Installation
|
22
21
|
|
23
|
-
gem install gmail-ruby
|
22
|
+
gem install gmail-api-ruby
|
24
23
|
|
25
|
-
##
|
24
|
+
## Initialization
|
26
25
|
|
26
|
+
```ruby
|
27
27
|
Gmail.client_id = "...Your app client id..."
|
28
28
|
Gmail.client_secret = "...Your app Secret..."
|
29
29
|
Gmail.refresh_token = "...the refresh token of the Gmail account you want to use..."
|
30
|
+
```
|
30
31
|
|
31
32
|
## Usage
|
32
33
|
|
34
|
+
```ruby
|
33
35
|
require "Gmail"
|
36
|
+
```
|
34
37
|
|
35
38
|
### Common methods
|
36
39
|
|
37
40
|
this works for Messages, Labels, Drafts and Threads (everything)
|
41
|
+
|
42
|
+
```ruby
|
38
43
|
Gmail::Message.all
|
39
44
|
Gmail::Message.all(maxResults: -1) #will parse everything. Use with care. Can through request timeout if used in web apps
|
40
45
|
Gmail::Message.get(message_id)
|
41
46
|
some_gmail_message.delete
|
47
|
+
```
|
48
|
+
|
42
49
|
this will work for Messages and Threads
|
50
|
+
|
51
|
+
```ruby
|
43
52
|
some_message.archive
|
44
53
|
some_message.un_archive
|
45
54
|
some_message.trash
|
@@ -48,24 +57,28 @@ this will work for Messages and Threads
|
|
48
57
|
some_message.un_star
|
49
58
|
some_message.mark_as_read
|
50
59
|
some_message.mark_as_unread
|
51
|
-
|
60
|
+
|
52
61
|
Gmail::Message.search(in: "labelId" from: "me@gmail.com", to: "you@gmail.com, theothers@gmail.com", subject: "some subject", after: "date", before: "date", has_words: "some words", has_not_words: "some text")
|
53
62
|
Gmail::Message.search("some words") #search as you would do in gmail interface
|
54
|
-
|
63
|
+
|
64
|
+
```
|
55
65
|
|
56
66
|
|
57
67
|
### Message
|
58
68
|
|
59
69
|
Create a Message object
|
60
70
|
|
71
|
+
```ruby
|
61
72
|
m = Gmail::Message.new(
|
62
73
|
from: "test@test.com",
|
63
74
|
to: "hello@world.com",
|
64
75
|
subject: "this is the subject",
|
65
76
|
body: "this is a text body")
|
77
|
+
```
|
66
78
|
|
67
79
|
If you want a multipart message
|
68
80
|
|
81
|
+
```ruby
|
69
82
|
m = Gmail::Message.new(
|
70
83
|
from: "test@test.com",
|
71
84
|
to: "hello@world.com",
|
@@ -74,14 +87,19 @@ If you want a multipart message
|
|
74
87
|
html: "<div>this is a html body</div>",
|
75
88
|
labelIds: ["cool label", "Newsletter"] #labelIds is always array of labels
|
76
89
|
)
|
90
|
+
```
|
77
91
|
|
78
92
|
From this you can create a Draft in Gmail
|
79
93
|
|
94
|
+
```ruby
|
80
95
|
m.create_draft
|
96
|
+
```
|
81
97
|
|
82
98
|
or just send the Message
|
83
99
|
|
100
|
+
```ruby
|
84
101
|
m.deliver
|
102
|
+
```
|
85
103
|
|
86
104
|
Notice that the Message object can use from, to, cc, bcc, threadId, labelIds, text, html, body
|
87
105
|
|
@@ -90,20 +108,25 @@ Or if you need to create a different multipart email, you need to build the "raw
|
|
90
108
|
|
91
109
|
example:
|
92
110
|
|
111
|
+
```ruby
|
93
112
|
mail = Mail.new #this is the native ruby Mail object
|
94
113
|
#
|
95
114
|
# construct your Mail object
|
96
115
|
#
|
97
116
|
raw = Base64.urlsafe_encode64 mail.to_s
|
98
117
|
m = Gmail::Message.new(raw: raw)
|
118
|
+
```
|
99
119
|
|
100
120
|
In that scenario, you still assign, if needed, ThreadId and labelIds as previously
|
101
121
|
|
122
|
+
```ruby
|
102
123
|
m.threadId = "somethreadId"
|
103
124
|
m.labelIds = ["cool label"]
|
125
|
+
```
|
104
126
|
|
105
127
|
If you want to quickly generate a reply or a forward to message
|
106
128
|
|
129
|
+
```ruby
|
107
130
|
# this will handle everything for you, keeping the subject the thread etc as it would happen in Gmail
|
108
131
|
# reply only to the sender of Message m.
|
109
132
|
m.reply_sender_with Gmail::Message.new(body: "some reply text")
|
@@ -111,14 +134,17 @@ If you want to quickly generate a reply or a forward to message
|
|
111
134
|
m.reply_all_with Gmail::Message.new(body: "some reply text")
|
112
135
|
# forward
|
113
136
|
m.forward_with Gmail::Message.new(body: "some forward text", to: "address@toforward.com")
|
137
|
+
```
|
114
138
|
|
115
139
|
Other stuffs that you can do with Message object
|
116
140
|
|
141
|
+
```ruby
|
117
142
|
m.detailed #if for any reason Google did send us the full detail of on email object
|
118
143
|
m.thread #to get the associated Thread
|
119
144
|
m.inbox? #to know if email is in inbox
|
120
145
|
m.sent? #to know if email is a sent email
|
121
146
|
m.unread? #to know if email is unread
|
147
|
+
```
|
122
148
|
|
123
149
|
Those are basics helpers feel free to add more if you want (ex: starred?, important?, etc)
|
124
150
|
|
@@ -126,73 +152,101 @@ Those are basics helpers feel free to add more if you want (ex: starred?, import
|
|
126
152
|
## Thread
|
127
153
|
|
128
154
|
Get a thread
|
155
|
+
|
156
|
+
```ruby
|
129
157
|
one_thread = Gmail::Thread.get(thread_id)
|
158
|
+
```
|
159
|
+
|
130
160
|
or
|
161
|
+
|
162
|
+
```ruby
|
131
163
|
one_thread = one_message.thread
|
164
|
+
```
|
132
165
|
|
133
166
|
Filter messages in Thread
|
134
167
|
|
168
|
+
```ruby
|
135
169
|
one_thread.unread_messages
|
136
170
|
one_thread.sent_messages
|
171
|
+
```
|
137
172
|
|
138
173
|
Expand messages in Thread
|
139
174
|
|
175
|
+
```ruby
|
140
176
|
one_thread.detailed #this will return a thread object but with all messages detailed
|
141
177
|
one_thread.messages #this will return an array of message objects
|
178
|
+
```
|
142
179
|
|
143
180
|
## Draft
|
144
181
|
|
145
182
|
As we explained in Message, you create a draft with
|
146
183
|
|
184
|
+
```ruby
|
147
185
|
d = some_message.create_draft
|
186
|
+
```
|
148
187
|
|
149
188
|
Modify it with
|
150
189
|
|
190
|
+
```ruby
|
151
191
|
d.message.subject = "some different subject than before"
|
152
192
|
d.save
|
193
|
+
```
|
153
194
|
|
154
195
|
send it with
|
155
196
|
|
197
|
+
```ruby
|
156
198
|
d.deliver
|
199
|
+
```
|
157
200
|
|
158
201
|
## Label
|
159
202
|
|
160
203
|
You can create a label like this:
|
161
204
|
|
205
|
+
```ruby
|
162
206
|
l = Gmail::Label.new
|
163
207
|
l.name = "different Name"
|
164
208
|
l.messageListVisibility = "hide" #can be 'hide' or 'show'
|
165
209
|
l.labelListVisibility = "labelShowIfUnread" #can be "labelShowIfUnread", "labelShow", "labelHide"
|
166
210
|
l.save
|
211
|
+
```
|
167
212
|
|
168
213
|
You can modify a label like this:
|
169
214
|
|
215
|
+
```ruby
|
170
216
|
l = Gmail::Label.get("labelId")
|
171
217
|
l.name = "different Name"
|
172
218
|
l.messageListVisibility = "hide"
|
173
219
|
l.labelListVisibility = "labelShowIfUnread"
|
174
220
|
l.save
|
221
|
+
```
|
175
222
|
|
176
223
|
You can use Labels to directly access box information
|
177
224
|
|
225
|
+
```ruby
|
178
226
|
l.detailed #will display number of messages and number of threads if you don't see it
|
227
|
+
```
|
179
228
|
|
180
229
|
For system labels like inbox, sent, trash, important, starred, draft, spam, unread, category_updates, category_promotions, category_social, category_personal, category_forums
|
181
230
|
|
231
|
+
```ruby
|
182
232
|
l = Gmail::Label.inbox
|
233
|
+
```
|
183
234
|
|
184
235
|
Access threads and messages from labels
|
185
236
|
|
237
|
+
```ruby
|
186
238
|
l.threads
|
187
239
|
l.messages
|
188
240
|
|
189
241
|
l.unread_threads
|
190
242
|
l.unread_messages
|
243
|
+
```
|
191
244
|
|
192
245
|
Access threads, drafts and messages with labels
|
193
246
|
|
247
|
+
```ruby
|
194
248
|
Gmail::Message.all(labelIds: ["UNREAD", "INBOX"])
|
195
|
-
|
249
|
+
```
|
196
250
|
|
197
251
|
## License
|
198
252
|
|
data/Rakefile
CHANGED
@@ -23,13 +23,10 @@ end
|
|
23
23
|
|
24
24
|
Bundler::GemHelper.install_tasks
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
rescue LoadError
|
30
|
-
task :spec do
|
31
|
-
abort 'Run `gem install rspec` to install RSpec'
|
32
|
-
end
|
33
|
-
end
|
26
|
+
require 'rake/testtask'
|
27
|
+
|
28
|
+
task :default => [:test]
|
34
29
|
|
35
|
-
|
30
|
+
Rake::TestTask.new do |t|
|
31
|
+
t.pattern = './test/**/*_test.rb'
|
32
|
+
end
|
data/TODO.md
CHANGED
data/account.yml.example
ADDED
data/gmail.gemspec
CHANGED
@@ -24,8 +24,9 @@ Gem::Specification.new do |s|
|
|
24
24
|
|
25
25
|
# development dependencies
|
26
26
|
s.add_development_dependency "rake"
|
27
|
-
s.add_development_dependency "
|
28
|
-
s.add_development_dependency
|
27
|
+
s.add_development_dependency "test-unit"
|
28
|
+
s.add_development_dependency('mocha', '~> 0.13.2')
|
29
|
+
s.add_development_dependency('shoulda', '~> 3.4.0')
|
29
30
|
s.add_development_dependency "gem-release"
|
30
31
|
|
31
32
|
s.files = `git ls-files`.split("\n")
|
data/lib/gmail.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
require 'mail'
|
2
|
-
require 'date'
|
3
|
-
require 'time'
|
4
2
|
require 'hashie'
|
5
3
|
require 'hooks'
|
6
4
|
require 'google/api_client'
|
@@ -25,16 +23,24 @@ require 'gmail/label'
|
|
25
23
|
|
26
24
|
|
27
25
|
module Gmail
|
28
|
-
begin
|
29
|
-
@client_id ||= YAML.load_file("env.yml")["GOOGLE_CLIENT_ID"]
|
30
|
-
@client_secret ||= YAML.load_file("env.yml")["GOOGLE_CLIENT_SECRET"]
|
31
|
-
@refresh_token ||= YAML.load_file("env.yml")["GOOGLE_REFRESH_TOKEN"]
|
32
|
-
rescue
|
33
26
|
|
27
|
+
class << self
|
28
|
+
attr_accessor :client_id, :client_secret, :refresh_token, :client, :service, :application_name, :application_version
|
29
|
+
def new hash
|
30
|
+
[:client_id, :client_secret, :refresh_token, :application_name, :application_version].each do |accessor|
|
31
|
+
Gmail.send("#{accessor}=", hash[accessor.to_s])
|
32
|
+
end
|
33
|
+
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
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
|
+
|
38
44
|
end
|
39
45
|
|
40
46
|
def self.request(method, params={}, body={})
|
@@ -74,23 +80,23 @@ module Gmail
|
|
74
80
|
end
|
75
81
|
|
76
82
|
@client = Google::APIClient.new(
|
77
|
-
application_name:
|
78
|
-
application_version:
|
83
|
+
application_name: @application_name,
|
84
|
+
application_version: @application_version
|
79
85
|
)
|
80
86
|
@client.authorization.client_id = client_id
|
81
87
|
@client.authorization.client_secret = client_secret
|
82
88
|
@client.authorization.refresh_token = refresh_token
|
83
89
|
@client.authorization.grant_type = 'refresh_token'
|
84
90
|
@client.authorization.fetch_access_token!
|
91
|
+
@client.auto_refresh_token = true
|
85
92
|
|
86
|
-
|
93
|
+
#@service = @client.discovered_api('gmail', 'v1')
|
87
94
|
|
88
95
|
end
|
89
96
|
|
90
97
|
def self.parse(response)
|
91
98
|
begin
|
92
|
-
|
93
|
-
# some library out there that makes symbolize_names not work.
|
99
|
+
|
94
100
|
if response.body.empty?
|
95
101
|
return response.body
|
96
102
|
else
|
data/lib/gmail/api_resource.rb
CHANGED
data/lib/gmail/base/delete.rb
CHANGED
@@ -4,7 +4,9 @@ module Gmail
|
|
4
4
|
def delete(opts={})
|
5
5
|
response = Gmail.request(self.class.base_method.send("delete"),{id: id})
|
6
6
|
if response == ""
|
7
|
-
|
7
|
+
true
|
8
|
+
else
|
9
|
+
false
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
@@ -12,7 +14,9 @@ module Gmail
|
|
12
14
|
def delete(id, opts={})
|
13
15
|
response = Gmail.request(base_method.send("delete"),{id: id})
|
14
16
|
if response == ""
|
15
|
-
|
17
|
+
true
|
18
|
+
else
|
19
|
+
false
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
data/lib/gmail/base/list.rb
CHANGED
@@ -29,15 +29,19 @@ module Gmail
|
|
29
29
|
query = ""
|
30
30
|
[:from, :to, :subject].each do |prop|
|
31
31
|
query += "#{prop.to_s}:(#{q[prop].downcase}) " unless q[prop].nil?
|
32
|
+
q.delete(prop)
|
32
33
|
end
|
33
34
|
[:in, :before, :after].each do |prop|
|
34
35
|
query += "#{prop.to_s}:#{q[prop]} " unless q[prop].nil?
|
36
|
+
q.delete(prop)
|
35
37
|
end
|
36
38
|
|
37
39
|
query += "#{q[:has_words]} " unless q[:has_words].nil?
|
38
40
|
query += "-{#{q[:has_not_words]}}" unless q[:has_not_words].nil?
|
39
|
-
|
40
|
-
|
41
|
+
q.delete(:has_words)
|
42
|
+
q.delete(:has_not_words)
|
43
|
+
|
44
|
+
all(q.merge({q: query}))
|
41
45
|
end
|
42
46
|
end
|
43
47
|
end
|