voiceml 0.8.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../models/conversations_v1'
4
+
5
+ module VoiceML
6
+ # `client.conversations_v1` — Twilio Conversations v1 (conversations.twilio.com/v1).
7
+ # Sits outside the /2010-04-01/Accounts/... namespace; account resolved from Basic auth.
8
+ class ConversationsV1Resource
9
+ attr_reader :conversations, :roles, :users, :credentials, :configuration,
10
+ :participant_conversations, :conversation_with_participants,
11
+ :services
12
+
13
+ def initialize(transport)
14
+ @conversations = ConversationsV1ConversationsResource.new(transport)
15
+ @roles = ConversationsV1RolesResource.new(transport)
16
+ @users = ConversationsV1UsersResource.new(transport)
17
+ @credentials = ConversationsV1CredentialsResource.new(transport)
18
+ @configuration = ConversationsV1ConfigurationResource.new(transport)
19
+ @participant_conversations = ConversationsV1ParticipantConversationsResource.new(transport)
20
+ @conversation_with_participants = ConversationsV1ConversationWithParticipantsResource.new(transport)
21
+ @services = ConversationsV1ServicesResource.new(transport)
22
+ end
23
+ end
24
+
25
+ # ============================================================================
26
+ # /v1/Conversations and all nested sub-resources (messages, participants,
27
+ # webhooks, message receipts).
28
+ # ============================================================================
29
+ class ConversationsV1ConversationsResource
30
+ CONVERSATION_FIELDS = {
31
+ 'FriendlyName' => :friendly_name,
32
+ 'UniqueName' => :unique_name,
33
+ 'MessagingServiceSid' => :messaging_service_sid,
34
+ 'Attributes' => :attributes,
35
+ 'State' => :state,
36
+ 'Timers.Inactive' => :timers_inactive,
37
+ 'Timers.Closed' => :timers_closed,
38
+ 'Bindings.Email.Address' => :bindings_email_address,
39
+ 'Bindings.Email.Name' => :bindings_email_name
40
+ }.freeze
41
+
42
+ UPDATE_FIELDS = {
43
+ 'FriendlyName' => :friendly_name,
44
+ 'UniqueName' => :unique_name,
45
+ 'MessagingServiceSid' => :messaging_service_sid,
46
+ 'Attributes' => :attributes,
47
+ 'State' => :state,
48
+ 'Timers.Inactive' => :timers_inactive,
49
+ 'Timers.Closed' => :timers_closed
50
+ }.freeze
51
+
52
+ MESSAGE_FIELDS = {
53
+ 'Author' => :author,
54
+ 'Body' => :body,
55
+ 'Attributes' => :attributes,
56
+ 'ContentSid' => :content_sid
57
+ }.freeze
58
+
59
+ MESSAGE_UPDATE_FIELDS = {
60
+ 'Author' => :author,
61
+ 'Body' => :body,
62
+ 'Attributes' => :attributes
63
+ }.freeze
64
+
65
+ PARTICIPANT_FIELDS = {
66
+ 'Identity' => :identity,
67
+ 'Attributes' => :attributes,
68
+ 'RoleSid' => :role_sid,
69
+ 'MessagingBinding.Address' => :messaging_binding_address,
70
+ 'MessagingBinding.ProxyAddress' => :messaging_binding_proxy_address,
71
+ 'MessagingBinding.ProjectedAddress' => :messaging_binding_projected_address
72
+ }.freeze
73
+
74
+ PARTICIPANT_UPDATE_FIELDS = {
75
+ 'Identity' => :identity,
76
+ 'Attributes' => :attributes,
77
+ 'RoleSid' => :role_sid,
78
+ 'LastReadMessageIndex' => :last_read_message_index,
79
+ 'LastReadTimestamp' => :last_read_timestamp
80
+ }.freeze
81
+
82
+ WEBHOOK_FIELDS = {
83
+ 'Target' => :target,
84
+ 'Configuration.Url' => :configuration_url,
85
+ 'Configuration.Method' => :configuration_method,
86
+ 'Configuration.FlowSid' => :configuration_flow_sid,
87
+ 'Configuration.ReplayAfter' => :configuration_replay_after
88
+ }.freeze
89
+
90
+ WEBHOOK_UPDATE_FIELDS = {
91
+ 'Configuration.Url' => :configuration_url,
92
+ 'Configuration.Method' => :configuration_method,
93
+ 'Configuration.FlowSid' => :configuration_flow_sid
94
+ }.freeze
95
+
96
+ def initialize(transport)
97
+ @transport = transport
98
+ end
99
+
100
+ # --- Conversations ---
101
+ def list(page_size: nil)
102
+ params = {}
103
+ params['PageSize'] = page_size unless page_size.nil?
104
+ ConversationsV1ConversationList.new(@transport.request(:get, '/v1/Conversations', params: params))
105
+ end
106
+
107
+ def create(**kwargs)
108
+ ConversationsV1Conversation.from_hash(
109
+ @transport.request(:post, '/v1/Conversations', form: build_form(CONVERSATION_FIELDS, kwargs))
110
+ )
111
+ end
112
+
113
+ def fetch(sid)
114
+ ConversationsV1Conversation.from_hash(@transport.request(:get, "/v1/Conversations/#{sid}"))
115
+ end
116
+
117
+ def update(sid, **kwargs)
118
+ ConversationsV1Conversation.from_hash(
119
+ @transport.request(:post, "/v1/Conversations/#{sid}", form: build_form(UPDATE_FIELDS, kwargs))
120
+ )
121
+ end
122
+
123
+ def delete(sid)
124
+ @transport.request(:delete, "/v1/Conversations/#{sid}")
125
+ nil
126
+ end
127
+
128
+ # --- Messages ---
129
+ def list_messages(conversation_sid, page_size: nil)
130
+ params = {}
131
+ params['PageSize'] = page_size unless page_size.nil?
132
+ ConversationsV1ConversationMessageList.new(
133
+ @transport.request(:get, "/v1/Conversations/#{conversation_sid}/Messages", params: params)
134
+ )
135
+ end
136
+
137
+ def create_message(conversation_sid, **kwargs)
138
+ ConversationsV1ConversationMessage.from_hash(
139
+ @transport.request(:post, "/v1/Conversations/#{conversation_sid}/Messages",
140
+ form: build_form(MESSAGE_FIELDS, kwargs))
141
+ )
142
+ end
143
+
144
+ def fetch_message(conversation_sid, message_sid)
145
+ ConversationsV1ConversationMessage.from_hash(
146
+ @transport.request(:get, "/v1/Conversations/#{conversation_sid}/Messages/#{message_sid}")
147
+ )
148
+ end
149
+
150
+ def update_message(conversation_sid, message_sid, **kwargs)
151
+ ConversationsV1ConversationMessage.from_hash(
152
+ @transport.request(:post, "/v1/Conversations/#{conversation_sid}/Messages/#{message_sid}",
153
+ form: build_form(MESSAGE_UPDATE_FIELDS, kwargs))
154
+ )
155
+ end
156
+
157
+ def delete_message(conversation_sid, message_sid)
158
+ @transport.request(:delete, "/v1/Conversations/#{conversation_sid}/Messages/#{message_sid}")
159
+ nil
160
+ end
161
+
162
+ # --- Message Receipts (read-only) ---
163
+ def list_message_receipts(conversation_sid, message_sid, page_size: nil)
164
+ params = {}
165
+ params['PageSize'] = page_size unless page_size.nil?
166
+ ConversationsV1ConversationMessageReceiptList.new(
167
+ @transport.request(:get, "/v1/Conversations/#{conversation_sid}/Messages/#{message_sid}/Receipts",
168
+ params: params)
169
+ )
170
+ end
171
+
172
+ def fetch_message_receipt(conversation_sid, message_sid, sid)
173
+ ConversationsV1ConversationMessageReceipt.from_hash(
174
+ @transport.request(:get, "/v1/Conversations/#{conversation_sid}/Messages/#{message_sid}/Receipts/#{sid}")
175
+ )
176
+ end
177
+
178
+ # --- Participants ---
179
+ def list_participants(conversation_sid, page_size: nil)
180
+ params = {}
181
+ params['PageSize'] = page_size unless page_size.nil?
182
+ ConversationsV1ConversationParticipantList.new(
183
+ @transport.request(:get, "/v1/Conversations/#{conversation_sid}/Participants", params: params)
184
+ )
185
+ end
186
+
187
+ def create_participant(conversation_sid, **kwargs)
188
+ ConversationsV1ConversationParticipant.from_hash(
189
+ @transport.request(:post, "/v1/Conversations/#{conversation_sid}/Participants",
190
+ form: build_form(PARTICIPANT_FIELDS, kwargs))
191
+ )
192
+ end
193
+
194
+ def fetch_participant(conversation_sid, participant_sid)
195
+ ConversationsV1ConversationParticipant.from_hash(
196
+ @transport.request(:get, "/v1/Conversations/#{conversation_sid}/Participants/#{participant_sid}")
197
+ )
198
+ end
199
+
200
+ def update_participant(conversation_sid, participant_sid, **kwargs)
201
+ ConversationsV1ConversationParticipant.from_hash(
202
+ @transport.request(:post, "/v1/Conversations/#{conversation_sid}/Participants/#{participant_sid}",
203
+ form: build_form(PARTICIPANT_UPDATE_FIELDS, kwargs))
204
+ )
205
+ end
206
+
207
+ def delete_participant(conversation_sid, participant_sid)
208
+ @transport.request(:delete, "/v1/Conversations/#{conversation_sid}/Participants/#{participant_sid}")
209
+ nil
210
+ end
211
+
212
+ # --- Scoped Webhooks ---
213
+ def list_webhooks(conversation_sid, page_size: nil)
214
+ params = {}
215
+ params['PageSize'] = page_size unless page_size.nil?
216
+ ConversationsV1ConversationScopedWebhookList.new(
217
+ @transport.request(:get, "/v1/Conversations/#{conversation_sid}/Webhooks", params: params)
218
+ )
219
+ end
220
+
221
+ def create_webhook(conversation_sid, target:, **kwargs)
222
+ kwargs[:target] = target
223
+ ConversationsV1ConversationScopedWebhook.from_hash(
224
+ @transport.request(:post, "/v1/Conversations/#{conversation_sid}/Webhooks",
225
+ form: build_form(WEBHOOK_FIELDS, kwargs))
226
+ )
227
+ end
228
+
229
+ def fetch_webhook(conversation_sid, webhook_sid)
230
+ ConversationsV1ConversationScopedWebhook.from_hash(
231
+ @transport.request(:get, "/v1/Conversations/#{conversation_sid}/Webhooks/#{webhook_sid}")
232
+ )
233
+ end
234
+
235
+ def update_webhook(conversation_sid, webhook_sid, **kwargs)
236
+ ConversationsV1ConversationScopedWebhook.from_hash(
237
+ @transport.request(:post, "/v1/Conversations/#{conversation_sid}/Webhooks/#{webhook_sid}",
238
+ form: build_form(WEBHOOK_UPDATE_FIELDS, kwargs))
239
+ )
240
+ end
241
+
242
+ def delete_webhook(conversation_sid, webhook_sid)
243
+ @transport.request(:delete, "/v1/Conversations/#{conversation_sid}/Webhooks/#{webhook_sid}")
244
+ nil
245
+ end
246
+
247
+ private
248
+
249
+ def build_form(map, kwargs)
250
+ out = {}
251
+ map.each do |wire, k|
252
+ value = kwargs[k]
253
+ next if value.nil?
254
+
255
+ out[wire] = value
256
+ end
257
+ out
258
+ end
259
+ end
260
+
261
+ # ============================================================================
262
+ # /v1/Roles
263
+ # ============================================================================
264
+ class ConversationsV1RolesResource
265
+ def initialize(transport)
266
+ @transport = transport
267
+ end
268
+
269
+ def list(page_size: nil)
270
+ params = {}
271
+ params['PageSize'] = page_size unless page_size.nil?
272
+ ConversationsV1RoleList.new(@transport.request(:get, '/v1/Roles', params: params))
273
+ end
274
+
275
+ def create(friendly_name:, type:, permission:)
276
+ form = { 'FriendlyName' => friendly_name, 'Type' => type, 'Permission' => Array(permission) }
277
+ ConversationsV1Role.from_hash(@transport.request(:post, '/v1/Roles', form: form))
278
+ end
279
+
280
+ def fetch(sid)
281
+ ConversationsV1Role.from_hash(@transport.request(:get, "/v1/Roles/#{sid}"))
282
+ end
283
+
284
+ def update(sid, permission:)
285
+ form = { 'Permission' => Array(permission) }
286
+ ConversationsV1Role.from_hash(@transport.request(:post, "/v1/Roles/#{sid}", form: form))
287
+ end
288
+
289
+ def delete(sid)
290
+ @transport.request(:delete, "/v1/Roles/#{sid}")
291
+ nil
292
+ end
293
+ end
294
+
295
+ # ============================================================================
296
+ # /v1/Users + nested /v1/Users/{Sid}/Conversations (UserConversation)
297
+ # ============================================================================
298
+ class ConversationsV1UsersResource
299
+ USER_FIELDS = {
300
+ 'Identity' => :identity,
301
+ 'FriendlyName' => :friendly_name,
302
+ 'Attributes' => :attributes,
303
+ 'RoleSid' => :role_sid
304
+ }.freeze
305
+
306
+ USER_UPDATE_FIELDS = {
307
+ 'FriendlyName' => :friendly_name,
308
+ 'Attributes' => :attributes,
309
+ 'RoleSid' => :role_sid
310
+ }.freeze
311
+
312
+ USER_CONVERSATION_UPDATE_FIELDS = {
313
+ 'NotificationLevel' => :notification_level,
314
+ 'LastReadMessageIndex' => :last_read_message_index,
315
+ 'LastReadTimestamp' => :last_read_timestamp
316
+ }.freeze
317
+
318
+ def initialize(transport)
319
+ @transport = transport
320
+ end
321
+
322
+ def list(page_size: nil)
323
+ params = {}
324
+ params['PageSize'] = page_size unless page_size.nil?
325
+ ConversationsV1UserList.new(@transport.request(:get, '/v1/Users', params: params))
326
+ end
327
+
328
+ def create(identity:, friendly_name: nil, attributes: nil, role_sid: nil)
329
+ kwargs = { identity: identity, friendly_name: friendly_name, attributes: attributes, role_sid: role_sid }
330
+ ConversationsV1User.from_hash(@transport.request(:post, '/v1/Users', form: build_form(USER_FIELDS, kwargs)))
331
+ end
332
+
333
+ def fetch(sid)
334
+ ConversationsV1User.from_hash(@transport.request(:get, "/v1/Users/#{sid}"))
335
+ end
336
+
337
+ def update(sid, **kwargs)
338
+ ConversationsV1User.from_hash(
339
+ @transport.request(:post, "/v1/Users/#{sid}", form: build_form(USER_UPDATE_FIELDS, kwargs))
340
+ )
341
+ end
342
+
343
+ def delete(sid)
344
+ @transport.request(:delete, "/v1/Users/#{sid}")
345
+ nil
346
+ end
347
+
348
+ # --- /v1/Users/{Sid}/Conversations ---
349
+ def list_user_conversations(user_sid, page_size: nil)
350
+ params = {}
351
+ params['PageSize'] = page_size unless page_size.nil?
352
+ ConversationsV1UserConversationList.new(
353
+ @transport.request(:get, "/v1/Users/#{user_sid}/Conversations", params: params)
354
+ )
355
+ end
356
+
357
+ def fetch_user_conversation(user_sid, conversation_sid)
358
+ ConversationsV1UserConversation.from_hash(
359
+ @transport.request(:get, "/v1/Users/#{user_sid}/Conversations/#{conversation_sid}")
360
+ )
361
+ end
362
+
363
+ def update_user_conversation(user_sid, conversation_sid, **kwargs)
364
+ ConversationsV1UserConversation.from_hash(
365
+ @transport.request(:post, "/v1/Users/#{user_sid}/Conversations/#{conversation_sid}",
366
+ form: build_form(USER_CONVERSATION_UPDATE_FIELDS, kwargs))
367
+ )
368
+ end
369
+
370
+ def delete_user_conversation(user_sid, conversation_sid)
371
+ @transport.request(:delete, "/v1/Users/#{user_sid}/Conversations/#{conversation_sid}")
372
+ nil
373
+ end
374
+
375
+ private
376
+
377
+ def build_form(map, kwargs)
378
+ out = {}
379
+ map.each do |wire, k|
380
+ value = kwargs[k]
381
+ next if value.nil?
382
+
383
+ out[wire] = value
384
+ end
385
+ out
386
+ end
387
+ end
388
+
389
+ # ============================================================================
390
+ # /v1/Credentials (push credentials — distinct from /SIP/Credentials)
391
+ # ============================================================================
392
+ class ConversationsV1CredentialsResource
393
+ CREDENTIAL_FIELDS = {
394
+ 'Type' => :type,
395
+ 'FriendlyName' => :friendly_name,
396
+ 'Certificate' => :certificate,
397
+ 'PrivateKey' => :private_key,
398
+ 'Sandbox' => :sandbox,
399
+ 'ApiKey' => :api_key,
400
+ 'Secret' => :secret
401
+ }.freeze
402
+
403
+ def initialize(transport)
404
+ @transport = transport
405
+ end
406
+
407
+ def list(page_size: nil)
408
+ params = {}
409
+ params['PageSize'] = page_size unless page_size.nil?
410
+ ConversationsV1CredentialList.new(@transport.request(:get, '/v1/Credentials', params: params))
411
+ end
412
+
413
+ def create(type:, **kwargs)
414
+ kwargs[:type] = type
415
+ ConversationsV1Credential.from_hash(
416
+ @transport.request(:post, '/v1/Credentials', form: build_form(kwargs))
417
+ )
418
+ end
419
+
420
+ def fetch(sid)
421
+ ConversationsV1Credential.from_hash(@transport.request(:get, "/v1/Credentials/#{sid}"))
422
+ end
423
+
424
+ def update(sid, **kwargs)
425
+ ConversationsV1Credential.from_hash(
426
+ @transport.request(:post, "/v1/Credentials/#{sid}", form: build_form(kwargs))
427
+ )
428
+ end
429
+
430
+ def delete(sid)
431
+ @transport.request(:delete, "/v1/Credentials/#{sid}")
432
+ nil
433
+ end
434
+
435
+ private
436
+
437
+ def build_form(kwargs)
438
+ out = {}
439
+ CREDENTIAL_FIELDS.each do |wire, k|
440
+ value = kwargs[k]
441
+ next if value.nil?
442
+
443
+ out[wire] = value
444
+ end
445
+ out
446
+ end
447
+ end
448
+
449
+ # ============================================================================
450
+ # /v1/Configuration (singleton) + nested /Webhooks (singleton) + /Addresses (CRUD)
451
+ # ============================================================================
452
+ class ConversationsV1ConfigurationResource
453
+ CONFIG_FIELDS = {
454
+ 'DefaultChatServiceSid' => :default_chat_service_sid,
455
+ 'DefaultMessagingServiceSid' => :default_messaging_service_sid,
456
+ 'DefaultInactiveTimer' => :default_inactive_timer,
457
+ 'DefaultClosedTimer' => :default_closed_timer
458
+ }.freeze
459
+
460
+ WEBHOOK_FIELDS = {
461
+ 'Method' => :method,
462
+ 'Filters' => :filters,
463
+ 'PreWebhookUrl' => :pre_webhook_url,
464
+ 'PostWebhookUrl' => :post_webhook_url,
465
+ 'Target' => :target
466
+ }.freeze
467
+
468
+ ADDRESS_FIELDS = {
469
+ 'Type' => :type,
470
+ 'Address' => :address,
471
+ 'FriendlyName' => :friendly_name,
472
+ 'AutoCreation.Enabled' => :auto_creation_enabled,
473
+ 'AutoCreation.Type' => :auto_creation_type,
474
+ 'AutoCreation.WebhookUrl' => :auto_creation_webhook_url,
475
+ 'AddressCountry' => :address_country
476
+ }.freeze
477
+
478
+ ADDRESS_UPDATE_FIELDS = {
479
+ 'FriendlyName' => :friendly_name,
480
+ 'AutoCreation.Enabled' => :auto_creation_enabled,
481
+ 'AutoCreation.Type' => :auto_creation_type,
482
+ 'AutoCreation.WebhookUrl' => :auto_creation_webhook_url
483
+ }.freeze
484
+
485
+ def initialize(transport)
486
+ @transport = transport
487
+ end
488
+
489
+ # --- Configuration singleton ---
490
+ def fetch
491
+ ConversationsV1Configuration.from_hash(@transport.request(:get, '/v1/Configuration'))
492
+ end
493
+
494
+ def update(**kwargs)
495
+ ConversationsV1Configuration.from_hash(
496
+ @transport.request(:post, '/v1/Configuration', form: build_form(CONFIG_FIELDS, kwargs))
497
+ )
498
+ end
499
+
500
+ # --- Webhooks singleton ---
501
+ def fetch_webhooks
502
+ ConversationsV1ConfigurationWebhook.from_hash(@transport.request(:get, '/v1/Configuration/Webhooks'))
503
+ end
504
+
505
+ def update_webhooks(**kwargs)
506
+ ConversationsV1ConfigurationWebhook.from_hash(
507
+ @transport.request(:post, '/v1/Configuration/Webhooks', form: build_form(WEBHOOK_FIELDS, kwargs))
508
+ )
509
+ end
510
+
511
+ # --- Addresses CRUD ---
512
+ def list_addresses(page_size: nil)
513
+ params = {}
514
+ params['PageSize'] = page_size unless page_size.nil?
515
+ ConversationsV1ConfigAddressList.new(
516
+ @transport.request(:get, '/v1/Configuration/Addresses', params: params)
517
+ )
518
+ end
519
+
520
+ def create_address(type:, address:, **kwargs)
521
+ kwargs[:type] = type
522
+ kwargs[:address] = address
523
+ ConversationsV1ConfigAddress.from_hash(
524
+ @transport.request(:post, '/v1/Configuration/Addresses', form: build_form(ADDRESS_FIELDS, kwargs))
525
+ )
526
+ end
527
+
528
+ def fetch_address(sid)
529
+ ConversationsV1ConfigAddress.from_hash(@transport.request(:get, "/v1/Configuration/Addresses/#{sid}"))
530
+ end
531
+
532
+ def update_address(sid, **kwargs)
533
+ ConversationsV1ConfigAddress.from_hash(
534
+ @transport.request(:post, "/v1/Configuration/Addresses/#{sid}", form: build_form(ADDRESS_UPDATE_FIELDS, kwargs))
535
+ )
536
+ end
537
+
538
+ def delete_address(sid)
539
+ @transport.request(:delete, "/v1/Configuration/Addresses/#{sid}")
540
+ nil
541
+ end
542
+
543
+ private
544
+
545
+ def build_form(map, kwargs)
546
+ out = {}
547
+ map.each do |wire, k|
548
+ value = kwargs[k]
549
+ next if value.nil?
550
+
551
+ out[wire] = value
552
+ end
553
+ out
554
+ end
555
+ end
556
+
557
+ # ============================================================================
558
+ # /v1/ParticipantConversations (read-only list)
559
+ # ============================================================================
560
+ class ConversationsV1ParticipantConversationsResource
561
+ def initialize(transport)
562
+ @transport = transport
563
+ end
564
+
565
+ def list(identity: nil, address: nil, page_size: nil)
566
+ params = {}
567
+ params['Identity'] = identity unless identity.nil?
568
+ params['Address'] = address unless address.nil?
569
+ params['PageSize'] = page_size unless page_size.nil?
570
+ ConversationsV1ParticipantConversationList.new(
571
+ @transport.request(:get, '/v1/ParticipantConversations', params: params)
572
+ )
573
+ end
574
+ end
575
+
576
+ # ============================================================================
577
+ # /v1/ConversationWithParticipants (single-call conv + participants)
578
+ # ============================================================================
579
+ class ConversationsV1ConversationWithParticipantsResource
580
+ FIELDS = {
581
+ 'FriendlyName' => :friendly_name,
582
+ 'UniqueName' => :unique_name,
583
+ 'MessagingServiceSid' => :messaging_service_sid,
584
+ 'Attributes' => :attributes,
585
+ 'State' => :state,
586
+ 'Timers.Inactive' => :timers_inactive,
587
+ 'Timers.Closed' => :timers_closed,
588
+ 'Participant' => :participant
589
+ }.freeze
590
+
591
+ def initialize(transport)
592
+ @transport = transport
593
+ end
594
+
595
+ def create(participant: nil, **kwargs)
596
+ kwargs[:participant] = participant unless participant.nil?
597
+ form = {}
598
+ FIELDS.each do |wire, k|
599
+ value = kwargs[k]
600
+ next if value.nil?
601
+
602
+ form[wire] = value
603
+ end
604
+ ConversationsV1ConversationWithParticipants.from_hash(
605
+ @transport.request(:post, '/v1/ConversationWithParticipants', form: form)
606
+ )
607
+ end
608
+ end
609
+
610
+ # ============================================================================
611
+ # /v1/Services + nested /Conversations
612
+ # ============================================================================
613
+ class ConversationsV1ServicesResource
614
+ SERVICE_CONVERSATION_FIELDS = {
615
+ 'FriendlyName' => :friendly_name,
616
+ 'UniqueName' => :unique_name,
617
+ 'MessagingServiceSid' => :messaging_service_sid,
618
+ 'Attributes' => :attributes,
619
+ 'State' => :state,
620
+ 'Timers.Inactive' => :timers_inactive,
621
+ 'Timers.Closed' => :timers_closed
622
+ }.freeze
623
+
624
+ SERVICE_CONVERSATION_UPDATE_FIELDS = {
625
+ 'FriendlyName' => :friendly_name,
626
+ 'UniqueName' => :unique_name,
627
+ 'Attributes' => :attributes,
628
+ 'State' => :state,
629
+ 'Timers.Inactive' => :timers_inactive,
630
+ 'Timers.Closed' => :timers_closed
631
+ }.freeze
632
+
633
+ def initialize(transport)
634
+ @transport = transport
635
+ end
636
+
637
+ def list(page_size: nil)
638
+ params = {}
639
+ params['PageSize'] = page_size unless page_size.nil?
640
+ ConversationsV1ServiceList.new(@transport.request(:get, '/v1/Services', params: params))
641
+ end
642
+
643
+ def create(friendly_name:)
644
+ ConversationsV1Service.from_hash(
645
+ @transport.request(:post, '/v1/Services', form: { 'FriendlyName' => friendly_name })
646
+ )
647
+ end
648
+
649
+ def fetch(chat_service_sid)
650
+ ConversationsV1Service.from_hash(@transport.request(:get, "/v1/Services/#{chat_service_sid}"))
651
+ end
652
+
653
+ def delete(chat_service_sid)
654
+ @transport.request(:delete, "/v1/Services/#{chat_service_sid}")
655
+ nil
656
+ end
657
+
658
+ # --- /v1/Services/{ChatServiceSid}/Conversations ---
659
+ def list_conversations(chat_service_sid, page_size: nil)
660
+ params = {}
661
+ params['PageSize'] = page_size unless page_size.nil?
662
+ ConversationsV1ServiceConversationList.new(
663
+ @transport.request(:get, "/v1/Services/#{chat_service_sid}/Conversations", params: params)
664
+ )
665
+ end
666
+
667
+ def create_conversation(chat_service_sid, **kwargs)
668
+ ConversationsV1ServiceConversation.from_hash(
669
+ @transport.request(:post, "/v1/Services/#{chat_service_sid}/Conversations",
670
+ form: build_form(SERVICE_CONVERSATION_FIELDS, kwargs))
671
+ )
672
+ end
673
+
674
+ def fetch_conversation(chat_service_sid, conversation_sid)
675
+ ConversationsV1ServiceConversation.from_hash(
676
+ @transport.request(:get, "/v1/Services/#{chat_service_sid}/Conversations/#{conversation_sid}")
677
+ )
678
+ end
679
+
680
+ def update_conversation(chat_service_sid, conversation_sid, **kwargs)
681
+ ConversationsV1ServiceConversation.from_hash(
682
+ @transport.request(:post, "/v1/Services/#{chat_service_sid}/Conversations/#{conversation_sid}",
683
+ form: build_form(SERVICE_CONVERSATION_UPDATE_FIELDS, kwargs))
684
+ )
685
+ end
686
+
687
+ def delete_conversation(chat_service_sid, conversation_sid)
688
+ @transport.request(:delete, "/v1/Services/#{chat_service_sid}/Conversations/#{conversation_sid}")
689
+ nil
690
+ end
691
+
692
+ # Returns a scope object exposing the 48 Phase-4 sub-resource ops under
693
+ # `/v1/Services/{chat_service_sid}/...`. The scope binds `chat_service_sid`
694
+ # once so callers don't need to thread it through each call.
695
+ def scope(chat_service_sid)
696
+ ConversationsV1ServiceScopeResource.new(@transport, chat_service_sid)
697
+ end
698
+
699
+ private
700
+
701
+ def build_form(map, kwargs)
702
+ out = {}
703
+ map.each do |wire, k|
704
+ value = kwargs[k]
705
+ next if value.nil?
706
+
707
+ out[wire] = value
708
+ end
709
+ out
710
+ end
711
+ end
712
+
713
+ # ============================================================================
714
+ # Phase 4 — /v1/Services/{ChatServiceSid}/... — 15 sub-resource families,
715
+ # 48 ops. Scoped via `client.conversations_v1.services.scope(IS_sid)`.
716
+ # Flat method style matches the rest of conversations_v1.
717
+ # ============================================================================
718
+ class ConversationsV1ServiceScopeResource
719
+ CONVERSATION_FIELDS = {
720
+ 'FriendlyName' => :friendly_name,
721
+ 'UniqueName' => :unique_name,
722
+ 'MessagingServiceSid' => :messaging_service_sid,
723
+ 'Attributes' => :attributes,
724
+ 'State' => :state,
725
+ 'Timers.Inactive' => :timers_inactive,
726
+ 'Timers.Closed' => :timers_closed
727
+ }.freeze
728
+
729
+ CONVERSATION_UPDATE_FIELDS = {
730
+ 'FriendlyName' => :friendly_name,
731
+ 'UniqueName' => :unique_name,
732
+ 'Attributes' => :attributes,
733
+ 'State' => :state,
734
+ 'Timers.Inactive' => :timers_inactive,
735
+ 'Timers.Closed' => :timers_closed
736
+ }.freeze
737
+
738
+ MESSAGE_FIELDS = {
739
+ 'Author' => :author,
740
+ 'Body' => :body,
741
+ 'Attributes' => :attributes,
742
+ 'ContentSid' => :content_sid
743
+ }.freeze
744
+
745
+ MESSAGE_UPDATE_FIELDS = {
746
+ 'Author' => :author,
747
+ 'Body' => :body,
748
+ 'Attributes' => :attributes
749
+ }.freeze
750
+
751
+ PARTICIPANT_FIELDS = {
752
+ 'Identity' => :identity,
753
+ 'Attributes' => :attributes,
754
+ 'RoleSid' => :role_sid,
755
+ 'MessagingBinding.Address' => :messaging_binding_address,
756
+ 'MessagingBinding.ProxyAddress' => :messaging_binding_proxy_address,
757
+ 'MessagingBinding.ProjectedAddress' => :messaging_binding_projected_address
758
+ }.freeze
759
+
760
+ PARTICIPANT_UPDATE_FIELDS = {
761
+ 'Attributes' => :attributes,
762
+ 'RoleSid' => :role_sid
763
+ }.freeze
764
+
765
+ WEBHOOK_FIELDS = {
766
+ 'Target' => :target,
767
+ 'Configuration.Url' => :configuration_url,
768
+ 'Configuration.Method' => :configuration_method,
769
+ 'Configuration.FlowSid' => :configuration_flow_sid
770
+ }.freeze
771
+
772
+ WEBHOOK_UPDATE_FIELDS = {
773
+ 'Configuration.Url' => :configuration_url,
774
+ 'Configuration.Method' => :configuration_method,
775
+ 'Configuration.FlowSid' => :configuration_flow_sid
776
+ }.freeze
777
+
778
+ USER_FIELDS = {
779
+ 'Identity' => :identity,
780
+ 'FriendlyName' => :friendly_name,
781
+ 'Attributes' => :attributes,
782
+ 'RoleSid' => :role_sid
783
+ }.freeze
784
+
785
+ USER_UPDATE_FIELDS = {
786
+ 'FriendlyName' => :friendly_name,
787
+ 'Attributes' => :attributes,
788
+ 'RoleSid' => :role_sid
789
+ }.freeze
790
+
791
+ CONV_WITH_PARTICIPANTS_FIELDS = {
792
+ 'FriendlyName' => :friendly_name,
793
+ 'UniqueName' => :unique_name,
794
+ 'MessagingServiceSid' => :messaging_service_sid,
795
+ 'Attributes' => :attributes,
796
+ 'State' => :state,
797
+ 'Timers.Inactive' => :timers_inactive,
798
+ 'Timers.Closed' => :timers_closed,
799
+ 'Participant' => :participant
800
+ }.freeze
801
+
802
+ CONFIG_UPDATE_FIELDS = {
803
+ 'DefaultChatServiceRoleSid' => :default_chat_service_role_sid,
804
+ 'DefaultConversationCreatorRoleSid' => :default_conversation_creator_role_sid,
805
+ 'DefaultConversationRoleSid' => :default_conversation_role_sid,
806
+ 'ReachabilityEnabled' => :reachability_enabled
807
+ }.freeze
808
+
809
+ NOTIFICATION_UPDATE_FIELDS = {
810
+ 'LogEnabled' => :log_enabled,
811
+ 'NewMessage.Enabled' => :new_message_enabled,
812
+ 'NewMessage.Template' => :new_message_template,
813
+ 'NewMessage.Sound' => :new_message_sound,
814
+ 'NewMessage.BadgeCountEnabled' => :new_message_badge_count_enabled,
815
+ 'NewMessage.WithMedia.Enabled' => :new_message_with_media_enabled,
816
+ 'NewMessage.WithMedia.Template' => :new_message_with_media_template,
817
+ 'AddedToConversation.Enabled' => :added_to_conversation_enabled,
818
+ 'AddedToConversation.Template' => :added_to_conversation_template,
819
+ 'AddedToConversation.Sound' => :added_to_conversation_sound,
820
+ 'RemovedFromConversation.Enabled' => :removed_from_conversation_enabled,
821
+ 'RemovedFromConversation.Template' => :removed_from_conversation_template,
822
+ 'RemovedFromConversation.Sound' => :removed_from_conversation_sound
823
+ }.freeze
824
+
825
+ WEBHOOK_CONFIG_UPDATE_FIELDS = {
826
+ 'PreWebhookUrl' => :pre_webhook_url,
827
+ 'PostWebhookUrl' => :post_webhook_url,
828
+ 'Method' => :method,
829
+ 'Filters' => :filters
830
+ }.freeze
831
+
832
+ attr_reader :chat_service_sid
833
+
834
+ def initialize(transport, chat_service_sid)
835
+ @transport = transport
836
+ @chat_service_sid = chat_service_sid
837
+ end
838
+
839
+ # --- ServiceConversation (5 CRUD) ---
840
+ def list_conversations(page_size: nil)
841
+ params = {}
842
+ params['PageSize'] = page_size unless page_size.nil?
843
+ ConversationsV1ServiceConversationList.new(
844
+ @transport.request(:get, conv_root, params: params)
845
+ )
846
+ end
847
+
848
+ def create_conversation(**kwargs)
849
+ ConversationsV1ServiceConversation.from_hash(
850
+ @transport.request(:post, conv_root, form: build_form(CONVERSATION_FIELDS, kwargs))
851
+ )
852
+ end
853
+
854
+ def fetch_conversation(conversation_sid)
855
+ ConversationsV1ServiceConversation.from_hash(
856
+ @transport.request(:get, "#{conv_root}/#{conversation_sid}")
857
+ )
858
+ end
859
+
860
+ def update_conversation(conversation_sid, **kwargs)
861
+ ConversationsV1ServiceConversation.from_hash(
862
+ @transport.request(:post, "#{conv_root}/#{conversation_sid}",
863
+ form: build_form(CONVERSATION_UPDATE_FIELDS, kwargs))
864
+ )
865
+ end
866
+
867
+ def delete_conversation(conversation_sid)
868
+ @transport.request(:delete, "#{conv_root}/#{conversation_sid}")
869
+ nil
870
+ end
871
+
872
+ # --- ServiceConversationMessage (5 CRUD) ---
873
+ def list_messages(conversation_sid, page_size: nil)
874
+ params = {}
875
+ params['PageSize'] = page_size unless page_size.nil?
876
+ ConversationsV1ServiceConversationMessageList.new(
877
+ @transport.request(:get, "#{conv_root}/#{conversation_sid}/Messages", params: params)
878
+ )
879
+ end
880
+
881
+ def create_message(conversation_sid, **kwargs)
882
+ ConversationsV1ServiceConversationMessage.from_hash(
883
+ @transport.request(:post, "#{conv_root}/#{conversation_sid}/Messages",
884
+ form: build_form(MESSAGE_FIELDS, kwargs))
885
+ )
886
+ end
887
+
888
+ def fetch_message(conversation_sid, message_sid)
889
+ ConversationsV1ServiceConversationMessage.from_hash(
890
+ @transport.request(:get, "#{conv_root}/#{conversation_sid}/Messages/#{message_sid}")
891
+ )
892
+ end
893
+
894
+ def update_message(conversation_sid, message_sid, **kwargs)
895
+ ConversationsV1ServiceConversationMessage.from_hash(
896
+ @transport.request(:post, "#{conv_root}/#{conversation_sid}/Messages/#{message_sid}",
897
+ form: build_form(MESSAGE_UPDATE_FIELDS, kwargs))
898
+ )
899
+ end
900
+
901
+ def delete_message(conversation_sid, message_sid)
902
+ @transport.request(:delete, "#{conv_root}/#{conversation_sid}/Messages/#{message_sid}")
903
+ nil
904
+ end
905
+
906
+ # --- ServiceConversationMessageReceipt (list+fetch only) ---
907
+ def list_message_receipts(conversation_sid, message_sid, page_size: nil)
908
+ params = {}
909
+ params['PageSize'] = page_size unless page_size.nil?
910
+ ConversationsV1ServiceConversationMessageReceiptList.new(
911
+ @transport.request(:get,
912
+ "#{conv_root}/#{conversation_sid}/Messages/#{message_sid}/Receipts",
913
+ params: params)
914
+ )
915
+ end
916
+
917
+ def fetch_message_receipt(conversation_sid, message_sid, sid)
918
+ ConversationsV1ServiceConversationMessageReceipt.from_hash(
919
+ @transport.request(:get,
920
+ "#{conv_root}/#{conversation_sid}/Messages/#{message_sid}/Receipts/#{sid}")
921
+ )
922
+ end
923
+
924
+ # --- ServiceConversationParticipant (5 CRUD) ---
925
+ def list_participants(conversation_sid, page_size: nil)
926
+ params = {}
927
+ params['PageSize'] = page_size unless page_size.nil?
928
+ ConversationsV1ServiceConversationParticipantList.new(
929
+ @transport.request(:get, "#{conv_root}/#{conversation_sid}/Participants", params: params)
930
+ )
931
+ end
932
+
933
+ def create_participant(conversation_sid, **kwargs)
934
+ ConversationsV1ServiceConversationParticipant.from_hash(
935
+ @transport.request(:post, "#{conv_root}/#{conversation_sid}/Participants",
936
+ form: build_form(PARTICIPANT_FIELDS, kwargs))
937
+ )
938
+ end
939
+
940
+ def fetch_participant(conversation_sid, participant_sid)
941
+ ConversationsV1ServiceConversationParticipant.from_hash(
942
+ @transport.request(:get, "#{conv_root}/#{conversation_sid}/Participants/#{participant_sid}")
943
+ )
944
+ end
945
+
946
+ def update_participant(conversation_sid, participant_sid, **kwargs)
947
+ ConversationsV1ServiceConversationParticipant.from_hash(
948
+ @transport.request(:post, "#{conv_root}/#{conversation_sid}/Participants/#{participant_sid}",
949
+ form: build_form(PARTICIPANT_UPDATE_FIELDS, kwargs))
950
+ )
951
+ end
952
+
953
+ def delete_participant(conversation_sid, participant_sid)
954
+ @transport.request(:delete, "#{conv_root}/#{conversation_sid}/Participants/#{participant_sid}")
955
+ nil
956
+ end
957
+
958
+ # --- ServiceConversationScopedWebhook (5 CRUD) ---
959
+ def list_webhooks(conversation_sid, page_size: nil)
960
+ params = {}
961
+ params['PageSize'] = page_size unless page_size.nil?
962
+ ConversationsV1ServiceConversationScopedWebhookList.new(
963
+ @transport.request(:get, "#{conv_root}/#{conversation_sid}/Webhooks", params: params)
964
+ )
965
+ end
966
+
967
+ def create_webhook(conversation_sid, target:, **kwargs)
968
+ kwargs[:target] = target
969
+ ConversationsV1ServiceConversationScopedWebhook.from_hash(
970
+ @transport.request(:post, "#{conv_root}/#{conversation_sid}/Webhooks",
971
+ form: build_form(WEBHOOK_FIELDS, kwargs))
972
+ )
973
+ end
974
+
975
+ def fetch_webhook(conversation_sid, webhook_sid)
976
+ ConversationsV1ServiceConversationScopedWebhook.from_hash(
977
+ @transport.request(:get, "#{conv_root}/#{conversation_sid}/Webhooks/#{webhook_sid}")
978
+ )
979
+ end
980
+
981
+ def update_webhook(conversation_sid, webhook_sid, **kwargs)
982
+ ConversationsV1ServiceConversationScopedWebhook.from_hash(
983
+ @transport.request(:post, "#{conv_root}/#{conversation_sid}/Webhooks/#{webhook_sid}",
984
+ form: build_form(WEBHOOK_UPDATE_FIELDS, kwargs))
985
+ )
986
+ end
987
+
988
+ def delete_webhook(conversation_sid, webhook_sid)
989
+ @transport.request(:delete, "#{conv_root}/#{conversation_sid}/Webhooks/#{webhook_sid}")
990
+ nil
991
+ end
992
+
993
+ # --- ServiceConversationWithParticipants (create only) ---
994
+ def create_conversation_with_participants(**kwargs)
995
+ ConversationsV1ServiceConversationWithParticipants.from_hash(
996
+ @transport.request(:post, "#{svc_root}/ConversationWithParticipants",
997
+ form: build_form(CONV_WITH_PARTICIPANTS_FIELDS, kwargs))
998
+ )
999
+ end
1000
+
1001
+ # --- ServiceParticipantConversation (list only) ---
1002
+ def list_participant_conversations(identity: nil, address: nil, page_size: nil)
1003
+ params = {}
1004
+ params['Identity'] = identity unless identity.nil?
1005
+ params['Address'] = address unless address.nil?
1006
+ params['PageSize'] = page_size unless page_size.nil?
1007
+ ConversationsV1ServiceParticipantConversationList.new(
1008
+ @transport.request(:get, "#{svc_root}/ParticipantConversations", params: params)
1009
+ )
1010
+ end
1011
+
1012
+ # --- ServiceUserConversation (list only, under Users/{Sid}/Conversations) ---
1013
+ def list_user_conversations(user_sid, page_size: nil)
1014
+ params = {}
1015
+ params['PageSize'] = page_size unless page_size.nil?
1016
+ ConversationsV1ServiceUserConversationList.new(
1017
+ @transport.request(:get, "#{svc_root}/Users/#{user_sid}/Conversations", params: params)
1018
+ )
1019
+ end
1020
+
1021
+ # --- ServiceRole (5 CRUD) ---
1022
+ def list_roles(page_size: nil)
1023
+ params = {}
1024
+ params['PageSize'] = page_size unless page_size.nil?
1025
+ ConversationsV1ServiceRoleList.new(
1026
+ @transport.request(:get, "#{svc_root}/Roles", params: params)
1027
+ )
1028
+ end
1029
+
1030
+ def create_role(friendly_name:, type:, permission:)
1031
+ form = { 'FriendlyName' => friendly_name, 'Type' => type, 'Permission' => Array(permission) }
1032
+ ConversationsV1ServiceRole.from_hash(
1033
+ @transport.request(:post, "#{svc_root}/Roles", form: form)
1034
+ )
1035
+ end
1036
+
1037
+ def fetch_role(role_sid)
1038
+ ConversationsV1ServiceRole.from_hash(
1039
+ @transport.request(:get, "#{svc_root}/Roles/#{role_sid}")
1040
+ )
1041
+ end
1042
+
1043
+ def update_role(role_sid, permission:)
1044
+ form = { 'Permission' => Array(permission) }
1045
+ ConversationsV1ServiceRole.from_hash(
1046
+ @transport.request(:post, "#{svc_root}/Roles/#{role_sid}", form: form)
1047
+ )
1048
+ end
1049
+
1050
+ def delete_role(role_sid)
1051
+ @transport.request(:delete, "#{svc_root}/Roles/#{role_sid}")
1052
+ nil
1053
+ end
1054
+
1055
+ # --- ServiceUser (5 CRUD) ---
1056
+ def list_users(page_size: nil)
1057
+ params = {}
1058
+ params['PageSize'] = page_size unless page_size.nil?
1059
+ ConversationsV1ServiceUserList.new(
1060
+ @transport.request(:get, "#{svc_root}/Users", params: params)
1061
+ )
1062
+ end
1063
+
1064
+ def create_user(identity:, friendly_name: nil, attributes: nil, role_sid: nil)
1065
+ kwargs = { identity: identity, friendly_name: friendly_name,
1066
+ attributes: attributes, role_sid: role_sid }
1067
+ ConversationsV1ServiceUser.from_hash(
1068
+ @transport.request(:post, "#{svc_root}/Users", form: build_form(USER_FIELDS, kwargs))
1069
+ )
1070
+ end
1071
+
1072
+ def fetch_user(user_sid)
1073
+ ConversationsV1ServiceUser.from_hash(
1074
+ @transport.request(:get, "#{svc_root}/Users/#{user_sid}")
1075
+ )
1076
+ end
1077
+
1078
+ def update_user(user_sid, **kwargs)
1079
+ ConversationsV1ServiceUser.from_hash(
1080
+ @transport.request(:post, "#{svc_root}/Users/#{user_sid}",
1081
+ form: build_form(USER_UPDATE_FIELDS, kwargs))
1082
+ )
1083
+ end
1084
+
1085
+ def delete_user(user_sid)
1086
+ @transport.request(:delete, "#{svc_root}/Users/#{user_sid}")
1087
+ nil
1088
+ end
1089
+
1090
+ # --- ServiceBinding (list/fetch/delete only) ---
1091
+ def list_bindings(binding_type: nil, identity: nil, page_size: nil)
1092
+ params = {}
1093
+ params['BindingType'] = binding_type unless binding_type.nil?
1094
+ params['Identity'] = identity unless identity.nil?
1095
+ params['PageSize'] = page_size unless page_size.nil?
1096
+ ConversationsV1ServiceBindingList.new(
1097
+ @transport.request(:get, "#{svc_root}/Bindings", params: params)
1098
+ )
1099
+ end
1100
+
1101
+ def fetch_binding(sid)
1102
+ ConversationsV1ServiceBinding.from_hash(
1103
+ @transport.request(:get, "#{svc_root}/Bindings/#{sid}")
1104
+ )
1105
+ end
1106
+
1107
+ def delete_binding(sid)
1108
+ @transport.request(:delete, "#{svc_root}/Bindings/#{sid}")
1109
+ nil
1110
+ end
1111
+
1112
+ # --- ServiceConfiguration (fetch+update singleton) ---
1113
+ def fetch_configuration
1114
+ ConversationsV1ServiceConfiguration.from_hash(
1115
+ @transport.request(:get, "#{svc_root}/Configuration")
1116
+ )
1117
+ end
1118
+
1119
+ def update_configuration(**kwargs)
1120
+ ConversationsV1ServiceConfiguration.from_hash(
1121
+ @transport.request(:post, "#{svc_root}/Configuration",
1122
+ form: build_form(CONFIG_UPDATE_FIELDS, kwargs))
1123
+ )
1124
+ end
1125
+
1126
+ # --- ServiceNotification (fetch+update singleton) ---
1127
+ def fetch_notifications
1128
+ ConversationsV1ServiceNotification.from_hash(
1129
+ @transport.request(:get, "#{svc_root}/Configuration/Notifications")
1130
+ )
1131
+ end
1132
+
1133
+ def update_notifications(**kwargs)
1134
+ ConversationsV1ServiceNotification.from_hash(
1135
+ @transport.request(:post, "#{svc_root}/Configuration/Notifications",
1136
+ form: build_form(NOTIFICATION_UPDATE_FIELDS, kwargs))
1137
+ )
1138
+ end
1139
+
1140
+ # --- ServiceWebhookConfiguration (fetch+update singleton) ---
1141
+ def fetch_webhook_configuration
1142
+ ConversationsV1ServiceWebhookConfiguration.from_hash(
1143
+ @transport.request(:get, "#{svc_root}/Configuration/Webhooks")
1144
+ )
1145
+ end
1146
+
1147
+ def update_webhook_configuration(**kwargs)
1148
+ ConversationsV1ServiceWebhookConfiguration.from_hash(
1149
+ @transport.request(:post, "#{svc_root}/Configuration/Webhooks",
1150
+ form: build_form(WEBHOOK_CONFIG_UPDATE_FIELDS, kwargs))
1151
+ )
1152
+ end
1153
+
1154
+ private
1155
+
1156
+ def svc_root
1157
+ "/v1/Services/#{@chat_service_sid}"
1158
+ end
1159
+
1160
+ def conv_root
1161
+ "#{svc_root}/Conversations"
1162
+ end
1163
+
1164
+ def build_form(map, kwargs)
1165
+ out = {}
1166
+ map.each do |wire, k|
1167
+ value = kwargs[k]
1168
+ next if value.nil?
1169
+
1170
+ out[wire] = value
1171
+ end
1172
+ out
1173
+ end
1174
+ end
1175
+ end