move livekit client to herolib
This commit is contained in:
7
lib/clients/livekit/.heroscript
Normal file
7
lib/clients/livekit/.heroscript
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
!!hero_code.generate_client
|
||||||
|
name:'livekit'
|
||||||
|
classname:'LivekitClient'
|
||||||
|
singleton:0
|
||||||
|
default:1
|
||||||
|
reset:0
|
||||||
9
lib/clients/livekit/client.v
Normal file
9
lib/clients/livekit/client.v
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
module livekit
|
||||||
|
|
||||||
|
// App struct with `livekit.Client`, API keys, and other shared data
|
||||||
|
pub struct Client {
|
||||||
|
pub:
|
||||||
|
url string @[required]
|
||||||
|
api_key string @[required]
|
||||||
|
api_secret string @[required]
|
||||||
|
}
|
||||||
6
lib/clients/livekit/factory.v
Normal file
6
lib/clients/livekit/factory.v
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
module livekit
|
||||||
|
|
||||||
|
pub fn new(client Client) Client {
|
||||||
|
return Client{...client}
|
||||||
|
}
|
||||||
25
lib/clients/livekit/readme.md
Normal file
25
lib/clients/livekit/readme.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# livekit
|
||||||
|
|
||||||
|
To get started
|
||||||
|
|
||||||
|
```vlang
|
||||||
|
|
||||||
|
import freeflowuniverse.herolib.clients.livekit
|
||||||
|
|
||||||
|
mut client:= livekit.get()!
|
||||||
|
|
||||||
|
client...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## example heroscript
|
||||||
|
|
||||||
|
|
||||||
|
```hero
|
||||||
|
!!livekit.configure
|
||||||
|
livekit_url:''
|
||||||
|
livekit_api_key:''
|
||||||
|
livekit_api_secret:''
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
51
lib/clients/livekit/room.v
Normal file
51
lib/clients/livekit/room.v
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
module livekit
|
||||||
|
|
||||||
|
import net.http
|
||||||
|
import json
|
||||||
|
|
||||||
|
@[params]
|
||||||
|
pub struct ListRoomsParams {
|
||||||
|
names []string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ListRoomsResponse {
|
||||||
|
pub:
|
||||||
|
rooms []Room
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (c Client) list_rooms(params ListRoomsParams) !ListRoomsResponse {
|
||||||
|
// Prepare request body
|
||||||
|
request := params
|
||||||
|
request_json := json.encode(request)
|
||||||
|
|
||||||
|
|
||||||
|
// create token and give grant to list rooms
|
||||||
|
mut token := c.new_access_token()!
|
||||||
|
token.grants.video.room_list = true
|
||||||
|
|
||||||
|
// make POST request
|
||||||
|
url := '${c.url}/twirp/livekit.RoomService/ListRooms'
|
||||||
|
// Configure HTTP request
|
||||||
|
mut headers := http.new_header_from_map({
|
||||||
|
http.CommonHeader.authorization: 'Bearer ${token.to_jwt()!}',
|
||||||
|
http.CommonHeader.content_type: 'application/json'
|
||||||
|
})
|
||||||
|
|
||||||
|
response := http.fetch(http.FetchConfig{
|
||||||
|
url: url
|
||||||
|
method: .post
|
||||||
|
header: headers
|
||||||
|
data: request_json
|
||||||
|
})!
|
||||||
|
|
||||||
|
if response.status_code != 200 {
|
||||||
|
return error('Failed to list rooms: $response.status_code')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse response
|
||||||
|
rooms_response := json.decode(ListRoomsResponse, response.body) or {
|
||||||
|
return error('Failed to parse response: $err')
|
||||||
|
}
|
||||||
|
|
||||||
|
return rooms_response
|
||||||
|
}
|
||||||
33
lib/clients/livekit/room_model.v
Normal file
33
lib/clients/livekit/room_model.v
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
module livekit
|
||||||
|
|
||||||
|
import net.http
|
||||||
|
import json
|
||||||
|
|
||||||
|
pub struct Codec {
|
||||||
|
pub:
|
||||||
|
fmtp_line string
|
||||||
|
mime string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Version {
|
||||||
|
pub:
|
||||||
|
ticks u64
|
||||||
|
unix_micro string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Room {
|
||||||
|
pub:
|
||||||
|
active_recording bool
|
||||||
|
creation_time string
|
||||||
|
departure_timeout int
|
||||||
|
empty_timeout int
|
||||||
|
enabled_codecs []Codec
|
||||||
|
max_participants int
|
||||||
|
metadata string
|
||||||
|
name string
|
||||||
|
num_participants int
|
||||||
|
num_publishers int
|
||||||
|
sid string
|
||||||
|
turn_password string
|
||||||
|
version Version
|
||||||
|
}
|
||||||
22
lib/clients/livekit/room_test.v
Normal file
22
lib/clients/livekit/room_test.v
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
module livekit
|
||||||
|
|
||||||
|
import os
|
||||||
|
import freeflowuniverse.herolib.osal
|
||||||
|
|
||||||
|
fn testsuite_begin() ! {
|
||||||
|
osal.load_env_file('${os.dir(@FILE)}/.env')!
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_test_client() Client {
|
||||||
|
return new(
|
||||||
|
url: os.getenv('LIVEKIT_URL')
|
||||||
|
api_key: os.getenv('LIVEKIT_API_KEY')
|
||||||
|
api_secret: os.getenv('LIVEKIT_API_SECRET')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_client_list_rooms() ! {
|
||||||
|
client := new_test_client()
|
||||||
|
rooms := client.list_rooms()!
|
||||||
|
panic(rooms)
|
||||||
|
}
|
||||||
36
lib/clients/livekit/token.v
Normal file
36
lib/clients/livekit/token.v
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
module livekit
|
||||||
|
|
||||||
|
import time
|
||||||
|
import rand
|
||||||
|
import crypto.hmac
|
||||||
|
import crypto.sha256
|
||||||
|
import encoding.base64
|
||||||
|
import json
|
||||||
|
|
||||||
|
// Define AccessTokenOptions struct
|
||||||
|
@[params]
|
||||||
|
pub struct AccessTokenOptions {
|
||||||
|
pub mut:
|
||||||
|
ttl int | string // TTL in seconds or a time span (e.g., '2d', '5h')
|
||||||
|
name string // Display name for the participant
|
||||||
|
identity string // Identity of the user
|
||||||
|
metadata string // Custom metadata to be passed to participants
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor for AccessToken
|
||||||
|
pub fn (client Client) new_access_token(options AccessTokenOptions) !AccessToken {
|
||||||
|
ttl := if options.ttl is int { options.ttl } else { 21600 } // Default TTL of 6 hours (21600 seconds)
|
||||||
|
|
||||||
|
return AccessToken{
|
||||||
|
api_key: client.api_key
|
||||||
|
api_secret: client.api_secret
|
||||||
|
identity: options.identity
|
||||||
|
ttl: ttl
|
||||||
|
grants: ClaimGrants{
|
||||||
|
exp: time.now().unix()+ttl
|
||||||
|
iss: client.api_key
|
||||||
|
sub: options.name
|
||||||
|
name: options.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
lib/clients/livekit/token_model.v
Normal file
76
lib/clients/livekit/token_model.v
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
module livekit
|
||||||
|
|
||||||
|
import time
|
||||||
|
import rand
|
||||||
|
import crypto.hmac
|
||||||
|
import crypto.sha256
|
||||||
|
import encoding.base64
|
||||||
|
import json
|
||||||
|
|
||||||
|
// Struct representing grants
|
||||||
|
pub struct ClaimGrants {
|
||||||
|
pub mut:
|
||||||
|
video VideoGrant
|
||||||
|
iss string
|
||||||
|
exp i64
|
||||||
|
nbf int
|
||||||
|
sub string
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// VideoGrant struct placeholder
|
||||||
|
pub struct VideoGrant {
|
||||||
|
pub mut:
|
||||||
|
room string
|
||||||
|
room_join bool @[json: 'roomJoin']
|
||||||
|
room_list bool @[json: 'roomList']
|
||||||
|
can_publish bool @[json: 'canPublish']
|
||||||
|
can_publish_data bool @[json: 'canPublishData']
|
||||||
|
can_subscribe bool @[json: 'canSubscribe']
|
||||||
|
}
|
||||||
|
|
||||||
|
// SIPGrant struct placeholder
|
||||||
|
struct SIPGrant {}
|
||||||
|
|
||||||
|
// AccessToken class
|
||||||
|
pub struct AccessToken {
|
||||||
|
mut:
|
||||||
|
api_key string
|
||||||
|
api_secret string
|
||||||
|
grants ClaimGrants
|
||||||
|
identity string
|
||||||
|
ttl int | string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to add a video grant to the token
|
||||||
|
pub fn (mut token AccessToken) add_video_grant(grant VideoGrant) {
|
||||||
|
token.grants.video = grant
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to generate a JWT token
|
||||||
|
pub fn (token AccessToken) to_jwt() !string {
|
||||||
|
// Create JWT payload
|
||||||
|
payload := json.encode(token.grants)
|
||||||
|
|
||||||
|
println('payload: ${payload}')
|
||||||
|
|
||||||
|
// Create JWT header
|
||||||
|
header := '{"alg":"HS256","typ":"JWT"}'
|
||||||
|
|
||||||
|
// Encode header and payload in base64
|
||||||
|
header_encoded := base64.url_encode_str(header)
|
||||||
|
payload_encoded := base64.url_encode_str(payload)
|
||||||
|
|
||||||
|
// Create the unsigned token
|
||||||
|
unsigned_token := '${header_encoded}.${payload_encoded}'
|
||||||
|
|
||||||
|
// Create the HMAC-SHA256 signature
|
||||||
|
signature := hmac.new(token.api_secret.bytes(), unsigned_token.bytes(), sha256.sum, sha256.block_size)
|
||||||
|
|
||||||
|
// Encode the signature in base64
|
||||||
|
signature_encoded := base64.url_encode(signature)
|
||||||
|
|
||||||
|
// Create the final JWT
|
||||||
|
jwt := '${unsigned_token}.${signature_encoded}'
|
||||||
|
return jwt
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user