sfdcews 0.0.1x

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +15 -0
  2. data/Changelog.txt +1004 -0
  3. data/README.md +201 -0
  4. data/TODO +17 -0
  5. data/lib/ews/calendar_accessors.rb +34 -0
  6. data/lib/ews/connection.rb +126 -0
  7. data/lib/ews/connection_helper.rb +35 -0
  8. data/lib/ews/convert_accessors.rb +56 -0
  9. data/lib/ews/errors.rb +56 -0
  10. data/lib/ews/ews_client.rb +101 -0
  11. data/lib/ews/exceptions/exceptions.rb +61 -0
  12. data/lib/ews/folder_accessors.rb +264 -0
  13. data/lib/ews/impersonation.rb +30 -0
  14. data/lib/ews/item_accessors.rb +231 -0
  15. data/lib/ews/mailbox_accessors.rb +92 -0
  16. data/lib/ews/message_accessors.rb +93 -0
  17. data/lib/ews/push_subscription_accessors.rb +33 -0
  18. data/lib/ews/room_accessors.rb +48 -0
  19. data/lib/ews/roomlist_accessors.rb +47 -0
  20. data/lib/ews/soap.rb +64 -0
  21. data/lib/ews/soap/builders/ews_builder.rb +1361 -0
  22. data/lib/ews/soap/ews_response.rb +84 -0
  23. data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
  24. data/lib/ews/soap/ews_soap_free_busy_response.rb +119 -0
  25. data/lib/ews/soap/ews_soap_response.rb +103 -0
  26. data/lib/ews/soap/ews_soap_room_response.rb +53 -0
  27. data/lib/ews/soap/ews_soap_roomlist_response.rb +54 -0
  28. data/lib/ews/soap/exchange_availability.rb +61 -0
  29. data/lib/ews/soap/exchange_data_services.rb +780 -0
  30. data/lib/ews/soap/exchange_notification.rb +146 -0
  31. data/lib/ews/soap/exchange_synchronization.rb +93 -0
  32. data/lib/ews/soap/exchange_time_zones.rb +56 -0
  33. data/lib/ews/soap/exchange_user_configuration.rb +33 -0
  34. data/lib/ews/soap/exchange_web_service.rb +264 -0
  35. data/lib/ews/soap/parsers/ews_parser.rb +43 -0
  36. data/lib/ews/soap/parsers/ews_sax_document.rb +70 -0
  37. data/lib/ews/soap/response_message.rb +80 -0
  38. data/lib/ews/soap/responses/create_attachment_response_message.rb +47 -0
  39. data/lib/ews/soap/responses/create_item_response_message.rb +25 -0
  40. data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
  41. data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
  42. data/lib/ews/soap/responses/send_notification_response_message.rb +59 -0
  43. data/lib/ews/soap/responses/subscribe_response_message.rb +35 -0
  44. data/lib/ews/soap/responses/sync_folder_hierarchy_response_message.rb +36 -0
  45. data/lib/ews/soap/responses/sync_folder_items_response_message.rb +36 -0
  46. data/lib/ews/templates/calendar_item.rb +78 -0
  47. data/lib/ews/templates/forward_item.rb +24 -0
  48. data/lib/ews/templates/message.rb +73 -0
  49. data/lib/ews/templates/reply_to_item.rb +25 -0
  50. data/lib/ews/templates/task.rb +74 -0
  51. data/lib/ews/types.rb +194 -0
  52. data/lib/ews/types/attachment.rb +77 -0
  53. data/lib/ews/types/attendee.rb +27 -0
  54. data/lib/ews/types/calendar_folder.rb +50 -0
  55. data/lib/ews/types/calendar_item.rb +129 -0
  56. data/lib/ews/types/contact.rb +7 -0
  57. data/lib/ews/types/contacts_folder.rb +8 -0
  58. data/lib/ews/types/copied_event.rb +51 -0
  59. data/lib/ews/types/created_event.rb +24 -0
  60. data/lib/ews/types/deleted_event.rb +24 -0
  61. data/lib/ews/types/distribution_list.rb +7 -0
  62. data/lib/ews/types/event.rb +62 -0
  63. data/lib/ews/types/export_items_response_message.rb +52 -0
  64. data/lib/ews/types/file_attachment.rb +65 -0
  65. data/lib/ews/types/folder.rb +60 -0
  66. data/lib/ews/types/free_busy_changed_event.rb +24 -0
  67. data/lib/ews/types/generic_folder.rb +420 -0
  68. data/lib/ews/types/item.rb +442 -0
  69. data/lib/ews/types/item_attachment.rb +84 -0
  70. data/lib/ews/types/item_field_uri_map.rb +224 -0
  71. data/lib/ews/types/mailbox_user.rb +156 -0
  72. data/lib/ews/types/meeting_cancellation.rb +7 -0
  73. data/lib/ews/types/meeting_message.rb +7 -0
  74. data/lib/ews/types/meeting_request.rb +7 -0
  75. data/lib/ews/types/meeting_response.rb +7 -0
  76. data/lib/ews/types/message.rb +7 -0
  77. data/lib/ews/types/modified_event.rb +48 -0
  78. data/lib/ews/types/moved_event.rb +51 -0
  79. data/lib/ews/types/new_mail_event.rb +24 -0
  80. data/lib/ews/types/out_of_office.rb +147 -0
  81. data/lib/ews/types/search_folder.rb +8 -0
  82. data/lib/ews/types/status_event.rb +39 -0
  83. data/lib/ews/types/task.rb +37 -0
  84. data/lib/ews/types/tasks_folder.rb +27 -0
  85. data/lib/viewpoint.rb +109 -0
  86. data/lib/viewpoint/logging.rb +27 -0
  87. data/lib/viewpoint/logging/config.rb +24 -0
  88. data/lib/viewpoint/string_utils.rb +76 -0
  89. metadata +190 -0
@@ -0,0 +1,442 @@
1
+ module Viewpoint::EWS::Types
2
+ module Item
3
+ include Viewpoint::EWS
4
+ include Viewpoint::EWS::Types
5
+ include ItemFieldUriMap
6
+
7
+ def self.included(klass)
8
+ klass.extend ClassMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ def init_simple_item(ews, id, change_key = nil, parent = nil)
13
+ ews_item = {item_id: {attribs: {id: id, change_key: change_key}}}
14
+ self.new ews, ews_item, parent
15
+ end
16
+ end
17
+
18
+ ITEM_KEY_PATHS = {
19
+ item_id: [:item_id, :attribs],
20
+ id: [:item_id, :attribs, :id],
21
+ change_key: [:item_id, :attribs, :change_key],
22
+ subject: [:subject, :text],
23
+ sensitivity: [:sensitivity, :text],
24
+ size: [:size, :text],
25
+ date_time_sent: [:date_time_sent, :text],
26
+ date_time_created: [:date_time_created, :text],
27
+ mime_content: [:mime_content, :text],
28
+ has_attachments?:[:has_attachments, :text],
29
+ is_associated?: [:is_associated, :text],
30
+ is_read?: [:is_read, :text],
31
+ is_draft?: [:is_draft, :text],
32
+ is_submitted?: [:is_submitted, :text],
33
+ conversation_id:[:conversation_id, :attribs, :id],
34
+ categories: [:categories, :elems],
35
+ internet_message_id:[:internet_message_id, :text],
36
+ internet_message_headers:[:internet_message_headers, :elems],
37
+ sender: [:sender, :elems, 0, :mailbox, :elems],
38
+ from: [:from, :elems, 0, :mailbox, :elems],
39
+ to_recipients: [:to_recipients, :elems],
40
+ cc_recipients: [:cc_recipients, :elems],
41
+ attachments: [:attachments, :elems],
42
+ importance: [:importance, :text],
43
+ conversation_index: [:conversation_index, :text],
44
+ conversation_topic: [:conversation_topic, :text],
45
+ body_type: [:body, :attribs, :body_type],
46
+ body: [:body, :text]
47
+ }
48
+
49
+ ITEM_KEY_TYPES = {
50
+ size: ->(str){str.to_i},
51
+ date_time_sent: ->(str){DateTime.parse(str)},
52
+ date_time_created: ->(str){DateTime.parse(str)},
53
+ has_attachments?: ->(str){str.downcase == 'true'},
54
+ is_associated?: ->(str){str.downcase == 'true'},
55
+ is_read?: ->(str){str.downcase == 'true'},
56
+ is_draft?: ->(str){str.downcase == 'true'},
57
+ is_submitted?: ->(str){str.downcase == 'true'},
58
+ categories: ->(obj){obj.collect{|s| s[:string][:text]}},
59
+ internet_message_headers: ->(obj){obj.collect{|h|
60
+ {h[:internet_message_header][:attribs][:header_name] =>
61
+ h[:internet_message_header][:text]} } },
62
+ sender: :build_mailbox_user,
63
+ from: :build_mailbox_user,
64
+ to_recipients: :build_mailbox_users,
65
+ cc_recipients: :build_mailbox_users,
66
+ attachments: :build_attachments,
67
+ }
68
+
69
+ ITEM_KEY_ALIAS = {
70
+ :read? => :is_read?,
71
+ :draft? => :is_draft?,
72
+ :submitted? => :is_submitted?,
73
+ :associated? => :is_associated?,
74
+ }
75
+
76
+ attr_reader :ews_item, :parent
77
+
78
+ # @param ews [SOAP::ExchangeWebService] the EWS reference
79
+ # @param ews_item [Hash] the EWS parsed response document
80
+ # @param parent [GenericFolder] an optional parent object
81
+ def initialize(ews, ews_item, parent = nil)
82
+ super(ews, ews_item)
83
+ @parent = parent
84
+ @body_type = false
85
+ simplify!
86
+ @new_file_attachments = []
87
+ @new_item_attachments = []
88
+ @new_inline_attachments = []
89
+ end
90
+
91
+ # Specify a body_type to fetch this item with if it hasn't already been fetched.
92
+ # @param body_type [String, Symbol, FalseClass] must be :best, :text, or
93
+ # :html. You can also set it to false to make it use the default.
94
+ def default_body_type=(body_type)
95
+ @body_type = body_type
96
+ end
97
+
98
+ def delete!(deltype = :hard, opts = {})
99
+ opts = {
100
+ :delete_type => delete_type(deltype),
101
+ :item_ids => [{:item_id => {:id => id}}],
102
+ :send_meeting_cancellations => 'SendToNone'
103
+ }.merge(opts)
104
+
105
+ resp = @ews.delete_item(opts)
106
+ rmsg = resp.response_messages[0]
107
+ unless rmsg.success?
108
+ raise EwsError, "Could not delete #{self.class}. #{rmsg.response_code}: #{rmsg.message_text}"
109
+ end
110
+ true
111
+ end
112
+
113
+ def recycle!
114
+ delete! :recycle
115
+ end
116
+
117
+ def get_all_properties!
118
+ @ews_item = get_item(base_shape: 'AllProperties')
119
+ simplify!
120
+ end
121
+
122
+ # Mark an item as read or if you pass false, unread
123
+ # @param [Boolean] read mark read if true, unread if not.
124
+ def mark_read!(read = true)
125
+ resp = update_is_read_status read
126
+ end
127
+
128
+ # Move this item to a new folder
129
+ # @param [String,Symbol,GenericFolder] new_folder The new folder to move it to. This should
130
+ # be a subclass of GenericFolder, a DistinguishedFolderId (must me a Symbol) or a FolderId (String)
131
+ # @return [String] the new Id of the moved item
132
+ def move!(new_folder)
133
+ new_folder = new_folder.id if new_folder.kind_of?(GenericFolder)
134
+ move_opts = {
135
+ :to_folder_id => {:id => new_folder},
136
+ :item_ids => [{:item_id => {:id => self.id}}]
137
+ }
138
+ resp = @ews.move_item(move_opts)
139
+ rmsg = resp.response_messages[0]
140
+
141
+ if rmsg.success?
142
+ obj = rmsg.items.first
143
+ itype = obj.keys.first
144
+ obj[itype][:elems][0][:item_id][:attribs][:id]
145
+ else
146
+ raise EwsError, "Could not move item. #{resp.code}: #{resp.message}"
147
+ end
148
+ end
149
+
150
+ # Copy this item to a new folder
151
+ # @param [String,Symbol,GenericFolder] new_folder The new folder to move it to. This should
152
+ # be a subclass of GenericFolder, a DistinguishedFolderId (must me a Symbol) or a FolderId (String)
153
+ # @return [String] the new Id of the copied item
154
+ def copy(new_folder)
155
+ new_folder = new_folder.id if new_folder.kind_of?(GenericFolder)
156
+ copy_opts = {
157
+ :to_folder_id => {:id => new_folder},
158
+ :item_ids => [{:item_id => {:id => self.id}}]
159
+ }
160
+ resp = @ews.copy_item(copy_opts)
161
+ rmsg = resp.response_messages[0]
162
+
163
+ if rmsg.success?
164
+ obj = rmsg.items.first
165
+ itype = obj.keys.first
166
+ obj[itype][:elems][0][:item_id][:attribs][:id]
167
+ else
168
+ raise EwsError, "Could not copy item. #{rmsg.response_code}: #{rmsg.message_text}"
169
+ end
170
+ end
171
+
172
+ def add_file_attachment(file)
173
+ fa = OpenStruct.new
174
+ fa.name = File.basename(file.path)
175
+ fa.content = Base64.encode64(file.read)
176
+ @new_file_attachments << fa
177
+ end
178
+
179
+ def add_item_attachment(other_item, name = nil)
180
+ ia = OpenStruct.new
181
+ ia.name = (name ? name : other_item.subject)
182
+ ia.item = {id: other_item.id, change_key: other_item.change_key}
183
+ @new_item_attachments << ia
184
+ end
185
+
186
+ def add_inline_attachment(file)
187
+ fi = OpenStruct.new
188
+ fi.name = File.basename(file.path)
189
+ fi.content = Base64.encode64(file.read)
190
+ @new_inline_attachments << fi
191
+ end
192
+
193
+ def submit!
194
+ if draft?
195
+ submit_attachments!
196
+ resp = ews.send_item(item_ids: [{item_id: {id: self.id, change_key: self.change_key}}])
197
+ rm = resp.response_messages[0]
198
+ if rm.success?
199
+ true
200
+ else
201
+ raise EwsSendItemError, "#{rm.code}: #{rm.message_text}"
202
+ end
203
+ else
204
+ false
205
+ end
206
+ end
207
+
208
+ def submit_attachments!
209
+ return false unless draft? && !(@new_file_attachments.empty? && @new_item_attachments.empty? && @new_inline_attachments.empty?)
210
+
211
+ opts = {
212
+ parent_id: {id: self.id, change_key: self.change_key},
213
+ files: @new_file_attachments,
214
+ items: @new_item_attachments,
215
+ inline_files: @new_inline_attachments
216
+ }
217
+ resp = ews.create_attachment(opts)
218
+ set_change_key resp.response_messages[0].attachments[0].parent_change_key
219
+ @new_file_attachments = []
220
+ @new_item_attachments = []
221
+ @new_inline_attachments = []
222
+ end
223
+
224
+ # If you want to add to the body set #new_body_content. If you set #body
225
+ # it will override the body that is there.
226
+ # @see MessageAccessors#send_message for options
227
+ # additional options:
228
+ # :new_body_content, :new_body_type
229
+ # @example
230
+ # item.forward do |i|
231
+ # i.new_body_content = "Add this to the top"
232
+ # i.to_recipients << 'test@example.com'
233
+ # end
234
+ def forward(opts = {})
235
+ msg = Template::ForwardItem.new opts.clone
236
+ yield msg if block_given?
237
+ msg.reference_item_id = {id: self.id, change_key: self.change_key}
238
+ dispatch_create_item! msg
239
+ end
240
+
241
+ def reply_to(opts = {})
242
+ msg = Template::ReplyToItem.new opts.clone
243
+ yield msg if block_given?
244
+ msg.reference_item_id = {id: self.id, change_key: self.change_key}
245
+ dispatch_create_item! msg
246
+ end
247
+
248
+ def reply_to_all(opts = {})
249
+ msg = Template::ReplyToItem.new opts.clone
250
+ yield msg if block_given?
251
+ msg.reference_item_id = {id: self.id, change_key: self.change_key}
252
+ msg.ews_type = :reply_all_to_item
253
+ dispatch_create_item! msg
254
+ end
255
+
256
+
257
+ private
258
+
259
+ def key_paths
260
+ super.merge(ITEM_KEY_PATHS)
261
+ end
262
+
263
+ def key_types
264
+ super.merge(ITEM_KEY_TYPES)
265
+ end
266
+
267
+ def key_alias
268
+ super.merge(ITEM_KEY_ALIAS)
269
+ end
270
+
271
+ def update_is_read_status(read)
272
+ field = :is_read
273
+ opts = {item_changes:
274
+ [
275
+ { item_id: {id: id, change_key: change_key},
276
+ updates: [
277
+ {set_item_field: {field_uRI: {field_uRI: FIELD_URIS[field][:text]},
278
+ message: {sub_elements: [{field => {text: read}}]}}}
279
+ ]
280
+ }
281
+ ]
282
+ }
283
+ resp = ews.update_item({conflict_resolution: 'AutoResolve'}.merge(opts))
284
+ rmsg = resp.response_messages[0]
285
+ unless rmsg.success?
286
+ raise EwsError, "#{rmsg.response_code}: #{rmsg.message_text}"
287
+ end
288
+ true
289
+ end
290
+
291
+ def simplify!
292
+ return unless @ews_item.has_key?(:elems)
293
+ @ews_item = @ews_item[:elems].inject({}) do |o,i|
294
+ key = i.keys.first
295
+ if o.has_key?(key)
296
+ if o[key].is_a?(Array)
297
+ o[key] << i[key]
298
+ else
299
+ o[key] = [o.delete(key), i[key]]
300
+ end
301
+ else
302
+ o[key] = i[key]
303
+ end
304
+ o
305
+ end
306
+ end
307
+
308
+ # Get a specific item by its ID.
309
+ # @param [Hash] opts Misc options to control request
310
+ # @option opts [String] :base_shape IdOnly/Default/AllProperties
311
+ # @raise [EwsError] raised when the backend SOAP method returns an error.
312
+ def get_item(opts = {})
313
+ args = get_item_args(opts)
314
+ resp = ews.get_item(args)
315
+ get_item_parser(resp)
316
+ end
317
+
318
+ # Build up the arguements for #get_item
319
+ # @todo: should we really pass the ChangeKey or do we want the freshest obj?
320
+ def get_item_args(opts)
321
+ opts[:base_shape] ||= 'Default'
322
+ default_args = {
323
+ item_shape: {base_shape: opts[:base_shape]},
324
+ item_ids: [{item_id:{id: id, change_key: change_key}}]
325
+ }
326
+ default_args[:item_shape][:body_type] = @body_type if @body_type
327
+ default_args
328
+ end
329
+
330
+ def get_item_parser(resp)
331
+ rm = resp.response_messages[0]
332
+ if(rm.status == 'Success')
333
+ rm.items[0].values.first
334
+ else
335
+ raise EwsError, "Could not retrieve #{self.class}. #{rm.code}: #{rm.message_text}"
336
+ end
337
+ end
338
+
339
+ # Map a delete type to what EWS expects
340
+ # @param [Symbol] type. Must be :hard, :soft, or :recycle
341
+ def delete_type(type)
342
+ case type
343
+ when :hard then 'HardDelete'
344
+ when :soft then 'SoftDelete'
345
+ when :recycle then 'MoveToDeletedItems'
346
+ else 'MoveToDeletedItems'
347
+ end
348
+ end
349
+
350
+ def build_deleted_occurrences(occurrences)
351
+ occurrences.collect{|a| DateTime.parse a[:deleted_occurrence][:elems][0][:start][:text]}
352
+ end
353
+
354
+ def build_modified_occurrences(occurrences)
355
+ {}.tap do |h|
356
+ occurrences.collect do |a|
357
+ elems = a[:occurrence][:elems]
358
+
359
+ h[DateTime.parse(elems.find{|e| e[:original_start]}[:original_start][:text])] = {
360
+ start: elems.find{|e| e[:start]}[:start][:text],
361
+ end: elems.find{|e| e[:end]}[:end][:text]
362
+ }
363
+ end
364
+ end
365
+ end
366
+
367
+ def build_mailbox_user(mbox_ews)
368
+ MailboxUser.new(ews, mbox_ews)
369
+ end
370
+
371
+ def build_mailbox_users(users)
372
+ return [] if users.nil?
373
+ users.collect{|u| build_mailbox_user(u[:mailbox][:elems])}
374
+ end
375
+
376
+ def build_attendees_users(users)
377
+ return [] if users.nil?
378
+ users.collect do |u|
379
+ u[:attendee][:elems].collect do |a|
380
+ build_mailbox_user(a[:mailbox][:elems]) if a[:mailbox]
381
+ end
382
+ end.flatten.compact
383
+ end
384
+
385
+ def build_attachments(attachments)
386
+ return [] if attachments.nil?
387
+ attachments.collect do |att|
388
+ key = att.keys.first
389
+ class_by_name(key).new(self, att[key])
390
+ end
391
+ end
392
+
393
+ def set_change_key(ck)
394
+ p = resolve_key_path(ews_item, key_paths[:change_key][0..-2])
395
+ p[:change_key] = ck
396
+ end
397
+
398
+ # Handles the CreateItem call for Forward, ReplyTo, and ReplyAllTo
399
+ # It will handle the neccessary actions for adding attachments.
400
+ def dispatch_create_item!(msg)
401
+ if msg.has_attachments?
402
+ draft = msg.draft
403
+ msg.draft = true
404
+ resp = validate_created_item(ews.create_item(msg.to_ews))
405
+ msg.file_attachments.each do |f|
406
+ next unless f.kind_of?(File)
407
+ resp.add_file_attachment(f)
408
+ end
409
+ if draft
410
+ resp.submit_attachments!
411
+ resp
412
+ else
413
+ resp.submit!
414
+ end
415
+ else
416
+ resp = ews.create_item(msg.to_ews)
417
+ validate_created_item resp
418
+ end
419
+ end
420
+
421
+ # validate the CreateItem response.
422
+ # @return [Boolean, Item] returns true if items is empty and status is
423
+ # "Success" if items is not empty it will return the first Item since
424
+ # we are only dealing with single items here.
425
+ # @raise EwsCreateItemError on failure
426
+ def validate_created_item(response)
427
+ msg = response.response_messages[0]
428
+
429
+ if(msg.status == 'Success')
430
+ msg.items.empty? ? true : parse_created_item(msg.items.first)
431
+ else
432
+ raise EwsCreateItemError, "#{msg.code}: #{msg.message_text}"
433
+ end
434
+ end
435
+
436
+ def parse_created_item(msg)
437
+ mtype = msg.keys.first
438
+ message = class_by_name(mtype).new(ews, msg[mtype])
439
+ end
440
+
441
+ end
442
+ end
@@ -0,0 +1,84 @@
1
+ =begin
2
+ This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ module Viewpoint::EWS::Types
20
+ class ItemAttachment < Attachment
21
+
22
+ ITEM_ATTACH_KEY_PATHS = {
23
+ item: [:item],
24
+ message: [:message],
25
+ calendar_item: [:calendar_item],
26
+ contact: [:contact],
27
+ task: [:task],
28
+ meeting_message: [:meeting_message],
29
+ meeting_request: [:meeting_request],
30
+ meeting_response: [:meeting_response],
31
+ meeting_cancellation: [:meeting_cancellation]
32
+ }
33
+
34
+ ITEM_ATTACH_KEY_TYPES = {
35
+ message: :build_message,
36
+ calendar_item: :build_calendar_item,
37
+ contact: :build_contact,
38
+ task: :build_task,
39
+ meeting_message: :build_meeting_message,
40
+ meeting_request: :build_meeting_request,
41
+ meeting_response: :build_meeting_response,
42
+ meeting_cancellation: :build_meeting_cancellation
43
+ }
44
+
45
+ ITEM_ATTACH_KEY_ALIAS = { }
46
+
47
+ def get_all_properties!
48
+ resp = ews.get_attachment attachment_ids: [self.id]
49
+ @ews_item.merge!(parse_response(resp))
50
+ end
51
+
52
+ private
53
+
54
+ def self.method_missing(method, *args, &block)
55
+ if method.to_s =~ /^build_(.+)$/
56
+ class_by_name($1).new(ews, args[0])
57
+ else
58
+ super
59
+ end
60
+ end
61
+
62
+ def key_paths
63
+ super.merge(ITEM_ATTACH_KEY_PATHS)
64
+ end
65
+
66
+ def key_types
67
+ super.merge(ITEM_ATTACH_KEY_TYPES)
68
+ end
69
+
70
+ def key_alias
71
+ super.merge(ITEM_ATTACH_KEY_ALIAS)
72
+ end
73
+
74
+ def parse_response(resp)
75
+ if(resp.status == 'Success')
76
+ resp.response_message[:elems][:attachments][:elems][0][:item_attachment][:elems].inject(&:merge)
77
+ else
78
+ raise EwsError, "Could not retrieve #{self.class}. #{resp.code}: #{resp.message}"
79
+ end
80
+ end
81
+
82
+ end
83
+ end
84
+