livekit-server-sdk 0.9.0 → 1.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/banner_dark.png +0 -0
  4. data/.github/workflows/generate-protobufs.yml +82 -0
  5. data/.github/workflows/test-api.yml +43 -0
  6. data/.github/workflows/test.yml +10 -7
  7. data/CHANGELOG.md +18 -0
  8. data/Gemfile.lock +60 -37
  9. data/README.md +7 -5
  10. data/Rakefile +6 -1
  11. data/lib/livekit/agent_dispatch_service_client.rb +11 -9
  12. data/lib/livekit/auth_mixin.rb +23 -8
  13. data/lib/livekit/connector_service_client.rb +87 -0
  14. data/lib/livekit/dial_timeout.rb +26 -0
  15. data/lib/livekit/egress_service_client.rb +18 -14
  16. data/lib/livekit/errors.rb +60 -0
  17. data/lib/livekit/failover.rb +215 -0
  18. data/lib/livekit/grants.rb +6 -2
  19. data/lib/livekit/ingress_service_client.rb +8 -6
  20. data/lib/livekit/livekit_api.rb +67 -0
  21. data/lib/livekit/proto/livekit_agent_dispatch_pb.rb +3 -2
  22. data/lib/livekit/proto/livekit_agent_pb.rb +3 -5
  23. data/lib/livekit/proto/livekit_connector_pb.rb +20 -0
  24. data/lib/livekit/proto/livekit_connector_twilio_pb.rb +22 -0
  25. data/lib/livekit/proto/livekit_connector_twilio_twirp.rb +8 -0
  26. data/lib/livekit/proto/livekit_connector_twirp.rb +21 -0
  27. data/lib/livekit/proto/livekit_connector_whatsapp_pb.rb +32 -0
  28. data/lib/livekit/proto/livekit_connector_whatsapp_twirp.rb +8 -0
  29. data/lib/livekit/proto/livekit_egress_pb.rb +33 -18
  30. data/lib/livekit/proto/livekit_egress_twirp.rb +5 -4
  31. data/lib/livekit/proto/livekit_ingress_pb.rb +2 -2
  32. data/lib/livekit/proto/livekit_metrics_pb.rb +3 -2
  33. data/lib/livekit/proto/livekit_models_pb.rb +7 -2
  34. data/lib/livekit/proto/livekit_room_pb.rb +2 -2
  35. data/lib/livekit/proto/livekit_rtc_pb.rb +86 -0
  36. data/lib/livekit/proto/livekit_rtc_twirp.rb +8 -0
  37. data/lib/livekit/proto/livekit_sip_pb.rb +7 -2
  38. data/lib/livekit/proto/livekit_webhook_pb.rb +1 -1
  39. data/lib/livekit/proto/logger/options_pb.rb +3 -2
  40. data/lib/livekit/room_service_client.rb +17 -15
  41. data/lib/livekit/sip_service_client.rb +147 -21
  42. data/lib/livekit/version.rb +1 -1
  43. data/lib/livekit.rb +3 -0
  44. data/livekit_server_sdk.gemspec +6 -4
  45. metadata +43 -4
@@ -1,6 +1,8 @@
1
1
  require "livekit/proto/livekit_sip_twirp"
2
2
  require "livekit/auth_mixin"
3
3
  require 'livekit/utils'
4
+ require 'livekit/failover'
5
+ require 'livekit/dial_timeout'
4
6
 
5
7
  module LiveKit
6
8
  class SIPServiceClient < Twirp::Client
@@ -8,10 +10,11 @@ module LiveKit
8
10
  include AuthMixin
9
11
  attr_accessor :api_key, :api_secret
10
12
 
11
- def initialize(base_url, api_key: nil, api_secret: nil)
12
- super(File.join(Utils.to_http_url(base_url), "/twirp"))
13
+ def initialize(base_url, api_key: nil, api_secret: nil, token: nil, failover: true, connection: nil)
14
+ super(connection || LiveKit::Failover.connection(base_url, failover))
13
15
  @api_key = api_key
14
16
  @api_secret = api_secret
17
+ @token = token
15
18
  end
16
19
 
17
20
  def create_sip_inbound_trunk(
@@ -52,7 +55,7 @@ module LiveKit
52
55
  krisp_enabled: krisp_enabled
53
56
  )
54
57
  )
55
- self.rpc(
58
+ rpc!(
56
59
  :CreateSIPInboundTrunk,
57
60
  request,
58
61
  headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
@@ -91,7 +94,7 @@ module LiveKit
91
94
  headers_to_attributes: headers_to_attributes
92
95
  )
93
96
  )
94
- self.rpc(
97
+ rpc!(
95
98
  :CreateSIPOutboundTrunk,
96
99
  request,
97
100
  headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
@@ -100,7 +103,7 @@ module LiveKit
100
103
 
101
104
  def list_sip_inbound_trunk
102
105
  request = Proto::ListSIPInboundTrunkRequest.new
103
- self.rpc(
106
+ rpc!(
104
107
  :ListSIPInboundTrunk,
105
108
  request,
106
109
  headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
@@ -109,7 +112,7 @@ module LiveKit
109
112
 
110
113
  def list_sip_outbound_trunk
111
114
  request = Proto::ListSIPOutboundTrunkRequest.new
112
- self.rpc(
115
+ rpc!(
113
116
  :ListSIPOutboundTrunk,
114
117
  request,
115
118
  headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
@@ -120,7 +123,7 @@ module LiveKit
120
123
  request = Proto::DeleteSIPTrunkRequest.new(
121
124
  sip_trunk_id: sip_trunk_id,
122
125
  )
123
- self.rpc(
126
+ rpc!(
124
127
  :DeleteSIPTrunk,
125
128
  request,
126
129
  headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
@@ -147,7 +150,7 @@ module LiveKit
147
150
  attributes: attributes,
148
151
  room_config: room_config,
149
152
  )
150
- self.rpc(
153
+ rpc!(
151
154
  :CreateSIPDispatchRule,
152
155
  request,
153
156
  headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
@@ -156,7 +159,7 @@ module LiveKit
156
159
 
157
160
  def list_sip_dispatch_rule
158
161
  request = Proto::ListSIPDispatchRuleRequest.new
159
- self.rpc(
162
+ rpc!(
160
163
  :ListSIPDispatchRule,
161
164
  request,
162
165
  headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
@@ -167,7 +170,7 @@ module LiveKit
167
170
  request = Proto::DeleteSIPDispatchRuleRequest.new(
168
171
  sip_dispatch_rule_id: sip_dispatch_rule_id,
169
172
  )
170
- self.rpc(
173
+ rpc!(
171
174
  :DeleteSIPDispatchRule,
172
175
  request,
173
176
  headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
@@ -178,8 +181,13 @@ module LiveKit
178
181
  sip_trunk_id,
179
182
  sip_call_to,
180
183
  room_name,
184
+ # Optional inline outbound trunk configuration (SIPOutboundConfig). Use
185
+ # instead of a stored sip_trunk_id to configure the trunk per call.
186
+ trunk: nil,
181
187
  # Optional SIP From number to use. If empty, trunk number is used.
182
188
  from_number: nil,
189
+ # Optional custom caller ID shown to the callee. Requires provider support.
190
+ display_name: nil,
183
191
  # Optional identity of the participant in LiveKit room
184
192
  participant_identity: nil,
185
193
  # Optional name of the participant in LiveKit room
@@ -198,12 +206,22 @@ module LiveKit
198
206
  # Optional, max call duration in seconds
199
207
  max_call_duration: nil,
200
208
  # Optional, enable Krisp for this call
201
- krisp_enabled: false
209
+ krisp_enabled: false,
210
+ # Optional, wait for the call to be answered before returning
211
+ wait_until_answered: false,
212
+ # Optional, request timeout in seconds. Defaults to a longer value when
213
+ # wait_until_answered is set (dialing takes time).
214
+ timeout: nil
202
215
  )
216
+ # When waiting for an answer, pin the ring window explicitly so our request
217
+ # timeout doesn't depend on the server's default (which could change).
218
+ ringing_timeout = DialTimeout::DEFAULT_RINGING_TIMEOUT if wait_until_answered && ringing_timeout.nil?
203
219
  request = Proto::CreateSIPParticipantRequest.new(
204
220
  sip_trunk_id: sip_trunk_id,
221
+ trunk: trunk,
205
222
  sip_call_to: sip_call_to,
206
223
  sip_number: from_number,
224
+ display_name: display_name,
207
225
  room_name: room_name,
208
226
  participant_identity: participant_identity,
209
227
  participant_name: participant_name,
@@ -213,32 +231,140 @@ module LiveKit
213
231
  hide_phone_number: hide_phone_number,
214
232
  ringing_timeout: ringing_timeout,
215
233
  max_call_duration: max_call_duration,
216
- krisp_enabled: krisp_enabled
217
- )
218
- self.rpc(
219
- :CreateSIPParticipant,
220
- request,
221
- headers: auth_header(sip_grant: SIPGrant.new(call: true)),
234
+ krisp_enabled: krisp_enabled,
235
+ wait_until_answered: wait_until_answered
222
236
  )
237
+ headers = auth_header(sip_grant: SIPGrant.new(call: true))
238
+ # When waiting for an answer, dialing takes longer than a normal request
239
+ # and the request must outlast ringing; otherwise honor any user timeout.
240
+ effective_timeout = wait_until_answered ? DialTimeout.resolve(timeout, ringing_timeout) : timeout
241
+ headers[Failover::TIMEOUT_HEADER] = effective_timeout.to_s if effective_timeout
242
+ rpc!(:CreateSIPParticipant, request, headers: headers)
223
243
  end
224
244
 
225
245
  def transfer_sip_participant(
226
246
  room_name,
227
247
  participant_identity,
228
248
  transfer_to,
229
- play_dialtone: nil
249
+ play_dialtone: nil,
250
+ # Optional, max time for the transfer destination to answer, in seconds.
251
+ ringing_timeout: nil,
252
+ # Optional, request timeout in seconds. Defaults to a longer value since
253
+ # transferring dials a phone.
254
+ timeout: nil
230
255
  )
231
256
 
257
+ # Transferring a call dials a phone and must outlast ringing. Pin the ring
258
+ # window explicitly so our request timeout doesn't depend on the server default.
259
+ ringing_timeout ||= DialTimeout::DEFAULT_RINGING_TIMEOUT
232
260
  request = Proto::TransferSIPParticipantRequest.new(
233
261
  room_name: room_name,
234
262
  participant_identity: participant_identity,
235
263
  transfer_to: transfer_to,
236
264
  play_dialtone: play_dialtone,
265
+ ringing_timeout: ringing_timeout,
266
+ )
267
+ headers = auth_header(video_grant: VideoGrant.new(roomAdmin: true, room: room_name), sip_grant: SIPGrant.new(call: true))
268
+ headers[Failover::TIMEOUT_HEADER] = DialTimeout.resolve(timeout, ringing_timeout).to_s
269
+ rpc!(:TransferSIPParticipant, request, headers: headers)
270
+ end
271
+
272
+ # Updates an existing SIP inbound trunk, replacing it entirely.
273
+ #
274
+ # @param sip_trunk_id [String] ID of the SIP inbound trunk to update
275
+ # @param trunk [Proto::SIPInboundTrunkInfo] the full trunk definition to replace it with
276
+ def update_sip_inbound_trunk(sip_trunk_id, trunk)
277
+ request = Proto::UpdateSIPInboundTrunkRequest.new(
278
+ sip_trunk_id: sip_trunk_id,
279
+ replace: trunk,
280
+ )
281
+ rpc!(
282
+ :UpdateSIPInboundTrunk,
283
+ request,
284
+ headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
285
+ )
286
+ end
287
+
288
+ # Updates specific fields of an existing SIP inbound trunk. Only the fields
289
+ # set in +update+ are changed.
290
+ #
291
+ # @param sip_trunk_id [String] ID of the SIP inbound trunk to update
292
+ # @param update [Proto::SIPInboundTrunkUpdate] the fields to update
293
+ def update_sip_inbound_trunk_fields(sip_trunk_id, update)
294
+ request = Proto::UpdateSIPInboundTrunkRequest.new(
295
+ sip_trunk_id: sip_trunk_id,
296
+ update: update,
297
+ )
298
+ rpc!(
299
+ :UpdateSIPInboundTrunk,
300
+ request,
301
+ headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
302
+ )
303
+ end
304
+
305
+ # Updates an existing SIP outbound trunk, replacing it entirely.
306
+ #
307
+ # @param sip_trunk_id [String] ID of the SIP outbound trunk to update
308
+ # @param trunk [Proto::SIPOutboundTrunkInfo] the full trunk definition to replace it with
309
+ def update_sip_outbound_trunk(sip_trunk_id, trunk)
310
+ request = Proto::UpdateSIPOutboundTrunkRequest.new(
311
+ sip_trunk_id: sip_trunk_id,
312
+ replace: trunk,
237
313
  )
238
- self.rpc(
239
- :TransferSIPParticipant,
314
+ rpc!(
315
+ :UpdateSIPOutboundTrunk,
240
316
  request,
241
- headers: auth_header(video_grant: VideoGrant.new(roomAdmin: true, room: room_name), sip_grant: SIPGrant.new(call: true)),
317
+ headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
318
+ )
319
+ end
320
+
321
+ # Updates specific fields of an existing SIP outbound trunk. Only the fields
322
+ # set in +update+ are changed.
323
+ #
324
+ # @param sip_trunk_id [String] ID of the SIP outbound trunk to update
325
+ # @param update [Proto::SIPOutboundTrunkUpdate] the fields to update
326
+ def update_sip_outbound_trunk_fields(sip_trunk_id, update)
327
+ request = Proto::UpdateSIPOutboundTrunkRequest.new(
328
+ sip_trunk_id: sip_trunk_id,
329
+ update: update,
330
+ )
331
+ rpc!(
332
+ :UpdateSIPOutboundTrunk,
333
+ request,
334
+ headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
335
+ )
336
+ end
337
+
338
+ # Updates an existing SIP dispatch rule, replacing it entirely.
339
+ #
340
+ # @param sip_dispatch_rule_id [String] ID of the SIP dispatch rule to update
341
+ # @param rule [Proto::SIPDispatchRuleInfo] the full dispatch rule definition to replace it with
342
+ def update_sip_dispatch_rule(sip_dispatch_rule_id, rule)
343
+ request = Proto::UpdateSIPDispatchRuleRequest.new(
344
+ sip_dispatch_rule_id: sip_dispatch_rule_id,
345
+ replace: rule,
346
+ )
347
+ rpc!(
348
+ :UpdateSIPDispatchRule,
349
+ request,
350
+ headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
351
+ )
352
+ end
353
+
354
+ # Updates specific fields of an existing SIP dispatch rule. Only the fields
355
+ # set in +update+ are changed.
356
+ #
357
+ # @param sip_dispatch_rule_id [String] ID of the SIP dispatch rule to update
358
+ # @param update [Proto::SIPDispatchRuleUpdate] the fields to update
359
+ def update_sip_dispatch_rule_fields(sip_dispatch_rule_id, update)
360
+ request = Proto::UpdateSIPDispatchRuleRequest.new(
361
+ sip_dispatch_rule_id: sip_dispatch_rule_id,
362
+ update: update,
363
+ )
364
+ rpc!(
365
+ :UpdateSIPDispatchRule,
366
+ request,
367
+ headers: auth_header(sip_grant: SIPGrant.new(admin: true)),
242
368
  )
243
369
  end
244
370
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LiveKit
4
- VERSION = "0.9.0"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/livekit.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require "livekit/access_token"
4
4
  require "livekit/utils"
5
5
  require "livekit/grants"
6
+ require "livekit/errors"
6
7
  require "livekit/token_verifier"
7
8
  require "livekit/version"
8
9
 
@@ -13,3 +14,5 @@ require "livekit/egress_service_client"
13
14
  require "livekit/ingress_service_client"
14
15
  require "livekit/sip_service_client"
15
16
  require "livekit/agent_dispatch_service_client"
17
+ require "livekit/connector_service_client"
18
+ require "livekit/livekit_api"
@@ -11,11 +11,12 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = "LiveKit Server SDK for Ruby"
12
12
  spec.homepage = "https://livekit.io"
13
13
  spec.license = "Apache-2.0"
14
- spec.required_ruby_version = ">= 2.6.0"
14
+ # google-protobuf 4.x requires Ruby >= 3.1; Ruby 3.0 is EOL.
15
+ spec.required_ruby_version = ">= 3.1.0"
15
16
 
16
- # spec.metadata["homepage_uri"] = spec.homepage
17
- # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
18
- # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/livekit/server-sdk-ruby"
19
+ spec.metadata["changelog_uri"] = "https://github.com/livekit/server-sdk-ruby/blob/main/CHANGELOG.md"
19
20
 
20
21
  # Specify which files should be added to the gem when it is released.
21
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -26,6 +27,7 @@ Gem::Specification.new do |spec|
26
27
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
27
28
  spec.require_paths = ["lib"]
28
29
 
30
+ spec.add_dependency "faraday", ">= 2.0", "< 3.0"
29
31
  spec.add_dependency "google-protobuf", "~> 4.30", ">= 4.30.2"
30
32
  spec.add_dependency "jwt", ">= 2.2.3", "< 3.0"
31
33
  spec.add_dependency "twirp", "~> 1.13", ">= 1.13.1"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: livekit-server-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Omri Gabay
@@ -9,8 +9,28 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2026-02-07 00:00:00.000000000 Z
12
+ date: 2026-07-11 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '2.0'
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '3.0'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: '2.0'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
14
34
  - !ruby/object:Gem::Dependency
15
35
  name: google-protobuf
16
36
  requirement: !ruby/object:Gem::Requirement
@@ -80,8 +100,11 @@ extensions: []
80
100
  extra_rdoc_files: []
81
101
  files:
82
102
  - ".editorconfig"
103
+ - ".github/CODEOWNERS"
83
104
  - ".github/banner_dark.png"
84
105
  - ".github/banner_light.png"
106
+ - ".github/workflows/generate-protobufs.yml"
107
+ - ".github/workflows/test-api.yml"
85
108
  - ".github/workflows/test.yml"
86
109
  - ".gitignore"
87
110
  - ".gitmodules"
@@ -117,13 +140,24 @@ files:
117
140
  - lib/livekit/access_token.rb
118
141
  - lib/livekit/agent_dispatch_service_client.rb
119
142
  - lib/livekit/auth_mixin.rb
143
+ - lib/livekit/connector_service_client.rb
144
+ - lib/livekit/dial_timeout.rb
120
145
  - lib/livekit/egress_service_client.rb
146
+ - lib/livekit/errors.rb
147
+ - lib/livekit/failover.rb
121
148
  - lib/livekit/grants.rb
122
149
  - lib/livekit/ingress_service_client.rb
150
+ - lib/livekit/livekit_api.rb
123
151
  - lib/livekit/proto/livekit_agent_dispatch_pb.rb
124
152
  - lib/livekit/proto/livekit_agent_dispatch_twirp.rb
125
153
  - lib/livekit/proto/livekit_agent_pb.rb
126
154
  - lib/livekit/proto/livekit_agent_twirp.rb
155
+ - lib/livekit/proto/livekit_connector_pb.rb
156
+ - lib/livekit/proto/livekit_connector_twilio_pb.rb
157
+ - lib/livekit/proto/livekit_connector_twilio_twirp.rb
158
+ - lib/livekit/proto/livekit_connector_twirp.rb
159
+ - lib/livekit/proto/livekit_connector_whatsapp_pb.rb
160
+ - lib/livekit/proto/livekit_connector_whatsapp_twirp.rb
127
161
  - lib/livekit/proto/livekit_egress_pb.rb
128
162
  - lib/livekit/proto/livekit_egress_twirp.rb
129
163
  - lib/livekit/proto/livekit_ingress_pb.rb
@@ -134,6 +168,8 @@ files:
134
168
  - lib/livekit/proto/livekit_models_twirp.rb
135
169
  - lib/livekit/proto/livekit_room_pb.rb
136
170
  - lib/livekit/proto/livekit_room_twirp.rb
171
+ - lib/livekit/proto/livekit_rtc_pb.rb
172
+ - lib/livekit/proto/livekit_rtc_twirp.rb
137
173
  - lib/livekit/proto/livekit_sip_pb.rb
138
174
  - lib/livekit/proto/livekit_sip_twirp.rb
139
175
  - lib/livekit/proto/livekit_webhook_pb.rb
@@ -149,7 +185,10 @@ files:
149
185
  homepage: https://livekit.io
150
186
  licenses:
151
187
  - Apache-2.0
152
- metadata: {}
188
+ metadata:
189
+ homepage_uri: https://livekit.io
190
+ source_code_uri: https://github.com/livekit/server-sdk-ruby
191
+ changelog_uri: https://github.com/livekit/server-sdk-ruby/blob/main/CHANGELOG.md
153
192
  post_install_message:
154
193
  rdoc_options: []
155
194
  require_paths:
@@ -158,7 +197,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
158
197
  requirements:
159
198
  - - ">="
160
199
  - !ruby/object:Gem::Version
161
- version: 2.6.0
200
+ version: 3.1.0
162
201
  required_rubygems_version: !ruby/object:Gem::Requirement
163
202
  requirements:
164
203
  - - ">="