ruby_outlook 0.1.0

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.
@@ -0,0 +1,17 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+
4
+ # Custom for Visual Studio
5
+ *.cs diff=csharp
6
+
7
+ # Standard to msysgit
8
+ *.doc diff=astextplain
9
+ *.DOC diff=astextplain
10
+ *.docx diff=astextplain
11
+ *.DOCX diff=astextplain
12
+ *.dot diff=astextplain
13
+ *.DOT diff=astextplain
14
+ *.pdf diff=astextplain
15
+ *.PDF diff=astextplain
16
+ *.rtf diff=astextplain
17
+ *.RTF diff=astextplain
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ruby_outlook.gemspec
4
+ gemspec
@@ -0,0 +1,25 @@
1
+ ruby-outlook https://github.com/jasonjoh/ruby-outlook
2
+
3
+ Copyright (c) Microsoft Corporation
4
+ All rights reserved.
5
+
6
+ MIT License:
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ ""Software""), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,121 @@
1
+ # RubyOutlook
2
+
3
+ The RubyOutlook gem is a light-weight implementation of the Office 365 [Mail](https://msdn.microsoft.com/office/office365/APi/mail-rest-operations), [Calendar](https://msdn.microsoft.com/office/office365/APi/calendar-rest-operations), and [Contacts](https://msdn.microsoft.com/office/office365/APi/contacts-rest-operations) REST APIs. It provides basic CRUD functionality for all three APIs, along with the ability to extend functionality by making any arbitrary API call.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'ruby_outlook'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install ruby_outlook
20
+
21
+ ## Usage
22
+
23
+ ### Create the client
24
+
25
+ All functionality is accessed via the `Client` class. Create a new instance of the class to use it:
26
+
27
+ ```ruby
28
+ require 'ruby_outlook'
29
+ outlook_client = RubyOutlook::Client.new
30
+ ```
31
+
32
+ In addition, you can set the `enable_fiddler` property on the `Client` to true if you want to capture Fiddler traces. Setting this property to true sets the proxy for all traffic to `http://127.0.0.1:8888` (the default Fiddler proxy value), and turns off SSL verification. Note that if you set this property to true and do not have Fiddler running, all requests will fail.
33
+
34
+ ### Using a built-in function
35
+
36
+ All of the built-in functions have a required `token` parameter and an optional `user` parameter. The `token` parameter is the OAuth2 access token required for authentication. The `user` parameter is an email address. If passed, the library will make the call to that user's mailbox using the `/Users/user@domain.com/` URL. If omitted, the library will make the call using the `'/Me'` URL.
37
+
38
+ Other parameters are specific to the call being made. For example, here's how to call `get_contacts`:
39
+
40
+ ```ruby
41
+ # A valid access token retrieved via OAuth2
42
+ token = 'eyJ0eXAiOiJKV1QiLCJhbGciO...'
43
+ # Maximum 30 results per page.
44
+ view_size = 30
45
+ # Set the page from the query parameter.
46
+ page = 1
47
+ # Only retrieve display name.
48
+ fields = [
49
+ "DisplayName"
50
+ ]
51
+ # Sort by display name
52
+ sort = { :sort_field => 'DisplayName', :sort_order => 'ASC' }
53
+
54
+ contacts = outlook_client.get_contacts token,
55
+ view_size, page, fields, sort
56
+ ```
57
+
58
+ ### Extending functionality
59
+
60
+ All of the built-in functions wrap the `make_api_call` function. If there is not a built-in function that suits your needs, you can use the `make_api_call` function to implement any API call you want.
61
+
62
+ ```ruby
63
+ # method (string): The HTTP method to use for the API call.
64
+ # Must be 'GET', 'POST', 'PATCH', or 'DELETE'
65
+ # url (string): The URL to use for the API call. Must not contain
66
+ # the host. For example: '/api/v1.0/me/messages'
67
+ # token (string): access token
68
+ # params (hash) a Ruby hash containing any query parameters needed for the API call
69
+ # payload (hash): a JSON hash representing the API call's payload. Only used
70
+ # for POST or PATCH.
71
+ def make_api_call(method, url, token, params = nil, payload = nil)
72
+ ```
73
+
74
+ As an example, here's how the library implements `get_contacts`:
75
+
76
+ ```ruby
77
+ # token (string): access token
78
+ # view_size (int): maximum number of results
79
+ # page (int): What page to fetch (multiple of view size)
80
+ # fields (array): An array of field names to include in results
81
+ # sort (hash): { sort_on => field_to_sort_on, sort_order => 'ASC' | 'DESC' }
82
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
83
+ def get_contacts(token, view_size, page, fields = nil, sort = nil, user = nil)
84
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Contacts"
85
+ request_params = {
86
+ '$top' => view_size,
87
+ '$skip' => (page - 1) * view_size
88
+ }
89
+
90
+ if not fields.nil?
91
+ request_params['$select'] = fields.join(',')
92
+ end
93
+
94
+ if not sort.nil?
95
+ request_params['$orderby'] = sort[:sort_field] + " " + sort[:sort_order]
96
+ end
97
+
98
+ get_contacts_response = make_api_call "GET", request_url, token, request_params
99
+
100
+ return JSON.parse(get_contacts_response)
101
+ end
102
+ ```
103
+
104
+ Follow the same pattern to implement your own calls.
105
+
106
+ ## Contributing
107
+
108
+ 1. Fork it ( https://github.com/jasonjoh/ruby_outlook/fork )a
109
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
110
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
111
+ 4. Push to the branch (`git push origin my-new-feature`)
112
+ 5. Create a new Pull Request
113
+
114
+ ## Copyright ##
115
+
116
+ Copyright (c) Microsoft. All rights reserved.
117
+
118
+ ----------
119
+ Connect with me on Twitter [@JasonJohMSFT](https://twitter.com/JasonJohMSFT)
120
+
121
+ Follow the [Exchange Dev Blog](http://blogs.msdn.com/b/exchangedev/)
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ruby_outlook"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,414 @@
1
+ require "ruby_outlook/version"
2
+ require "faraday"
3
+ require "uuidtools"
4
+ require "json"
5
+
6
+ module RubyOutlook
7
+
8
+ class Client
9
+ # User agent
10
+ attr_reader :user_agent
11
+ # The server to make API calls to.
12
+ # Always "https://outlook.office365.com"
13
+ attr_writer :api_host
14
+ attr_writer :enable_fiddler
15
+
16
+ # method (string): The HTTP method to use for the API call.
17
+ # Must be 'GET', 'POST', 'PATCH', or 'DELETE'
18
+ # url (string): The URL to use for the API call. Must not contain
19
+ # the host. For example: '/api/v1.0/me/messages'
20
+ # token (string): access token
21
+ # params (hash) a Ruby hash containing any query parameters needed for the API call
22
+ # payload (hash): a JSON hash representing the API call's payload. Only used
23
+ # for POST or PATCH.
24
+ def make_api_call(method, url, token, params = nil, payload = nil)
25
+
26
+ conn_params = {
27
+ :url => 'https://outlook.office365.com'
28
+ }
29
+
30
+ if @enable_fiddler
31
+ conn_params[:proxy] = 'http://127.0.0.1:8888'
32
+ conn_params[:ssl] = {:verify => false}
33
+ end
34
+
35
+ conn = Faraday.new(conn_params) do |faraday|
36
+ # Uses the default Net::HTTP adapter
37
+ faraday.adapter Faraday.default_adapter
38
+
39
+ end
40
+
41
+ conn.headers = {
42
+ 'Authorization' => "Bearer #{token}",
43
+ 'Accept' => "application/json",
44
+
45
+ # Client instrumentation
46
+ # See https://msdn.microsoft.com/EN-US/library/office/dn720380(v=exchg.150).aspx
47
+ 'User-Agent' => @user_agent,
48
+ 'client-request-id' => UUIDTools::UUID.timestamp_create.to_str,
49
+ 'return-client-request-id' => "true"
50
+ }
51
+
52
+ case method.upcase
53
+ when "GET"
54
+ response = conn.get do |request|
55
+ request.url url, params
56
+ end
57
+ when "POST"
58
+ conn.headers['Content-Type'] = "application/json"
59
+ response = conn.post do |request|
60
+ request.url url, params
61
+ request.body = JSON.dump(payload)
62
+ end
63
+ when "PATCH"
64
+ conn.headers['Content-Type'] = "application/json"
65
+ response = conn.patch do |request|
66
+ request.url url, params
67
+ request.body = JSON.dump(payload)
68
+ end
69
+ when "DELETE"
70
+ response = conn.delete do |request|
71
+ request.url url, params
72
+ end
73
+ end
74
+
75
+ if response.status >= 300
76
+ return JSON.dump({ 'ruby_outlook_error' => response.status})
77
+ end
78
+
79
+ return response.body
80
+ end
81
+
82
+ #----- Begin Contacts API -----#
83
+
84
+ # token (string): access token
85
+ # view_size (int): maximum number of results
86
+ # page (int): What page to fetch (multiple of view size)
87
+ # fields (array): An array of field names to include in results
88
+ # sort (hash): { sort_on => field_to_sort_on, sort_order => 'ASC' | 'DESC' }
89
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
90
+ def get_contacts(token, view_size, page, fields = nil, sort = nil, user = nil)
91
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Contacts"
92
+ request_params = {
93
+ '$top' => view_size,
94
+ '$skip' => (page - 1) * view_size
95
+ }
96
+
97
+ if not fields.nil?
98
+ request_params['$select'] = fields.join(',')
99
+ end
100
+
101
+ if not sort.nil?
102
+ request_params['$orderby'] = sort[:sort_field] + " " + sort[:sort_order]
103
+ end
104
+
105
+ get_contacts_response = make_api_call "GET", request_url, token, request_params
106
+
107
+ return JSON.parse(get_contacts_response)
108
+ end
109
+
110
+ # token (string): access token
111
+ # id (string): The Id of the contact to retrieve
112
+ # fields (array): An array of field names to include in results
113
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
114
+ def get_contact_by_id(token, id, fields = nil, user = nil)
115
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Contacts/" << id
116
+ request_params = nil
117
+
118
+ if not fields.nil?
119
+ request_params = { '$select' => fields.join(',') }
120
+ end
121
+
122
+ get_contact_response = make_api_call "GET", request_url, token, request_params
123
+
124
+ return JSON.parse(get_contact_response)
125
+ end
126
+
127
+ # token (string): access token
128
+ # payload (hash): a JSON hash representing the contact entity
129
+ # folder_id (string): The Id of the contact folder to create the contact in.
130
+ # If nil, contact is created in the default contacts folder.
131
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
132
+ def create_contact(token, payload, folder_id = nil, user = nil)
133
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user))
134
+ if not folder_id.nil?
135
+ request_url << "/ContactFolders/" << folder_id
136
+ end
137
+ request_url << "/Contacts"
138
+
139
+ create_contact_response = make_api_call "POST", request_url, token, nil, payload
140
+
141
+ return JSON.parse(create_contact_response)
142
+ end
143
+
144
+ # token (string): access token
145
+ # payload (hash): a JSON hash representing the updated contact fields
146
+ # id (string): The Id of the contact to update.
147
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
148
+ def update_contact(token, payload, id, user = nil)
149
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Contacts/" << id
150
+
151
+ update_contact_response = make_api_call "PATCH", request_url, token, nil, payload
152
+
153
+ return JSON.parse(update_contact_response)
154
+ end
155
+
156
+ # token (string): access token
157
+ # id (string): The Id of the contact to delete.
158
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
159
+ def delete_contact(token, id, user = nil)
160
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Contacts/" << id
161
+
162
+ delete_response = make_api_call "DELETE", request_url, token
163
+
164
+ if not delete_response.nil? and not delete_response.empty?
165
+ return JSON.parse(delete_response)
166
+ else
167
+ return nil
168
+ end
169
+ end
170
+
171
+ #----- End Contacts API -----#
172
+
173
+ #----- Begin Mail API -----#
174
+
175
+ # token (string): access token
176
+ # view_size (int): maximum number of results
177
+ # page (int): What page to fetch (multiple of view size)
178
+ # fields (array): An array of field names to include in results
179
+ # sort (hash): { sort_on => field_to_sort_on, sort_order => 'ASC' | 'DESC' }
180
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
181
+ def get_messages(token, view_size, page, fields = nil, sort = nil, user = nil)
182
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Messages"
183
+ request_params = {
184
+ '$top' => view_size,
185
+ '$skip' => (page - 1) * view_size
186
+ }
187
+
188
+ if not fields.nil?
189
+ request_params['$select'] = fields.join(',')
190
+ end
191
+
192
+ if not sort.nil?
193
+ request_params['$orderby'] = sort[:sort_field] + " " + sort[:sort_order]
194
+ end
195
+
196
+ get_messages_response = make_api_call "GET", request_url, token, request_params
197
+
198
+ return JSON.parse(get_messages_response)
199
+ end
200
+
201
+ # token (string): access token
202
+ # id (string): The Id of the message to retrieve
203
+ # fields (array): An array of field names to include in results
204
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
205
+ def get_message_by_id(token, id, fields = nil, user = nil)
206
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Messages/" << id
207
+ request_params = nil
208
+
209
+ if not fields.nil?
210
+ request_params = { '$select' => fields.join(',') }
211
+ end
212
+
213
+ get_message_response = make_api_call "GET", request_url, token, request_params
214
+
215
+ return JSON.parse(get_message_response)
216
+ end
217
+
218
+ # token (string): access token
219
+ # payload (hash): a JSON hash representing the contact entity
220
+ # folder_id (string): The Id of the folder to create the message in.
221
+ # If nil, message is created in the default drafts folder.
222
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
223
+ def create_message(token, payload, folder_id = nil, user = nil)
224
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user))
225
+ if not folder_id.nil?
226
+ request_url << "/Folders/" << folder_id
227
+ end
228
+ request_url << "/Messages"
229
+
230
+ create_message_response = make_api_call "POST", request_url, token, nil, payload
231
+
232
+ return JSON.parse(create_message_response)
233
+ end
234
+
235
+ # token (string): access token
236
+ # payload (hash): a JSON hash representing the updated message fields
237
+ # id (string): The Id of the message to update.
238
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
239
+ def update_message(token, payload, id, user = nil)
240
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Messages/" << id
241
+
242
+ update_message_response = make_api_call "PATCH", request_url, token, nil, payload
243
+
244
+ return JSON.parse(update_message_response)
245
+ end
246
+
247
+ # token (string): access token
248
+ # id (string): The Id of the message to delete.
249
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
250
+ def delete_message(token, id, user = nil)
251
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Messages/" << id
252
+
253
+ delete_response = make_api_call "DELETE", request_url, token
254
+
255
+ if not delete_response.nil? and not delete_response.empty?
256
+ return JSON.parse(delete_response)
257
+ else
258
+ return nil
259
+ end
260
+ end
261
+
262
+ # token (string): access token
263
+ # payload (hash): a JSON hash representing the message to send
264
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
265
+ def send_message(token, payload, save_to_sentitems = true, user = nil)
266
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/SendMail"
267
+
268
+ # Wrap message in the sendmail JSON structure
269
+ send_mail_json = {
270
+ 'Message' => payload,
271
+ 'SaveToSentItems' => save_to_sentitems
272
+ }
273
+
274
+ send_response = make_api_call "POST", request_url, token, nil, send_mail_json
275
+
276
+ if not send_response.nil? and not send_response.empty?
277
+ return JSON.parse(send_response)
278
+ else
279
+ return nil
280
+ end
281
+ end
282
+
283
+ #----- End Mail API -----#
284
+
285
+ #----- Begin Calendar API -----#
286
+
287
+ # token (string): access token
288
+ # view_size (int): maximum number of results
289
+ # page (int): What page to fetch (multiple of view size)
290
+ # fields (array): An array of field names to include in results
291
+ # sort (hash): { sort_on => field_to_sort_on, sort_order => 'ASC' | 'DESC' }
292
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
293
+ def get_events(token, view_size, page, fields = nil, sort = nil, user = nil)
294
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Events"
295
+ request_params = {
296
+ '$top' => view_size,
297
+ '$skip' => (page - 1) * view_size
298
+ }
299
+
300
+ if not fields.nil?
301
+ request_params['$select'] = fields.join(',')
302
+ end
303
+
304
+ if not sort.nil?
305
+ request_params['$orderby'] = sort[:sort_field] + " " + sort[:sort_order]
306
+ end
307
+
308
+ get_events_response = make_api_call "GET", request_url, token, request_params
309
+
310
+ return JSON.parse(get_events_response)
311
+ end
312
+
313
+ # token (string): access token
314
+ # id (string): The Id of the event to retrieve
315
+ # fields (array): An array of field names to include in results
316
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
317
+ def get_event_by_id(token, id, fields = nil, user = nil)
318
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Events/" << id
319
+ request_params = nil
320
+
321
+ if not fields.nil?
322
+ request_params = { '$select' => fields.join(',') }
323
+ end
324
+
325
+ get_event_response = make_api_call "GET", request_url, token, request_params
326
+
327
+ return JSON.parse(get_event_response)
328
+ end
329
+
330
+ # token (string): access token
331
+ # window_start (DateTime): The earliest time (UTC) to include in the view
332
+ # window_end (DateTime): The latest time (UTC) to include in the view
333
+ # id (string): The Id of the calendar to view
334
+ # If nil, the default calendar is used
335
+ # fields (array): An array of field names to include in results
336
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
337
+ def get_calendar_view(token, window_start, window_end, id = nil, fields = nil, user = nil)
338
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user))
339
+
340
+ if not id.nil?
341
+ request_url << "/Calendars/" << id
342
+ end
343
+
344
+ request_url << "/CalendarView"
345
+
346
+ request_params = {
347
+ 'startDateTime' => window_start.strftime('%Y-%m-%dT00:00:00Z'),
348
+ 'endDateTime' => window_end.strftime('%Y-%m-%dT00:00:00Z')
349
+ }
350
+
351
+ if not fields.nil?
352
+ request_params['$select'] = fields.join(',')
353
+ end
354
+
355
+ get_view_response =make_api_call "GET", request_url, token, request_params
356
+
357
+ return JSON.parse(get_view_response)
358
+ end
359
+
360
+ # token (string): access token
361
+ # payload (hash): a JSON hash representing the event entity
362
+ # folder_id (string): The Id of the calendar folder to create the event in.
363
+ # If nil, event is created in the default calendar folder.
364
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
365
+ def create_event(token, payload, folder_id = nil, user = nil)
366
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user))
367
+ if not folder_id.nil?
368
+ request_url << "/Calendars/" << folder_id
369
+ end
370
+ request_url << "/Events"
371
+
372
+ create_event_response = make_api_call "POST", request_url, token, nil, payload
373
+
374
+ return JSON.parse(create_event_response)
375
+ end
376
+
377
+ # token (string): access token
378
+ # payload (hash): a JSON hash representing the updated event fields
379
+ # id (string): The Id of the event to update.
380
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
381
+ def update_event(token, payload, id, user = nil)
382
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Events/" << id
383
+
384
+ update_event_response = make_api_call "PATCH", request_url, token, nil, payload
385
+
386
+ return JSON.parse(update_event_response)
387
+ end
388
+
389
+ # token (string): access token
390
+ # id (string): The Id of the event to delete.
391
+ # user (string): The user to make the call for. If nil, use the 'Me' constant.
392
+ def delete_event(token, id, user = nil)
393
+ request_url = "/api/v1.0/" << (user.nil? ? "Me" : ("users/" << user)) << "/Events/" << id
394
+
395
+ delete_response = make_api_call "DELETE", request_url, token
396
+
397
+ if not delete_response.nil? and not delete_response.empty?
398
+ return JSON.parse(delete_response)
399
+ else
400
+ return nil
401
+ end
402
+ end
403
+
404
+ #----- End Calendar API -----#
405
+
406
+ private
407
+ def initialize
408
+ @user_agent = "RubyOutlookGem/" << RubyOutlook::VERSION
409
+ @api_host = "https://outlook.office365.com"
410
+ @enable_fiddler = false
411
+ super
412
+ end
413
+ end
414
+ end
@@ -0,0 +1,3 @@
1
+ module RubyOutlook
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,270 @@
1
+ require './ruby_outlook'
2
+ require 'json'
3
+
4
+ # TODO: Copy a valid, non-expired access token here.
5
+ access_token = 'eyJ0eXAiOiJKV1QiLCJhbGciO...'
6
+
7
+ def do_contact_api_tests(token)
8
+ # TODO: Copy a valid ID for a contact here
9
+ contact_id = 'AAMkADNhMjcxM2U5LWY2MmItNDRjYy05YzgwLWQwY2FmMTU1MjViOABGAAAAAAC_IsPnAGUWR4fYhDeYtiNFBwCDgDrpyW-uTL4a3VuSIF6OAAAAAAEOAACDgDrpyW-uTL4a3VuSIF6OAAAZHKwnAAA='
10
+
11
+ new_contact_payload = '{
12
+ "GivenName": "Pavel",
13
+ "Surname": "Bansky",
14
+ "EmailAddresses": [
15
+ {
16
+ "Address": "pavelb@a830edad9050849NDA1.onmicrosoft.com",
17
+ "Name": "Pavel Bansky"
18
+ }
19
+ ],
20
+ "BusinessPhones": [
21
+ "+1 732 555 0102"
22
+ ]
23
+ }'
24
+
25
+ update_contact_payload = '{
26
+ "HomeAddress": {
27
+ "Street": "Some street",
28
+ "City": "Seattle",
29
+ "State": "WA",
30
+ "PostalCode": "98121"
31
+ },
32
+ "Birthday": "1974-07-22"
33
+ }'
34
+
35
+ outlook_client = RubyOutlook::Client.new
36
+
37
+ # Maximum 30 results per page.
38
+ view_size = 30
39
+ # Set the page from the query parameter.
40
+ page = 1
41
+ # Only retrieve display name.
42
+ fields = [
43
+ "DisplayName"
44
+ ]
45
+ # Sort by display name
46
+ sort = { :sort_field => 'DisplayName', :sort_order => 'ASC' }
47
+
48
+ puts 'Testing GET /me/contacts'
49
+ contacts = outlook_client.get_contacts token,
50
+ view_size, page, fields, sort
51
+
52
+ puts contacts
53
+ puts ""
54
+
55
+ puts 'Testing GET /me/contacts/id'
56
+ contact = outlook_client.get_contact_by_id token, contact_id
57
+
58
+ puts contact
59
+ puts ""
60
+
61
+ puts 'Testing POST /me/contacts'
62
+ new_contact_json = JSON.parse(new_contact_payload)
63
+ new_contact = outlook_client.create_contact token, new_contact_json
64
+
65
+ puts new_contact
66
+ puts ""
67
+
68
+ puts 'Testing PATCH /me/contacts/id'
69
+ update_contact_json = JSON.parse(update_contact_payload)
70
+ updated_contact = outlook_client.update_contact token, update_contact_json, new_contact['Id']
71
+
72
+ puts updated_contact
73
+ puts ""
74
+
75
+ puts 'Testing DELETE /me/contacts/id'
76
+ delete_response = outlook_client.delete_contact token, new_contact['Id']
77
+
78
+ puts delete_response.nil? ? "SUCCESS" : delete_response
79
+ puts ""
80
+ end
81
+
82
+ def do_mail_api_tests(token)
83
+ # TODO: Copy a valid ID for a message here
84
+ message_id = 'AAMkADNhMjcxM2U5LWY2MmItNDRjYy05YzgwLWQwY2FmMTU1MjViOABGAAAAAAC_IsPnAGUWR4fYhDeYtiNFBwCDgDrpyW-uTL4a3VuSIF6OAAAAAAEMAACDgDrpyW-uTL4a3VuSIF6OAAAZHKJNAAA='
85
+
86
+ new_message_payload = '{
87
+ "Subject": "Did you see last night\'s game?",
88
+ "Importance": "Low",
89
+ "Body": {
90
+ "ContentType": "HTML",
91
+ "Content": "They were <b>awesome</b>!"
92
+ },
93
+ "ToRecipients": [
94
+ {
95
+ "EmailAddress": {
96
+ "Address": "katiej@a830edad9050849NDA1.onmicrosoft.com"
97
+ }
98
+ }
99
+ ]
100
+ }'
101
+
102
+ update_message_payload = '{
103
+ "Subject": "UPDATED"
104
+ }'
105
+
106
+ send_message_payload = '{
107
+ "Subject": "Meet for lunch?",
108
+ "Body": {
109
+ "ContentType": "Text",
110
+ "Content": "The new cafeteria is open."
111
+ },
112
+ "ToRecipients": [
113
+ {
114
+ "EmailAddress": {
115
+ "Address": "allieb@contoso.com"
116
+ }
117
+ }
118
+ ],
119
+ "Attachments": [
120
+ {
121
+ "@odata.type": "#Microsoft.OutlookServices.FileAttachment",
122
+ "Name": "menu.txt",
123
+ "ContentBytes": "bWFjIGFuZCBjaGVlc2UgdG9kYXk="
124
+ }
125
+ ]
126
+ }'
127
+
128
+ outlook_client = RubyOutlook::Client.new
129
+
130
+ # Maximum 30 results per page.
131
+ view_size = 30
132
+ # Set the page from the query parameter.
133
+ page = 1
134
+ # Only retrieve display name.
135
+ fields = [
136
+ "Subject"
137
+ ]
138
+ # Sort by display name
139
+ sort = { :sort_field => 'Subject', :sort_order => 'ASC' }
140
+
141
+ puts 'Testing GET /me/messages'
142
+ messages = outlook_client.get_messages token,
143
+ view_size, page, fields, sort
144
+
145
+ puts messages
146
+ puts ""
147
+
148
+ puts 'Testing GET /me/messages/id'
149
+ message = outlook_client.get_message_by_id token, message_id
150
+
151
+ puts message
152
+ puts ""
153
+
154
+ puts 'Testing POST /me/messages'
155
+ new_message_json = JSON.parse(new_message_payload)
156
+ new_message = outlook_client.create_message token, new_message_json
157
+
158
+ puts new_message
159
+ puts ""
160
+
161
+ puts 'Testing PATCH /me/messages/id'
162
+ update_message_json = JSON.parse(update_message_payload)
163
+ updated_message = outlook_client.update_message token, update_message_json, new_message['Id']
164
+
165
+ puts updated_message
166
+ puts ""
167
+
168
+ puts 'Testing DELETE /me/messages/id'
169
+ delete_response = outlook_client.delete_message token, new_message['Id']
170
+
171
+ puts delete_response.nil? ? "SUCCESS" : delete_response
172
+ puts ""
173
+
174
+ puts 'Testing POST /me/sendmail'
175
+ send_message_json = JSON.parse(send_message_payload)
176
+ send_response = outlook_client.send_message token, send_message_json
177
+
178
+ puts send_response.nil? ? "SUCCESS" : send_response
179
+ puts ""
180
+ end
181
+
182
+ def do_calendar_api_tests(token)
183
+ # TODO: Copy a valid ID for an event here
184
+ event_id = 'AAMkADNhMjcxM2U5LWY2MmItNDRjYy05YzgwLWQwY2FmMTU1MjViOABGAAAAAAC_IsPnAGUWR4fYhDeYtiNFBwCDgDrpyW-uTL4a3VuSIF6OAAAAAAENAACDgDrpyW-uTL4a3VuSIF6OAAAXZ15oAAA='
185
+
186
+ new_event_payload = '{
187
+ "Subject": "Discuss the Calendar REST API",
188
+ "Body": {
189
+ "ContentType": "HTML",
190
+ "Content": "I think it will meet our requirements!"
191
+ },
192
+ "Start": "2014-07-02T18:00:00Z",
193
+ "End": "2014-07-02T19:00:00Z",
194
+ "Attendees": [
195
+ {
196
+ "EmailAddress": {
197
+ "Address": "janets@a830edad9050849NDA1.onmicrosoft.com",
198
+ "Name": "Janet Schorr"
199
+ },
200
+ "Type": "Required"
201
+ }
202
+ ]
203
+ }'
204
+
205
+ update_event_payload = '{
206
+ "Location": {
207
+ "DisplayName": "Your office"
208
+ }
209
+ }'
210
+
211
+ outlook_client = RubyOutlook::Client.new
212
+
213
+
214
+ puts 'Testing GET /me/CalendarView'
215
+
216
+ start_time = DateTime.parse('2015-03-03T00:00:00Z')
217
+ end_time = DateTime.parse('2015-03-10T00:00:00Z')
218
+ view = outlook_client.get_calendar_view token, start_time, end_time
219
+
220
+ puts view
221
+ puts ""
222
+
223
+ # Maximum 30 results per page.
224
+ view_size = 30
225
+ # Set the page from the query parameter.
226
+ page = 1
227
+ # Only retrieve display name.
228
+ fields = [
229
+ "Subject"
230
+ ]
231
+ # Sort by display name
232
+ sort = { :sort_field => 'Subject', :sort_order => 'ASC' }
233
+
234
+ puts 'Testing GET /me/events'
235
+ events = outlook_client.get_events token,
236
+ view_size, page, fields, sort
237
+
238
+ puts events
239
+ puts ""
240
+
241
+ puts 'Testing GET /me/events/id'
242
+ event = outlook_client.get_event_by_id token, event_id
243
+
244
+ puts event
245
+ puts ""
246
+
247
+ puts 'Testing POST /me/events'
248
+ new_event_json = JSON.parse(new_event_payload)
249
+ new_event = outlook_client.create_event token, new_event_json
250
+
251
+ puts new_event
252
+ puts ""
253
+
254
+ puts 'Testing PATCH /me/events/id'
255
+ update_event_json = JSON.parse(update_event_payload)
256
+ updated_event = outlook_client.update_event token, update_event_json, new_event['Id']
257
+
258
+ puts updated_event
259
+ puts ""
260
+
261
+ puts 'Testing DELETE /me/events/id'
262
+ delete_response = outlook_client.delete_event token, new_event['Id']
263
+
264
+ puts delete_response.nil? ? "SUCCESS" : delete_response
265
+ puts ""
266
+ end
267
+
268
+ do_contact_api_tests access_token
269
+ do_mail_api_tests access_token
270
+ do_calendar_api_tests access_token
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ruby_outlook/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ruby_outlook"
8
+ spec.version = RubyOutlook::VERSION
9
+ spec.authors = ["Jason Johnston"]
10
+ spec.email = ["jasonjoh@microsoft.com"]
11
+
12
+ spec.summary = %q{A ruby gem to invoke the Office 365 REST APIs.}
13
+ spec.description = %q{This ruby gem provides functions for common operations with the Office 365 Mail, Calendar, and Contacts APIs.}
14
+ spec.homepage = "https://github.com/jasonjoh/ruby_outlook"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ if spec.respond_to?(:metadata)
22
+ spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server."
23
+ end
24
+
25
+ spec.add_dependency "faraday"
26
+ spec.add_dependency "uuidtools"
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.8"
29
+ spec.add_development_dependency "rake", "~> 10.0"
30
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_outlook
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jason Johnston
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2015-03-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: uuidtools
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.8'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '10.0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '10.0'
78
+ description: This ruby gem provides functions for common operations with the Office
79
+ 365 Mail, Calendar, and Contacts APIs.
80
+ email:
81
+ - jasonjoh@microsoft.com
82
+ executables: []
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .gitattributes
87
+ - .gitignore
88
+ - .travis.yml
89
+ - Gemfile
90
+ - LICENSE.TXT
91
+ - README.md
92
+ - Rakefile
93
+ - bin/console
94
+ - bin/setup
95
+ - lib/ruby_outlook.rb
96
+ - lib/ruby_outlook/version.rb
97
+ - lib/run-tests.rb
98
+ - ruby_outlook.gemspec
99
+ homepage: https://github.com/jasonjoh/ruby_outlook
100
+ licenses: []
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 1.8.29
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: A ruby gem to invoke the Office 365 REST APIs.
123
+ test_files: []