viewpoint 1.2.0 → 2.0.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.
- checksums.yaml +4 -4
- data/README.md +11 -6
- data/lib/ews/calendar_accessors.rb +37 -33
- data/lib/ews/connection.rb +152 -125
- data/lib/ews/connection_helper.rb +36 -33
- data/lib/ews/convert_accessors.rb +58 -54
- data/lib/ews/errors.rb +59 -53
- data/lib/ews/ews_client.rb +92 -79
- data/lib/ews/exceptions/exceptions.rb +61 -61
- data/lib/ews/folder_accessors.rb +235 -234
- data/lib/ews/impersonation.rb +29 -23
- data/lib/ews/item_accessors.rb +215 -213
- data/lib/ews/mailbox_accessors.rb +82 -79
- data/lib/ews/meeting_accessors.rb +38 -31
- data/lib/ews/message_accessors.rb +83 -81
- data/lib/ews/push_subscription_accessors.rb +29 -27
- data/lib/ews/room_accessors.rb +48 -46
- data/lib/ews/roomlist_accessors.rb +47 -45
- data/lib/ews/soap/builders/ews_builder.rb +1191 -1176
- data/lib/ews/soap/ews_response.rb +68 -73
- data/lib/ews/soap/ews_soap_availability_response.rb +57 -57
- data/lib/ews/soap/ews_soap_free_busy_response.rb +115 -117
- data/lib/ews/soap/ews_soap_response.rb +99 -101
- data/lib/ews/soap/ews_soap_room_response.rb +45 -45
- data/lib/ews/soap/ews_soap_roomlist_response.rb +45 -46
- data/lib/ews/soap/exchange_availability.rb +54 -52
- data/lib/ews/soap/exchange_data_services.rb +693 -711
- data/lib/ews/soap/exchange_notification.rb +123 -128
- data/lib/ews/soap/exchange_synchronization.rb +82 -82
- data/lib/ews/soap/exchange_time_zones.rb +41 -44
- data/lib/ews/soap/exchange_user_configuration.rb +30 -27
- data/lib/ews/soap/exchange_web_service.rb +237 -233
- data/lib/ews/soap/parsers/ews_parser.rb +46 -42
- data/lib/ews/soap/parsers/ews_sax_document.rb +63 -58
- data/lib/ews/soap/response_message.rb +69 -68
- data/lib/ews/soap/responses/create_attachment_response_message.rb +45 -45
- data/lib/ews/soap/responses/create_item_response_message.rb +26 -25
- data/lib/ews/soap/responses/find_item_response_message.rb +76 -78
- data/lib/ews/soap/responses/get_events_response_message.rb +52 -51
- data/lib/ews/soap/responses/send_notification_response_message.rb +53 -51
- data/lib/ews/soap/responses/subscribe_response_message.rb +37 -34
- data/lib/ews/soap/responses/sync_folder_hierarchy_response_message.rb +38 -35
- data/lib/ews/soap/responses/sync_folder_items_response_message.rb +38 -35
- data/lib/ews/soap.rb +27 -26
- data/lib/ews/templates/calendar_item.rb +64 -60
- data/lib/ews/templates/forward_item.rb +19 -17
- data/lib/ews/templates/message.rb +61 -58
- data/lib/ews/templates/reply_to_item.rb +20 -18
- data/lib/ews/templates/task.rb +55 -55
- data/lib/ews/types/attachment.rb +75 -74
- data/lib/ews/types/attendee.rb +27 -25
- data/lib/ews/types/calendar_folder.rb +58 -59
- data/lib/ews/types/calendar_item.rb +133 -131
- data/lib/ews/types/contact.rb +11 -5
- data/lib/ews/types/contacts_folder.rb +10 -5
- data/lib/ews/types/copied_event.rb +47 -48
- data/lib/ews/types/created_event.rb +22 -20
- data/lib/ews/types/deleted_event.rb +22 -20
- data/lib/ews/types/distribution_list.rb +11 -5
- data/lib/ews/types/event.rb +60 -59
- data/lib/ews/types/export_items_response_message.rb +54 -50
- data/lib/ews/types/file_attachment.rb +63 -61
- data/lib/ews/types/folder.rb +58 -57
- data/lib/ews/types/free_busy_changed_event.rb +22 -20
- data/lib/ews/types/generic_folder.rb +348 -372
- data/lib/ews/types/item.rb +401 -397
- data/lib/ews/types/item_attachment.rb +87 -80
- data/lib/ews/types/item_field_uri_map.rb +201 -200
- data/lib/ews/types/mailbox_user.rb +146 -154
- data/lib/ews/types/meeting_cancellation.rb +11 -5
- data/lib/ews/types/meeting_message.rb +11 -5
- data/lib/ews/types/meeting_request.rb +11 -5
- data/lib/ews/types/meeting_response.rb +11 -5
- data/lib/ews/types/message.rb +11 -5
- data/lib/ews/types/modified_event.rb +43 -45
- data/lib/ews/types/moved_event.rb +47 -48
- data/lib/ews/types/new_mail_event.rb +22 -20
- data/lib/ews/types/out_of_office.rb +145 -144
- data/lib/ews/types/post_item.rb +11 -5
- data/lib/ews/types/search_folder.rb +10 -5
- data/lib/ews/types/status_event.rb +37 -36
- data/lib/ews/types/task.rb +39 -33
- data/lib/ews/types/tasks_folder.rb +31 -25
- data/lib/ews/types.rb +134 -139
- data/lib/viewpoint/logging/config.rb +19 -19
- data/lib/viewpoint/logging.rb +23 -17
- data/lib/viewpoint/string_utils.rb +31 -32
- data/lib/viewpoint.rb +18 -18
- metadata +50 -25
- data/Changelog.txt +0 -1004
|
@@ -1,780 +1,762 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Viewpoint
|
|
4
|
+
module EWS
|
|
5
|
+
module SOAP
|
|
6
|
+
# Exchange Data Service operations as listed in the EWS Documentation.
|
|
7
|
+
# @see http://msdn.microsoft.com/en-us/library/bb409286.aspx
|
|
8
|
+
module ExchangeDataServices
|
|
9
|
+
include Viewpoint::EWS::SOAP
|
|
10
|
+
|
|
11
|
+
# -------------- Item Operations -------------
|
|
12
|
+
|
|
13
|
+
# Identifies items that are located in a specified folder
|
|
14
|
+
# @see http://msdn.microsoft.com/en-us/library/aa566107.aspx
|
|
15
|
+
#
|
|
16
|
+
# @param [Hash] opts
|
|
17
|
+
# @option opts [Array<Hash>] :parent_folder_ids An Array of folder id Hashes, either a
|
|
18
|
+
# DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
|
19
|
+
# [{:id => <myid>, :change_key => <ck>}, {:id => :root}]
|
|
20
|
+
# @option opts [String] :traversal Shallow/Deep/SoftDeleted
|
|
21
|
+
# @option opts [Hash] :item_shape defines the ItemShape node
|
|
22
|
+
# @option item_shape [String] :base_shape IdOnly/Default/AllProperties
|
|
23
|
+
# @option item_shape :additional_properties
|
|
24
|
+
# See: http://msdn.microsoft.com/en-us/library/aa563810.aspx
|
|
25
|
+
# @option opts [Hash] :calendar_view Limit FindItem by a start and end date
|
|
26
|
+
# {:calendar_view => {:max_entries_returned => 2, :start_date =>
|
|
27
|
+
# <DateTime Obj>, :end_date => <DateTime Obj>}}
|
|
28
|
+
# @option opts [Hash] :contacts_view Limit FindItem between contact names
|
|
29
|
+
# {:contacts_view => {:max_entries_returned => 2, :initial_name => 'Dan',
|
|
30
|
+
# :final_name => 'Wally'}}
|
|
31
|
+
# @example
|
|
32
|
+
# { :parent_folder_ids => [{:id => root}],
|
|
33
|
+
# :traversal => 'Shallow',
|
|
34
|
+
# :item_shape => {:base_shape => 'Default'} }
|
|
35
|
+
def find_item(opts)
|
|
36
|
+
opts = opts.clone
|
|
37
|
+
%i[parent_folder_ids traversal item_shape].each do |k|
|
|
38
|
+
validate_param(opts, k, true)
|
|
39
|
+
end
|
|
40
|
+
req = build_soap! { |type, builder|
|
|
41
|
+
unless type == :header
|
|
42
|
+
builder.nbuild.FindItem(Traversal: camel_case(opts[:traversal])) {
|
|
43
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
44
|
+
builder.item_shape!(opts[:item_shape])
|
|
45
|
+
builder.indexed_page_item_view!(opts[:indexed_page_item_view]) if opts[:indexed_page_item_view]
|
|
46
|
+
# @todo add FractionalPageFolderView
|
|
47
|
+
builder.calendar_view!(opts[:calendar_view]) if opts[:calendar_view]
|
|
48
|
+
builder.contacts_view!(opts[:contacts_view]) if opts[:contacts_view]
|
|
49
|
+
builder.restriction!(opts[:restriction]) if opts[:restriction]
|
|
50
|
+
builder.parent_folder_ids!(opts[:parent_folder_ids])
|
|
51
|
+
}
|
|
52
|
+
end
|
|
49
53
|
}
|
|
54
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
50
55
|
end
|
|
51
|
-
end
|
|
52
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
53
|
-
end
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
57
|
+
# Gets items from the Exchange store
|
|
58
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565934(v=EXCHG.140).aspx
|
|
59
|
+
#
|
|
60
|
+
# @param [Hash] opts
|
|
61
|
+
# @option opts [Hash] :item_shape The item shape properties
|
|
62
|
+
# Ex: {:base_shape => 'Default'}
|
|
63
|
+
# @option opts [Array<Hash>] :item_ids ItemIds Hash. The keys in these Hashes can be
|
|
64
|
+
# :item_id, :occurrence_item_id, or :recurring_master_item_id. Please see the
|
|
65
|
+
# Microsoft docs for more information.
|
|
66
|
+
# @example
|
|
67
|
+
# opts = {
|
|
68
|
+
# :item_shape => {:base_shape => 'Default'},
|
|
69
|
+
# :item_ids => [
|
|
70
|
+
# {:item_id => {:id => 'id1'}},
|
|
71
|
+
# {:occurrence_item_id => {:recurring_master_id => 'rid1', :change_key => 'ck', :instance_index => 1}},
|
|
72
|
+
# {:recurring_master_item_id => {:occurrence_id => 'oid1', :change_key => 'ck'}}
|
|
73
|
+
# ]}
|
|
74
|
+
def get_item(opts)
|
|
75
|
+
opts = opts.clone
|
|
76
|
+
%i[item_shape item_ids].each do |k|
|
|
77
|
+
validate_param(opts, k, true)
|
|
78
|
+
end
|
|
79
|
+
req = build_soap! { |type, builder|
|
|
80
|
+
unless type == :header
|
|
81
|
+
builder.nbuild.GetItem {
|
|
82
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
83
|
+
builder.item_shape!(opts[:item_shape])
|
|
84
|
+
builder.item_ids!(opts[:item_ids])
|
|
85
|
+
}
|
|
86
|
+
end
|
|
84
87
|
}
|
|
88
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
85
89
|
end
|
|
86
|
-
end
|
|
87
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
88
|
-
end
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
91
|
+
# Defines a request to create an item in the Exchange store.
|
|
92
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565209(v=EXCHG.140).aspx
|
|
93
|
+
#
|
|
94
|
+
# @param [Hash] opts
|
|
95
|
+
# @option opts [String] :message_disposition How the item will be handled after it is created.
|
|
96
|
+
# Only applicable for to e-mail. Must be one of 'SaveOnly', 'SendOnly', or 'SendAndSaveCopy'
|
|
97
|
+
# @option opts [String] :send_meeting_invitations How meeting requests are handled after they
|
|
98
|
+
# are created. Required for calendar items. Must be one of 'SendToNone', 'SendOnlyToAll',
|
|
99
|
+
# 'SendToAllAndSaveCopy'
|
|
100
|
+
# @option opts [Hash] :saved_item_folder_id A well formatted folder_id Hash. Ex: {:id => :inbox}
|
|
101
|
+
# Will on work if 'SendOnly' is specified for :message_disposition
|
|
102
|
+
# @option opts [Array<Hash>] :items This is a complex Hash that conforms to various Item types.
|
|
103
|
+
# Please see the Microsoft documentation for this element.
|
|
104
|
+
# @example
|
|
105
|
+
# opts = {
|
|
106
|
+
# message_disposition: 'SendAndSaveCopy',
|
|
107
|
+
# items: [ {message:
|
|
108
|
+
# {subject: 'test2',
|
|
109
|
+
# body: {body_type: 'Text', text: 'this is a test'},
|
|
110
|
+
# to_recipients: [{mailbox: {email_address: 'dan.wanek@gmail.com'}}]
|
|
111
|
+
# }
|
|
112
|
+
# }]}
|
|
113
|
+
#
|
|
114
|
+
# opts = {
|
|
115
|
+
# send_meeting_invitations: 'SendToAllAndSaveCopy',
|
|
116
|
+
# items: [ {calendar_item:
|
|
117
|
+
# {subject: 'test cal item',
|
|
118
|
+
# body: {body_type: 'Text', text: 'this is a test cal item'},
|
|
119
|
+
# start: {text: Chronic.parse('tomorrow at 4pm').to_datetime.to_s},
|
|
120
|
+
# end: {text: Chronic.parse('tomorrow at 5pm').to_datetime.to_s},
|
|
121
|
+
# required_attendees: [
|
|
122
|
+
# {attendee: {mailbox: {email_address: 'dan.wanek@gmail.com'}}},
|
|
123
|
+
# ]
|
|
124
|
+
# }
|
|
125
|
+
# }]
|
|
126
|
+
def create_item(opts)
|
|
127
|
+
opts = opts.clone
|
|
128
|
+
[:items].each do |k|
|
|
129
|
+
validate_param(opts, k, true)
|
|
130
|
+
end
|
|
131
|
+
req = build_soap! { |type, builder|
|
|
132
|
+
attribs = {}
|
|
133
|
+
attribs['MessageDisposition'] = opts[:message_disposition] if opts[:message_disposition]
|
|
134
|
+
attribs['SendMeetingInvitations'] = opts[:send_meeting_invitations] if opts[:send_meeting_invitations]
|
|
135
|
+
unless type == :header
|
|
136
|
+
builder.nbuild.CreateItem(attribs) {
|
|
137
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
138
|
+
builder.saved_item_folder_id!(opts[:saved_item_folder_id]) if opts[:saved_item_folder_id]
|
|
139
|
+
builder.nbuild.Items {
|
|
140
|
+
opts[:items].each { |i|
|
|
141
|
+
# The key can be any number of item types like :message,
|
|
142
|
+
# :calendar, etc
|
|
143
|
+
ikey = i.keys.first
|
|
144
|
+
builder.send("#{ikey}!", i[ikey])
|
|
145
|
+
}
|
|
146
|
+
}
|
|
145
147
|
}
|
|
146
|
-
|
|
148
|
+
end
|
|
147
149
|
}
|
|
150
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
148
151
|
end
|
|
149
|
-
end
|
|
150
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
151
|
-
end
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
153
|
+
# Used to modify the properties of an existing item in the Exchange store
|
|
154
|
+
# @see http://msdn.microsoft.com/en-us/library/aa581084(v=exchg.140).aspx
|
|
155
|
+
#
|
|
156
|
+
# @param [Hash] opts
|
|
157
|
+
# @option opts [String] :conflict_resolution Identifies the type of conflict resolution to
|
|
158
|
+
# try during an update. The default value is AutoResolve. Available options are
|
|
159
|
+
# 'NeverOverwrite', 'AutoResolve', 'AlwaysOverwrite'
|
|
160
|
+
# @option opts [String] :message_disposition How the item will be handled after it is updated.
|
|
161
|
+
# Only applicable for to e-mail. Must be one of 'SaveOnly', 'SendOnly', or 'SendAndSaveCopy'
|
|
162
|
+
# @option opts [String] :send_meeting_invitations_or_cancellations How meeting requests are
|
|
163
|
+
# handled after they are updated. Required for calendar items. Must be one of 'SendToNone',
|
|
164
|
+
# 'SendOnlyToAll', 'SendOnlyToChanged', 'SendToAllAndSaveCopy', 'SendToChangedAndSaveCopy'
|
|
165
|
+
# @option opts [Hash] :saved_item_folder_id A well formatted folder_id Hash. Ex: {:id => :sentitems}
|
|
166
|
+
# Will on work if 'SendOnly' is specified for :message_disposition
|
|
167
|
+
# @option opts [Array<Hash>] :item_changes an array of ItemChange elements that identify items
|
|
168
|
+
# and the updates to apply to the items. See the Microsoft docs for more information.
|
|
169
|
+
# @example
|
|
170
|
+
# opts = {
|
|
171
|
+
# :send_meeting_invitations_or_cancellations => 'SendOnlyToChangedAndSaveCopy',
|
|
172
|
+
# :item_changes => [
|
|
173
|
+
# { :item_id => {:id => 'id1'},
|
|
174
|
+
# :updates => [
|
|
175
|
+
# {:set_item_field => {
|
|
176
|
+
# :field_uRI => {:field_uRI => 'item:Subject'},
|
|
177
|
+
# # The following needs to conform to #build_xml! format for now
|
|
178
|
+
# :calendar_item => { :sub_elements => [{:subject => {:text => 'Test Subject'}}]}
|
|
179
|
+
# }}
|
|
180
|
+
# ]
|
|
181
|
+
# }
|
|
182
|
+
# ]
|
|
183
|
+
# }
|
|
184
|
+
def update_item(opts)
|
|
185
|
+
opts = opts.clone
|
|
186
|
+
[:item_changes].each do |k|
|
|
187
|
+
validate_param(opts, k, true)
|
|
188
|
+
end
|
|
189
|
+
req = build_soap! { |type, builder|
|
|
190
|
+
attribs = {}
|
|
191
|
+
attribs['MessageDisposition'] = opts[:message_disposition] if opts[:message_disposition]
|
|
192
|
+
attribs['ConflictResolution'] = opts[:conflict_resolution] if opts[:conflict_resolution]
|
|
193
|
+
if opts[:send_meeting_invitations_or_cancellations]
|
|
194
|
+
attribs['SendMeetingInvitationsOrCancellations'] =
|
|
195
|
+
opts[:send_meeting_invitations_or_cancellations]
|
|
196
|
+
end
|
|
197
|
+
unless type == :header
|
|
198
|
+
builder.nbuild.UpdateItem(attribs) {
|
|
199
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
200
|
+
builder.saved_item_folder_id!(opts[:saved_item_folder_id]) if opts[:saved_item_folder_id]
|
|
201
|
+
builder.item_changes!(opts[:item_changes])
|
|
202
|
+
}
|
|
203
|
+
end
|
|
200
204
|
}
|
|
205
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
201
206
|
end
|
|
202
|
-
end
|
|
203
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
204
|
-
end
|
|
205
207
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
208
|
+
# Delete an item from a mailbox in the Exchange store
|
|
209
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580484(v=exchg.140).aspx
|
|
210
|
+
#
|
|
211
|
+
# @param [Hash] opts
|
|
212
|
+
# @option opts [String] :delete_type Describes how an item is deleted. Must be one of
|
|
213
|
+
# 'HardDelete', 'SoftDelete', or 'MoveToDeletedItems'
|
|
214
|
+
# @option opts [String] :send_meeting_cancellations How meetings are handled after they
|
|
215
|
+
# are deleted. Required for calendar items. Must be one of 'SendToNone', 'SendOnlyToAll',
|
|
216
|
+
# 'SendToAllAndSaveCopy'
|
|
217
|
+
# @option opts [String] :affected_task_occurrences Describes whether a task instance or a
|
|
218
|
+
# task master is deleted by a DeleteItem Operation. This attribute is required when
|
|
219
|
+
# tasks are deleted. Must be one of 'AllOccurrences' or 'SpecifiedOccurrenceOnly'
|
|
220
|
+
# @option opts [Array<Hash>] :item_ids ItemIds Hash. The keys in these Hashes can be
|
|
221
|
+
# :item_id, :occurrence_item_id, or :recurring_master_item_id. Please see the
|
|
222
|
+
# Microsoft docs for more information.
|
|
223
|
+
# @example
|
|
224
|
+
# opts = {
|
|
225
|
+
# :delete_type => 'MoveToDeletedItems',
|
|
226
|
+
# :item_ids => [{:item_id => {:id => 'id1'}}]
|
|
227
|
+
# }
|
|
228
|
+
# inst.delete_item(opts)
|
|
229
|
+
def delete_item(opts)
|
|
230
|
+
opts = opts.clone
|
|
231
|
+
%i[delete_type item_ids].each do |k|
|
|
232
|
+
validate_param(opts, k, true)
|
|
233
|
+
end
|
|
234
|
+
req = build_soap! { |type, builder|
|
|
235
|
+
attribs = { 'DeleteType' => opts[:delete_type] }
|
|
236
|
+
attribs['SendMeetingCancellations'] = opts[:send_meeting_cancellations] if opts[:send_meeting_cancellations]
|
|
237
|
+
attribs['AffectedTaskOccurrences'] = opts[:affected_task_occurrences] if opts[:affected_task_occurrences]
|
|
238
|
+
unless type == :header
|
|
239
|
+
builder.nbuild.DeleteItem(attribs) {
|
|
240
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
241
|
+
builder.item_ids!(opts[:item_ids])
|
|
242
|
+
}
|
|
243
|
+
end
|
|
241
244
|
}
|
|
245
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
242
246
|
end
|
|
243
|
-
end
|
|
244
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
245
|
-
end
|
|
246
247
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
248
|
+
# Used to move one or more items to a single destination folder.
|
|
249
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565781(v=exchg.140).aspx
|
|
250
|
+
#
|
|
251
|
+
# @param [Hash] opts
|
|
252
|
+
# @option opts [Hash] :to_folder_id A well formatted folder_id Hash. Ex: {:id => :inbox}
|
|
253
|
+
# @option opts [Array<Hash>] :item_ids ItemIds Hash. The keys in these Hashes can be
|
|
254
|
+
# :item_id, :occurrence_item_id, or :recurring_master_item_id. Please see the
|
|
255
|
+
# Microsoft docs for more information.
|
|
256
|
+
# @option opts [Boolean] :return_new_item_ids Indicates whether the item identifiers of
|
|
257
|
+
# new items are returned in the response
|
|
258
|
+
# @example
|
|
259
|
+
# opts = {
|
|
260
|
+
# :to_folder_id => {:id => :inbox},
|
|
261
|
+
# :item_ids => [
|
|
262
|
+
# {:item_id => {:id => 'id1'}},
|
|
263
|
+
# {:item_id => {:id => 'id2'}},
|
|
264
|
+
# ],
|
|
265
|
+
# :return_new_item_ids => true
|
|
266
|
+
# }
|
|
267
|
+
# obj.move_item(opts)
|
|
268
|
+
def move_item(opts)
|
|
269
|
+
opts = opts.clone
|
|
270
|
+
%i[to_folder_id item_ids].each do |k|
|
|
271
|
+
validate_param(opts, k, true)
|
|
272
|
+
end
|
|
273
|
+
return_new_ids = validate_param(opts, :return_new_item_ids, false, true)
|
|
274
|
+
|
|
275
|
+
req = build_soap! { |type, builder|
|
|
276
|
+
unless type == :header
|
|
277
|
+
builder.nbuild.MoveItem {
|
|
278
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
279
|
+
builder.to_folder_id!(opts[:to_folder_id])
|
|
280
|
+
builder.item_ids!(opts[:item_ids])
|
|
281
|
+
builder.return_new_item_ids!(return_new_ids)
|
|
282
|
+
}
|
|
283
|
+
end
|
|
282
284
|
}
|
|
285
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
283
286
|
end
|
|
284
|
-
end
|
|
285
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
286
|
-
end
|
|
287
287
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
288
|
+
# Copies items and puts the items in a different folder
|
|
289
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565012(v=exchg.140).aspx
|
|
290
|
+
#
|
|
291
|
+
# @param [Hash] opts
|
|
292
|
+
# @option opts [Hash] :to_folder_id A well formatted folder_id Hash. Ex: {:id => :inbox}
|
|
293
|
+
# @option opts [Array<Hash>] :item_ids ItemIds Hash. The keys in these Hashes can be
|
|
294
|
+
# :item_id, :occurrence_item_id, or :recurring_master_item_id. Please see the
|
|
295
|
+
# Microsoft docs for more information.
|
|
296
|
+
# @option opts [Boolean] :return_new_item_ids Indicates whether the item identifiers of
|
|
297
|
+
# new items are returned in the response
|
|
298
|
+
# @example
|
|
299
|
+
# opts = {
|
|
300
|
+
# :to_folder_id => {:id => :inbox},
|
|
301
|
+
# :item_ids => [
|
|
302
|
+
# {:item_id => {:id => 'id1'}},
|
|
303
|
+
# {:item_id => {:id => 'id2'}},
|
|
304
|
+
# ],
|
|
305
|
+
# :return_new_item_ids => true
|
|
306
|
+
# }
|
|
307
|
+
# obj.copy_item(opts)
|
|
308
|
+
def copy_item(opts)
|
|
309
|
+
opts = opts.clone
|
|
310
|
+
%i[to_folder_id item_ids].each do |k|
|
|
311
|
+
validate_param(opts, k, true)
|
|
312
|
+
end
|
|
313
|
+
return_new_ids = validate_param(opts, :return_new_item_ids, false, true)
|
|
314
|
+
|
|
315
|
+
req = build_soap! { |type, builder|
|
|
316
|
+
unless type == :header
|
|
317
|
+
builder.nbuild.CopyItem {
|
|
318
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
319
|
+
builder.to_folder_id!(opts[:to_folder_id])
|
|
320
|
+
builder.item_ids!(opts[:item_ids])
|
|
321
|
+
builder.return_new_item_ids!(return_new_ids)
|
|
322
|
+
}
|
|
323
|
+
end
|
|
323
324
|
}
|
|
325
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
324
326
|
end
|
|
325
|
-
end
|
|
326
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
327
|
-
end
|
|
328
327
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
328
|
+
# Used to send e-mail messages that are located in the Exchange store.
|
|
329
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580238(v=exchg.140).aspx
|
|
330
|
+
#
|
|
331
|
+
# @param [Hash] opts
|
|
332
|
+
# @option opts [Boolean] :save_item_to_folder To save or not to save... save! :-)
|
|
333
|
+
# @option opts [Hash] :saved_item_folder_id A well formatted folder_id Hash. Ex: {:id => :sentitems}
|
|
334
|
+
# @option opts [Array<Hash>] :item_ids ItemIds Hash. The keys in these Hashes can be
|
|
335
|
+
# :item_id, :occurrence_item_id, or :recurring_master_item_id. Please see the
|
|
336
|
+
# Microsoft docs for more information.
|
|
337
|
+
# @example
|
|
338
|
+
# opts = {
|
|
339
|
+
# :save_item_to_folder => true,
|
|
340
|
+
# :saved_item_folder_id => {:id => :sentitems},
|
|
341
|
+
# :item_ids => [
|
|
342
|
+
# {:item_id => {:id => 'id1'}},
|
|
343
|
+
# {:item_id => {:id => 'id2'}},
|
|
344
|
+
# ]}
|
|
345
|
+
# obj.send_item(opts)
|
|
346
|
+
def send_item(opts)
|
|
347
|
+
opts = opts.clone
|
|
348
|
+
[:item_ids].each do |k|
|
|
349
|
+
validate_param(opts, k, true)
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
req = build_soap! { |type, builder|
|
|
353
|
+
attribs = {}
|
|
354
|
+
attribs['SaveItemToFolder'] = validate_param(opts, :save_item_to_folder, false, true)
|
|
355
|
+
unless type == :header
|
|
356
|
+
builder.nbuild.SendItem(attribs) {
|
|
357
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
358
|
+
builder.item_ids!(opts[:item_ids])
|
|
359
|
+
builder.saved_item_folder_id!(opts[:saved_item_folder_id]) if opts[:saved_item_folder_id]
|
|
360
|
+
}
|
|
361
|
+
end
|
|
362
362
|
}
|
|
363
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
363
364
|
end
|
|
364
|
-
end
|
|
365
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
366
|
-
end
|
|
367
365
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
366
|
+
# Export items as a base64 string
|
|
367
|
+
# @see http://msdn.microsoft.com/en-us/library/ff709503(v=exchg.140).aspx
|
|
368
|
+
#
|
|
369
|
+
# (Requires Exchange version equal or newer than VERSION 2010 SP 1)
|
|
370
|
+
#
|
|
371
|
+
# @param ids [Array] array of item ids. Can also be a single id value
|
|
372
|
+
def export_items(ids)
|
|
373
|
+
validate_version(VERSION_2010_SP1)
|
|
374
|
+
ids = ids.clone
|
|
375
|
+
[:item_ids].each do |k|
|
|
376
|
+
validate_param(ids, k, true)
|
|
377
|
+
end
|
|
378
|
+
req = build_soap! { |type, builder|
|
|
379
|
+
builder.export_item_ids!(ids[:item_ids]) unless type == :header
|
|
380
|
+
}
|
|
381
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
384
382
|
end
|
|
385
|
-
end
|
|
386
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
387
|
-
end
|
|
388
383
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
384
|
+
# ------------- Folder Operations ------------
|
|
385
|
+
|
|
386
|
+
# Creates folders, calendar folders, contacts folders, tasks folders, and search folders.
|
|
387
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563574.aspx CreateFolder
|
|
388
|
+
#
|
|
389
|
+
# @param [Hash] opts
|
|
390
|
+
# @option opts [Hash] :parent_folder_id A hash with either the name of a
|
|
391
|
+
# folder or it's numerical ID.
|
|
392
|
+
# See: http://msdn.microsoft.com/en-us/library/aa565998.aspx
|
|
393
|
+
# {:id => :root} or {:id => 'myfolderid#'}
|
|
394
|
+
# @option opts [Array<Hash>] :folders An array of hashes of folder types
|
|
395
|
+
# that conform to input for build_xml!
|
|
396
|
+
# @example [
|
|
397
|
+
# {:folder =>
|
|
398
|
+
# {:display_name => "New Folder"}},
|
|
399
|
+
# {:calendar_folder =>
|
|
400
|
+
# {:folder_id => {:id => 'blah', :change_key => 'blah'}}}
|
|
401
|
+
def create_folder(opts)
|
|
402
|
+
opts = opts.clone
|
|
403
|
+
req = build_soap! { |type, builder|
|
|
404
|
+
unless type == :header
|
|
405
|
+
builder.nbuild.CreateFolder { |x|
|
|
406
|
+
x.parent.default_namespace = @default_ns
|
|
407
|
+
builder.parent_folder_id!(opts[:parent_folder_id])
|
|
408
|
+
builder.folders!(opts[:folders])
|
|
409
|
+
}
|
|
410
|
+
end
|
|
415
411
|
}
|
|
412
|
+
do_soap_request(req)
|
|
416
413
|
end
|
|
417
|
-
end
|
|
418
|
-
do_soap_request(req)
|
|
419
|
-
end
|
|
420
414
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
415
|
+
# Defines a request to copy folders in the Exchange store
|
|
416
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563949.aspx
|
|
417
|
+
# @param [Hash] to_folder_id The target FolderId
|
|
418
|
+
# {:id => <myid>, :change_key => <optional ck>}
|
|
419
|
+
# @param [Array<Hash>] *sources The source Folders
|
|
420
|
+
# {:id => <myid>, :change_key => <optional_ck>},
|
|
421
|
+
# {:id => <myid2>, :change_key => <optional_ck>}
|
|
422
|
+
def copy_folder(to_folder_id, *sources)
|
|
423
|
+
req = build_soap! { |type, builder|
|
|
424
|
+
unless type == :header
|
|
425
|
+
builder.nbuild.CopyFolder {
|
|
426
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
427
|
+
builder.to_folder_id!(to_folder_id)
|
|
428
|
+
builder.folder_ids!(sources.flatten)
|
|
429
|
+
}
|
|
430
|
+
end
|
|
436
431
|
}
|
|
432
|
+
do_soap_request(req)
|
|
437
433
|
end
|
|
438
|
-
end
|
|
439
|
-
do_soap_request(req)
|
|
440
|
-
end
|
|
441
434
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
435
|
+
# Deletes folders from a mailbox.
|
|
436
|
+
# @see http://msdn.microsoft.com/en-us/library/aa564767.aspx DeleteFolder
|
|
437
|
+
#
|
|
438
|
+
# @param [Hash] opts
|
|
439
|
+
# @option opts [Array<Hash>] :folder_ids An array of folder_ids in the form:
|
|
440
|
+
# [ {:id => 'myfolderID##asdfs', :change_key => 'asdfasdf'},
|
|
441
|
+
# {:id => :msgfolderroot} ] # Don't do this for real
|
|
442
|
+
# @option opts [String,nil] :delete_type Type of delete to do:
|
|
443
|
+
# HardDelete/SoftDelete/MoveToDeletedItems
|
|
444
|
+
# @option opts [String,nil] :act_as User to act on behalf as. This user
|
|
445
|
+
# must have been given delegate access to this folder or else this
|
|
446
|
+
# operation will fail.
|
|
447
|
+
def delete_folder(opts)
|
|
448
|
+
req = build_soap! { |type, builder|
|
|
449
|
+
unless type == :header
|
|
450
|
+
builder.nbuild.DeleteFolder('DeleteType' => opts[:delete_type]) {
|
|
451
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
452
|
+
builder.folder_ids!(opts[:folder_ids], opts[:act_as])
|
|
453
|
+
}
|
|
454
|
+
end
|
|
461
455
|
}
|
|
456
|
+
do_soap_request(req)
|
|
462
457
|
end
|
|
463
|
-
end
|
|
464
|
-
do_soap_request(req)
|
|
465
|
-
end
|
|
466
|
-
|
|
467
|
-
# Find subfolders of an identified folder
|
|
468
|
-
# @see http://msdn.microsoft.com/en-us/library/aa563918.aspx
|
|
469
|
-
#
|
|
470
|
-
# @param [Hash] opts
|
|
471
|
-
# @option opts [Array<Hash>] :parent_folder_ids An Array of folder id Hashes,
|
|
472
|
-
# either a DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
|
473
|
-
# [{:id => <myid>, :change_key => <ck>}, {:id => :root}]
|
|
474
|
-
# @option opts [String] :traversal Shallow/Deep/SoftDeleted
|
|
475
|
-
# @option opts [Hash] :folder_shape defines the FolderShape node
|
|
476
|
-
# See: http://msdn.microsoft.com/en-us/library/aa494311.aspx
|
|
477
|
-
# @option folder_shape [String] :base_shape IdOnly/Default/AllProperties
|
|
478
|
-
# @option folder_shape :additional_properties
|
|
479
|
-
# See: http://msdn.microsoft.com/en-us/library/aa563810.aspx
|
|
480
|
-
# @option opts [Hash] :restriction A well formatted restriction Hash.
|
|
481
|
-
# @example
|
|
482
|
-
# { :parent_folder_ids => [{:id => root}],
|
|
483
|
-
# :traversal => 'Deep',
|
|
484
|
-
# :folder_shape => {:base_shape => 'Default'} }
|
|
485
|
-
# @todo add FractionalPageFolderView
|
|
486
|
-
def find_folder(opts)
|
|
487
|
-
opts = opts.clone
|
|
488
|
-
[:parent_folder_ids, :traversal, :folder_shape].each do |k|
|
|
489
|
-
validate_param(opts, k, true)
|
|
490
|
-
end
|
|
491
458
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
459
|
+
# Find subfolders of an identified folder
|
|
460
|
+
# @see http://msdn.microsoft.com/en-us/library/aa563918.aspx
|
|
461
|
+
#
|
|
462
|
+
# @param [Hash] opts
|
|
463
|
+
# @option opts [Array<Hash>] :parent_folder_ids An Array of folder id Hashes,
|
|
464
|
+
# either a DistinguishedFolderId (must me a Symbol) or a FolderId (String)
|
|
465
|
+
# [{:id => <myid>, :change_key => <ck>}, {:id => :root}]
|
|
466
|
+
# @option opts [String] :traversal Shallow/Deep/SoftDeleted
|
|
467
|
+
# @option opts [Hash] :folder_shape defines the FolderShape node
|
|
468
|
+
# See: http://msdn.microsoft.com/en-us/library/aa494311.aspx
|
|
469
|
+
# @option folder_shape [String] :base_shape IdOnly/Default/AllProperties
|
|
470
|
+
# @option folder_shape :additional_properties
|
|
471
|
+
# See: http://msdn.microsoft.com/en-us/library/aa563810.aspx
|
|
472
|
+
# @option opts [Hash] :restriction A well formatted restriction Hash.
|
|
473
|
+
# @example
|
|
474
|
+
# { :parent_folder_ids => [{:id => root}],
|
|
475
|
+
# :traversal => 'Deep',
|
|
476
|
+
# :folder_shape => {:base_shape => 'Default'} }
|
|
477
|
+
# @todo add FractionalPageFolderView
|
|
478
|
+
def find_folder(opts)
|
|
479
|
+
opts = opts.clone
|
|
480
|
+
%i[parent_folder_ids traversal folder_shape].each do |k|
|
|
481
|
+
validate_param(opts, k, true)
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
req = build_soap! { |type, builder|
|
|
485
|
+
unless type == :header
|
|
486
|
+
builder.nbuild.FindFolder(Traversal: camel_case(opts[:traversal])) {
|
|
487
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
488
|
+
builder.folder_shape!(opts[:folder_shape])
|
|
489
|
+
builder.restriction!(opts[:restriction]) if opts[:restriction]
|
|
490
|
+
builder.parent_folder_ids!(opts[:parent_folder_ids])
|
|
491
|
+
}
|
|
492
|
+
end
|
|
500
493
|
}
|
|
494
|
+
do_soap_request(req)
|
|
501
495
|
end
|
|
502
|
-
end
|
|
503
|
-
do_soap_request(req)
|
|
504
|
-
end
|
|
505
496
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
497
|
+
# Gets folders from the Exchange store
|
|
498
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580274.aspx
|
|
499
|
+
#
|
|
500
|
+
# @param [Hash] opts
|
|
501
|
+
# @option opts [Array<Hash>] :folder_ids An array of folder_ids in the form:
|
|
502
|
+
# [ {:id => 'myfolderID##asdfs', :change_key => 'asdfasdf'},
|
|
503
|
+
# {:id => :msgfolderroot} ]
|
|
504
|
+
# @option opts [Hash] :folder_shape defines the FolderShape node
|
|
505
|
+
# @option folder_shape [String] :base_shape IdOnly/Default/AllProperties
|
|
506
|
+
# @option folder_shape :additional_properties
|
|
507
|
+
# @option opts [String,nil] :act_as User to act on behalf as. This user must
|
|
508
|
+
# have been given delegate access to this folder or else this operation
|
|
509
|
+
# will fail.
|
|
510
|
+
# @example
|
|
511
|
+
# { :folder_ids => [{:id => :msgfolderroot}],
|
|
512
|
+
# :folder_shape => {:base_shape => 'Default'} }
|
|
513
|
+
def get_folder(opts)
|
|
514
|
+
opts = opts.clone
|
|
515
|
+
%i[folder_ids folder_shape].each do |k|
|
|
516
|
+
validate_param(opts, k, true)
|
|
517
|
+
end
|
|
518
|
+
validate_param(opts[:folder_shape], :base_shape, true)
|
|
519
|
+
req = build_soap! { |type, builder|
|
|
520
|
+
unless type == :header
|
|
521
|
+
builder.nbuild.GetFolder {
|
|
522
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
523
|
+
builder.folder_shape!(opts[:folder_shape])
|
|
524
|
+
builder.folder_ids!(opts[:folder_ids], opts[:act_as])
|
|
525
|
+
}
|
|
526
|
+
end
|
|
535
527
|
}
|
|
528
|
+
do_soap_request(req)
|
|
536
529
|
end
|
|
537
|
-
end
|
|
538
|
-
do_soap_request(req)
|
|
539
|
-
end
|
|
540
530
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
531
|
+
# Defines a request to move folders in the Exchange store
|
|
532
|
+
# @see http://msdn.microsoft.com/en-us/library/aa566202.aspx
|
|
533
|
+
# @param [Hash] to_folder_id The target FolderId
|
|
534
|
+
# {:id => <myid>, :change_key => <optional ck>}
|
|
535
|
+
# @param [Array<Hash>] *sources The source Folders
|
|
536
|
+
# {:id => <myid>, :change_key => <optional_ck>},
|
|
537
|
+
# {:id => <myid2>, :change_key => <optional_ck>}
|
|
538
|
+
def move_folder(to_folder_id, *sources)
|
|
539
|
+
req = build_soap! { |type, builder|
|
|
540
|
+
unless type == :header
|
|
541
|
+
builder.nbuild.MoveFolder {
|
|
542
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
543
|
+
builder.to_folder_id!(to_folder_id)
|
|
544
|
+
builder.folder_ids!(sources.flatten)
|
|
545
|
+
}
|
|
546
|
+
end
|
|
556
547
|
}
|
|
548
|
+
do_soap_request(req)
|
|
557
549
|
end
|
|
558
|
-
end
|
|
559
|
-
do_soap_request(req)
|
|
560
|
-
end
|
|
561
550
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
551
|
+
# Update properties for a specified folder
|
|
552
|
+
# There is a lot more building in this method because most of the builders
|
|
553
|
+
# are only used for this operation so there was no need to externalize them
|
|
554
|
+
# for re-use.
|
|
555
|
+
# @see http://msdn.microsoft.com/en-us/library/aa580519(v=EXCHG.140).aspx
|
|
556
|
+
# @param [Array<Hash>] folder_changes an Array of well formatted Hashes
|
|
557
|
+
def update_folder(folder_changes)
|
|
558
|
+
req = build_soap! { |type, builder|
|
|
559
|
+
unless type == :header
|
|
560
|
+
builder.nbuild.UpdateFolder {
|
|
561
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
562
|
+
builder.nbuild.FolderChanges {
|
|
563
|
+
folder_changes.each do |fc|
|
|
564
|
+
builder[NS_EWS_TYPES].FolderChange {
|
|
565
|
+
builder.dispatch_folder_id!(fc)
|
|
566
|
+
builder[NS_EWS_TYPES].Updates {
|
|
567
|
+
# @todo finish implementation
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
end
|
|
581
571
|
}
|
|
582
|
-
|
|
583
|
-
|
|
572
|
+
}
|
|
573
|
+
end
|
|
584
574
|
}
|
|
575
|
+
do_soap_request(req)
|
|
585
576
|
end
|
|
586
|
-
end
|
|
587
|
-
do_soap_request(req)
|
|
588
|
-
end
|
|
589
577
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
578
|
+
# Empties folders in a mailbox.
|
|
579
|
+
# @see http://msdn.microsoft.com/en-us/library/ff709484.aspx
|
|
580
|
+
# @param [Hash] opts
|
|
581
|
+
# @option opts [String] :delete_type Must be one of
|
|
582
|
+
# ExchangeDataServices::HARD_DELETE, SOFT_DELETE, or MOVE_TO_DELETED_ITEMS
|
|
583
|
+
# @option opts [Boolean] :delete_sub_folders
|
|
584
|
+
# @option opts [Array<Hash>] :folder_ids An array of folder_ids in the form:
|
|
585
|
+
# [ {:id => 'myfolderID##asdfs', :change_key => 'asdfasdf'},
|
|
586
|
+
# {:id => 'blah'} ]
|
|
587
|
+
# @todo Finish
|
|
588
|
+
def empty_folder(opts)
|
|
589
|
+
validate_version(VERSION_2010_SP1)
|
|
590
|
+
ef_opts = {}
|
|
591
|
+
%i[delete_type delete_sub_folders].each do |k|
|
|
592
|
+
ef_opts[camel_case(k)] = validate_param(opts, k, true)
|
|
593
|
+
end
|
|
594
|
+
fids = validate_param opts, :folder_ids, true
|
|
595
|
+
|
|
596
|
+
req = build_soap! { |type, builder|
|
|
597
|
+
unless type == :header
|
|
598
|
+
builder.nbuild.EmptyFolder(ef_opts) { |_x|
|
|
599
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
600
|
+
builder.folder_ids!(fids)
|
|
601
|
+
}
|
|
602
|
+
end
|
|
614
603
|
}
|
|
604
|
+
do_soap_request(req)
|
|
615
605
|
end
|
|
616
|
-
end
|
|
617
|
-
do_soap_request(req)
|
|
618
|
-
end
|
|
619
606
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
607
|
+
# ----------- Attachment Operations ----------
|
|
608
|
+
|
|
609
|
+
# Used to retrieve existing attachments on items in the Exchange store
|
|
610
|
+
# @see http://msdn.microsoft.com/en-us/library/aa494316.aspx
|
|
611
|
+
# @param [Hash] opts
|
|
612
|
+
# @option opts [Array] :attachment_ids Attachment Ids to fetch
|
|
613
|
+
# @option opts [Hash] :attachment_shape Attachment shape
|
|
614
|
+
# include_mime_content: true or false (optional)
|
|
615
|
+
# body_type: "Best" | "HTML" | "Text" (optional)
|
|
616
|
+
# filter_html_content: true or false (optional)
|
|
617
|
+
# additional_properties: @todo finish implementation
|
|
618
|
+
def get_attachment(opts)
|
|
619
|
+
opts = opts.clone
|
|
620
|
+
[:attachment_ids].each do |k|
|
|
621
|
+
validate_param(opts, k, true)
|
|
622
|
+
end
|
|
623
|
+
req = build_soap! { |type, builder|
|
|
624
|
+
unless type == :header
|
|
625
|
+
builder.nbuild.GetAttachment { |_x|
|
|
626
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
627
|
+
builder.attachment_ids!(opts[:attachment_ids])
|
|
628
|
+
}
|
|
629
|
+
end
|
|
642
630
|
}
|
|
631
|
+
do_soap_request(req)
|
|
643
632
|
end
|
|
644
|
-
end
|
|
645
|
-
do_soap_request(req)
|
|
646
|
-
end
|
|
647
633
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
634
|
+
# Creates either an item or file attachment and attaches it to the specified item.
|
|
635
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565877.aspx
|
|
636
|
+
# @param [Hash] opts
|
|
637
|
+
# @option opts [Hash] :parent_id {id: <id>, change_key: <ck>}
|
|
638
|
+
# @option opts [Array<Hash>] :files An Array of Base64 encoded Strings with
|
|
639
|
+
# an associated name:
|
|
640
|
+
# {:name => <name>, :content => <Base64 encoded string>}
|
|
641
|
+
# @option opts [Array] :items Exchange Items to attach to this Item
|
|
642
|
+
# @todo Need to implement attachment of Item types
|
|
643
|
+
def create_attachment(opts)
|
|
644
|
+
opts = opts.clone
|
|
645
|
+
[:parent_id].each do |k|
|
|
646
|
+
validate_param(opts, k, true)
|
|
647
|
+
end
|
|
648
|
+
validate_param(opts, :files, false, [])
|
|
649
|
+
validate_param(opts, :items, false, [])
|
|
650
|
+
|
|
651
|
+
req = build_soap! { |type, builder|
|
|
652
|
+
unless type == :header
|
|
653
|
+
builder.nbuild.CreateAttachment { |x|
|
|
654
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
655
|
+
builder.parent_item_id!(opts[:parent_id])
|
|
656
|
+
x.Attachments {
|
|
657
|
+
opts[:files].each do |fa|
|
|
658
|
+
builder.file_attachment!(fa)
|
|
659
|
+
end
|
|
660
|
+
opts[:items].each do |ia|
|
|
661
|
+
builder.item_attachment!(ia)
|
|
662
|
+
end
|
|
663
|
+
opts[:inline_files].each do |fi|
|
|
664
|
+
builder.inline_attachment!(fi)
|
|
665
|
+
end
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
end
|
|
682
669
|
}
|
|
670
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
683
671
|
end
|
|
684
|
-
end
|
|
685
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
686
|
-
end
|
|
687
|
-
|
|
688
672
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
673
|
+
# ------------ Utility Operations ------------
|
|
674
|
+
|
|
675
|
+
# Exposes the full membership of distribution lists.
|
|
676
|
+
# @see http://msdn.microsoft.com/en-us/library/aa494152.aspx ExpandDL
|
|
677
|
+
#
|
|
678
|
+
# @todo Fully support all of the ExpandDL operations. Today it just supports
|
|
679
|
+
# taking an e-mail address as an argument
|
|
680
|
+
# @param [Hash] opts
|
|
681
|
+
# @option opts [String] :email_address The e-mail address of the
|
|
682
|
+
# distribution to resolve
|
|
683
|
+
# @option opts [Hash] :item_id The ItemId of the private distribution to resolve.
|
|
684
|
+
# {:id => 'my id'}
|
|
685
|
+
def expand_dl(opts)
|
|
686
|
+
opts = opts.clone
|
|
687
|
+
req = build_soap! { |type, builder|
|
|
688
|
+
unless type == :header
|
|
689
|
+
builder.nbuild.ExpandDL { |x|
|
|
690
|
+
x.parent.default_namespace = @default_ns
|
|
691
|
+
x.Mailbox { |mb|
|
|
692
|
+
key = :email_address
|
|
693
|
+
mb[NS_EWS_TYPES].EmailAddress(opts[key]) if opts[key]
|
|
694
|
+
builder.item_id! if opts[:item_id]
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
end
|
|
712
698
|
}
|
|
713
|
-
|
|
699
|
+
do_soap_request(req)
|
|
714
700
|
end
|
|
715
|
-
end
|
|
716
|
-
do_soap_request(req)
|
|
717
|
-
end
|
|
718
701
|
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
702
|
+
# Resolve ambiguous e-mail addresses and display names
|
|
703
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565329.aspx ResolveNames
|
|
704
|
+
# @see http://msdn.microsoft.com/en-us/library/aa581054.aspx UnresolvedEntry
|
|
705
|
+
# @param [Hash] opts
|
|
706
|
+
# @option opts [String] :name the unresolved entry
|
|
707
|
+
# @option opts [Boolean] :full_contact_data (true) Whether or not to return
|
|
708
|
+
# the full contact details.
|
|
709
|
+
# @option opts [String] :search_scope where to seach for this entry, one of
|
|
710
|
+
# SOAP::Contacts, SOAP::ActiveDirectory, SOAP::ActiveDirectoryContacts
|
|
711
|
+
# (default), SOAP::ContactsActiveDirectory
|
|
712
|
+
# @option opts [String, FolderId] :parent_folder_id either the name of a
|
|
713
|
+
# folder or it's numerical ID.
|
|
714
|
+
# @see http://msdn.microsoft.com/en-us/library/aa565998.aspx
|
|
715
|
+
def resolve_names(opts)
|
|
716
|
+
opts = opts.clone
|
|
717
|
+
fcd = opts.key?(:full_contact_data) ? opts[:full_contact_data] : true
|
|
718
|
+
req = build_soap! { |type, builder|
|
|
719
|
+
unless type == :header
|
|
720
|
+
builder.nbuild.ResolveNames { |x|
|
|
721
|
+
x.parent['ReturnFullContactData'] = fcd.to_s
|
|
722
|
+
x.parent['SearchScope'] = opts[:search_scope] if opts[:search_scope]
|
|
723
|
+
x.parent.default_namespace = @default_ns
|
|
724
|
+
# @todo builder.nbuild.ParentFolderIds
|
|
725
|
+
x.UnresolvedEntry(opts[:name])
|
|
726
|
+
}
|
|
727
|
+
end
|
|
728
|
+
}
|
|
729
|
+
do_soap_request(req)
|
|
745
730
|
end
|
|
746
|
-
end
|
|
747
|
-
do_soap_request(req)
|
|
748
|
-
end
|
|
749
|
-
|
|
750
|
-
# Converts item and folder identifiers between formats.
|
|
751
|
-
# @see http://msdn.microsoft.com/en-us/library/bb799665.aspx
|
|
752
|
-
# @todo Needs to be finished
|
|
753
|
-
def convert_id(opts)
|
|
754
|
-
opts = opts.clone
|
|
755
731
|
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
x.parent['
|
|
732
|
+
# Converts item and folder identifiers between formats.
|
|
733
|
+
# @see http://msdn.microsoft.com/en-us/library/bb799665.aspx
|
|
734
|
+
# @todo Needs to be finished
|
|
735
|
+
def convert_id(opts)
|
|
736
|
+
opts = opts.clone
|
|
737
|
+
|
|
738
|
+
%i[id format destination_format mailbox].each do |k|
|
|
739
|
+
validate_param(opts, k, true)
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
req = build_soap! { |type, builder|
|
|
743
|
+
unless type == :header
|
|
744
|
+
builder.nbuild.ConvertId { |x|
|
|
745
|
+
builder.nbuild.parent.default_namespace = @default_ns
|
|
746
|
+
x.parent['DestinationFormat'] = opts[:destination_format].to_s.camel_case
|
|
747
|
+
x.SourceIds { |x|
|
|
748
|
+
x[NS_EWS_TYPES].AlternateId { |x|
|
|
749
|
+
x.parent['Format'] = opts[:format].to_s.camel_case
|
|
750
|
+
x.parent['Id'] = opts[:id]
|
|
751
|
+
x.parent['Mailbox'] = opts[:mailbox]
|
|
752
|
+
}
|
|
753
|
+
}
|
|
771
754
|
}
|
|
772
|
-
|
|
755
|
+
end
|
|
773
756
|
}
|
|
757
|
+
do_soap_request(req, response_class: EwsResponse)
|
|
774
758
|
end
|
|
775
759
|
end
|
|
776
|
-
do_soap_request(req, response_class: EwsResponse)
|
|
777
760
|
end
|
|
778
|
-
|
|
779
|
-
end #ExchangeDataServices
|
|
761
|
+
end
|
|
780
762
|
end
|