viewpoint 0.1.26 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
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