gmail-api-ruby 0.0.1
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 +7 -0
- data/.gitignore +34 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +218 -0
- data/Rakefile +35 -0
- data/TODO.md +4 -0
- data/gmail.gemspec +35 -0
- data/lib/gmail.rb +112 -0
- data/lib/gmail/api_resource.rb +13 -0
- data/lib/gmail/base/create.rb +16 -0
- data/lib/gmail/base/delete.rb +27 -0
- data/lib/gmail/base/get.rb +17 -0
- data/lib/gmail/base/list.rb +50 -0
- data/lib/gmail/base/modify.rb +66 -0
- data/lib/gmail/base/trash.rb +33 -0
- data/lib/gmail/base/update.rb +26 -0
- data/lib/gmail/draft.rb +49 -0
- data/lib/gmail/gmail_object.rb +138 -0
- data/lib/gmail/label.rb +52 -0
- data/lib/gmail/message.rb +189 -0
- data/lib/gmail/thread.rb +32 -0
- data/lib/gmail/util.rb +45 -0
- data/lib/gmail/version.rb +3 -0
- metadata +196 -0
data/lib/gmail/label.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module Gmail
|
2
|
+
class Label < APIResource
|
3
|
+
include Gmail::Base::List
|
4
|
+
include Gmail::Base::Create
|
5
|
+
include Gmail::Base::Delete
|
6
|
+
include Gmail::Base::Get
|
7
|
+
include Gmail::Base::Update
|
8
|
+
|
9
|
+
def save
|
10
|
+
update(@values.to_hash)
|
11
|
+
end
|
12
|
+
|
13
|
+
def save!
|
14
|
+
update!(@values.to_hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.boxes
|
18
|
+
@boxes ||= [:inbox, :sent, :trash, :important, :starred, :draft, :spam, :unread, :category_updates, :category_promotions, :category_social, :category_personal, :category_forums ]
|
19
|
+
end
|
20
|
+
|
21
|
+
boxes.each do |method|
|
22
|
+
define_singleton_method method do
|
23
|
+
Gmail::Label.get(method.to_s.upcase)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def messages filters={}
|
28
|
+
filters = {labelIds: [id]}.merge(filters)
|
29
|
+
filters[:labelIds] = filters[:labelIds] | [id]
|
30
|
+
Gmail::Message.all(filters)
|
31
|
+
end
|
32
|
+
|
33
|
+
def unread_messages
|
34
|
+
if messagesUnread == 0
|
35
|
+
[]
|
36
|
+
else
|
37
|
+
Gmail::Message.all({labelIds: [id, "UNREAD"]})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def threads filters={}
|
42
|
+
filters = {labelIds: [id]}.merge(filters)
|
43
|
+
filters[:labelIds] = filters[:labelIds] | [id]
|
44
|
+
Gmail::Thread.all(filters)
|
45
|
+
end
|
46
|
+
|
47
|
+
def unread_threads
|
48
|
+
Gmail::Thread.all({labelIds: [id, "UNREAD"]})
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end # Gmail
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module Gmail
|
2
|
+
class Message < APIResource
|
3
|
+
include Gmail::Base::List
|
4
|
+
include Gmail::Base::Delete
|
5
|
+
include Gmail::Base::Get
|
6
|
+
include Gmail::Base::Modify
|
7
|
+
include Gmail::Base::Trash
|
8
|
+
|
9
|
+
after_initialize :set_basics
|
10
|
+
|
11
|
+
def thread
|
12
|
+
Gmail::Thread.get(threadId)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_draft
|
16
|
+
Gmail::Draft.create(message: msg_parameters)
|
17
|
+
end
|
18
|
+
|
19
|
+
def deliver!
|
20
|
+
response = Gmail.request(self.class.base_method.to_h['gmail.users.messages.send'],{}, msg_parameters)
|
21
|
+
@values = Gmail::Message.get(response[:id]).values
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def deliver
|
26
|
+
response = Gmail.request(self.class.base_method.to_h['gmail.users.messages.send'],{}, msg_parameters)
|
27
|
+
Gmail::Message.get(response[:id])
|
28
|
+
end
|
29
|
+
|
30
|
+
def reply_all_with msg
|
31
|
+
msg = set_headers_for_reply msg
|
32
|
+
msg = quote_in msg
|
33
|
+
msg.deliver
|
34
|
+
end
|
35
|
+
|
36
|
+
def reply_sender_with msg
|
37
|
+
msg = set_headers_for_reply msg
|
38
|
+
msg = quote_in msg
|
39
|
+
msg.cc = nil
|
40
|
+
msg.deliver
|
41
|
+
end
|
42
|
+
|
43
|
+
def forward_with msg
|
44
|
+
# save headers that need to be override by users compared to a classic reply
|
45
|
+
x_cc = msg.cc
|
46
|
+
x_to = msg.to
|
47
|
+
x_bcc = msg.bcc
|
48
|
+
x_subject = msg.subject || subject #if user doesn't override keep classic behavior
|
49
|
+
# set headers as for reply
|
50
|
+
msg = set_headers_for_reply msg
|
51
|
+
# quote message
|
52
|
+
msg = quote_in msg
|
53
|
+
# reset saved overridden headers
|
54
|
+
msg.cc = x_cc
|
55
|
+
msg.to = x_to
|
56
|
+
msg.bcc = x_bcc
|
57
|
+
msg.subject = x_subject
|
58
|
+
#send message
|
59
|
+
msg.deliver
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def thread_id
|
64
|
+
threadId
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def unread?
|
69
|
+
labelIds.include?("UNREAD")
|
70
|
+
end
|
71
|
+
|
72
|
+
def sent?
|
73
|
+
labelIds.include?("SENT")
|
74
|
+
end
|
75
|
+
|
76
|
+
def inbox?
|
77
|
+
labelIds.include?("INBOX")
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
def raw # is not in private because the method is used in Draft
|
83
|
+
if super #check if raw is set to allow fully custom message to be sent
|
84
|
+
super
|
85
|
+
else
|
86
|
+
s = self
|
87
|
+
msg = Mail.new
|
88
|
+
msg.subject = subject
|
89
|
+
if body
|
90
|
+
msg.body = body
|
91
|
+
end
|
92
|
+
msg.from = from
|
93
|
+
msg.to = to
|
94
|
+
msg.cc = cc
|
95
|
+
msg.header['X-Bcc'] = bcc unless bcc.nil?#because Mail gem doesn't allow bcc headers...
|
96
|
+
msg.header['In-Reply-To'] = in_reply_to unless in_reply_to.nil?
|
97
|
+
msg.header['References'] = references unless references.nil?
|
98
|
+
if text
|
99
|
+
msg.text_part = Mail::Part.new do |p|
|
100
|
+
p.body s.text
|
101
|
+
end
|
102
|
+
end
|
103
|
+
if html
|
104
|
+
msg.html_part = Mail::Part.new do |p|
|
105
|
+
content_type 'text/html; charset=UTF-8'
|
106
|
+
p.body s.html
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
Base64.urlsafe_encode64 msg.to_s.sub("X-Bcc", "Bcc") #because Mail gem doesn't allow bcc headers...
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def msg_parameters
|
117
|
+
msg = {raw: raw}
|
118
|
+
if threadId
|
119
|
+
msg[:threadId] = threadId
|
120
|
+
end
|
121
|
+
if labelIds
|
122
|
+
msg[:labelIds] = labelIds
|
123
|
+
end
|
124
|
+
msg
|
125
|
+
end
|
126
|
+
|
127
|
+
def set_headers_for_reply msg
|
128
|
+
to_ar = []
|
129
|
+
if delivered_to
|
130
|
+
to_ar = to.split(",")
|
131
|
+
result = to_ar.grep(Regexp.new delivered_to)
|
132
|
+
if result
|
133
|
+
to_ar.delete(result)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
msg.subject = subject
|
138
|
+
msg.to = from
|
139
|
+
if cc.nil?
|
140
|
+
msg.cc = to_ar.join(", ")
|
141
|
+
else
|
142
|
+
msg.cc = to_ar.join(", ")+", "+ cc
|
143
|
+
end
|
144
|
+
msg.bcc = nil
|
145
|
+
msg.threadId = thread_id
|
146
|
+
msg.references = (references || "") + " " + message_id
|
147
|
+
msg.in_reply_to = (in_reply_to || "") + " " + message_id
|
148
|
+
msg
|
149
|
+
end
|
150
|
+
|
151
|
+
def quote_in reply_msg
|
152
|
+
text_to_append = "\n\n#{date} #{from}:\n\n>" + (body || text).gsub("\n", "\n>") unless body.nil? && text.nil?
|
153
|
+
html_to_append = "\r\n<br><br><div class=\"gmail_quote\"> #{date} #{CGI.escapeHTML(from)}:<br><blockquote class=\"gmail_quote\" style=\"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex\">" + html + "</blockquote></div><br>" unless html.nil?
|
154
|
+
reply_msg.html = "<div>" + reply_msg.html + "</div>" + html_to_append unless reply_msg.html.nil?
|
155
|
+
reply_msg.text = reply_msg.text + text_to_append unless reply_msg.text.nil?
|
156
|
+
reply_msg.body = reply_msg.body + text_to_append unless reply_msg.body.nil?
|
157
|
+
reply_msg
|
158
|
+
end
|
159
|
+
|
160
|
+
def urlsafe_decode64 code
|
161
|
+
Base64.urlsafe_decode64(code).force_encoding('UTF-8').encode
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
def set_basics
|
166
|
+
if @values.payload
|
167
|
+
["From", "To", "Cc", "Subject", "Bcc", "Date", "Message-ID", "References", "In-Reply-To", "Delivered-To"].each do |n|
|
168
|
+
if payload_n = @values.payload.headers.select{|h| h.name.downcase == n.downcase}.first
|
169
|
+
@values.send(n.downcase.tr("-", "_") + "=", payload_n.value)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
if payload.parts
|
174
|
+
text_part=@values.payload.parts.select{|h| h.mimeType=="text/plain"}.first
|
175
|
+
if text_part
|
176
|
+
@values.text = urlsafe_decode64(text_part.body.data)
|
177
|
+
end
|
178
|
+
html_part=@values.payload.parts.select{|h| h.mimeType=="text/html"}.first
|
179
|
+
if html_part
|
180
|
+
@values.html = urlsafe_decode64(html_part.body.data)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
if payload.body.data
|
184
|
+
@values.body = urlsafe_decode64(@values.payload.body.data)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
data/lib/gmail/thread.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Gmail
|
2
|
+
class Thread < APIResource
|
3
|
+
include Gmail::Base::List
|
4
|
+
include Gmail::Base::Create
|
5
|
+
include Gmail::Base::Delete
|
6
|
+
include Gmail::Base::Get
|
7
|
+
include Gmail::Base::Modify
|
8
|
+
include Gmail::Base::Trash
|
9
|
+
|
10
|
+
def messages
|
11
|
+
|
12
|
+
msgs = to_hash["messages"] || detailed.messages
|
13
|
+
|
14
|
+
Util.convert_to_gmail_object(msgs, key="message")
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def unread_messages
|
19
|
+
|
20
|
+
messages.select{|m| m.unread?}
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def sent_messages
|
26
|
+
|
27
|
+
messages.select{|m| m.sent?}
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
data/lib/gmail/util.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Gmail
|
2
|
+
module Util
|
3
|
+
|
4
|
+
def self.object_classes
|
5
|
+
@object_classes ||= {
|
6
|
+
# data structures
|
7
|
+
|
8
|
+
# business objects
|
9
|
+
'draft' => Draft,
|
10
|
+
'label' => Label,
|
11
|
+
'message' => Message,
|
12
|
+
'thread' => Thread
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.convert_to_gmail_object(resp, key=nil)
|
17
|
+
case resp
|
18
|
+
when Array
|
19
|
+
resp.map { |i| convert_to_gmail_object(i, key) }
|
20
|
+
when Hash
|
21
|
+
# Try converting to a known object class. If none available, fall back to generic StripeObject
|
22
|
+
object_classes.fetch(key , GmailObject).new(resp)
|
23
|
+
else
|
24
|
+
resp
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def self.symbolize_names(object)
|
30
|
+
case object
|
31
|
+
when Hash
|
32
|
+
new_hash = {}
|
33
|
+
object.each do |key, value|
|
34
|
+
key = (key.to_sym rescue key) || key
|
35
|
+
new_hash[key] = symbolize_names(value)
|
36
|
+
end
|
37
|
+
new_hash
|
38
|
+
when Array
|
39
|
+
object.map { |value| symbolize_names(value) }
|
40
|
+
else
|
41
|
+
object
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gmail-api-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Julien Hobeika
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mime
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mail
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.2.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.2.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: google-api-client
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: hooks
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: hashie
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: mocha
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.9'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.9'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: gem-release
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: "A Rubyesque interface to Gmail, with all the tools you will need.\n
|
140
|
+
\ Search, read and send multipart emails; archive, mark as read/unread,\n delete
|
141
|
+
emails; and manage labels.\n "
|
142
|
+
email:
|
143
|
+
executables: []
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- ".gitignore"
|
148
|
+
- ".rspec"
|
149
|
+
- CHANGELOG.md
|
150
|
+
- Gemfile
|
151
|
+
- LICENSE
|
152
|
+
- README.md
|
153
|
+
- Rakefile
|
154
|
+
- TODO.md
|
155
|
+
- gmail.gemspec
|
156
|
+
- lib/gmail.rb
|
157
|
+
- lib/gmail/api_resource.rb
|
158
|
+
- lib/gmail/base/create.rb
|
159
|
+
- lib/gmail/base/delete.rb
|
160
|
+
- lib/gmail/base/get.rb
|
161
|
+
- lib/gmail/base/list.rb
|
162
|
+
- lib/gmail/base/modify.rb
|
163
|
+
- lib/gmail/base/trash.rb
|
164
|
+
- lib/gmail/base/update.rb
|
165
|
+
- lib/gmail/draft.rb
|
166
|
+
- lib/gmail/gmail_object.rb
|
167
|
+
- lib/gmail/label.rb
|
168
|
+
- lib/gmail/message.rb
|
169
|
+
- lib/gmail/thread.rb
|
170
|
+
- lib/gmail/util.rb
|
171
|
+
- lib/gmail/version.rb
|
172
|
+
homepage: http://github.com/jhk753/gmail-ruby-api
|
173
|
+
licenses: []
|
174
|
+
metadata: {}
|
175
|
+
post_install_message:
|
176
|
+
rdoc_options: []
|
177
|
+
require_paths:
|
178
|
+
- lib
|
179
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ">="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - ">="
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
requirements: []
|
190
|
+
rubyforge_project:
|
191
|
+
rubygems_version: 2.4.5
|
192
|
+
signing_key:
|
193
|
+
specification_version: 4
|
194
|
+
summary: A Rubyesque interface to Gmail API (NO IMAP, NO SMTP), with all the tools
|
195
|
+
you will need.
|
196
|
+
test_files: []
|