viewpoint 0.1.26 → 1.1.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.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +203 -0
  3. data/lib/ews/calendar_accessors.rb +34 -0
  4. data/lib/ews/connection.rb +140 -0
  5. data/lib/ews/connection_helper.rb +35 -0
  6. data/lib/ews/convert_accessors.rb +56 -0
  7. data/lib/{exceptions/exceptions.rb → ews/errors.rb} +29 -19
  8. data/lib/ews/ews_client.rb +105 -0
  9. data/lib/ews/exceptions/exceptions.rb +61 -0
  10. data/lib/ews/folder_accessors.rb +264 -0
  11. data/lib/ews/impersonation.rb +30 -0
  12. data/lib/ews/item_accessors.rb +242 -0
  13. data/lib/ews/mailbox_accessors.rb +92 -0
  14. data/lib/ews/meeting_accessors.rb +39 -0
  15. data/lib/ews/message_accessors.rb +93 -0
  16. data/lib/ews/push_subscription_accessors.rb +33 -0
  17. data/lib/ews/room_accessors.rb +48 -0
  18. data/lib/ews/roomlist_accessors.rb +47 -0
  19. data/lib/ews/soap.rb +64 -0
  20. data/lib/ews/soap/builders/ews_builder.rb +1384 -0
  21. data/lib/ews/soap/ews_response.rb +84 -0
  22. data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
  23. data/lib/ews/soap/ews_soap_free_busy_response.rb +119 -0
  24. data/lib/ews/soap/ews_soap_response.rb +103 -0
  25. data/lib/ews/soap/ews_soap_room_response.rb +53 -0
  26. data/lib/ews/soap/ews_soap_roomlist_response.rb +54 -0
  27. data/lib/ews/soap/exchange_availability.rb +61 -0
  28. data/lib/ews/soap/exchange_data_services.rb +780 -0
  29. data/lib/ews/soap/exchange_notification.rb +146 -0
  30. data/lib/ews/soap/exchange_synchronization.rb +93 -0
  31. data/lib/ews/soap/exchange_time_zones.rb +56 -0
  32. data/lib/ews/soap/exchange_user_configuration.rb +33 -0
  33. data/lib/ews/soap/exchange_web_service.rb +264 -0
  34. data/lib/{model/item_attachment.rb → ews/soap/parsers/ews_parser.rb} +24 -14
  35. data/lib/ews/soap/parsers/ews_sax_document.rb +70 -0
  36. data/lib/ews/soap/response_message.rb +80 -0
  37. data/lib/ews/soap/responses/create_attachment_response_message.rb +47 -0
  38. data/lib/{model/meeting_message.rb → ews/soap/responses/create_item_response_message.rb} +7 -10
  39. data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
  40. data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
  41. data/lib/ews/soap/responses/send_notification_response_message.rb +59 -0
  42. data/lib/{model/attachment.rb → ews/soap/responses/subscribe_response_message.rb} +17 -13
  43. data/lib/{model/attendee.rb → ews/soap/responses/sync_folder_hierarchy_response_message.rb} +14 -15
  44. data/lib/ews/soap/responses/sync_folder_items_response_message.rb +36 -0
  45. data/lib/ews/templates/calendar_item.rb +79 -0
  46. data/lib/ews/templates/forward_item.rb +24 -0
  47. data/lib/ews/templates/message.rb +85 -0
  48. data/lib/ews/templates/reply_to_item.rb +25 -0
  49. data/lib/ews/templates/task.rb +74 -0
  50. data/lib/ews/types.rb +194 -0
  51. data/lib/ews/types/attachment.rb +77 -0
  52. data/lib/{model/meeting_cancellation.rb → ews/types/attendee.rb} +9 -8
  53. data/lib/ews/types/calendar_folder.rb +50 -0
  54. data/lib/ews/types/calendar_item.rb +130 -0
  55. data/lib/ews/types/contact.rb +7 -0
  56. data/lib/ews/types/contacts_folder.rb +8 -0
  57. data/lib/ews/types/copied_event.rb +51 -0
  58. data/lib/{soap/handsoap/builder.rb → ews/types/created_event.rb} +5 -2
  59. data/lib/ews/types/deleted_event.rb +24 -0
  60. data/lib/ews/types/distribution_list.rb +7 -0
  61. data/lib/ews/types/event.rb +62 -0
  62. data/lib/ews/types/export_items_response_message.rb +52 -0
  63. data/lib/ews/types/file_attachment.rb +65 -0
  64. data/lib/ews/types/folder.rb +60 -0
  65. data/lib/ews/types/free_busy_changed_event.rb +24 -0
  66. data/lib/ews/types/generic_folder.rb +418 -0
  67. data/lib/ews/types/item.rb +447 -0
  68. data/lib/ews/types/item_attachment.rb +84 -0
  69. data/lib/{model → ews/types}/item_field_uri_map.rb +2 -18
  70. data/lib/ews/types/mailbox_user.rb +156 -0
  71. data/lib/ews/types/meeting_cancellation.rb +7 -0
  72. data/lib/ews/types/meeting_message.rb +7 -0
  73. data/lib/ews/types/meeting_request.rb +7 -0
  74. data/lib/ews/types/meeting_response.rb +7 -0
  75. data/lib/ews/types/message.rb +7 -0
  76. data/lib/ews/types/modified_event.rb +48 -0
  77. data/lib/{extensions/string.rb → ews/types/moved_event.rb} +31 -15
  78. data/lib/ews/types/new_mail_event.rb +24 -0
  79. data/lib/ews/types/out_of_office.rb +147 -0
  80. data/lib/ews/types/post_item.rb +7 -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 +41 -0
  84. data/lib/ews/types/tasks_folder.rb +27 -0
  85. data/lib/viewpoint.rb +85 -108
  86. data/lib/{model/distribution_list.rb → viewpoint/logging.rb} +6 -3
  87. data/lib/{model/meeting_response.rb → viewpoint/logging/config.rb} +3 -3
  88. data/lib/viewpoint/string_utils.rb +76 -0
  89. metadata +156 -123
  90. data/README +0 -114
  91. data/lib/model/calendar_folder.rb +0 -67
  92. data/lib/model/calendar_item.rb +0 -267
  93. data/lib/model/contact.rb +0 -238
  94. data/lib/model/contacts_folder.rb +0 -46
  95. data/lib/model/event.rb +0 -116
  96. data/lib/model/file_attachment.rb +0 -53
  97. data/lib/model/folder.rb +0 -47
  98. data/lib/model/generic_folder.rb +0 -461
  99. data/lib/model/item.rb +0 -312
  100. data/lib/model/mailbox_user.rb +0 -146
  101. data/lib/model/meeting_request.rb +0 -39
  102. data/lib/model/message.rb +0 -142
  103. data/lib/model/model.rb +0 -269
  104. data/lib/model/search_folder.rb +0 -48
  105. data/lib/model/task.rb +0 -121
  106. data/lib/model/tasks_folder.rb +0 -44
  107. data/lib/soap/handsoap/builders/ews_build_helpers.rb +0 -383
  108. data/lib/soap/handsoap/builders/ews_builder.rb +0 -146
  109. data/lib/soap/handsoap/ews_service.rb +0 -790
  110. data/lib/soap/handsoap/parser.rb +0 -104
  111. data/lib/soap/handsoap/parsers/ews_parser.rb +0 -245
  112. data/lib/soap/soap_provider.rb +0 -64
@@ -0,0 +1,30 @@
1
+ module Viewpoint::EWS
2
+
3
+ ConnectingSID = {
4
+ :UPN => 'PrincipalName',
5
+ :SID => 'SID',
6
+ :PSMTP => 'PrimarySmtpAddress',
7
+ :SMTP => 'SmtpAddress'
8
+ }
9
+
10
+ # @param connecting_type [String] should be one of the ConnectingSID variables
11
+ # ConnectingSID[:UPN] - use User Principal Name method
12
+ # ConnectingSID[:SID] - use Security Identifier method
13
+ # ConnectingSID[:PSMTP] - use primary Simple Mail Transfer Protocol method
14
+ # ConnectingSID[:SMTP] - use Simple Mail Transfer Protocol method
15
+ # you can add any other string, it will be converted into xml tag on soap request
16
+ # @param address [String] an address to include to requests for impersonation
17
+ def set_impersonation(connecting_type, address)
18
+ if ConnectingSID.has_value? connecting_type or connecting_type.is_a? String then
19
+ ews.impersonation_type = connecting_type
20
+ ews.impersonation_address = address
21
+ else
22
+ raise EwsBadArgumentError, "Not a proper connecting method: #{connecting_type.class}"
23
+ end
24
+ end
25
+
26
+ def remove_impersonation
27
+ ews.impersonation_type = ""
28
+ ews.impersonation_address = ""
29
+ end
30
+ end
@@ -0,0 +1,242 @@
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
+ module Viewpoint::EWS::ItemAccessors
19
+ include Viewpoint::EWS
20
+
21
+ # This is a class method that fetches an existing Item from the
22
+ # Exchange Store.
23
+ # @param [String] item_id The id of the item. You can also pass a Hash in the
24
+ # form: {id: <fold_id>, change_key: <change_key>}
25
+ # @param [Hash] opts Misc options to control request
26
+ # @option opts [Symbol] :shape :id_only/:default/:all_properties
27
+ # @return [Item] Returns an Item or subclass of Item
28
+ # @todo Add support to fetch an item with a ChangeKey
29
+ def get_item(item_id, opts = {})
30
+ args = get_item_args(item_id, opts.clone)
31
+ obj = OpenStruct.new(opts: args)
32
+ yield obj if block_given?
33
+ resp = ews.get_item(args)
34
+ get_item_parser(resp)
35
+ end
36
+
37
+ # @param [Hash] opts Misc options to control request
38
+ # @option opts [Symbol] :folder_id
39
+ # @see GenericFolder#items
40
+ def find_items(opts = {})
41
+ args = find_items_args(opts.clone)
42
+ obj = OpenStruct.new(opts: args, restriction: {})
43
+ yield obj if block_given?
44
+ merge_restrictions! obj
45
+ resp = ews.find_item(args)
46
+ find_items_parser resp
47
+ end
48
+
49
+ # This is a class method that fetches an existing Item from the
50
+ # Exchange Store.
51
+ # @param [String] item_id The id of the item. You can also pass a Hash in the
52
+ # form: {id: <fold_id>, change_key: <change_key>}
53
+ # @param [Hash] opts Misc options to control request
54
+ # @option opts [Symbol] :shape :id_only/:default/:all_properties
55
+ # @return [Item] Returns an Item or subclass of Item
56
+ # @todo Add support to fetch an item with a ChangeKey
57
+ def get_items(item_ids, opts = {})
58
+ args = get_item_args(item_ids, opts.clone)
59
+ obj = OpenStruct.new(opts: args)
60
+ yield obj if block_given?
61
+ resp = ews.get_item(args)
62
+ get_items_parser(resp)
63
+ end
64
+
65
+ # Copy an array of items to the specified folder
66
+ # @param items [Array] an array of EWS Items that you want to copy
67
+ # @param folder [String,Symbol,GenericFolder] The folder to copy to. This must
68
+ # be a subclass of GenericFolder, a DistinguishedFolderId (must me a Symbol)
69
+ # or a FolderId (String)
70
+ # @return [Array<Hash>] returns a Hash for each item passed
71
+ # on success:
72
+ # {:success => true, :item_id => <new_item_id>}
73
+ # on failure:
74
+ # {:success => false, :error_message => <the message>}
75
+ def copy_items(items, folder)
76
+ folder = folder.id if folder.kind_of?(Types::GenericFolder)
77
+ item_ids = items.collect{|i| {item_id: {id: i.id, change_key: i.change_key}}}
78
+ copy_opts = {
79
+ :to_folder_id => {:id => folder},
80
+ :item_ids => item_ids
81
+ }
82
+ resp = ews.copy_item(copy_opts)
83
+ copy_move_items_parser(resp)
84
+ end
85
+
86
+ # Move an array of items to the specified folder
87
+ # @see #copy_items for parameter info
88
+ def move_items(items, folder)
89
+ folder = folder.id if folder.kind_of?(Types::GenericFolder)
90
+ item_ids = items.collect{|i| {item_id: {id: i.id, change_key: i.change_key}}}
91
+ move_opts = {
92
+ :to_folder_id => {:id => folder},
93
+ :item_ids => item_ids
94
+ }
95
+ resp = ews.move_item(move_opts)
96
+ copy_move_items_parser(resp, :move_item_response_message)
97
+ end
98
+
99
+ # Exports an entire item into base64 string
100
+ # @param item_ids [Array] array of item ids. Can also be a single id value
101
+ # return [Array] array of bulk items
102
+ def export_items(item_ids)
103
+ args = export_items_args(item_ids)
104
+
105
+ resp = ews.export_items(args)
106
+ export_items_parser(resp)
107
+ end
108
+
109
+ private
110
+
111
+ def get_item_args(item_id, opts)
112
+ opts[:shape] ||= :default
113
+ default_args = {
114
+ :item_shape => {:base_shape => opts[:shape]}
115
+ }
116
+ default_args[:item_ids] = case item_id
117
+ when Hash
118
+ if item_id.keys.index(:id)
119
+ [{:item_id => item_id}]
120
+ else
121
+ [item_id]
122
+ end
123
+ when Array
124
+ item_id.map do |i|
125
+ case i
126
+ when Hash
127
+ i
128
+ else
129
+ {:item_id => {:id => i}}
130
+ end
131
+ end
132
+ else
133
+ [{:item_id => {:id => item_id}}]
134
+ end
135
+ default_args.merge opts
136
+ end
137
+
138
+ def get_item_parser(resp)
139
+ rm = resp.response_messages[0]
140
+
141
+ if(rm && rm.status == 'Success')
142
+ i = rm.items.first
143
+ itype = i.keys.first
144
+ class_by_name(itype).new(ews, i[itype])
145
+ else
146
+ code = rm.respond_to?(:code) ? rm.code : "Unknown"
147
+ text = rm.respond_to?(:message_text) ? rm.message_text : "Unknown"
148
+ raise EwsItemNotFound, "Could not retrieve item. #{rm.code}: #{rm.message_text}"
149
+ end
150
+ end
151
+
152
+ def get_items_parser(resp)
153
+ items = []
154
+
155
+ resp.response_messages.each do |rm|
156
+ if(rm && rm.status == 'Success')
157
+ rm.items.each do |i|
158
+ type = i.keys.first
159
+ items << class_by_name(type).new(ews, i[type])
160
+ end
161
+ end
162
+ end
163
+
164
+ items
165
+ end
166
+
167
+ def find_items_args(opts)
168
+ default_args = {
169
+ :traversal => 'Shallow',
170
+ :item_shape => {:base_shape => 'Default'}
171
+ }
172
+
173
+ if opts[:folder_id].is_a?(Hash)
174
+ default_args[:parent_folder_ids] = [opts.delete(:folder_id)]
175
+ else
176
+ default_args[:parent_folder_ids] = [{:id => opts.delete(:folder_id)}]
177
+ end
178
+ default_args.merge(opts)
179
+ end
180
+
181
+ def find_items_parser(resp)
182
+ rm = resp.response_messages[0]
183
+ if rm.success?
184
+ items = []
185
+ rm.root_folder.items.each do |i|
186
+ type = i.keys.first
187
+ items << class_by_name(type).new(ews, i[type])
188
+ end
189
+ items
190
+ else
191
+ raise EwsError, "Could not retrieve folder. #{rm.code}: #{rm.message_text}"
192
+ end
193
+ end
194
+
195
+ def copy_move_items_parser(resp, resp_type = :copy_item_response_message)
196
+ resp.response_messages.collect {|r|
197
+ obj = {}
198
+ if r.success?
199
+ obj[:success] = true
200
+ item = r.items.first
201
+ key = item.keys.first
202
+ obj[:item_id] = item[key][:elems][0][:item_id][:attribs][:id]
203
+ else
204
+ obj[:success] = false
205
+ obj[:error_message] = "#{r.response_code}: #{r.message_text}"
206
+ end
207
+ obj
208
+ }
209
+ end
210
+
211
+ def export_items_args(item_ids)
212
+ default_args = {}
213
+ default_args[:item_ids] = []
214
+ if item_ids.is_a?(Array) then
215
+ item_ids.each do |id|
216
+ default_args[:item_ids] = default_args[:item_ids] + [{:item_id => {:id => id}}]
217
+ end
218
+ else
219
+ default_args[:item_ids] = [{:item_id => {:id => item_ids}}]
220
+ end
221
+ default_args
222
+ end
223
+
224
+ def export_items_parser(resp)
225
+ rm = resp.response_messages
226
+ if(rm)
227
+ items = []
228
+ rm.each do |i|
229
+ if i.success? then
230
+ type = i.type
231
+ items << class_by_name(type).new(ews, i.message[:elems])
232
+ else
233
+ code = i.respond_to?(:code) ? i.code : "Unknown"
234
+ text = i.respond_to?(:message_text) ? i.message_text : "Unknown"
235
+ items << "Could not retrieve item. #{code}: #{text}"
236
+ end
237
+ end
238
+ items
239
+ end
240
+ end
241
+
242
+ end # Viewpoint::EWS::ItemAccessors
@@ -0,0 +1,92 @@
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::MailboxAccessors
20
+ include Viewpoint::EWS
21
+
22
+ # Resolve contacts in the Exchange Data Store
23
+ # @param [String] ustring A string to resolve contacts to.
24
+ # @return [Array<MailboxUser>] It returns an Array of MailboxUsers.
25
+ def search_contacts(ustring)
26
+ resp = ews.resolve_names(:name => ustring)
27
+
28
+ users = []
29
+ if(resp.status == 'Success')
30
+ mb = resp.response_message[:elems][:resolution_set][:elems][0][:resolution][:elems][0]
31
+ users << Types::MailboxUser.new(ews, mb[:mailbox][:elems])
32
+ elsif(resp.code == 'ErrorNameResolutionMultipleResults')
33
+ resp.response_message[:elems][:resolution_set][:elems].each do |u|
34
+ if u[:resolution][:elems][0][:mailbox]
35
+ users << Types::MailboxUser.new(ews, u[:resolution][:elems][0][:mailbox][:elems])
36
+ end
37
+ end
38
+ else
39
+ raise EwsError, "Find User produced an error: #{resp.code}: #{resp.message}"
40
+ end
41
+ users
42
+ end
43
+
44
+ # GetUserAvailability request
45
+ # @see http://msdn.microsoft.com/en-us/library/aa563800.aspx
46
+ # @param [Array<String>] emails A list of emails you want to retrieve free-busy info for.
47
+ # @param [Hash] opts
48
+ # @option opts [DateTime] :start_time
49
+ # @option opts [DateTime] :end_time
50
+ # @option opts [Symbol] :requested_view :merged_only/:free_busy/
51
+ # :free_busy_merged/:detailed/:detailed_merged
52
+ # @option opts [Hash] :time_zone The TimeZone data
53
+ # Example: {:bias => 'UTC offset in minutes',
54
+ # :standard_time => {:bias => 480, :time => '02:00:00',
55
+ # :day_order => 5, :month => 10, :day_of_week => 'Sunday'},
56
+ # :daylight_time => {same options as :standard_time}}
57
+ def get_user_availability(emails, opts)
58
+ opts = opts.clone
59
+ args = get_user_availability_args(emails, opts)
60
+ resp = ews.get_user_availability(args.merge(opts))
61
+ get_user_availability_parser(resp)
62
+ end
63
+
64
+
65
+ private
66
+
67
+ def get_user_availability_args(emails, opts)
68
+ unless opts.has_key?(:start_time) && opts.has_key?(:end_time) && opts.has_key?(:requested_view)
69
+ raise EwsBadArgumentError, "You must specify a start_time, end_time and requested_view."
70
+ end
71
+
72
+ default_args = {
73
+ mailbox_data: (emails.collect{|e| [email: {address: e}]}.flatten),
74
+ free_busy_view_options: {
75
+ time_window: {
76
+ start_time: opts[:start_time],
77
+ end_time: opts[:end_time]
78
+ },
79
+ requested_view: { :requested_free_busy_view => opts[:requested_view] },
80
+ }
81
+ }
82
+ end
83
+
84
+ def get_user_availability_parser(resp)
85
+ if(resp.status == 'Success')
86
+ resp
87
+ else
88
+ raise EwsError, "GetUserAvailability produced an error: #{resp.code}: #{resp.message}"
89
+ end
90
+ end
91
+
92
+ end # Viewpoint::EWS::MailboxAccessors
@@ -0,0 +1,39 @@
1
+ module Viewpoint::EWS::MeetingAccessors
2
+ include Viewpoint::EWS
3
+
4
+ def accept_meeting(opts)
5
+ ews.create_item({
6
+ message_disposition: 'SendOnly',
7
+ items: [ { accept_item: opts_to_item(opts) } ]
8
+ })
9
+ end
10
+
11
+ def decline_meeting(opts)
12
+ ews.create_item({
13
+ message_disposition: 'SendOnly',
14
+ items: [ { decline_item: opts_to_item(opts) } ]
15
+ })
16
+ end
17
+
18
+ def tentatively_accept_meeting(opts)
19
+ ews.create_item({
20
+ message_disposition: 'SendOnly',
21
+ items: [ { tentatively_accept_item: opts_to_item(opts) } ]
22
+ })
23
+ end
24
+
25
+ private
26
+
27
+ def opts_to_item(opts)
28
+ hash = {
29
+ id: opts[:id],
30
+ change_key: opts[:change_key],
31
+ sensitivity: opts[:sensitivity]
32
+ }
33
+
34
+ hash[:text] = opts[:text] if opts[:text]
35
+ hash[:body_type] = (opts[:body_type] || 'Text') if opts[:text]
36
+
37
+ hash
38
+ end
39
+ end
@@ -0,0 +1,93 @@
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
+ module Viewpoint::EWS::MessageAccessors
19
+ include Viewpoint::EWS
20
+
21
+ # Send an E-mail message
22
+ #
23
+ # @param [Hash] opts A Hash with message params
24
+ # @option opts [String] :subject The message subject
25
+ # @option opts [String] :body The message body
26
+ # @option opts [Array] :to_recipients An array of e-mail addresses to send to
27
+ # @option opts [Array] :cc_recipients An array of e-mail addresses to send to
28
+ # @option opts [Array] :bcc_recipients An array of e-mail addresses to send to
29
+ # @option opts [Array] :extended_properties An array of extended properties
30
+ # [{extended_field_uri: {epros}, value: <val>}] or values: [<val>, <val>]
31
+ # @option opts [Boolean] :draft if true it will save to the draft folder
32
+ # without sending the message.
33
+ # @option opts [String,Symbol,Hash] saved_item_folder_id Either a
34
+ # FolderId(String) or a DistinguishedFolderId(Symbol). You can also pass a
35
+ # Hash in the form: {id: <fold_id>, change_key: <change_key>}
36
+ # @option opts [Array<File>] :file_attachments an Array of File or Tempfile objects
37
+ # @option opts [Array<File>] :inline_attachments an Array of Inline File or Tempfile objects
38
+ # @return [Message,Boolean] Returns true if the message is sent, false if
39
+ # nothing is returned from EWS or if draft is true it will return the
40
+ # Message object. Finally, if something goes wrong, it raises an error
41
+ # with a message stating why the e-mail could not be sent.
42
+ # @todo Finish ItemAttachments
43
+ def send_message(opts = {}, &block)
44
+ msg = Template::Message.new opts.clone
45
+ yield msg if block_given?
46
+ if msg.has_attachments?
47
+ draft = msg.draft
48
+ msg.draft = true
49
+ resp = parse_create_item(ews.create_item(msg.to_ews))
50
+ msg.file_attachments.each do |f|
51
+ next unless f.kind_of?(File) or f.kind_of?(Tempfile)
52
+ resp.add_file_attachment(f)
53
+ end
54
+ msg.inline_attachments.each do |f|
55
+ next unless f.kind_of?(File) or f.kind_of?(Tempfile)
56
+ resp.add_inline_attachment(f)
57
+ end
58
+ if draft
59
+ resp.submit_attachments!
60
+ resp
61
+ else
62
+ resp.submit!
63
+ end
64
+ else
65
+ resp = ews.create_item(msg.to_ews)
66
+ resp.response_messages ? parse_create_item(resp) : false
67
+ end
68
+ end
69
+
70
+ # See #send_message for options
71
+ def draft_message(opts = {}, &block)
72
+ send_message opts.merge(draft: true), &block
73
+ end
74
+
75
+
76
+ private
77
+
78
+
79
+ def parse_create_item(resp)
80
+ rm = resp.response_messages[0]
81
+ if(rm.status == 'Success')
82
+ rm.items.empty? ? true : parse_message(rm.items.first)
83
+ else
84
+ raise EwsError, "Could not send message. #{rm.code}: #{rm.message_text}"
85
+ end
86
+ end
87
+
88
+ def parse_message(msg)
89
+ mtype = msg.keys.first
90
+ message = class_by_name(mtype).new(ews, msg[mtype])
91
+ end
92
+
93
+ end # Viewpoint::EWS::MessageAccessors