livekit-server-sdk 0.8.3 → 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.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -0
- data/.github/banner_dark.png +0 -0
- data/.github/banner_light.png +0 -0
- data/.github/workflows/generate-protobufs.yml +82 -0
- data/.github/workflows/test-api.yml +43 -0
- data/.github/workflows/test.yml +10 -7
- data/CHANGELOG.md +18 -0
- data/Gemfile.lock +70 -39
- data/README.md +7 -5
- data/Rakefile +8 -2
- data/bin/bootstrap.sh +1 -1
- data/lib/livekit/agent_dispatch_service_client.rb +11 -9
- data/lib/livekit/auth_mixin.rb +23 -8
- data/lib/livekit/connector_service_client.rb +87 -0
- data/lib/livekit/dial_timeout.rb +26 -0
- data/lib/livekit/egress_service_client.rb +41 -19
- data/lib/livekit/errors.rb +60 -0
- data/lib/livekit/failover.rb +215 -0
- data/lib/livekit/grants.rb +6 -2
- data/lib/livekit/ingress_service_client.rb +8 -6
- data/lib/livekit/livekit_api.rb +67 -0
- data/lib/livekit/proto/livekit_agent_dispatch_pb.rb +3 -1
- data/lib/livekit/proto/livekit_agent_dispatch_twirp.rb +1 -1
- data/lib/livekit/proto/livekit_agent_pb.rb +2 -1
- data/lib/livekit/proto/livekit_agent_twirp.rb +1 -1
- data/lib/livekit/proto/livekit_connector_pb.rb +20 -0
- data/lib/livekit/proto/livekit_connector_twilio_pb.rb +22 -0
- data/lib/livekit/proto/livekit_connector_twilio_twirp.rb +8 -0
- data/lib/livekit/proto/livekit_connector_twirp.rb +21 -0
- data/lib/livekit/proto/livekit_connector_whatsapp_pb.rb +32 -0
- data/lib/livekit/proto/livekit_connector_whatsapp_twirp.rb +8 -0
- data/lib/livekit/proto/livekit_egress_pb.rb +33 -16
- data/lib/livekit/proto/livekit_egress_twirp.rb +6 -5
- data/lib/livekit/proto/livekit_ingress_pb.rb +2 -1
- data/lib/livekit/proto/livekit_ingress_twirp.rb +1 -1
- data/lib/livekit/proto/livekit_metrics_pb.rb +3 -1
- data/lib/livekit/proto/livekit_metrics_twirp.rb +1 -1
- data/lib/livekit/proto/livekit_models_pb.rb +20 -1
- data/lib/livekit/proto/livekit_models_twirp.rb +1 -1
- data/lib/livekit/proto/livekit_room_pb.rb +8 -1
- data/lib/livekit/proto/livekit_room_twirp.rb +4 -1
- data/lib/livekit/proto/livekit_rtc_pb.rb +86 -0
- data/lib/livekit/proto/livekit_rtc_twirp.rb +8 -0
- data/lib/livekit/proto/livekit_sip_pb.rb +20 -1
- data/lib/livekit/proto/livekit_sip_twirp.rb +4 -1
- data/lib/livekit/proto/livekit_webhook_pb.rb +1 -1
- data/lib/livekit/proto/livekit_webhook_twirp.rb +1 -1
- data/lib/livekit/proto/logger/options_pb.rb +19 -0
- data/lib/livekit/proto/logger/options_twirp.rb +8 -0
- data/lib/livekit/room_service_client.rb +31 -13
- data/lib/livekit/sip_service_client.rb +147 -21
- data/lib/livekit/version.rb +1 -1
- data/lib/livekit.rb +3 -0
- data/livekit_server_sdk.gemspec +8 -8
- metadata +59 -32
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5ea2a9dbfe91bc5b18d22b6f5d7003e012f8b12cfbcc8888608a6caf17f2547f
|
|
4
|
+
data.tar.gz: 23b228981cd42c60a7126c069abb2cf0e5d32f0023e503dd245dcaada56597eb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9ace72abe5c36e81223b1da3039d0bee5bde9997c6321a78fbce561ec0a5e2a3c0e0bc4aa4cc54da18b2586d6ea9c0717329808298c06c9d0e64d8f281ad4d42
|
|
7
|
+
data.tar.gz: cad3174b5fa4d01280a943290bb0fc1688ec21eea1c33a09850ad75f8c38988de14715edec40ab4be23cab8f2cdfba0533ee5453d577fa6bbb8ee5448d013f75
|
data/.github/CODEOWNERS
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @livekit/cs-devs
|
data/.github/banner_dark.png
CHANGED
|
Binary file
|
data/.github/banner_light.png
CHANGED
|
Binary file
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Copyright 2026 LiveKit, Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
# Regenerates the vendored protobuf/Twirp stubs (lib/livekit/proto) from the
|
|
16
|
+
# `protocol` submodule and commits them back, so generated code is never
|
|
17
|
+
# produced on a developer's machine. Runs on PRs that bump the submodule (or
|
|
18
|
+
# change the generation task) and commits the regenerated files onto the PR
|
|
19
|
+
# branch; also available on demand.
|
|
20
|
+
|
|
21
|
+
name: Generate Protobufs
|
|
22
|
+
|
|
23
|
+
permissions:
|
|
24
|
+
contents: write
|
|
25
|
+
|
|
26
|
+
on:
|
|
27
|
+
workflow_dispatch:
|
|
28
|
+
pull_request:
|
|
29
|
+
branches: [main]
|
|
30
|
+
paths:
|
|
31
|
+
- "protocol"
|
|
32
|
+
- "Rakefile"
|
|
33
|
+
- ".github/workflows/generate-protobufs.yml"
|
|
34
|
+
|
|
35
|
+
concurrency:
|
|
36
|
+
group: generate-protobufs-${{ github.ref }}
|
|
37
|
+
cancel-in-progress: true
|
|
38
|
+
|
|
39
|
+
jobs:
|
|
40
|
+
generate:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
# Actions cannot push to a fork's branch, so skip generation there. The
|
|
43
|
+
# checked-in files are still validated by the gem's test workflow.
|
|
44
|
+
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository
|
|
45
|
+
steps:
|
|
46
|
+
- name: Checkout code
|
|
47
|
+
uses: actions/checkout@v4
|
|
48
|
+
with:
|
|
49
|
+
submodules: recursive
|
|
50
|
+
# Commit regenerated files back onto the PR branch (or the dispatched branch).
|
|
51
|
+
ref: ${{ github.head_ref || github.ref_name }}
|
|
52
|
+
|
|
53
|
+
- name: Set up Ruby
|
|
54
|
+
uses: ruby/setup-ruby@v1.190.0
|
|
55
|
+
with:
|
|
56
|
+
ruby-version: "3.3"
|
|
57
|
+
bundler-cache: true
|
|
58
|
+
|
|
59
|
+
- name: Set up Go
|
|
60
|
+
uses: actions/setup-go@v5
|
|
61
|
+
with:
|
|
62
|
+
go-version: "1.23"
|
|
63
|
+
|
|
64
|
+
- name: Install protoc
|
|
65
|
+
uses: arduino/setup-protoc@v3
|
|
66
|
+
with:
|
|
67
|
+
version: "30.2"
|
|
68
|
+
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
69
|
+
|
|
70
|
+
- name: Install protoc-gen-twirp_ruby
|
|
71
|
+
run: go install github.com/arthurnn/twirp-ruby/protoc-gen-twirp_ruby@v1.14.1
|
|
72
|
+
|
|
73
|
+
- name: Generate protobufs
|
|
74
|
+
run: |
|
|
75
|
+
export PATH="$(go env GOPATH)/bin:$PATH"
|
|
76
|
+
bundle exec rake proto
|
|
77
|
+
|
|
78
|
+
- name: Commit regenerated protobufs
|
|
79
|
+
uses: stefanzweifel/git-auto-commit-action@v5
|
|
80
|
+
with:
|
|
81
|
+
commit_message: "chore: regenerate protobufs"
|
|
82
|
+
file_pattern: "lib/livekit/proto/**"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Test API
|
|
2
|
+
|
|
3
|
+
permissions:
|
|
4
|
+
contents: read
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
pull_request:
|
|
11
|
+
branches: [main]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
failover:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
services:
|
|
17
|
+
mock-server:
|
|
18
|
+
image: livekit/test-server:latest
|
|
19
|
+
ports:
|
|
20
|
+
- 9999:9999
|
|
21
|
+
- 10000:10000
|
|
22
|
+
- 10001:10001
|
|
23
|
+
- 10002:10002
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout code
|
|
26
|
+
uses: actions/checkout@v4
|
|
27
|
+
|
|
28
|
+
- name: Setup Ruby
|
|
29
|
+
uses: ruby/setup-ruby@v1.190.0
|
|
30
|
+
with:
|
|
31
|
+
ruby-version: "3.3"
|
|
32
|
+
bundler-cache: true
|
|
33
|
+
|
|
34
|
+
- name: Wait for mock server
|
|
35
|
+
run: |
|
|
36
|
+
for i in $(seq 1 30); do
|
|
37
|
+
curl -sf http://127.0.0.1:9999/settings/regions >/dev/null && exit 0
|
|
38
|
+
sleep 1
|
|
39
|
+
done
|
|
40
|
+
echo "mock server did not become ready" && exit 1
|
|
41
|
+
|
|
42
|
+
- name: Run API tests
|
|
43
|
+
run: bundle exec rspec spec/api
|
data/.github/workflows/test.yml
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
on:
|
|
1
|
+
on:
|
|
2
|
+
push:
|
|
3
|
+
branches: [main]
|
|
4
|
+
pull_request:
|
|
2
5
|
name: Test
|
|
3
6
|
jobs:
|
|
4
7
|
test:
|
|
@@ -7,17 +10,17 @@ jobs:
|
|
|
7
10
|
strategy:
|
|
8
11
|
matrix:
|
|
9
12
|
include:
|
|
10
|
-
|
|
11
|
-
- { os: ubuntu-latest, ruby_version: "3.
|
|
13
|
+
# Ruby 3.1 is the floor (google-protobuf 4.x requires >= 3.1; 3.0 is EOL).
|
|
14
|
+
- { os: ubuntu-latest, ruby_version: "3.1" }
|
|
15
|
+
- { os: ubuntu-latest, ruby_version: "3.4" }
|
|
12
16
|
- { os: ubuntu-latest, ruby_version: "jruby-9.4" }
|
|
13
17
|
steps:
|
|
18
|
+
- name: Checkout code
|
|
19
|
+
uses: actions/checkout@v4
|
|
14
20
|
- name: Setup Ruby, JRuby and TruffleRuby
|
|
15
|
-
uses: ruby/setup-ruby@v1.
|
|
21
|
+
uses: ruby/setup-ruby@v1.315.0
|
|
16
22
|
with:
|
|
17
|
-
bundler: 1
|
|
18
23
|
ruby-version: ${{ matrix.ruby_version }}
|
|
19
|
-
- name: Checkout code
|
|
20
|
-
uses: actions/checkout@v2
|
|
21
24
|
- name: Run tests
|
|
22
25
|
run: |
|
|
23
26
|
gem install bundler:2.3.7
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.0.0]
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `LiveKit::LiveKitAPI`, a single entry point exposing every service through a reader (`room`, `egress`, `ingress`, `sip`, `agent_dispatch`, `connector`).
|
|
8
|
+
- Token authentication: construct clients (or `LiveKitAPI`) with a pre-signed `token:` that is sent verbatim, enabling client-side use without an API secret. Credentials fall back to `LIVEKIT_URL`, `LIVEKIT_TOKEN`, `LIVEKIT_API_KEY`, and `LIVEKIT_API_SECRET`.
|
|
9
|
+
- `LiveKit::SipCallError` (a `LiveKit::TwirpError`) raised by SIP dialing calls, exposing `sip_status_code` and `sip_status`.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **Breaking:** service methods now return the response message directly and raise `LiveKit::TwirpError` on failure, instead of returning a `Twirp::ClientResp`. Replace `resp = client.create_room(...); resp.data` with `room = client.create_room(...)`, and rescue `LiveKit::TwirpError` for errors.
|
|
14
|
+
- `faraday` is now a declared runtime dependency.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- `EgressServiceClient` no longer raises when a single output is passed to `start_participant_egress` (the request has no deprecated singular output field).
|
|
19
|
+
- `AgentDispatchServiceClient#get_dispatch` / `#list_dispatch` now return correctly (they previously assumed the RPC returned data directly).
|
|
20
|
+
|
|
3
21
|
## [0.1.0] - 2021-07-25
|
|
4
22
|
|
|
5
23
|
- Initial release
|
data/Gemfile.lock
CHANGED
|
@@ -1,60 +1,91 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
livekit-server-sdk (0.
|
|
5
|
-
|
|
4
|
+
livekit-server-sdk (1.0.0)
|
|
5
|
+
faraday (>= 2.0, < 3.0)
|
|
6
|
+
google-protobuf (~> 4.30, >= 4.30.2)
|
|
6
7
|
jwt (>= 2.2.3, < 3.0)
|
|
7
|
-
|
|
8
|
-
twirp (>= 1.10.0, < 2.0)
|
|
8
|
+
twirp (~> 1.13, >= 1.13.1)
|
|
9
9
|
|
|
10
10
|
GEM
|
|
11
11
|
remote: https://rubygems.org/
|
|
12
12
|
specs:
|
|
13
|
-
base64 (0.
|
|
13
|
+
base64 (0.3.0)
|
|
14
|
+
bigdecimal (4.1.2)
|
|
15
|
+
bigdecimal (4.1.2-java)
|
|
14
16
|
coderay (1.1.3)
|
|
15
|
-
diff-lcs (1.
|
|
16
|
-
faraday (2.
|
|
17
|
-
faraday-net_http (>= 2.0, < 3.
|
|
17
|
+
diff-lcs (1.6.2)
|
|
18
|
+
faraday (2.14.3)
|
|
19
|
+
faraday-net_http (>= 2.0, < 3.5)
|
|
20
|
+
json
|
|
18
21
|
logger
|
|
19
|
-
faraday-net_http (3.
|
|
20
|
-
net-http
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
faraday-net_http (3.4.4)
|
|
23
|
+
net-http (~> 0.5)
|
|
24
|
+
ffi (1.17.4-java)
|
|
25
|
+
ffi-compiler (1.4.2)
|
|
26
|
+
ffi (>= 1.15.5)
|
|
27
|
+
rake
|
|
28
|
+
google-protobuf (4.35.1)
|
|
29
|
+
bigdecimal
|
|
30
|
+
rake (~> 13.3)
|
|
31
|
+
google-protobuf (4.35.1-java)
|
|
32
|
+
bigdecimal
|
|
33
|
+
ffi (~> 1)
|
|
34
|
+
ffi-compiler (~> 1)
|
|
35
|
+
rake (~> 13.3)
|
|
36
|
+
google-protobuf (4.35.1-x86_64-linux-gnu)
|
|
37
|
+
bigdecimal
|
|
38
|
+
rake (~> 13.3)
|
|
39
|
+
io-console (0.8.2)
|
|
40
|
+
io-console (0.8.2-java)
|
|
41
|
+
json (2.20.0)
|
|
42
|
+
json (2.20.0-java)
|
|
43
|
+
jwt (2.10.3)
|
|
23
44
|
base64
|
|
24
|
-
logger (1.
|
|
25
|
-
method_source (1.
|
|
26
|
-
net-http (0.
|
|
27
|
-
uri
|
|
28
|
-
pry (0.
|
|
45
|
+
logger (1.7.0)
|
|
46
|
+
method_source (1.1.0)
|
|
47
|
+
net-http (0.9.1)
|
|
48
|
+
uri (>= 0.11.1)
|
|
49
|
+
pry (0.16.0)
|
|
50
|
+
coderay (~> 1.1)
|
|
51
|
+
method_source (~> 1.0)
|
|
52
|
+
reline (>= 0.6.0)
|
|
53
|
+
pry (0.16.0-java)
|
|
29
54
|
coderay (~> 1.1)
|
|
30
55
|
method_source (~> 1.0)
|
|
31
|
-
|
|
56
|
+
reline (>= 0.6.0)
|
|
57
|
+
spoon (~> 0.0)
|
|
58
|
+
pry-doc (1.7.0)
|
|
32
59
|
pry (~> 0.11)
|
|
33
|
-
yard (~> 0.9.
|
|
34
|
-
rack (3.
|
|
35
|
-
rake (13.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
rspec-
|
|
40
|
-
|
|
41
|
-
rspec-
|
|
42
|
-
rspec-
|
|
60
|
+
yard (~> 0.9.21)
|
|
61
|
+
rack (3.2.6)
|
|
62
|
+
rake (13.4.2)
|
|
63
|
+
reline (0.6.3)
|
|
64
|
+
io-console (~> 0.5)
|
|
65
|
+
rspec (3.13.2)
|
|
66
|
+
rspec-core (~> 3.13.0)
|
|
67
|
+
rspec-expectations (~> 3.13.0)
|
|
68
|
+
rspec-mocks (~> 3.13.0)
|
|
69
|
+
rspec-core (3.13.6)
|
|
70
|
+
rspec-support (~> 3.13.0)
|
|
71
|
+
rspec-expectations (3.13.5)
|
|
43
72
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
44
|
-
rspec-support (~> 3.
|
|
45
|
-
rspec-mocks (3.
|
|
73
|
+
rspec-support (~> 3.13.0)
|
|
74
|
+
rspec-mocks (3.13.8)
|
|
46
75
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
47
|
-
rspec-support (~> 3.
|
|
48
|
-
rspec-support (3.
|
|
49
|
-
|
|
76
|
+
rspec-support (~> 3.13.0)
|
|
77
|
+
rspec-support (3.13.7)
|
|
78
|
+
spoon (0.0.6)
|
|
79
|
+
ffi
|
|
80
|
+
twirp (1.13.1)
|
|
50
81
|
faraday (< 3)
|
|
51
|
-
google-protobuf (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
yard (0.9.
|
|
55
|
-
webrick (~> 1.7.0)
|
|
82
|
+
google-protobuf (>= 3.25, < 5.a)
|
|
83
|
+
rack (>= 2.2.3)
|
|
84
|
+
uri (1.1.1)
|
|
85
|
+
yard (0.9.44)
|
|
56
86
|
|
|
57
87
|
PLATFORMS
|
|
88
|
+
java
|
|
58
89
|
ruby
|
|
59
90
|
x86_64-linux
|
|
60
91
|
|
|
@@ -67,4 +98,4 @@ DEPENDENCIES
|
|
|
67
98
|
yard
|
|
68
99
|
|
|
69
100
|
BUNDLED WITH
|
|
70
|
-
2.
|
|
101
|
+
2.6.9
|
data/README.md
CHANGED
|
@@ -139,12 +139,14 @@ The gem is available as open source under the terms of Apache 2.0 License.
|
|
|
139
139
|
<br/><table>
|
|
140
140
|
<thead><tr><th colspan="2">LiveKit Ecosystem</th></tr></thead>
|
|
141
141
|
<tbody>
|
|
142
|
-
<tr><td>
|
|
142
|
+
<tr><td>Agents SDKs</td><td><a href="https://github.com/livekit/agents">Python</a> · <a href="https://github.com/livekit/agents-js">Node.js</a></td></tr><tr></tr>
|
|
143
|
+
<tr><td>LiveKit SDKs</td><td><a href="https://github.com/livekit/client-sdk-js">Browser</a> · <a href="https://github.com/livekit/client-sdk-swift">Swift</a> · <a href="https://github.com/livekit/client-sdk-android">Android</a> · <a href="https://github.com/livekit/client-sdk-flutter">Flutter</a> · <a href="https://github.com/livekit/client-sdk-react-native">React Native</a> · <a href="https://github.com/livekit/rust-sdks">Rust</a> · <a href="https://github.com/livekit/node-sdks">Node.js</a> · <a href="https://github.com/livekit/python-sdks">Python</a> · <a href="https://github.com/livekit/client-sdk-unity">Unity</a> · <a href="https://github.com/livekit/client-sdk-unity-web">Unity (WebGL)</a> · <a href="https://github.com/livekit/client-sdk-esp32">ESP32</a> · <a href="https://github.com/livekit/client-sdk-cpp">C++</a></td></tr><tr></tr>
|
|
144
|
+
<tr><td>Starter Apps</td><td><a href="https://github.com/livekit-examples/agent-starter-python">Python Agent</a> · <a href="https://github.com/livekit-examples/agent-starter-node">TypeScript Agent</a> · <a href="https://github.com/livekit-examples/agent-starter-react">React App</a> · <a href="https://github.com/livekit-examples/agent-starter-swift">SwiftUI App</a> · <a href="https://github.com/livekit-examples/agent-starter-android">Android App</a> · <a href="https://github.com/livekit-examples/agent-starter-flutter">Flutter App</a> · <a href="https://github.com/livekit-examples/agent-starter-react-native">React Native App</a> · <a href="https://github.com/livekit-examples/agent-starter-embed">Web Embed</a></td></tr><tr></tr>
|
|
145
|
+
<tr><td>UI Components</td><td><a href="https://github.com/livekit/components-js">React</a> · <a href="https://github.com/livekit/components-android">Android Compose</a> · <a href="https://github.com/livekit/components-swift">SwiftUI</a> · <a href="https://github.com/livekit/components-flutter">Flutter</a></td></tr><tr></tr>
|
|
143
146
|
<tr><td>Server APIs</td><td><a href="https://github.com/livekit/node-sdks">Node.js</a> · <a href="https://github.com/livekit/server-sdk-go">Golang</a> · <b>Ruby</b> · <a href="https://github.com/livekit/server-sdk-kotlin">Java/Kotlin</a> · <a href="https://github.com/livekit/python-sdks">Python</a> · <a href="https://github.com/livekit/rust-sdks">Rust</a> · <a href="https://github.com/agence104/livekit-server-sdk-php">PHP (community)</a> · <a href="https://github.com/pabloFuente/livekit-server-sdk-dotnet">.NET (community)</a></td></tr><tr></tr>
|
|
144
|
-
<tr><td>
|
|
145
|
-
<tr><td>
|
|
146
|
-
<tr><td>
|
|
147
|
-
<tr><td>Resources</td><td><a href="https://docs.livekit.io">Docs</a> · <a href="https://github.com/livekit-examples">Example apps</a> · <a href="https://livekit.io/cloud">Cloud</a> · <a href="https://docs.livekit.io/home/self-hosting/deployment">Self-hosting</a> · <a href="https://github.com/livekit/livekit-cli">CLI</a></td></tr>
|
|
147
|
+
<tr><td>Resources</td><td><a href="https://docs.livekit.io">Docs</a> · <a href="https://docs.livekit.io/mcp">Docs MCP Server</a> · <a href="https://github.com/livekit/livekit-cli">CLI</a> · <a href="https://cloud.livekit.io">LiveKit Cloud</a></td></tr><tr></tr>
|
|
148
|
+
<tr><td>LiveKit Server OSS</td><td><a href="https://github.com/livekit/livekit">LiveKit server</a> · <a href="https://github.com/livekit/egress">Egress</a> · <a href="https://github.com/livekit/ingress">Ingress</a> · <a href="https://github.com/livekit/sip">SIP</a></td></tr><tr></tr>
|
|
149
|
+
<tr><td>Community</td><td><a href="https://community.livekit.io">Developer Community</a> · <a href="https://livekit.io/join-slack">Slack</a> · <a href="https://x.com/livekit">X</a> · <a href="https://www.youtube.com/@livekit_io">YouTube</a></td></tr>
|
|
148
150
|
</tbody>
|
|
149
151
|
</table>
|
|
150
152
|
<!--END_REPO_NAV-->
|
data/Rakefile
CHANGED
|
@@ -7,7 +7,7 @@ task default: %i[spec]
|
|
|
7
7
|
|
|
8
8
|
desc "Generate protobuf stubs"
|
|
9
9
|
task :proto do
|
|
10
|
-
system("protoc",
|
|
10
|
+
ok = system("protoc",
|
|
11
11
|
"--proto_path=protocol/protobufs",
|
|
12
12
|
"--ruby_out=lib/livekit/proto",
|
|
13
13
|
"--twirp_ruby_out=lib/livekit/proto",
|
|
@@ -20,5 +20,11 @@ task :proto do
|
|
|
20
20
|
"./protocol/protobufs/livekit_metrics.proto",
|
|
21
21
|
"./protocol/protobufs/livekit_models.proto",
|
|
22
22
|
"./protocol/protobufs/livekit_room.proto",
|
|
23
|
-
"./protocol/protobufs/
|
|
23
|
+
"./protocol/protobufs/livekit_rtc.proto",
|
|
24
|
+
"./protocol/protobufs/livekit_webhook.proto",
|
|
25
|
+
"./protocol/protobufs/livekit_connector.proto",
|
|
26
|
+
"./protocol/protobufs/livekit_connector_twilio.proto",
|
|
27
|
+
"./protocol/protobufs/livekit_connector_whatsapp.proto",
|
|
28
|
+
"./protocol/protobufs/logger/options.proto")
|
|
29
|
+
abort("protoc failed to generate protobuf stubs") unless ok
|
|
24
30
|
end
|
data/bin/bootstrap.sh
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require "livekit/proto/livekit_agent_dispatch_twirp"
|
|
2
2
|
require "livekit/auth_mixin"
|
|
3
3
|
require 'livekit/utils'
|
|
4
|
+
require 'livekit/failover'
|
|
4
5
|
|
|
5
6
|
module LiveKit
|
|
6
7
|
# Client for LiveKit's Agent Dispatch Service, which manages agent assignments to rooms
|
|
@@ -10,10 +11,11 @@ module LiveKit
|
|
|
10
11
|
include AuthMixin
|
|
11
12
|
attr_accessor :api_key, :api_secret
|
|
12
13
|
|
|
13
|
-
def initialize(base_url, api_key: nil, api_secret: nil)
|
|
14
|
-
super(
|
|
14
|
+
def initialize(base_url, api_key: nil, api_secret: nil, token: nil, failover: true, connection: nil)
|
|
15
|
+
super(connection || LiveKit::Failover.connection(base_url, failover))
|
|
15
16
|
@api_key = api_key
|
|
16
17
|
@api_secret = api_secret
|
|
18
|
+
@token = token
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
# Creates a new agent dispatch for a named agent
|
|
@@ -34,7 +36,7 @@ module LiveKit
|
|
|
34
36
|
agent_name: agent_name,
|
|
35
37
|
metadata: metadata,
|
|
36
38
|
)
|
|
37
|
-
|
|
39
|
+
rpc!(
|
|
38
40
|
:CreateDispatch,
|
|
39
41
|
request,
|
|
40
42
|
headers: auth_header(video_grant: VideoGrant.new(roomAdmin: true, room: room_name)),
|
|
@@ -50,10 +52,10 @@ module LiveKit
|
|
|
50
52
|
dispatch_id: dispatch_id,
|
|
51
53
|
room: room_name,
|
|
52
54
|
)
|
|
53
|
-
|
|
55
|
+
rpc!(
|
|
54
56
|
:DeleteDispatch,
|
|
55
57
|
request,
|
|
56
|
-
headers: auth_header(VideoGrant.new(roomAdmin: true, room: room_name)),
|
|
58
|
+
headers: auth_header(video_grant: VideoGrant.new(roomAdmin: true, room: room_name)),
|
|
57
59
|
)
|
|
58
60
|
end
|
|
59
61
|
|
|
@@ -66,10 +68,10 @@ module LiveKit
|
|
|
66
68
|
dispatch_id: dispatch_id,
|
|
67
69
|
room: room_name,
|
|
68
70
|
)
|
|
69
|
-
res =
|
|
71
|
+
res = rpc!(
|
|
70
72
|
:ListDispatch,
|
|
71
73
|
request,
|
|
72
|
-
headers: auth_header(VideoGrant.new(roomAdmin: true, room: room_name)),
|
|
74
|
+
headers: auth_header(video_grant: VideoGrant.new(roomAdmin: true, room: room_name)),
|
|
73
75
|
)
|
|
74
76
|
if res.agent_dispatches.size > 0
|
|
75
77
|
return res.agent_dispatches[0]
|
|
@@ -84,10 +86,10 @@ module LiveKit
|
|
|
84
86
|
request = Proto::ListAgentDispatchRequest.new(
|
|
85
87
|
room: room_name,
|
|
86
88
|
)
|
|
87
|
-
res =
|
|
89
|
+
res = rpc!(
|
|
88
90
|
:ListDispatch,
|
|
89
91
|
request,
|
|
90
|
-
headers: auth_header(VideoGrant.new(roomAdmin: true, room: room_name)),
|
|
92
|
+
headers: auth_header(video_grant: VideoGrant.new(roomAdmin: true, room: room_name)),
|
|
91
93
|
)
|
|
92
94
|
res.agent_dispatches
|
|
93
95
|
end
|
data/lib/livekit/auth_mixin.rb
CHANGED
|
@@ -1,23 +1,38 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "livekit/errors"
|
|
4
|
+
|
|
3
5
|
module LiveKit
|
|
4
|
-
#
|
|
6
|
+
# Shared behavior for the Twirp-based service clients: builds authenticated
|
|
7
|
+
# request headers and issues RPCs that raise on error.
|
|
5
8
|
module AuthMixin
|
|
9
|
+
# Builds request headers. When a pre-signed token is set it is sent verbatim
|
|
10
|
+
# (the caller is responsible for its grants); otherwise a token is signed per
|
|
11
|
+
# call from the API key and secret.
|
|
6
12
|
def auth_header(
|
|
7
13
|
video_grant: nil,
|
|
8
14
|
sip_grant: nil
|
|
9
15
|
)
|
|
10
16
|
headers = {}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
15
|
-
if sip_grant != nil
|
|
16
|
-
t.sip_grant = sip_grant
|
|
17
|
+
if @token
|
|
18
|
+
headers["Authorization"] = "Bearer #{@token}"
|
|
19
|
+
return headers
|
|
17
20
|
end
|
|
21
|
+
|
|
22
|
+
t = ::LiveKit::AccessToken.new(api_key: @api_key, api_secret: @api_secret)
|
|
23
|
+
t.video_grant = video_grant if video_grant != nil
|
|
24
|
+
t.sip_grant = sip_grant if sip_grant != nil
|
|
18
25
|
headers["Authorization"] = "Bearer #{t.to_jwt}"
|
|
19
|
-
headers["User-Agent"] = "LiveKit Ruby SDK"
|
|
20
26
|
headers
|
|
21
27
|
end
|
|
28
|
+
|
|
29
|
+
# Issues a Twirp RPC and returns the response message, raising a
|
|
30
|
+
# {LiveKit::ServerError} (or {LiveKit::SipCallError}) on failure.
|
|
31
|
+
def rpc!(rpc_method, input, headers:)
|
|
32
|
+
resp = rpc(rpc_method, input, headers: headers)
|
|
33
|
+
raise ::LiveKit::ServerError.from(resp.error) if resp.error
|
|
34
|
+
|
|
35
|
+
resp.data
|
|
36
|
+
end
|
|
22
37
|
end
|
|
23
38
|
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require "livekit/proto/livekit_connector_twirp"
|
|
2
|
+
require "livekit/auth_mixin"
|
|
3
|
+
require 'livekit/utils'
|
|
4
|
+
require 'livekit/failover'
|
|
5
|
+
require 'livekit/dial_timeout'
|
|
6
|
+
|
|
7
|
+
module LiveKit
|
|
8
|
+
# Client for LiveKit's Connector service, bridging WhatsApp and Twilio calls
|
|
9
|
+
# into LiveKit rooms.
|
|
10
|
+
#
|
|
11
|
+
# The request types carry many fields, so each method takes a fully-built
|
|
12
|
+
# protobuf request and returns the protobuf response.
|
|
13
|
+
class ConnectorServiceClient < Twirp::Client
|
|
14
|
+
client_for Proto::ConnectorService
|
|
15
|
+
include AuthMixin
|
|
16
|
+
attr_accessor :api_key, :api_secret
|
|
17
|
+
|
|
18
|
+
def initialize(base_url, api_key: nil, api_secret: nil, token: nil, failover: true, connection: nil)
|
|
19
|
+
super(connection || LiveKit::Failover.connection(base_url, failover))
|
|
20
|
+
@api_key = api_key
|
|
21
|
+
@api_secret = api_secret
|
|
22
|
+
@token = token
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Initiates an outbound WhatsApp call.
|
|
26
|
+
# @param request [Proto::DialWhatsAppCallRequest]
|
|
27
|
+
# @return [Proto::DialWhatsAppCallResponse]
|
|
28
|
+
def dial_whatsapp_call(request)
|
|
29
|
+
rpc!(
|
|
30
|
+
:DialWhatsAppCall,
|
|
31
|
+
request,
|
|
32
|
+
headers: auth_header(video_grant: VideoGrant.new(roomCreate: true)),
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Accepts an inbound WhatsApp call.
|
|
37
|
+
# @param request [Proto::AcceptWhatsAppCallRequest]
|
|
38
|
+
# @param timeout [Numeric, nil] optional request timeout in seconds. When the
|
|
39
|
+
# request waits for the inbound party to join, it defaults to the standard
|
|
40
|
+
# ring window.
|
|
41
|
+
# @return [Proto::AcceptWhatsAppCallResponse]
|
|
42
|
+
def accept_whatsapp_call(request, timeout: nil)
|
|
43
|
+
headers = auth_header(video_grant: VideoGrant.new(roomCreate: true))
|
|
44
|
+
# Waiting for the inbound party to join can block, so default the request
|
|
45
|
+
# timeout to the standard ring window; otherwise honor any user timeout.
|
|
46
|
+
if request.wait_until_answered
|
|
47
|
+
headers[Failover::TIMEOUT_HEADER] = (timeout || DialTimeout::DEFAULT_RINGING_TIMEOUT).to_s
|
|
48
|
+
elsif timeout
|
|
49
|
+
headers[Failover::TIMEOUT_HEADER] = timeout.to_s
|
|
50
|
+
end
|
|
51
|
+
rpc!(:AcceptWhatsAppCall, request, headers: headers)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Connects an established WhatsApp call (used for business-initiated calls).
|
|
55
|
+
# @param request [Proto::ConnectWhatsAppCallRequest]
|
|
56
|
+
# @return [Proto::ConnectWhatsAppCallResponse]
|
|
57
|
+
def connect_whatsapp_call(request)
|
|
58
|
+
rpc!(
|
|
59
|
+
:ConnectWhatsAppCall,
|
|
60
|
+
request,
|
|
61
|
+
headers: auth_header(video_grant: VideoGrant.new(roomCreate: true)),
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Disconnects an active WhatsApp call.
|
|
66
|
+
# @param request [Proto::DisconnectWhatsAppCallRequest]
|
|
67
|
+
# @return [Proto::DisconnectWhatsAppCallResponse]
|
|
68
|
+
def disconnect_whatsapp_call(request)
|
|
69
|
+
rpc!(
|
|
70
|
+
:DisconnectWhatsAppCall,
|
|
71
|
+
request,
|
|
72
|
+
headers: auth_header(video_grant: VideoGrant.new(roomCreate: true)),
|
|
73
|
+
)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Connects a Twilio call to a LiveKit room.
|
|
77
|
+
# @param request [Proto::ConnectTwilioCallRequest]
|
|
78
|
+
# @return [Proto::ConnectTwilioCallResponse]
|
|
79
|
+
def connect_twilio_call(request)
|
|
80
|
+
rpc!(
|
|
81
|
+
:ConnectTwilioCall,
|
|
82
|
+
request,
|
|
83
|
+
headers: auth_header(video_grant: VideoGrant.new(roomCreate: true)),
|
|
84
|
+
)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LiveKit
|
|
4
|
+
# Request-timeout handling shared by calls that may block until a call is
|
|
5
|
+
# answered (SIP CreateSIPParticipant/TransferSIPParticipant, WhatsApp
|
|
6
|
+
# AcceptWhatsAppCall). These take longer than a normal request, and the request
|
|
7
|
+
# must outlast the wait or it would abort before the call can be answered.
|
|
8
|
+
module DialTimeout
|
|
9
|
+
# Ring window (seconds) assumed when a request doesn't set a ringing timeout;
|
|
10
|
+
# matches the server default. A dialing request must outlast it.
|
|
11
|
+
DEFAULT_RINGING_TIMEOUT = 30
|
|
12
|
+
# Keep the request timeout at least this many seconds above the ringing
|
|
13
|
+
# timeout, so the request doesn't abort before the call can be answered.
|
|
14
|
+
RINGING_TIMEOUT_MARGIN = 2
|
|
15
|
+
|
|
16
|
+
# Request timeout (seconds): the ring window plus a margin, so the request
|
|
17
|
+
# doesn't abort before the call can be answered. The ring window is
|
|
18
|
+
# +ringing_timeout+ (seconds) when set, else DEFAULT_RINGING_TIMEOUT. A longer
|
|
19
|
+
# user-supplied +timeout+ is honored; a shorter one is raised to the floor.
|
|
20
|
+
def self.resolve(timeout, ringing_timeout)
|
|
21
|
+
ring = ringing_timeout || DEFAULT_RINGING_TIMEOUT
|
|
22
|
+
floor = ring + RINGING_TIMEOUT_MARGIN
|
|
23
|
+
[timeout || floor, floor].max
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|