signalwire-sdk 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 +7 -0
- data/LICENSE +21 -0
- data/README.md +259 -0
- data/bin/swaig-test +872 -0
- data/lib/signalwire/agent/agent_base.rb +2134 -0
- data/lib/signalwire/contexts/context_builder.rb +861 -0
- data/lib/signalwire/core/logging_config.rb +54 -0
- data/lib/signalwire/datamap/data_map.rb +315 -0
- data/lib/signalwire/logging.rb +92 -0
- data/lib/signalwire/pom/prompt_object_model.rb +269 -0
- data/lib/signalwire/pom/section.rb +202 -0
- data/lib/signalwire/prefabs/concierge.rb +92 -0
- data/lib/signalwire/prefabs/faq_bot.rb +67 -0
- data/lib/signalwire/prefabs/info_gatherer.rb +79 -0
- data/lib/signalwire/prefabs/receptionist.rb +74 -0
- data/lib/signalwire/prefabs/survey.rb +75 -0
- data/lib/signalwire/relay/action.rb +291 -0
- data/lib/signalwire/relay/call.rb +523 -0
- data/lib/signalwire/relay/client.rb +789 -0
- data/lib/signalwire/relay/constants.rb +124 -0
- data/lib/signalwire/relay/message.rb +137 -0
- data/lib/signalwire/relay/relay_event.rb +670 -0
- data/lib/signalwire/rest/http_client.rb +159 -0
- data/lib/signalwire/rest/namespaces/addresses.rb +19 -0
- data/lib/signalwire/rest/namespaces/calling.rb +179 -0
- data/lib/signalwire/rest/namespaces/chat.rb +18 -0
- data/lib/signalwire/rest/namespaces/compat.rb +229 -0
- data/lib/signalwire/rest/namespaces/datasphere.rb +39 -0
- data/lib/signalwire/rest/namespaces/fabric.rb +235 -0
- data/lib/signalwire/rest/namespaces/imported_numbers.rb +18 -0
- data/lib/signalwire/rest/namespaces/logs.rb +46 -0
- data/lib/signalwire/rest/namespaces/lookup.rb +18 -0
- data/lib/signalwire/rest/namespaces/mfa.rb +26 -0
- data/lib/signalwire/rest/namespaces/number_groups.rb +32 -0
- data/lib/signalwire/rest/namespaces/phone_numbers.rb +124 -0
- data/lib/signalwire/rest/namespaces/project.rb +33 -0
- data/lib/signalwire/rest/namespaces/pubsub.rb +18 -0
- data/lib/signalwire/rest/namespaces/queues.rb +28 -0
- data/lib/signalwire/rest/namespaces/recordings.rb +18 -0
- data/lib/signalwire/rest/namespaces/registry.rb +67 -0
- data/lib/signalwire/rest/namespaces/short_codes.rb +26 -0
- data/lib/signalwire/rest/namespaces/sip_profile.rb +22 -0
- data/lib/signalwire/rest/namespaces/verified_callers.rb +24 -0
- data/lib/signalwire/rest/namespaces/video.rb +129 -0
- data/lib/signalwire/rest/pagination.rb +89 -0
- data/lib/signalwire/rest/phone_call_handler.rb +56 -0
- data/lib/signalwire/rest/rest_client.rb +114 -0
- data/lib/signalwire/runtime.rb +98 -0
- data/lib/signalwire/security/session_manager.rb +124 -0
- data/lib/signalwire/security/webhook_middleware.rb +191 -0
- data/lib/signalwire/security/webhook_validator.rb +327 -0
- data/lib/signalwire/server/agent_server.rb +413 -0
- data/lib/signalwire/serverless/lambda_handler.rb +251 -0
- data/lib/signalwire/skills/builtin/api_ninjas_trivia.rb +99 -0
- data/lib/signalwire/skills/builtin/claude_skills.rb +92 -0
- data/lib/signalwire/skills/builtin/custom_skills.rb +54 -0
- data/lib/signalwire/skills/builtin/datasphere.rb +153 -0
- data/lib/signalwire/skills/builtin/datasphere_serverless.rb +107 -0
- data/lib/signalwire/skills/builtin/datetime.rb +97 -0
- data/lib/signalwire/skills/builtin/google_maps.rb +168 -0
- data/lib/signalwire/skills/builtin/info_gatherer.rb +189 -0
- data/lib/signalwire/skills/builtin/joke.rb +65 -0
- data/lib/signalwire/skills/builtin/math.rb +176 -0
- data/lib/signalwire/skills/builtin/mcp_gateway.rb +121 -0
- data/lib/signalwire/skills/builtin/native_vector_search.rb +116 -0
- data/lib/signalwire/skills/builtin/play_background_file.rb +86 -0
- data/lib/signalwire/skills/builtin/spider.rb +169 -0
- data/lib/signalwire/skills/builtin/swml_transfer.rb +118 -0
- data/lib/signalwire/skills/builtin/weather_api.rb +92 -0
- data/lib/signalwire/skills/builtin/web_search.rb +141 -0
- data/lib/signalwire/skills/builtin/wikipedia_search.rb +125 -0
- data/lib/signalwire/skills/skill_base.rb +82 -0
- data/lib/signalwire/skills/skill_manager.rb +97 -0
- data/lib/signalwire/skills/skill_registry.rb +258 -0
- data/lib/signalwire/swaig/function_result.rb +777 -0
- data/lib/signalwire/swml/document.rb +84 -0
- data/lib/signalwire/swml/schema.json +12250 -0
- data/lib/signalwire/swml/schema.rb +81 -0
- data/lib/signalwire/swml/service.rb +650 -0
- data/lib/signalwire/utils/schema_utils.rb +298 -0
- data/lib/signalwire/utils/serverless.rb +19 -0
- data/lib/signalwire/utils/url_validator.rb +138 -0
- data/lib/signalwire/version.rb +5 -0
- data/lib/signalwire.rb +114 -0
- metadata +225 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# Standard fabric resource with CRUD + addresses.
|
|
7
|
+
class FabricResource < CrudResource
|
|
8
|
+
def list_addresses(resource_id, **params)
|
|
9
|
+
@http.get(_path(resource_id, 'addresses'), params.empty? ? nil : params)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Fabric resource that uses PUT for updates.
|
|
14
|
+
class FabricResourcePUT < FabricResource
|
|
15
|
+
self.update_method = 'PUT'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Fabric webhook resource that's normally auto-created by
|
|
19
|
+
# +phone_numbers.set_*_webhook+. Exposed for backwards compatibility.
|
|
20
|
+
#
|
|
21
|
+
# The binding model for these resources is on the phone number (see
|
|
22
|
+
# +phone_numbers.set_swml_webhook+ / +set_cxml_webhook+) -- setting
|
|
23
|
+
# +call_handler+ on a phone number auto-materializes the webhook
|
|
24
|
+
# Fabric resource. Calling +create+ directly here produces an orphan
|
|
25
|
+
# resource that isn't bound to any phone number.
|
|
26
|
+
class AutoMaterializedWebhook < FabricResource
|
|
27
|
+
# Subclasses override to advertise the correct helper in the warning.
|
|
28
|
+
AUTO_HELPER_NAME = 'phone_numbers.set_*_webhook'
|
|
29
|
+
|
|
30
|
+
# @deprecated Creating a webhook Fabric resource directly produces an
|
|
31
|
+
# orphan that isn't bound to any phone number. Use the matching
|
|
32
|
+
# +phone_numbers.set_*_webhook+ helper instead; it updates the
|
|
33
|
+
# phone number and the server auto-materializes the resource.
|
|
34
|
+
# See porting-sdk's +phone-binding.md+.
|
|
35
|
+
def create(**kwargs)
|
|
36
|
+
Kernel.warn(
|
|
37
|
+
"DEPRECATION: creating a webhook Fabric resource directly produces " \
|
|
38
|
+
"an orphan not bound to any phone number. Use " \
|
|
39
|
+
"#{self.class::AUTO_HELPER_NAME} instead; it updates the phone " \
|
|
40
|
+
"number and the server auto-materializes the resource. " \
|
|
41
|
+
"See porting-sdk's phone-binding.md.",
|
|
42
|
+
uplevel: 1
|
|
43
|
+
)
|
|
44
|
+
super
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# SWML webhooks -- auto-materialized by +phone_numbers.set_swml_webhook+.
|
|
49
|
+
class SwmlWebhooksResource < AutoMaterializedWebhook
|
|
50
|
+
AUTO_HELPER_NAME = 'phone_numbers.set_swml_webhook(sid, url: ...)'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# cXML webhooks -- auto-materialized by +phone_numbers.set_cxml_webhook+.
|
|
54
|
+
class CxmlWebhooksResource < AutoMaterializedWebhook
|
|
55
|
+
AUTO_HELPER_NAME = 'phone_numbers.set_cxml_webhook(sid, url: ...)'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Call flows with version management.
|
|
59
|
+
class CallFlowsResource < FabricResourcePUT
|
|
60
|
+
def list_addresses(resource_id, **params)
|
|
61
|
+
path = @base_path.sub('/call_flows', '/call_flow')
|
|
62
|
+
@http.get("#{path}/#{resource_id}/addresses", params.empty? ? nil : params)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def list_versions(resource_id, **params)
|
|
66
|
+
path = @base_path.sub('/call_flows', '/call_flow')
|
|
67
|
+
@http.get("#{path}/#{resource_id}/versions", params.empty? ? nil : params)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def deploy_version(resource_id, **kwargs)
|
|
71
|
+
path = @base_path.sub('/call_flows', '/call_flow')
|
|
72
|
+
@http.post("#{path}/#{resource_id}/versions", kwargs)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Conference rooms -- uses singular 'conference_room' for sub-resource paths.
|
|
77
|
+
class ConferenceRoomsResource < FabricResourcePUT
|
|
78
|
+
def list_addresses(resource_id, **params)
|
|
79
|
+
path = @base_path.sub('/conference_rooms', '/conference_room')
|
|
80
|
+
@http.get("#{path}/#{resource_id}/addresses", params.empty? ? nil : params)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Subscribers with SIP endpoint management.
|
|
85
|
+
class SubscribersResource < FabricResourcePUT
|
|
86
|
+
def list_sip_endpoints(subscriber_id, **params)
|
|
87
|
+
@http.get(_path(subscriber_id, 'sip_endpoints'), params.empty? ? nil : params)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def create_sip_endpoint(subscriber_id, **kwargs)
|
|
91
|
+
@http.post(_path(subscriber_id, 'sip_endpoints'), kwargs)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def get_sip_endpoint(subscriber_id, endpoint_id)
|
|
95
|
+
@http.get(_path(subscriber_id, 'sip_endpoints', endpoint_id))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def update_sip_endpoint(subscriber_id, endpoint_id, **kwargs)
|
|
99
|
+
@http.patch(_path(subscriber_id, 'sip_endpoints', endpoint_id), kwargs)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def delete_sip_endpoint(subscriber_id, endpoint_id)
|
|
103
|
+
@http.delete(_path(subscriber_id, 'sip_endpoints', endpoint_id))
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# cXML applications -- no create method.
|
|
108
|
+
class CxmlApplicationsResource < FabricResourcePUT
|
|
109
|
+
def create(**_kwargs)
|
|
110
|
+
raise NotImplementedError, 'cXML applications cannot be created via this API'
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Generic resource operations across all fabric resource types.
|
|
115
|
+
class GenericResources < BaseResource
|
|
116
|
+
def list(**params)
|
|
117
|
+
@http.get(@base_path, params.empty? ? nil : params)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def get(resource_id)
|
|
121
|
+
@http.get(_path(resource_id))
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def delete(resource_id)
|
|
125
|
+
@http.delete(_path(resource_id))
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def list_addresses(resource_id, **params)
|
|
129
|
+
@http.get(_path(resource_id, 'addresses'), params.empty? ? nil : params)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @deprecated For the common binding cases use +phone_numbers.set_*+ helpers.
|
|
133
|
+
#
|
|
134
|
+
# This endpoint (+POST /api/fabric/resources/{id}/phone_routes+) accepts
|
|
135
|
+
# only a narrow set of legacy resource types as the attach target. It
|
|
136
|
+
# *does not work* for +swml_webhook+ / +cxml_webhook+ / +ai_agent+
|
|
137
|
+
# bindings -- those are configured on the phone number and the Fabric
|
|
138
|
+
# resource is auto-materialized (see +phone_numbers.set_swml_webhook+
|
|
139
|
+
# etc.). The authoritative list of accepting resource types lives in
|
|
140
|
+
# the OpenAPI spec; routing here for those types returns 404 or 422.
|
|
141
|
+
def assign_phone_route(resource_id, **kwargs)
|
|
142
|
+
Kernel.warn(
|
|
143
|
+
"DEPRECATION: assign_phone_route does not bind phone numbers to " \
|
|
144
|
+
"swml_webhook/cxml_webhook/ai_agent resources -- those are " \
|
|
145
|
+
"configured via phone_numbers.set_swml_webhook / set_cxml_webhook " \
|
|
146
|
+
"/ set_ai_agent. This method applies only to a narrow set of " \
|
|
147
|
+
"legacy resource types. See porting-sdk's phone-binding.md.",
|
|
148
|
+
uplevel: 1
|
|
149
|
+
)
|
|
150
|
+
@http.post(_path(resource_id, 'phone_routes'), kwargs)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def assign_domain_application(resource_id, **kwargs)
|
|
154
|
+
@http.post(_path(resource_id, 'domain_applications'), kwargs)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Read-only fabric addresses.
|
|
159
|
+
class FabricAddresses < BaseResource
|
|
160
|
+
def list(**params)
|
|
161
|
+
@http.get(@base_path, params.empty? ? nil : params)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def get(address_id)
|
|
165
|
+
@http.get(_path(address_id))
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Subscriber, guest, invite, and embed token creation.
|
|
170
|
+
class FabricTokens < BaseResource
|
|
171
|
+
def initialize(http)
|
|
172
|
+
super(http, '/api/fabric')
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def create_subscriber_token(**kwargs)
|
|
176
|
+
@http.post(_path('subscribers', 'tokens'), kwargs)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def refresh_subscriber_token(**kwargs)
|
|
180
|
+
@http.post(_path('subscribers', 'tokens', 'refresh'), kwargs)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def create_invite_token(**kwargs)
|
|
184
|
+
@http.post(_path('subscriber', 'invites'), kwargs)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def create_guest_token(**kwargs)
|
|
188
|
+
@http.post(_path('guests', 'tokens'), kwargs)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def create_embed_token(**kwargs)
|
|
192
|
+
@http.post(_path('embeds', 'tokens'), kwargs)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Fabric API namespace grouping all resource types.
|
|
197
|
+
class FabricNamespace
|
|
198
|
+
attr_reader :swml_scripts, :relay_applications, :call_flows,
|
|
199
|
+
:conference_rooms, :freeswitch_connectors, :subscribers,
|
|
200
|
+
:sip_endpoints, :cxml_scripts, :cxml_applications,
|
|
201
|
+
:swml_webhooks, :ai_agents, :sip_gateways, :cxml_webhooks,
|
|
202
|
+
:resources, :addresses, :tokens
|
|
203
|
+
|
|
204
|
+
def initialize(http)
|
|
205
|
+
base = '/api/fabric/resources'
|
|
206
|
+
|
|
207
|
+
# PUT-update resources
|
|
208
|
+
@swml_scripts = FabricResourcePUT.new(http, "#{base}/swml_scripts")
|
|
209
|
+
@relay_applications = FabricResourcePUT.new(http, "#{base}/relay_applications")
|
|
210
|
+
@call_flows = CallFlowsResource.new(http, "#{base}/call_flows")
|
|
211
|
+
@conference_rooms = ConferenceRoomsResource.new(http, "#{base}/conference_rooms")
|
|
212
|
+
@freeswitch_connectors = FabricResourcePUT.new(http, "#{base}/freeswitch_connectors")
|
|
213
|
+
@subscribers = SubscribersResource.new(http, "#{base}/subscribers")
|
|
214
|
+
@sip_endpoints = FabricResourcePUT.new(http, "#{base}/sip_endpoints")
|
|
215
|
+
@cxml_scripts = FabricResourcePUT.new(http, "#{base}/cxml_scripts")
|
|
216
|
+
@cxml_applications = CxmlApplicationsResource.new(http, "#{base}/cxml_applications")
|
|
217
|
+
|
|
218
|
+
# PATCH-update resources
|
|
219
|
+
# swml_webhooks and cxml_webhooks are normally auto-materialized by
|
|
220
|
+
# phone_numbers.set_swml_webhook / set_cxml_webhook. Direct create
|
|
221
|
+
# still works for backcompat but emits a deprecation warning.
|
|
222
|
+
@swml_webhooks = SwmlWebhooksResource.new(http, "#{base}/swml_webhooks")
|
|
223
|
+
@ai_agents = FabricResource.new(http, "#{base}/ai_agents")
|
|
224
|
+
@sip_gateways = FabricResource.new(http, "#{base}/sip_gateways")
|
|
225
|
+
@cxml_webhooks = CxmlWebhooksResource.new(http, "#{base}/cxml_webhooks")
|
|
226
|
+
|
|
227
|
+
# Special resources
|
|
228
|
+
@resources = GenericResources.new(http, base)
|
|
229
|
+
@addresses = FabricAddresses.new(http, '/api/fabric/addresses')
|
|
230
|
+
@tokens = FabricTokens.new(http)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# Import externally-hosted phone numbers.
|
|
7
|
+
class ImportedNumbersResource < BaseResource
|
|
8
|
+
def initialize(http)
|
|
9
|
+
super(http, '/api/relay/rest/imported_phone_numbers')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def create(**kwargs)
|
|
13
|
+
@http.post(@base_path, kwargs)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# Message log queries.
|
|
7
|
+
class MessageLogs < BaseResource
|
|
8
|
+
def list(**params) = @http.get(@base_path, params.empty? ? nil : params)
|
|
9
|
+
def get(log_id) = @http.get(_path(log_id))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Voice log queries.
|
|
13
|
+
class VoiceLogs < BaseResource
|
|
14
|
+
def list(**params) = @http.get(@base_path, params.empty? ? nil : params)
|
|
15
|
+
def get(log_id) = @http.get(_path(log_id))
|
|
16
|
+
|
|
17
|
+
def list_events(log_id, **params)
|
|
18
|
+
@http.get(_path(log_id, 'events'), params.empty? ? nil : params)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Fax log queries.
|
|
23
|
+
class FaxLogs < BaseResource
|
|
24
|
+
def list(**params) = @http.get(@base_path, params.empty? ? nil : params)
|
|
25
|
+
def get(log_id) = @http.get(_path(log_id))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Conference log queries.
|
|
29
|
+
class ConferenceLogs < BaseResource
|
|
30
|
+
def list(**params) = @http.get(@base_path, params.empty? ? nil : params)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Logs API namespace.
|
|
34
|
+
class LogsNamespace
|
|
35
|
+
attr_reader :messages, :voice, :fax, :conferences
|
|
36
|
+
|
|
37
|
+
def initialize(http)
|
|
38
|
+
@messages = MessageLogs.new(http, '/api/messaging/logs')
|
|
39
|
+
@voice = VoiceLogs.new(http, '/api/voice/logs')
|
|
40
|
+
@fax = FaxLogs.new(http, '/api/fax/logs')
|
|
41
|
+
@conferences = ConferenceLogs.new(http, '/api/logs/conferences')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# Phone number lookup (carrier, CNAM).
|
|
7
|
+
class LookupResource < BaseResource
|
|
8
|
+
def initialize(http)
|
|
9
|
+
super(http, '/api/relay/rest/lookup')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def phone_number(e164, **params)
|
|
13
|
+
@http.get(_path('phone_number', e164), params.empty? ? nil : params)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# Multi-factor authentication via SMS or phone call.
|
|
7
|
+
class MfaResource < BaseResource
|
|
8
|
+
def initialize(http)
|
|
9
|
+
super(http, '/api/relay/rest/mfa')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def sms(**kwargs)
|
|
13
|
+
@http.post(_path('sms'), kwargs)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call(**kwargs)
|
|
17
|
+
@http.post(_path('call'), kwargs)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def verify(request_id, **kwargs)
|
|
21
|
+
@http.post(_path(request_id, 'verify'), kwargs)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# Number group management with membership operations.
|
|
7
|
+
class NumberGroupsResource < CrudResource
|
|
8
|
+
self.update_method = 'PUT'
|
|
9
|
+
|
|
10
|
+
def initialize(http)
|
|
11
|
+
super(http, '/api/relay/rest/number_groups')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def list_memberships(group_id, **params)
|
|
15
|
+
@http.get(_path(group_id, 'number_group_memberships'), params.empty? ? nil : params)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def add_membership(group_id, **kwargs)
|
|
19
|
+
@http.post(_path(group_id, 'number_group_memberships'), kwargs)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_membership(membership_id)
|
|
23
|
+
@http.get("/api/relay/rest/number_group_memberships/#{membership_id}")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def delete_membership(membership_id)
|
|
27
|
+
@http.delete("/api/relay/rest/number_group_memberships/#{membership_id}")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../phone_call_handler'
|
|
4
|
+
|
|
5
|
+
module SignalWire
|
|
6
|
+
module REST
|
|
7
|
+
module Namespaces
|
|
8
|
+
# Phone number management.
|
|
9
|
+
#
|
|
10
|
+
# Supports the standard CRUD surface plus typed helpers for binding an
|
|
11
|
+
# inbound call to a handler (SWML webhook, cXML webhook, AI agent, call
|
|
12
|
+
# flow, RELAY application/topic). The binding model is: set
|
|
13
|
+
# +call_handler+ and the handler-specific companion field on the phone
|
|
14
|
+
# number; the server auto-materializes the matching Fabric resource.
|
|
15
|
+
# See +SignalWire::REST::PhoneCallHandler+ for the enum, and the
|
|
16
|
+
# porting-sdk's +phone-binding.md+ for the full model.
|
|
17
|
+
class PhoneNumbersResource < CrudResource
|
|
18
|
+
self.update_method = 'PUT'
|
|
19
|
+
|
|
20
|
+
def initialize(http)
|
|
21
|
+
super(http, '/api/relay/rest/phone_numbers')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def search(**params)
|
|
25
|
+
@http.get(_path('search'), params.empty? ? nil : params)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# -- Typed binding helpers -----------------------------------------
|
|
29
|
+
#
|
|
30
|
+
# Each helper is a one-line wrapper over +update+ with the right
|
|
31
|
+
# +call_handler+ value and companion field already set. Pass extra
|
|
32
|
+
# kwargs through for cases the helper doesn't name explicitly (e.g.
|
|
33
|
+
# +call_fallback_url+ on cXML webhooks).
|
|
34
|
+
|
|
35
|
+
# Route inbound calls to an SWML webhook URL.
|
|
36
|
+
#
|
|
37
|
+
# Your backend returns an SWML document per call. The server
|
|
38
|
+
# auto-creates a +swml_webhook+ Fabric resource keyed off this URL.
|
|
39
|
+
#
|
|
40
|
+
# @param sid [String] the phone number SID (e.g. +pn-...+)
|
|
41
|
+
# @param url [String] the SWML webhook URL
|
|
42
|
+
# @param extra [Hash] additional fields passed to +update+
|
|
43
|
+
# @return [Hash] the updated phone number representation
|
|
44
|
+
def set_swml_webhook(sid, url:, **extra)
|
|
45
|
+
update(
|
|
46
|
+
sid,
|
|
47
|
+
call_handler: PhoneCallHandler::RELAY_SCRIPT,
|
|
48
|
+
call_relay_script_url: url,
|
|
49
|
+
**extra
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Route inbound calls to a cXML (Twilio-compat / LAML) webhook.
|
|
54
|
+
#
|
|
55
|
+
# Despite the wire value +laml_webhooks+ being plural, this creates a
|
|
56
|
+
# single +cxml_webhook+ Fabric resource. +fallback_url+ is used when
|
|
57
|
+
# the primary URL fails; +status_callback_url+ receives call status
|
|
58
|
+
# updates.
|
|
59
|
+
def set_cxml_webhook(sid, url:, fallback_url: nil, status_callback_url: nil, **extra)
|
|
60
|
+
body = {
|
|
61
|
+
call_handler: PhoneCallHandler::LAML_WEBHOOKS,
|
|
62
|
+
call_request_url: url
|
|
63
|
+
}
|
|
64
|
+
body[:call_fallback_url] = fallback_url unless fallback_url.nil?
|
|
65
|
+
body[:call_status_callback_url] = status_callback_url unless status_callback_url.nil?
|
|
66
|
+
update(sid, **body, **extra)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Route inbound calls to an existing cXML application by ID.
|
|
70
|
+
def set_cxml_application(sid, application_id:, **extra)
|
|
71
|
+
update(
|
|
72
|
+
sid,
|
|
73
|
+
call_handler: PhoneCallHandler::LAML_APPLICATION,
|
|
74
|
+
call_laml_application_id: application_id,
|
|
75
|
+
**extra
|
|
76
|
+
)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Route inbound calls to an AI Agent Fabric resource by ID.
|
|
80
|
+
def set_ai_agent(sid, agent_id:, **extra)
|
|
81
|
+
update(
|
|
82
|
+
sid,
|
|
83
|
+
call_handler: PhoneCallHandler::AI_AGENT,
|
|
84
|
+
call_ai_agent_id: agent_id,
|
|
85
|
+
**extra
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Route inbound calls to a Call Flow by ID.
|
|
90
|
+
#
|
|
91
|
+
# +version+ accepts +"working_copy"+ or +"current_deployed"+ (server
|
|
92
|
+
# default when omitted).
|
|
93
|
+
def set_call_flow(sid, flow_id:, version: nil, **extra)
|
|
94
|
+
body = {
|
|
95
|
+
call_handler: PhoneCallHandler::CALL_FLOW,
|
|
96
|
+
call_flow_id: flow_id
|
|
97
|
+
}
|
|
98
|
+
body[:call_flow_version] = version unless version.nil?
|
|
99
|
+
update(sid, **body, **extra)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Route inbound calls to a named RELAY application.
|
|
103
|
+
def set_relay_application(sid, name:, **extra)
|
|
104
|
+
update(
|
|
105
|
+
sid,
|
|
106
|
+
call_handler: PhoneCallHandler::RELAY_APPLICATION,
|
|
107
|
+
call_relay_application: name,
|
|
108
|
+
**extra
|
|
109
|
+
)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Route inbound calls to a RELAY topic (client subscription).
|
|
113
|
+
def set_relay_topic(sid, topic:, status_callback_url: nil, **extra)
|
|
114
|
+
body = {
|
|
115
|
+
call_handler: PhoneCallHandler::RELAY_TOPIC,
|
|
116
|
+
call_relay_topic: topic
|
|
117
|
+
}
|
|
118
|
+
body[:call_relay_topic_status_callback_url] = status_callback_url unless status_callback_url.nil?
|
|
119
|
+
update(sid, **body, **extra)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# Project API token management.
|
|
7
|
+
class ProjectTokens < BaseResource
|
|
8
|
+
def initialize(http)
|
|
9
|
+
super(http, '/api/project/tokens')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def create(**kwargs) = @http.post(@base_path, kwargs)
|
|
13
|
+
|
|
14
|
+
def update(token_id, **kwargs)
|
|
15
|
+
@http.patch(_path(token_id), kwargs)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def delete(token_id)
|
|
19
|
+
@http.delete(_path(token_id))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Project API namespace.
|
|
24
|
+
class ProjectNamespace
|
|
25
|
+
attr_reader :tokens
|
|
26
|
+
|
|
27
|
+
def initialize(http)
|
|
28
|
+
@tokens = ProjectTokens.new(http)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# PubSub token generation.
|
|
7
|
+
class PubSubResource < BaseResource
|
|
8
|
+
def initialize(http)
|
|
9
|
+
super(http, '/api/pubsub/tokens')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def create_token(**kwargs)
|
|
13
|
+
@http.post(@base_path, kwargs)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# Queue management with member operations.
|
|
7
|
+
class QueuesResource < CrudResource
|
|
8
|
+
self.update_method = 'PUT'
|
|
9
|
+
|
|
10
|
+
def initialize(http)
|
|
11
|
+
super(http, '/api/relay/rest/queues')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def list_members(queue_id, **params)
|
|
15
|
+
@http.get(_path(queue_id, 'members'), params.empty? ? nil : params)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get_next_member(queue_id)
|
|
19
|
+
@http.get(_path(queue_id, 'members', 'next'))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_member(queue_id, member_id)
|
|
23
|
+
@http.get(_path(queue_id, 'members', member_id))
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# Recording management (read-only + delete).
|
|
7
|
+
class RecordingsResource < BaseResource
|
|
8
|
+
def initialize(http)
|
|
9
|
+
super(http, '/api/relay/rest/recordings')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def list(**params) = @http.get(@base_path, params.empty? ? nil : params)
|
|
13
|
+
def get(recording_id) = @http.get(_path(recording_id))
|
|
14
|
+
def delete(recording_id) = @http.delete(_path(recording_id))
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SignalWire
|
|
4
|
+
module REST
|
|
5
|
+
module Namespaces
|
|
6
|
+
# 10DLC brand management.
|
|
7
|
+
class RegistryBrands < BaseResource
|
|
8
|
+
def list(**params) = @http.get(@base_path, params.empty? ? nil : params)
|
|
9
|
+
def create(**kwargs) = @http.post(@base_path, kwargs)
|
|
10
|
+
def get(brand_id) = @http.get(_path(brand_id))
|
|
11
|
+
|
|
12
|
+
def list_campaigns(brand_id, **params)
|
|
13
|
+
@http.get(_path(brand_id, 'campaigns'), params.empty? ? nil : params)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create_campaign(brand_id, **kwargs)
|
|
17
|
+
@http.post(_path(brand_id, 'campaigns'), kwargs)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# 10DLC campaign management.
|
|
22
|
+
class RegistryCampaigns < BaseResource
|
|
23
|
+
def get(campaign_id) = @http.get(_path(campaign_id))
|
|
24
|
+
def update(campaign_id, **kwargs) = @http.put(_path(campaign_id), kwargs)
|
|
25
|
+
|
|
26
|
+
def list_numbers(campaign_id, **params)
|
|
27
|
+
@http.get(_path(campaign_id, 'numbers'), params.empty? ? nil : params)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def list_orders(campaign_id, **params)
|
|
31
|
+
@http.get(_path(campaign_id, 'orders'), params.empty? ? nil : params)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def create_order(campaign_id, **kwargs)
|
|
35
|
+
@http.post(_path(campaign_id, 'orders'), kwargs)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# 10DLC assignment order management.
|
|
40
|
+
class RegistryOrders < BaseResource
|
|
41
|
+
def get(order_id)
|
|
42
|
+
@http.get(_path(order_id))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# 10DLC number assignment management.
|
|
47
|
+
class RegistryNumbers < BaseResource
|
|
48
|
+
def delete(number_id)
|
|
49
|
+
@http.delete(_path(number_id))
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# 10DLC Campaign Registry namespace.
|
|
54
|
+
class RegistryNamespace
|
|
55
|
+
attr_reader :brands, :campaigns, :orders, :numbers
|
|
56
|
+
|
|
57
|
+
def initialize(http)
|
|
58
|
+
base = '/api/relay/rest/registry/beta'
|
|
59
|
+
@brands = RegistryBrands.new(http, "#{base}/brands")
|
|
60
|
+
@campaigns = RegistryCampaigns.new(http, "#{base}/campaigns")
|
|
61
|
+
@orders = RegistryOrders.new(http, "#{base}/orders")
|
|
62
|
+
@numbers = RegistryNumbers.new(http, "#{base}/numbers")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|